Merge
authorohair
Wed, 26 Mar 2008 17:48:05 -0700
changeset 143 583cac727433
parent 142 f78032e8a30b (current diff)
parent 104 94a4cf011510 (diff)
child 144 8d655ddd5a03
child 304 defb1d0d07df
Merge
--- a/jdk/make/java/java/mapfile-vers	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/make/java/java/mapfile-vers	Wed Mar 26 17:48:05 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/jdk/make/java/jli/Makefile	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/make/java/jli/Makefile	Wed Mar 26 17:48:05 2008 -0700
@@ -107,6 +107,7 @@
 
 ifeq ($(PLATFORM), windows)
 	EXTRA_LIBS = advapi32.lib \
+		     comctl32.lib \
 		     user32.lib
 
 	JAVALIB =
--- a/jdk/make/java/main/java/Makefile	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/make/java/main/java/Makefile	Wed Mar 26 17:48:05 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/jdk/make/java/main/javaw/Makefile	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/make/java/main/javaw/Makefile	Wed Mar 26 17:48:05 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/jdk/make/tools/src/build/tools/jdwpgen/CommandNode.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/make/tools/src/build/tools/jdwpgen/CommandNode.java	Wed Mar 26 17:48:05 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/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/make/tools/src/build/tools/jdwpgen/ConstantSetNode.java	Wed Mar 26 17:48:05 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/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/make/tools/src/build/tools/jdwpgen/RepeatNode.java	Wed Mar 26 17:48:05 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/jdk/src/share/bin/java.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/bin/java.c	Wed Mar 26 17:48:05 2008 -0700
@@ -205,9 +205,7 @@
     _wc_enabled = cpwildcard;
     _ergo_policy = ergo;
 
-    if (javaw == JNI_TRUE)
-        SetJavaw();
-
+    InitLauncher(javaw);
     DumpState();
 
     /*
--- a/jdk/src/share/bin/java.h	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/bin/java.h	Wed Mar 26 17:48:05 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/jdk/src/share/bin/main.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/bin/main.c	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpec.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/EventRequestSpecList.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ExecutionManager.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/LineBreakpointSpec.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/MethodBreakpointSpec.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadGroupIterator.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/bdi/ThreadIterator.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/ClassTreeTool.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/CommandInterpreter.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/JDBFileFilter.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/LaunchTool.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SearchPath.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceManager.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/SourceModel.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/StackTraceTool.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/gui/ThreadTreeTool.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/Commands.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/Env.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/Env.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventHandler.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpec.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/EventRequestSpecList.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/SourceMapper.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/TTY.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/TTY.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadGroupIterator.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadInfo.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/ThreadIterator.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/tty/VMConnection.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/ClassQuery.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/hat/internal/server/PlatformClasses.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/AbstractLauncher.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ConcreteMethodImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/EventSetImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/EventSetImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/JNITypeParser.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/JNITypeParser.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/PacketStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/PacketStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/SDE.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/SDE.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/StackFrameImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/TargetVM.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/TargetVM.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ThreadGroupReferenceImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/io/FileInputStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/io/FileInputStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/io/FileOutputStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/io/FileOutputStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/io/ObjectInputStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/io/ObjectStreamClass.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/Class.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/Class.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/ClassLoader.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/Compiler.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/Compiler.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/Long.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/Long.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/Package.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/Package.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/Process.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/Process.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/ProcessBuilder.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/ProcessBuilder.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/StringCoding.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/StringCoding.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/ref/Finalizer.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/ref/Finalizer.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/reflect/Modifier.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Modifier.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/lang/reflect/Proxy.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/Proxy.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/DatagramSocket.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/DatagramSocket.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/InterfaceAddress.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/InterfaceAddress.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/NetworkInterface.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/NetworkInterface.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/ServerSocket.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/ServerSocket.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/Socket.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/Socket.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/SocksSocketImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/SocksSocketImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/URLClassLoader.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/URLClassLoader.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/net/URLConnection.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/net/URLConnection.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/nio/StringCharBuffer.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/nio/StringCharBuffer.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/nio/channels/Channels.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/nio/channels/Channels.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/nio/channels/spi/SelectorProvider.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/nio/charset/Charset.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/nio/charset/Charset.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/rmi/activation/ActivationGroupDesc.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/rmi/activation/ActivationGroupDesc.java	Wed Mar 26 17:48:05 2008 -0700
@@ -263,7 +263,7 @@
          * @since 1.2
          */
         public String[] getCommandOptions() {
-            return (String[]) options.clone();
+            return options.clone();
         }
 
         /**
--- a/jdk/src/share/classes/java/rmi/dgc/VMID.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/rmi/dgc/VMID.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/security/AccessControlContext.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/security/AccessControlContext.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/security/KeyStore.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/security/KeyStore.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/security/cert/TrustAnchor.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/security/cert/TrustAnchor.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/security/cert/X509CertSelector.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/security/cert/X509CertSelector.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/ArrayList.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/ArrayList.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/Arrays.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/Arrays.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/EnumMap.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/EnumMap.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/HashMap.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/HashMap.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/Hashtable.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/Hashtable.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/IdentityHashMap.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/IdentityHashMap.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/JumboEnumSet.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/JumboEnumSet.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/Random.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/Random.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/TreeSet.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/TreeSet.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/Vector.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/Vector.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/WeakHashMap.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/WeakHashMap.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/concurrent/DelayQueue.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/DelayQueue.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/concurrent/ExecutorService.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ExecutorService.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/prefs/AbstractPreferences.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/prefs/Preferences.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/prefs/Preferences.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/java/util/regex/Matcher.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/java/util/regex/Matcher.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/AndQueryExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/AndQueryExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/AttributeValueExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/AttributeValueExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/BetweenQueryExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/BetweenQueryExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/BinaryOpValueExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/BinaryOpValueExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/BooleanValueExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/BooleanValueExp.java	Wed Mar 26 17:48:05 2008 -0700
@@ -84,4 +84,10 @@
         return this;
     }
 
+    @Deprecated
+    public void setMBeanServer(MBeanServer s) {
+        super.setMBeanServer(s);
+    }
+
+
  }
--- a/jdk/src/share/classes/javax/management/InQueryExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/InQueryExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/MatchQueryExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/MatchQueryExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/NotQueryExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/NotQueryExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/NumericValueExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/NumericValueExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/ObjectName.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/ObjectName.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/OrQueryExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/OrQueryExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/QualifiedAttributeValueExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/QualifiedAttributeValueExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/Query.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/Query.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/QueryEval.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/QueryEval.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/QueryExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/QueryExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/QueryParser.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/StringValueExp.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/StringValueExp.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/ToQueryString.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/monitor/Monitor.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/monitor/Monitor.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/management/remote/JMXServiceURL.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/rmi/ssl/SslRMIClientSocketFactory.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/rmi/ssl/SslRMIServerSocketFactory.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KerberosTicket.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/javax/security/cert/X509Certificate.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/javax/security/cert/X509Certificate.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/management/ConnectorAddressLink.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/management/ConnectorAddressLink.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/management/snmp/jvminstr/JvmMemPoolEntryImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/ClassFileTransformer.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/ClassFileTransformer.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/Cleaner.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/Cleaner.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/ExtensionDependency.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/ExtensionDependency.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/GC.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/GC.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/JavaIOFileDescriptorAccess.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/Launcher.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/Launcher.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/PerformanceLogger.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/PerformanceLogger.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/ProxyGenerator.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/ProxyGenerator.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/misc/URLClassPath.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/misc/URLClassPath.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/NetProperties.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/NetProperties.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/NetworkClient.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/NetworkClient.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/ftp/FtpClient.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/ftp/FtpClient.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/MessageHeader.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/MessageHeader.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/MimeTable.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/MimeTable.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/http/ChunkedOutputStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/http/ChunkedOutputStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/http/HttpClient.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveCache.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/jar/URLJarFile.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/nio/ch/Reflect.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/Reflect.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/nio/ch/Util.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/Util.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/reflect/ClassDefiner.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/reflect/ClassDefiner.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/reflect/MethodAccessorGenerator.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/reflect/MethodAccessorGenerator.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/reflect/ReflectionFactory.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/reflect/ReflectionFactory.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/reflect/misc/MethodUtil.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/log/ReliableLog.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/log/ReliableLog.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/rmic/RemoteClass.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/rmic/RemoteClass.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/rmic/newrmic/jrmp/RemoteClass.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/runtime/Log.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/runtime/Log.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/server/MarshalOutputStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/server/MarshalOutputStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/server/Util.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/server/Util.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/transport/DGCClient.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/transport/DGCClient.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/transport/Target.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/transport/Target.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/transport/Transport.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/transport/Transport.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/GSSManagerImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/Config.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/APRep.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/APRep.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/APReq.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/APReq.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/ASRep.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ASRep.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/ASReq.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ASReq.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/Authenticator.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/Authenticator.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationData.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/AuthorizationDataEntry.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ETypeInfo2.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncAPRepPart.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncASRepPart.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncKDCRepPart.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncKrbCredPart.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncKrbPrivPart.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncTGSRepPart.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/EncTicketPart.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/EncTicketPart.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/KDCRep.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/KDCRep.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/KDCReq.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/KRBCred.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/KRBCred.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/KrbCredInfo.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/Credentials.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/AesDkCrypto.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/crypto/dk/ArcFourCrypto.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/CipherSuite.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/DHCrypt.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/DHCrypt.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/Handshaker.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/InputRecord.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/InputRecord.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/JsseJce.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/OutputRecord.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/OutputRecord.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/ProtocolList.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/ProtocolList.java	Wed Mar 26 17:48:05 2008 -0700
@@ -98,7 +98,7 @@
                 protocolNames[i++] = version.name;
             }
         }
-        return (String[])protocolNames.clone();
+        return protocolNames.clone();
     }
 
     public String toString() {
--- a/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/SessionId.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SessionId.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SunX509KeyManagerImpl.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/x509/AVA.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/x509/AVA.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/x509/CertificatePolicySet.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/x509/CertificatePolicySet.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/security/x509/X509Cert.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/security/x509/X509Cert.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jar/JarVerifierStream.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBean.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBean.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanOperations.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextFieldEditor.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java	Wed Mar 26 17:48:05 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/jdk/src/share/classes/sun/tools/native2ascii/N2AFilter.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/classes/sun/tools/native2ascii/N2AFilter.java	Wed Mar 26 17:48:05 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/jdk/src/share/native/java/io/io_util.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/share/native/java/io/io_util.c	Wed Mar 26 17:48:05 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/jdk/src/solaris/bin/java_md.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/bin/java_md.c	Wed Mar 26 17:48:05 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/jdk/src/solaris/classes/java/io/FileDescriptor.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/classes/java/io/FileDescriptor.java	Wed Mar 26 17:48:05 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/jdk/src/solaris/classes/java/lang/ProcessImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/classes/java/lang/ProcessImpl.java	Wed Mar 26 17:48:05 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/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.linux	Wed Mar 26 17:48:05 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/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java.solaris	Wed Mar 26 17:48:05 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/jdk/src/solaris/classes/java/net/PlainSocketImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/classes/java/net/PlainSocketImpl.java	Wed Mar 26 17:48:05 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/jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/classes/java/util/prefs/FileSystemPreferences.java	Wed Mar 26 17:48:05 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/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java	Wed Mar 26 17:48:05 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/jdk/src/solaris/classes/sun/security/provider/NativePRNG.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/classes/sun/security/provider/NativePRNG.java	Wed Mar 26 17:48:05 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/jdk/src/solaris/native/java/io/FileOutputStream_md.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/native/java/io/FileOutputStream_md.c	Wed Mar 26 17:48:05 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/jdk/src/solaris/native/java/lang/UNIXProcess_md.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/native/java/lang/UNIXProcess_md.c	Wed Mar 26 17:48:05 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/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c	Wed Mar 26 17:48:05 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/jdk/src/windows/bin/java_md.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/bin/java_md.c	Wed Mar 26 17:48:05 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/jdk/src/windows/classes/java/io/FileDescriptor.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/classes/java/io/FileDescriptor.java	Wed Mar 26 17:48:05 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/jdk/src/windows/classes/java/lang/ProcessImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java	Wed Mar 26 17:48:05 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/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java	Wed Mar 26 17:48:05 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/jdk/src/windows/classes/java/net/PlainSocketImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/classes/java/net/PlainSocketImpl.java	Wed Mar 26 17:48:05 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/jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/classes/java/net/TwoStacksPlainSocketImpl.java	Wed Mar 26 17:48:05 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/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Wed Mar 26 17:48:05 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/jdk/src/windows/native/java/io/FileOutputStream_md.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/native/java/io/FileOutputStream_md.c	Wed Mar 26 17:48:05 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/jdk/src/windows/native/java/io/io_util_md.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/native/java/io/io_util_md.c	Wed Mar 26 17:48:05 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/jdk/src/windows/native/java/io/io_util_md.h	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/native/java/io/io_util_md.h	Wed Mar 26 17:48:05 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/jdk/src/windows/native/java/lang/ProcessImpl_md.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c	Wed Mar 26 17:48:05 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/jdk/src/windows/native/java/lang/java_props_md.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/native/java/lang/java_props_md.c	Wed Mar 26 17:48:05 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/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/native/sun/net/www/protocol/http/NTLMAuthSequence.c	Wed Mar 26 17:48:05 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/jdk/src/windows/native/sun/security/krb5/NativeCreds.c	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/src/windows/native/sun/security/krb5/NativeCreds.c	Wed Mar 26 17:48:05 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;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/KeyFactory/TestProviderLeak.java	Wed Mar 26 17:48:05 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/jdk/test/java/io/FileOutputStream/AtomicAppend.java	Wed Mar 26 17:48:05 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/jdk/test/java/lang/ProcessBuilder/Basic.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java	Wed Mar 26 17:48:05 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/jdk/test/java/net/CookieHandler/CookieManagerTest.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/java/net/CookieHandler/CookieManagerTest.java	Wed Mar 26 17:48:05 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/jdk/test/java/net/InterfaceAddress/Equals.java	Wed Mar 26 17:48:05 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/jdk/test/java/net/ResponseCache/file2.1	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/java/net/ResponseCache/file2.1	Wed Mar 26 17:48:05 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/jdk/test/java/nio/Buffer/StringCharBufferSliceTest.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/java/nio/Buffer/StringCharBufferSliceTest.java	Wed Mar 26 17:48:05 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/jdk/test/java/nio/channels/Channels/ShortWrite.java	Wed Mar 26 17:48:05 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/jdk/test/java/nio/channels/TestUtil.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/java/nio/channels/TestUtil.java	Wed Mar 26 17:48:05 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/jdk/test/java/security/AccessControlContext/FailureDebugOption.java	Wed Mar 26 17:48:05 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/jdk/test/java/util/Map/LockStep.java	Wed Mar 26 17:48:05 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/jdk/test/java/util/concurrent/DelayQueue/Stress.java	Wed Mar 26 17:48:05 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/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/java/util/concurrent/LinkedBlockingQueue/OfferRemoveLoops.java	Wed Mar 26 17:48:05 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/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java	Wed Mar 26 17:48:05 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/jdk/test/java/util/concurrent/ScheduledThreadPoolExecutor/Stress.java	Wed Mar 26 17:48:05 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/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/java/util/concurrent/SynchronousQueue/Fairness.java	Wed Mar 26 17:48:05 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/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/java/util/concurrent/locks/ReentrantReadWriteLock/Count.java	Wed Mar 26 17:48:05 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/jdk/test/javax/management/mxbean/JMXServiceURLTest.java	Wed Mar 26 17:48:05 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/jdk/test/javax/management/query/QueryDottedAttrTest.java	Wed Mar 26 17:48:05 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/jdk/test/javax/management/query/QueryExpStringTest.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/javax/management/query/QueryExpStringTest.java	Wed Mar 26 17:48:05 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/jdk/test/javax/management/query/QueryParseTest.java	Wed Mar 26 17:48:05 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/jdk/test/javax/security/auth/x500/X500Principal/RFC4514.java	Wed Mar 26 17:48:05 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/jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java	Wed Mar 26 17:48:05 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/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/sun/net/www/http/ChunkedOutputStream/Test.java	Wed Mar 26 17:48:05 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/jdk/test/sun/net/www/protocol/http/B6641309.java	Wed Mar 26 17:48:05 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/jdk/test/sun/net/www/protocol/http/B6660405.java	Wed Mar 26 17:48:05 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/jdk/test/sun/security/krb5/DnsFallback.java	Wed Mar 26 17:48:05 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/jdk/test/sun/security/krb5/OptionPADataInKDCReq.java	Wed Mar 26 17:48:05 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/jdk/test/sun/security/krb5/TimeInCCache.java	Wed Mar 26 17:48:05 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/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java	Wed Mar 26 17:48:05 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/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java	Wed Mar 26 17:48:05 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/jdk/test/sun/security/tools/keytool/StartDateTest.java	Tue Mar 25 14:40:43 2008 -0700
+++ b/jdk/test/sun/security/tools/keytool/StartDateTest.java	Wed Mar 26 17:48:05 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();