Merge
authorlana
Thu, 09 Jun 2016 19:07:27 +0000
changeset 38872 b260c7cac3bc
parent 38851 7fb69ea0a328 (current diff)
parent 38871 ec08bf1979d4 (diff)
child 38873 0d1f3f5d7898
Merge
jdk/src/java.httpclient/share/classes/java/net/http/WSDisposableText.java
jdk/test/sun/security/provider/SecureRandom/AbstractDrbgSpec.java
--- a/jdk/src/java.base/share/classes/java/lang/System.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/System.java	Thu Jun 09 19:07:27 2016 +0000
@@ -1942,6 +1942,10 @@
      * the application classpath or modulepath.
      */
     private static void initPhase3() {
+        // Initialize publicLookup early, to avoid bootstrapping circularities
+        // with security manager using java.lang.invoke infrastructure.
+        java.lang.invoke.MethodHandles.publicLookup();
+
         // set security manager
         String cn = System.getProperty("java.security.manager");
         if (cn != null) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Jun 09 19:07:27 2016 +0000
@@ -2204,15 +2204,7 @@
             }
         }
 
-        private static final Class<?> PUBLIC_LOOKUP_CLASS;
-        static {
-            PrivilegedAction<Class<?>> pa = new PrivilegedAction<Class<?>>() {
-                public Class<?> run() {
-                    return createClass();
-                }
-            };
-            PUBLIC_LOOKUP_CLASS = AccessController.doPrivileged(pa);
-        }
+        private static final Class<?> PUBLIC_LOOKUP_CLASS = createClass();
 
         /**
          * Lookup that is trusted minimally. It can only be used to create
--- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Thu Jun 09 19:07:27 2016 +0000
@@ -1733,41 +1733,32 @@
             // no instantiation
         }
 
-        // This one is deliberately non-lambdified to optimize startup time:
-        private static final Function<Class<?>, MethodHandle> MOST = new Function<Class<?>, MethodHandle>() {
+        private static class StringifierMost extends ClassValue<MethodHandle> {
             @Override
-            public MethodHandle apply(Class<?> cl) {
-                MethodHandle mhObject = lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, Object.class);
-
-                // We need the additional conversion here, because String.valueOf(Object) may return null.
-                // String conversion rules in Java state we need to produce "null" String in this case.
-                // It can be easily done with applying valueOf the second time.
-                MethodHandle mhObjectNoNulls = MethodHandles.filterReturnValue(mhObject,
-                        mhObject.asType(MethodType.methodType(String.class, String.class)));
-
+            protected MethodHandle computeValue(Class<?> cl) {
                 if (cl == String.class) {
-                    return mhObject;
+                    return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, Object.class);
                 } else if (cl == float.class) {
                     return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, float.class);
                 } else if (cl == double.class) {
                     return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, double.class);
                 } else if (!cl.isPrimitive()) {
-                    return mhObjectNoNulls;
+                    MethodHandle mhObject = lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, Object.class);
+
+                    // We need the additional conversion here, because String.valueOf(Object) may return null.
+                    // String conversion rules in Java state we need to produce "null" String in this case.
+                    // It can be easily done with applying valueOf the second time.
+                    return MethodHandles.filterReturnValue(mhObject,
+                            mhObject.asType(MethodType.methodType(String.class, String.class)));
                 }
 
                 return null;
             }
-        };
+        }
 
-        // This one is deliberately non-lambdified to optimize startup time:
-        private static final Function<Class<?>, MethodHandle> ANY = new Function<Class<?>, MethodHandle>() {
+        private static class StringifierAny extends ClassValue<MethodHandle> {
             @Override
-            public MethodHandle apply(Class<?> cl) {
-                MethodHandle mh = MOST.apply(cl);
-                if (mh != null) {
-                    return mh;
-                }
-
+            protected MethodHandle computeValue(Class<?> cl) {
                 if (cl == byte.class || cl == short.class || cl == int.class) {
                     return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, int.class);
                 } else if (cl == boolean.class) {
@@ -1777,13 +1768,18 @@
                 } else if (cl == long.class) {
                     return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, long.class);
                 } else {
-                    throw new IllegalStateException("Unknown class: " + cl);
+                    MethodHandle mh = STRINGIFIERS_MOST.get(cl);
+                    if (mh != null) {
+                        return mh;
+                    } else {
+                        throw new IllegalStateException("Unknown class: " + cl);
+                    }
                 }
             }
-        };
+        }
 
-        private static final ConcurrentMap<Class<?>, MethodHandle> STRINGIFIERS_MOST = new ConcurrentHashMap<>();
-        private static final ConcurrentMap<Class<?>, MethodHandle> STRINGIFIERS_ANY = new ConcurrentHashMap<>();
+        private static final ClassValue<MethodHandle> STRINGIFIERS_MOST = new StringifierMost();
+        private static final ClassValue<MethodHandle> STRINGIFIERS_ANY = new StringifierAny();
 
         /**
          * Returns a stringifier for references and floats/doubles only.
@@ -1793,7 +1789,7 @@
          * @return stringifier; null, if not available
          */
         static MethodHandle forMost(Class<?> t) {
-            return STRINGIFIERS_MOST.computeIfAbsent(t, MOST);
+            return STRINGIFIERS_MOST.get(t);
         }
 
         /**
@@ -1803,7 +1799,7 @@
          * @return stringifier
          */
         static MethodHandle forAny(Class<?> t) {
-            return STRINGIFIERS_ANY.computeIfAbsent(t, ANY);
+            return STRINGIFIERS_ANY.get(t);
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/net/URI.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URI.java	Thu Jun 09 19:07:27 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -92,9 +92,9 @@
  * URIs are:
  *
  * <blockquote>
- * {@code http://java.sun.com/j2se/1.3/}<br>
- * {@code docs/guide/collections/designfaq.html#28}<br>
- * {@code ../../../demo/jfc/SwingSet2/src/SwingSet2.java}<br>
+ * {@code http://example.com/languages/java/}<br>
+ * {@code sample/a/index.html#28}<br>
+ * {@code ../../demo/b/index.html}<br>
  * {@code file:///~/calendar}
  * </blockquote>
  *
@@ -178,28 +178,28 @@
  * normalized.  The result, for example, of resolving
  *
  * <blockquote>
- * {@code docs/guide/collections/designfaq.html#28}
+ * {@code sample/a/index.html#28}
  * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  * &nbsp;&nbsp;&nbsp;&nbsp;(1)
  * </blockquote>
  *
- * against the base URI {@code http://java.sun.com/j2se/1.3/} is the result
+ * against the base URI {@code http://example.com/languages/java/} is the result
  * URI
  *
  * <blockquote>
- * {@code http://docs.oracle.com/javase/1.3/docs/guide/collections/designfaq.html#28}
+ * {@code http://example.com/languages/java/sample/a/index.html#28}
  * </blockquote>
  *
  * Resolving the relative URI
  *
  * <blockquote>
- * {@code ../../../demo/jfc/SwingSet2/src/SwingSet2.java}&nbsp;&nbsp;&nbsp;&nbsp;(2)
+ * {@code ../../demo/b/index.html}&nbsp;&nbsp;&nbsp;&nbsp;(2)
  * </blockquote>
  *
  * against this result yields, in turn,
  *
  * <blockquote>
- * {@code http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java}
+ * {@code http://example.com/languages/java/demo/b/index.html}
  * </blockquote>
  *
  * Resolution of both absolute and relative URIs, and of both absolute and
@@ -210,7 +210,7 @@
  * URI
  *
  * <blockquote>
- * {@code demo/jfc/SwingSet2/src/SwingSet2.java}
+ * {@code demo/b/index.html}
  * </blockquote>
  *
  * <p> <i>Relativization</i>, finally, is the inverse of resolution: For any
@@ -226,16 +226,16 @@
  * possible.  For example, relativizing the URI
  *
  * <blockquote>
- * {@code http://docs.oracle.com/javase/1.3/docs/guide/index.html}
+ * {@code http://example.com/languages/java/sample/a/index.html#28}
  * </blockquote>
  *
  * against the base URI
  *
  * <blockquote>
- * {@code http://java.sun.com/j2se/1.3}
+ * {@code http://example.com/languages/java/}
  * </blockquote>
  *
- * yields the relative URI {@code docs/guide/index.html}.
+ * yields the relative URI {@code sample/a/index.html#28}.
  *
  *
  * <h4> Character categories </h4>
--- a/jdk/src/java.base/share/classes/java/security/SecureRandomParameters.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandomParameters.java	Thu Jun 09 19:07:27 2016 +0000
@@ -33,6 +33,7 @@
  * can be passed to those implementations that support them.
  *
  * @see DrbgParameters
+ * @since 9
  */
 public interface SecureRandomParameters {
 }
--- a/jdk/src/java.base/share/classes/java/util/Locale.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java	Thu Jun 09 19:07:27 2016 +0000
@@ -2858,6 +2858,8 @@
          * @param range a language range
          * @throws NullPointerException if the given {@code range} is
          *     {@code null}
+         * @throws IllegalArgumentException if the given {@code range} does not
+         * comply with the syntax of the language range mentioned in RFC 4647
          */
         public LanguageRange(String range) {
             this(range, MAX_WEIGHT);
@@ -2873,8 +2875,10 @@
          *     {@code MAX_WEIGHT}
          * @throws NullPointerException if the given {@code range} is
          *     {@code null}
-         * @throws IllegalArgumentException if the given {@code weight} is less
-         *     than {@code MIN_WEIGHT} or greater than {@code MAX_WEIGHT}
+         * @throws IllegalArgumentException if the given {@code range} does not
+         * comply with the syntax of the language range mentioned in RFC 4647
+         * or if the given {@code weight} is less than {@code MIN_WEIGHT}
+         * or greater than {@code MAX_WEIGHT}
          */
         public LanguageRange(String range, double weight) {
             if (range == null) {
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java	Thu Jun 09 19:07:27 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -118,16 +118,22 @@
         members = new HashMap<>(methods.length+1, 1.0f);
 
         for (Method method : methods) {
-            if (method.getParameterTypes().length != 0)
-                throw new IllegalArgumentException(method + " has params");
-            String name = method.getName();
-            Class<?> type = method.getReturnType();
-            memberTypes.put(name, invocationHandlerReturnType(type));
-            members.put(name, method);
+            if (Modifier.isPublic(method.getModifiers()) &&
+                Modifier.isAbstract(method.getModifiers()) &&
+                !method.isSynthetic()) {
+                if (method.getParameterTypes().length != 0) {
+                    throw new IllegalArgumentException(method + " has params");
+                }
+                String name = method.getName();
+                Class<?> type = method.getReturnType();
+                memberTypes.put(name, invocationHandlerReturnType(type));
+                members.put(name, method);
 
-            Object defaultValue = method.getDefaultValue();
-            if (defaultValue != null)
-                memberDefaults.put(name, defaultValue);
+                Object defaultValue = method.getDefaultValue();
+                if (defaultValue != null) {
+                    memberDefaults.put(name, defaultValue);
+                }
+            }
         }
 
         // Initialize retention, & inherited fields.  Special treatment
--- a/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java	Thu Jun 09 19:07:27 2016 +0000
@@ -33,12 +33,13 @@
 import static java.security.DrbgParameters.Capability.*;
 
 /**
- * The abstract base class for all DRBGs.
+ * The abstract base class for all DRBGs. It is used as {@link DRBG#impl}.
  * <p>
- * This class creates 5 new abstract methods. 3 are defined by the SP800-90A:
+ * This class has 5 abstract methods. 3 are defined by SP800-90A:
  * <ol>
  *  <li>{@link #generateAlgorithm(byte[], byte[])}
- *  <li>{@link #reseedAlgorithm(byte[], byte[])} (might not be supported)
+ *  <li>{@link #reseedAlgorithm(byte[], byte[])} (In fact this is not an
+ *      abstract method, but any DRBG supporting reseeding must override it.)
  *  <li>{@link #instantiateAlgorithm(byte[])}
  * </ol>
  * and 2 for implementation purpose:
@@ -46,18 +47,19 @@
  *  <li>{@link #initEngine()}
  *  <li>{@link #chooseAlgorithmAndStrength}
  * </ol>
- * All existing {@link SecureRandomSpi} methods are implemented based on the
- * methods above as final. The initialization process is divided into 2 phases:
- * configuration is eagerly called to set up parameters, and instantiation
- * is lazily called only when nextBytes or reseed is called.
+ * Although this class is not a child class of {@link SecureRandomSpi}, it
+ * implements all abstract methods there as final.
+ * <p>
+ * The initialization process of a DRBG is divided into 2 phases:
+ * {@link #configure configuration} is eagerly called to set up parameters,
+ * and {@link #instantiateIfNecessary instantiation} is lazily called only
+ * when nextBytes or reseed is called.
  * <p>
  * SecureRandom methods like reseed and nextBytes are not thread-safe.
  * An implementation is required to protect shared access to instantiate states
- * (instantiated, nonce) and DRBG states (v, c, key, reseedCounter).
+ * (instantiated, nonce) and DRBG states (v, c, key, reseedCounter, etc).
  */
-public abstract class AbstractDrbg extends SecureRandomSpi {
-
-    private static final long serialVersionUID = 9L;
+public abstract class AbstractDrbg {
 
     /**
      * This field is not null if {@code -Djava.security.debug=securerandom} is
@@ -69,7 +71,7 @@
 
     // Common working status
 
-    private transient boolean instantiated = false;
+    private boolean instantiated = false;
 
     /**
      * Reseed counter of a DRBG instance. A mechanism should increment it
@@ -78,7 +80,7 @@
      *
      * Volatile, will be used in a double checked locking.
      */
-    protected transient volatile int reseedCounter = 0;
+    protected volatile int reseedCounter = 0;
 
     // Mech features. If not same as below, must be redefined in constructor.
 
@@ -170,7 +172,7 @@
     /**
      * Algorithm used by this instance (SHA-512 or AES-256). Must be assigned
      * in {@link #chooseAlgorithmAndStrength}. This field is used in
-     * {@link #toString()} and {@link DRBG#algorithmName}.
+     * {@link #toString()}.
      */
     protected String algorithm;
 
@@ -217,7 +219,7 @@
      * After instantiation, this field is not null. Do not modify it
      * in a mechanism.
      */
-    protected transient byte[] nonce;
+    protected byte[] nonce;
 
     /**
      * Requested nonce in {@link MoreDrbgParameters}. If set to null,
@@ -237,7 +239,7 @@
      * {@link #configure(SecureRandomParameters)}. This field
      * can be null. {@link #getEntropyInput} will take care of null check.
      */
-    private transient EntropySource es;
+    private EntropySource es;
 
     // Five abstract methods for SP 800-90A DRBG
 
@@ -286,10 +288,7 @@
 
     /**
      * Initiates security engines ({@code MessageDigest}, {@code Mac},
-     * or {@code Cipher}). Must be called in deserialization. Please note
-     * that before instantiation the algorithm might not be available yet.
-     * In this case, just return and this method will be called
-     * automatically at instantiation.
+     * or {@code Cipher}). This method is called during instantiation.
      */
     protected abstract void initEngine();
 
@@ -331,13 +330,11 @@
 
     // SecureRandomSpi methods taken care of here. All final.
 
-    @Override
     protected final void engineNextBytes(byte[] result) {
         engineNextBytes(result, DrbgParameters.nextBytes(
                 -1, predictionResistanceFlag, null));
     }
 
-    @Override
     protected final void engineNextBytes(
             byte[] result, SecureRandomParameters params) {
 
@@ -402,7 +399,6 @@
         }
     }
 
-    @Override
     public final void engineReseed(SecureRandomParameters params) {
         if (debug != null) {
             debug.println(this, "reseed with params");
@@ -454,7 +450,6 @@
      * @param numBytes the number of seed bytes to generate.
      * @return the seed bytes.
      */
-    @Override
     public final byte[] engineGenerateSeed(int numBytes) {
         byte[] b = new byte[numBytes];
         SeedGenerator.generateSeed(b);
@@ -469,7 +464,6 @@
      *
      * @param input the seed
      */
-    @Override
     public final synchronized void engineSetSeed(byte[] input) {
         if (debug != null) {
             debug.println(this, "setSeed");
@@ -598,7 +592,6 @@
      *
      * @return the curent configuration
      */
-    @Override
     protected SecureRandomParameters engineGetParameters() {
         // Or read from variable.
         return DrbgParameters.instantiation(
@@ -631,7 +624,8 @@
             this.es = m.es;
             this.requestedAlgorithm = m.algorithm;
             this.usedf = m.usedf;
-            params = m.config;
+            params = DrbgParameters.instantiation(m.strength,
+                    m.capability, m.personalizationString);
         }
         if (params != null) {
             if (params instanceof DrbgParameters.Instantiation) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java	Thu Jun 09 19:07:27 2016 +0000
@@ -32,8 +32,6 @@
 
 public abstract class AbstractHashDrbg extends AbstractDrbg {
 
-    private static final long serialVersionUID = 9L;
-
     protected int outLen;
     protected int seedLen;
 
--- a/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java	Thu Jun 09 19:07:27 2016 +0000
@@ -28,14 +28,12 @@
 import javax.crypto.Cipher;
 import javax.crypto.NoSuchPaddingException;
 import javax.crypto.spec.SecretKeySpec;
-import java.io.IOException;
 import java.security.*;
 import java.util.Arrays;
 import java.util.Locale;
 
 public class CtrDrbg extends AbstractDrbg {
 
-    private static final long serialVersionUID = 9L;
     private static final int AES_LIMIT;
 
     static {
@@ -47,7 +45,7 @@
         }
     }
 
-    private transient Cipher cipher;
+    private Cipher cipher;
 
     private String cipherAlg;
     private String keyAlg;
@@ -57,8 +55,8 @@
     private int keyLen;
     private int seedLen;
 
-    private transient byte[] v;
-    private transient byte[] k;
+    private byte[] v;
+    private byte[] k;
 
     public CtrDrbg(SecureRandomParameters params) {
         mechName = "CTR_DRBG";
@@ -165,7 +163,7 @@
     protected void initEngine() {
         try {
             /*
-             * Use the local SUN implementation to avoid native
+             * Use the local SunJCE implementation to avoid native
              * performance overhead.
              */
             cipher = Cipher.getInstance(cipherAlg, "SunJCE");
@@ -463,12 +461,6 @@
         // Step 8. Return
     }
 
-    private void readObject(java.io.ObjectInputStream s)
-            throws IOException, ClassNotFoundException {
-        s.defaultReadObject ();
-        initEngine();
-    }
-
     @Override
     public String toString() {
         return super.toString() + ","
--- a/jdk/src/java.base/share/classes/sun/security/provider/DRBG.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/DRBG.java	Thu Jun 09 19:07:27 2016 +0000
@@ -25,6 +25,7 @@
 
 package sun.security.provider;
 
+import java.io.IOException;
 import java.security.AccessController;
 import java.security.DrbgParameters;
 import java.security.PrivilegedAction;
@@ -61,11 +62,12 @@
 
     private static final long serialVersionUID = 9L;
 
-    private final AbstractDrbg impl;
+    private transient AbstractDrbg impl;
 
-    private final String mechName;
-
-    private final String algorithmName;
+    /**
+     * @serial
+     */
+    private final MoreDrbgParameters mdp;
 
     public DRBG(SecureRandomParameters params) {
 
@@ -91,7 +93,7 @@
         // Can be configured with a security property
 
         String config = AccessController.doPrivileged((PrivilegedAction<String>)
-                    () -> Security.getProperty(PROP_NAME));
+                () -> Security.getProperty(PROP_NAME));
 
         if (config != null && !config.isEmpty()) {
             for (String part : config.split(",")) {
@@ -151,8 +153,9 @@
         if (params != null) {
             // MoreDrbgParameters is used for testing.
             if (params instanceof MoreDrbgParameters) {
-                MoreDrbgParameters m = (MoreDrbgParameters)params;
-                params = m.config;
+                MoreDrbgParameters m = (MoreDrbgParameters) params;
+                params = DrbgParameters.instantiation(m.strength,
+                        m.capability, m.personalizationString);
 
                 // No need to check null for es and nonce, they are still null
                 es = m.es;
@@ -197,26 +200,27 @@
             usedf = true;
         }
 
-        MoreDrbgParameters m = new MoreDrbgParameters(
+        mdp = new MoreDrbgParameters(
                 es, mech, algorithm, nonce, usedf,
                 DrbgParameters.instantiation(strength, cap, ps));
 
-        switch (mech.toLowerCase(Locale.ROOT)) {
+        createImpl();
+    }
+
+    private void createImpl() {
+        switch (mdp.mech.toLowerCase(Locale.ROOT)) {
             case "hash_drbg":
-                impl = new HashDrbg(m);
+                impl = new HashDrbg(mdp);
                 break;
             case "hmac_drbg":
-                impl = new HmacDrbg(m);
+                impl = new HmacDrbg(mdp);
                 break;
             case "ctr_drbg":
-                impl = new CtrDrbg(m);
+                impl = new CtrDrbg(mdp);
                 break;
             default:
-                throw new IllegalArgumentException("Unsupported mech: " + mech);
+                throw new IllegalArgumentException("Unsupported mech: " + mdp.mech);
         }
-
-        mechName = mech;
-        algorithmName = impl.algorithm;
     }
 
     @Override
@@ -268,4 +272,13 @@
                     + " cannot be provided more than once in " + PROP_NAME);
         }
     }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        if (mdp.mech == null) {
+            throw new IllegalArgumentException("Input data is corrupted");
+        }
+        createImpl();
+    }
 }
--- a/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java	Thu Jun 09 19:07:27 2016 +0000
@@ -25,7 +25,6 @@
 
 package sun.security.provider;
 
-import java.io.IOException;
 import java.math.BigInteger;
 import java.security.DigestException;
 import java.security.MessageDigest;
@@ -36,15 +35,13 @@
 
 public class HashDrbg extends AbstractHashDrbg {
 
-    private static final long serialVersionUID = 9L;
-
     private static final byte[] ZERO = new byte[1];
     private static final byte[] ONE = new byte[]{1};
 
-    private transient MessageDigest digest;
+    private MessageDigest digest;
 
-    private transient byte[] v;
-    private transient byte[] c;
+    private byte[] v;
+    private byte[] c;
 
     public HashDrbg(SecureRandomParameters params) {
         mechName = "Hash_DRBG";
@@ -267,10 +264,4 @@
         // Step 5: No need to truncate
         // Step 6: Return
     }
-
-    private void readObject(java.io.ObjectInputStream s)
-            throws IOException, ClassNotFoundException {
-        s.defaultReadObject ();
-        initEngine();
-    }
 }
--- a/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java	Thu Jun 09 19:07:27 2016 +0000
@@ -27,7 +27,6 @@
 
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
-import java.io.IOException;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
@@ -36,14 +35,12 @@
 
 public class HmacDrbg extends AbstractHashDrbg {
 
-    private static final long serialVersionUID = 9L;
-
-    private transient Mac mac;
+    private Mac mac;
 
     private String macAlg;
 
-    private transient byte[] v;
-    private transient byte[] k;
+    private byte[] v;
+    private byte[] k;
 
     public HmacDrbg(SecureRandomParameters params) {
         mechName = "HMAC_DRBG";
@@ -101,6 +98,10 @@
     protected void initEngine() {
         macAlg = "HmacSHA" + algorithm.substring(4);
         try {
+            /*
+             * Use the local SunJCE implementation to avoid native
+             * performance overhead.
+             */
             mac = Mac.getInstance(macAlg, "SunJCE");
         } catch (NoSuchProviderException | NoSuchAlgorithmException e) {
             // Fallback to any available.
@@ -194,10 +195,4 @@
 
         // Step 8. Return
     }
-
-    private void readObject(java.io.ObjectInputStream s)
-            throws IOException, ClassNotFoundException {
-        s.defaultReadObject ();
-        initEngine();
-    }
 }
--- a/jdk/src/java.base/share/classes/sun/security/provider/MoreDrbgParameters.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/MoreDrbgParameters.java	Thu Jun 09 19:07:27 2016 +0000
@@ -25,20 +25,30 @@
 
 package sun.security.provider;
 
+import java.io.IOException;
+import java.io.Serializable;
 import java.security.DrbgParameters;
 import java.security.SecureRandomParameters;
 
 /**
- * Extra non-standard parameters that can be used by DRBGs.
+ * Exported and non-exported parameters that can be used by DRBGs.
  */
-public class MoreDrbgParameters implements SecureRandomParameters {
+public class MoreDrbgParameters implements SecureRandomParameters, Serializable {
+
+    private static final long serialVersionUID = 9L;
+
+    final transient EntropySource es;
 
     final String mech;
     final String algorithm;
-    final EntropySource es;
-    final byte[] nonce;
     final boolean usedf;
-    final DrbgParameters.Instantiation config;
+    final int strength;
+    final DrbgParameters.Capability capability;
+
+    // The following 2 fields will be reassigned in readObject and
+    // thus cannot be final
+    byte[] nonce;
+    byte[] personalizationString;
 
     /**
      * Creates a new {@code MoreDrbgParameters} object.
@@ -61,13 +71,31 @@
         this.mech = mech;
         this.algorithm = algorithm;
         this.es = es;
-        this.nonce = nonce;
+        this.nonce = (nonce == null) ? null : nonce.clone();
         this.usedf = usedf;
-        this.config = config;
+
+        this.strength = config.getStrength();
+        this.capability = config.getCapability();
+        this.personalizationString = config.getPersonalizationString();
     }
 
     @Override
     public String toString() {
-        return mech + "," + algorithm + "," + usedf + "," + config;
+        return mech + "," + algorithm + "," + usedf + "," + strength
+                + "," + capability + "," + personalizationString;
+    }
+
+    private void readObject(java.io.ObjectInputStream s)
+            throws IOException, ClassNotFoundException {
+        s.defaultReadObject();
+        if (nonce != null) {
+            nonce = nonce.clone();
+        }
+        if (personalizationString != null) {
+            personalizationString = personalizationString.clone();
+        }
+        if (capability == null) {
+            throw new IllegalArgumentException("Input data is corrupted");
+        }
     }
 }
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java	Thu Jun 09 19:07:27 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -347,7 +347,7 @@
         SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode,
             enabledCipherSuites, clientAuthType, enableSessionCreation,
             enabledProtocols, identificationProtocol, algorithmConstraints,
-            sniMatchers, preferLocalCipherSuites);
+            sniMatchers, preferLocalCipherSuites, applicationProtocols);
 
         implAccept(s);
         s.doneConnect();
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java	Thu Jun 09 19:07:27 2016 +0000
@@ -497,7 +497,8 @@
             String identificationProtocol,
             AlgorithmConstraints algorithmConstraints,
             Collection<SNIMatcher> sniMatchers,
-            boolean preferLocalCipherSuites) throws IOException {
+            boolean preferLocalCipherSuites,
+            String[] applicationProtocols) throws IOException {
 
         super();
         doClientAuth = clientAuth;
@@ -506,6 +507,7 @@
         this.algorithmConstraints = algorithmConstraints;
         this.sniMatchers = sniMatchers;
         this.preferLocalCipherSuites = preferLocalCipherSuites;
+        this.applicationProtocols = applicationProtocols;
         init(context, serverMode);
 
         /*
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Thu Jun 09 19:07:27 2016 +0000
@@ -206,7 +206,7 @@
         IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore",
             SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE,
             DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS,
-            SRCPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
+            SRCPROTECTED, DESTPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
             SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
             NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
             V),
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WS.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WS.java	Thu Jun 09 19:07:27 2016 +0000
@@ -86,7 +86,7 @@
                 }
             }
         };
-        transmitter = new WSTransmitter(executor, channel, errorHandler);
+        transmitter = new WSTransmitter(this, executor, channel, errorHandler);
         receiver = new WSReceiver(this.listener, this, executor, channel);
     }
 
@@ -95,12 +95,7 @@
     }
 
     @Override
-    public CompletableFuture<Void> sendText(ByteBuffer message, boolean isLast) {
-        throw new UnsupportedOperationException("Not implemented");
-    }
-
-    @Override
-    public CompletableFuture<Void> sendText(CharSequence message, boolean isLast) {
+    public CompletableFuture<WebSocket> sendText(CharSequence message, boolean isLast) {
         requireNonNull(message, "message");
         synchronized (stateLock) {
             checkState();
@@ -109,7 +104,7 @@
     }
 
     @Override
-    public CompletableFuture<Void> sendText(Stream<? extends CharSequence> message) {
+    public CompletableFuture<WebSocket> sendText(Stream<? extends CharSequence> message) {
         requireNonNull(message, "message");
         synchronized (stateLock) {
             checkState();
@@ -118,7 +113,7 @@
     }
 
     @Override
-    public CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast) {
+    public CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast) {
         requireNonNull(message, "message");
         synchronized (stateLock) {
             checkState();
@@ -127,7 +122,7 @@
     }
 
     @Override
-    public CompletableFuture<Void> sendPing(ByteBuffer message) {
+    public CompletableFuture<WebSocket> sendPing(ByteBuffer message) {
         requireNonNull(message, "message");
         synchronized (stateLock) {
             checkState();
@@ -136,7 +131,7 @@
     }
 
     @Override
-    public CompletableFuture<Void> sendPong(ByteBuffer message) {
+    public CompletableFuture<WebSocket> sendPong(ByteBuffer message) {
         requireNonNull(message, "message");
         synchronized (stateLock) {
             checkState();
@@ -145,7 +140,7 @@
     }
 
     @Override
-    public CompletableFuture<Void> sendClose(CloseCode code, CharSequence reason) {
+    public CompletableFuture<WebSocket> sendClose(CloseCode code, CharSequence reason) {
         requireNonNull(code, "code");
         requireNonNull(reason, "reason");
         synchronized (stateLock) {
@@ -154,13 +149,13 @@
     }
 
     @Override
-    public CompletableFuture<Void> sendClose() {
+    public CompletableFuture<WebSocket> sendClose() {
         synchronized (stateLock) {
             return doSendClose(() -> transmitter.sendClose());
         }
     }
 
-    private CompletableFuture<Void> doSendClose(Supplier<CompletableFuture<Void>> s) {
+    private CompletableFuture<WebSocket> doSendClose(Supplier<CompletableFuture<WebSocket>> s) {
         checkState();
         boolean closeChannel = false;
         synchronized (stateLock) {
@@ -170,7 +165,7 @@
                 tryChangeState(State.CLOSED_LOCALLY);
             }
         }
-        CompletableFuture<Void> sent = s.get();
+        CompletableFuture<WebSocket> sent = s.get();
         if (closeChannel) {
             sent.whenComplete((v, t) -> {
                 try {
@@ -239,7 +234,7 @@
             }
 
             @Override
-            public CompletionStage<?> onText(WebSocket webSocket, Text message,
+            public CompletionStage<?> onText(WebSocket webSocket, CharSequence message,
                                              MessagePart part) {
                 synchronized (visibilityLock) {
                     return listener.onText(webSocket, message, part);
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSDisposableText.java	Thu Jun 09 17:28:37 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General  License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General  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  License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.net.http;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-
-final class WSDisposableText implements WebSocket.Text, WSDisposable {
-
-    private final WSShared<CharBuffer> text;
-
-    WSDisposableText(WSShared<CharBuffer> text) {
-        this.text = text;
-    }
-
-    @Override
-    public int length() {
-        return text.buffer().length();
-    }
-
-    @Override
-    public char charAt(int index) {
-        return text.buffer().charAt(index);
-    }
-
-    @Override
-    public CharSequence subSequence(int start, int end) {
-        return text.buffer().subSequence(start, end);
-    }
-
-    @Override
-    public ByteBuffer asByteBuffer() {
-        throw new UnsupportedOperationException("To be removed from the API");
-    }
-
-    @Override
-    public String toString() {
-        return text.buffer().toString();
-    }
-
-    @Override
-    public void dispose() {
-        text.dispose();
-    }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSFrameConsumer.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSFrameConsumer.java	Thu Jun 09 19:07:27 2016 +0000
@@ -214,7 +214,7 @@
                 if (!(binaryNonEmpty && !textData.hasRemaining())) {
                     // If there's a binary data, that result in no text, then we
                     // don't deliver anything
-                    output.onText(part, new WSDisposableText(textData));
+                    output.onText(part, textData);
                 }
             }
         }
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSMessageConsumer.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSMessageConsumer.java	Thu Jun 09 19:07:27 2016 +0000
@@ -27,10 +27,11 @@
 import java.net.http.WebSocket.CloseCode;
 import java.net.http.WebSocket.MessagePart;
 import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
 
 interface WSMessageConsumer {
 
-    void onText(MessagePart part, WSDisposableText data);
+    void onText(MessagePart part, WSShared<CharBuffer> data);
 
     void onBinary(MessagePart part, WSShared<ByteBuffer> data);
 
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSReceiver.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSReceiver.java	Thu Jun 09 19:07:27 2016 +0000
@@ -29,6 +29,7 @@
 import java.net.ProtocolException;
 import java.net.http.WebSocket.Listener;
 import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
 import java.nio.channels.SelectionKey;
 import java.util.Optional;
 import java.util.concurrent.CompletionStage;
@@ -169,11 +170,11 @@
     private final class MessageConsumer implements WSMessageConsumer {
 
         @Override
-        public void onText(WebSocket.MessagePart part, WSDisposableText data) {
+        public void onText(WebSocket.MessagePart part, WSShared<CharBuffer> data) {
             decrementDemand();
             CompletionStage<?> cs;
             try {
-                cs = listener.onText(webSocket, data, part);
+                cs = listener.onText(webSocket, data.buffer(), part);
             } catch (Exception e) {
                 closeExceptionally(new RuntimeException("onText threw an exception", e));
                 return;
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSTransmitter.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSTransmitter.java	Thu Jun 09 19:07:27 2016 +0000
@@ -51,15 +51,17 @@
  */
 final class WSTransmitter {
 
-    private final BlockingQueue<Pair<WSOutgoingMessage, CompletableFuture<Void>>>
+    private final BlockingQueue<Pair<WSOutgoingMessage, CompletableFuture<WebSocket>>>
             backlog = new LinkedBlockingQueue<>();
     private final WSMessageSender sender;
     private final WSSignalHandler handler;
+    private final WebSocket webSocket;
     private boolean previousMessageSent = true;
     private boolean canSendBinary = true;
     private boolean canSendText = true;
 
-    WSTransmitter(Executor executor, RawChannel channel, Consumer<Throwable> errorHandler) {
+    WSTransmitter(WebSocket ws, Executor executor, RawChannel channel, Consumer<Throwable> errorHandler) {
+        this.webSocket = ws;
         this.handler = new WSSignalHandler(executor, this::handleSignal);
         Consumer<Throwable> sendCompletion = (error) -> {
             synchronized (this) {
@@ -76,41 +78,41 @@
         this.sender = new WSMessageSender(channel, sendCompletion);
     }
 
-    CompletableFuture<Void> sendText(CharSequence message, boolean isLast) {
+    CompletableFuture<WebSocket> sendText(CharSequence message, boolean isLast) {
         checkAndUpdateText(isLast);
         return acceptMessage(new Text(isLast, message));
     }
 
-    CompletableFuture<Void> sendText(Stream<? extends CharSequence> message) {
+    CompletableFuture<WebSocket> sendText(Stream<? extends CharSequence> message) {
         checkAndUpdateText(true);
         return acceptMessage(new StreamedText(message));
     }
 
-    CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast) {
+    CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast) {
         checkAndUpdateBinary(isLast);
         return acceptMessage(new Binary(isLast, message));
     }
 
-    CompletableFuture<Void> sendPing(ByteBuffer message) {
+    CompletableFuture<WebSocket> sendPing(ByteBuffer message) {
         checkSize(message.remaining(), 125);
         return acceptMessage(new Ping(message));
     }
 
-    CompletableFuture<Void> sendPong(ByteBuffer message) {
+    CompletableFuture<WebSocket> sendPong(ByteBuffer message) {
         checkSize(message.remaining(), 125);
         return acceptMessage(new Pong(message));
     }
 
-    CompletableFuture<Void> sendClose(WebSocket.CloseCode code, CharSequence reason) {
+    CompletableFuture<WebSocket> sendClose(WebSocket.CloseCode code, CharSequence reason) {
         return acceptMessage(createCloseMessage(code, reason));
     }
 
-    CompletableFuture<Void> sendClose() {
+    CompletableFuture<WebSocket> sendClose() {
         return acceptMessage(new Close(ByteBuffer.allocate(0)));
     }
 
-    private CompletableFuture<Void> acceptMessage(WSOutgoingMessage m) {
-        CompletableFuture<Void> cf = new CompletableFuture<>();
+    private CompletableFuture<WebSocket> acceptMessage(WSOutgoingMessage m) {
+        CompletableFuture<WebSocket> cf = new CompletableFuture<>();
         synchronized (this) {
             backlog.offer(pair(m, cf));
         }
@@ -123,11 +125,11 @@
         synchronized (this) {
             while (!backlog.isEmpty() && previousMessageSent) {
                 previousMessageSent = false;
-                Pair<WSOutgoingMessage, CompletableFuture<Void>> p = backlog.peek();
+                Pair<WSOutgoingMessage, CompletableFuture<WebSocket>> p = backlog.peek();
                 boolean sent = sender.trySendFully(p.first);
                 if (sent) {
                     backlog.remove();
-                    p.second.complete(null);
+                    p.second.complete(webSocket);
                     previousMessageSent = true;
                 }
             }
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WebSocket.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WebSocket.java	Thu Jun 09 19:07:27 2016 +0000
@@ -52,8 +52,8 @@
  *
  * <p> Messages of type {@code X} are sent through the {@code WebSocket.sendX}
  * methods and received through {@link WebSocket.Listener}{@code .onX} methods
- * asynchronously. Each of the methods begins the operation and returns a {@link
- * CompletionStage} which completes when the operation has completed.
+ * asynchronously. Each of the methods returns a {@link CompletionStage} which
+ * completes when the operation has completed.
  *
  * <p> Messages are received only if {@linkplain #request(long) requested}.
  *
@@ -79,6 +79,9 @@
  * or method of this type will cause a {@link NullPointerException
  * NullPointerException} to be thrown.
  *
+ * @implNote The default implementation's methods do not block before returning
+ * a {@code CompletableFuture}.
+ *
  * @since 9
  */
 public interface WebSocket {
@@ -234,9 +237,9 @@
         /**
          * Builds a {@code WebSocket}.
          *
-         * <p> Returns immediately with a {@code CompletableFuture<WebSocket>}
-         * which completes with the {@code WebSocket} when it is connected, or
-         * completes exceptionally if an error occurs.
+         * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+         * normally with the {@code WebSocket} when it is connected or completes
+         * exceptionally if an error occurs.
          *
          * <p> {@code CompletableFuture} may complete exceptionally with the
          * following errors:
@@ -252,7 +255,7 @@
          *          if the opening handshake fails
          * </ul>
          *
-         * @return a {@code CompletableFuture} of {@code WebSocket}
+         * @return a {@code CompletableFuture} with the {@code WebSocket}
          */
         CompletableFuture<WebSocket> buildAsync();
     }
@@ -264,7 +267,7 @@
      * <ul>
      * <li> {@link #onOpen onOpen} <br>
      * This method is always the first to be invoked.
-     * <li> {@link #onText(WebSocket, WebSocket.Text, WebSocket.MessagePart)
+     * <li> {@link #onText(WebSocket, CharSequence, WebSocket.MessagePart)
      * onText}, {@link #onBinary(WebSocket, ByteBuffer, WebSocket.MessagePart)
      * onBinary}, {@link #onPing(WebSocket, ByteBuffer) onPing} and {@link
      * #onPong(WebSocket, ByteBuffer) onPong} <br>
@@ -375,6 +378,9 @@
          * @implSpec The default implementation {@linkplain WebSocket#request(long)
          * requests one more message}.
          *
+         * @implNote This implementation passes only complete UTF-16 sequences
+         * to the {@code onText} method.
+         *
          * @param webSocket
          *         the WebSocket
          * @param message
@@ -386,7 +392,7 @@
          * is done; or {@code null} if already done
          */
         default CompletionStage<?> onText(WebSocket webSocket,
-                                          Text message,
+                                          CharSequence message,
                                           MessagePart part) {
             webSocket.request(1);
             return null;
@@ -596,59 +602,11 @@
     }
 
     /**
-     * Sends a Text message with bytes from the given {@code ByteBuffer}.
-     *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
-     *
-     * <p> This message may be a partial UTF-8 sequence. However, the
-     * concatenation of all messages through the last must be a whole UTF-8
-     * sequence.
-     *
-     * <p> The {@code ByteBuffer} should not be modified until the returned
-     * {@code CompletableFuture} completes (either normally or exceptionally).
-     *
-     * <p> The returned {@code CompletableFuture} can complete exceptionally
-     * with:
-     * <ul>
-     * <li> {@link IOException}
-     *          if an I/O error occurs during this operation; or the
-     *          {@code WebSocket} closes while this operation is in progress;
-     *          or the {@code message} is a malformed UTF-8 sequence
-     * </ul>
+     * Sends a Text message with characters from the given {@code CharSequence}.
      *
-     * @param message
-     *         the message
-     * @param isLast
-     *         {@code true} if this is the final part of the message,
-     *         {@code false} otherwise
-     *
-     * @return a CompletableFuture of Void
-     *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been sent already
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
-     * @throws IllegalStateException
-     *         if a previous Binary message
-     *         was not sent with {@code isLast == true}
-     */
-    CompletableFuture<Void> sendText(ByteBuffer message, boolean isLast);
-
-    /**
-     * Sends a Text message with characters from the given {@code
-     * CharSequence}.
-     *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
-     *
-     * <p> This message may be a partial UTF-16 sequence. However, the
-     * concatenation of all messages through the last must be a whole UTF-16
-     * sequence.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> The {@code CharSequence} should not be modified until the returned
      * {@code CompletableFuture} completes (either normally or exceptionally).
@@ -657,30 +615,30 @@
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation; or the
-     *          {@code WebSocket} closes while this operation is in progress;
-     *          or the {@code message} is a malformed UTF-16 sequence
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation;
+     *          or if a previous Binary message was not sent with {@code isLast == true}
      * </ul>
      *
+     * @implNote This implementation does not accept partial UTF-16
+     * sequences. In case such a sequence is passed, a returned {@code
+     * CompletableFuture} completes exceptionally.
+     *
      * @param message
      *         the message
      * @param isLast
-     *         {@code true} if this is the final part of the message
+     *         {@code true} if this is the final part of the message,
      *         {@code false} otherwise
      *
-     * @return a CompletableFuture of Void
+     * @return a CompletableFuture with this WebSocket
      *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
-     * @throws IllegalStateException
-     *         if a previous Binary message was not sent
-     *         with {@code isLast == true}
+     * @throws IllegalArgumentException
+     *         if {@code message} is a malformed (or an incomplete) UTF-16 sequence
      */
-    CompletableFuture<Void> sendText(CharSequence message, boolean isLast);
+    CompletableFuture<WebSocket> sendText(CharSequence message, boolean isLast);
 
     /**
      * Sends a whole Text message with characters from the given {@code
@@ -689,9 +647,9 @@
      * <p> This is a convenience method. For the general case, use {@link
      * #sendText(CharSequence, boolean)}.
      *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> The {@code CharSequence} should not be modified until the returned
      * {@code CompletableFuture} completes (either normally or exceptionally).
@@ -700,27 +658,23 @@
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation; or the
-     *          {@code WebSocket} closes while this operation is in progress;
-     *          or the message is a malformed UTF-16 sequence
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation;
+     *          or if a previous Binary message was not sent with {@code isLast == true}
      * </ul>
      *
      * @param message
      *         the message
      *
-     * @return a CompletableFuture of Void
+     * @return a CompletableFuture with this WebSocket
      *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
-     * @throws IllegalStateException
-     *         if a previous Binary message was not sent
-     *         with {@code isLast == true}
+     * @throws IllegalArgumentException
+     *         if {@code message} is a malformed (or an incomplete) UTF-16 sequence
      */
-    default CompletableFuture<Void> sendText(CharSequence message) {
+    default CompletableFuture<WebSocket> sendText(CharSequence message) {
         return sendText(message, true);
     }
 
@@ -731,9 +685,9 @@
      * <p> This is a convenience method. For the general case use {@link
      * #sendText(CharSequence, boolean)}.
      *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> Streamed character sequences should not be modified until the
      * returned {@code CompletableFuture} completes (either normally or
@@ -743,41 +697,41 @@
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation; or the
-     *          {@code WebSocket} closes while this operation is in progress;
-     *          or the message is a malformed UTF-16 sequence
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation;
+     *          or if a previous Binary message was not sent with {@code isLast == true}
      * </ul>
      *
      * @param message
      *         the message
      *
-     * @return a CompletableFuture of Void
+     * @return a CompletableFuture with this WebSocket
      *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
-     * @throws IllegalStateException
-     *         if a previous Binary message was not sent
-     *         with {@code isLast == true}
+     * @throws IllegalArgumentException
+     *         if {@code message} is a malformed (or an incomplete) UTF-16 sequence
      */
-    CompletableFuture<Void> sendText(Stream<? extends CharSequence> message);
+    CompletableFuture<WebSocket> sendText(Stream<? extends CharSequence> message);
 
     /**
      * Sends a Binary message with bytes from the given {@code ByteBuffer}.
      *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> The returned {@code CompletableFuture} can complete exceptionally
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation or the
-     *          {@code WebSocket} closes while this operation is in progress
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation;
+     *          or if a previous Text message was not sent with {@code isLast == true}
      * </ul>
      *
      * @param message
@@ -786,33 +740,27 @@
      *         {@code true} if this is the final part of the message,
      *         {@code false} otherwise
      *
-     * @return a CompletableFuture of Void
-     *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
-     * @throws IllegalStateException
-     *         if a previous Text message was not sent
-     *         with {@code isLast == true}
+     * @return a CompletableFuture with this WebSocket
      */
-    CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast);
+    CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast);
 
     /**
      * Sends a Binary message with bytes from the given {@code byte[]}.
      *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> The returned {@code CompletableFuture} can complete exceptionally
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation or the
-     *          {@code WebSocket} closes while this operation is in progress
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation;
+     *          or if a previous Text message was not sent with {@code isLast == true}
      * </ul>
      *
      * @implSpec This is equivalent to:
@@ -826,19 +774,9 @@
      *         {@code true} if this is the final part of the message,
      *         {@code false} otherwise
      *
-     * @return a CompletableFuture of Void
-     *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
-     * @throws IllegalStateException
-     *         if a previous Text message was not sent
-     *         with {@code isLast == true}
+     * @return a CompletableFuture with this WebSocket
      */
-    default CompletableFuture<Void> sendBinary(byte[] message, boolean isLast) {
+    default CompletableFuture<WebSocket> sendBinary(byte[] message, boolean isLast) {
         Objects.requireNonNull(message, "message");
         return sendBinary(ByteBuffer.wrap(message), isLast);
     }
@@ -846,9 +784,9 @@
     /**
      * Sends a Ping message.
      *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> A Ping message may be sent or received by either client or server.
      * It may serve either as a keepalive or as a means to verify that the
@@ -861,32 +799,29 @@
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation or the
-     *          {@code WebSocket} closes while this operation is in progress
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation
      * </ul>
      *
      * @param message
      *         the message
      *
-     * @return a CompletableFuture of Void
+     * @return a CompletableFuture with this WebSocket
      *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
      * @throws IllegalArgumentException
      *         if {@code message.remaining() > 125}
      */
-    CompletableFuture<Void> sendPing(ByteBuffer message);
+    CompletableFuture<WebSocket> sendPing(ByteBuffer message);
 
     /**
      * Sends a Pong message.
      *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> A Pong message may be unsolicited or may be sent in response to a
      * previously received Ping. In latter case the contents of the Pong is
@@ -899,32 +834,29 @@
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation or the
-     *          {@code WebSocket} closes while this operation is in progress
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation
      * </ul>
      *
      * @param message
      *         the message
      *
-     * @return a CompletableFuture of Void
+     * @return a CompletableFuture with this WebSocket
      *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
      * @throws IllegalArgumentException
      *         if {@code message.remaining() > 125}
      */
-    CompletableFuture<Void> sendPong(ByteBuffer message);
+    CompletableFuture<WebSocket> sendPong(ByteBuffer message);
 
     /**
      * Sends a Close message with the given close code and the reason.
      *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> A Close message may consist of a close code and a reason for closing.
      * The reason must have a valid UTF-8 representation not longer than {@code
@@ -935,8 +867,11 @@
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation or the
-     *          {@code WebSocket} closes while this operation is in progress
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation
      * </ul>
      *
      * @param code
@@ -944,45 +879,35 @@
      * @param reason
      *         the reason; can be empty
      *
-     * @return a CompletableFuture of Void
+     * @return a CompletableFuture with this WebSocket
      *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
      * @throws IllegalArgumentException
-     *         if the {@code reason} doesn't have a valid UTF-8
-     *         representation not longer than {@code 123} bytes
+     *         if {@code reason} doesn't have an UTF-8 representation not longer
+     *         than {@code 123} bytes
      */
-    CompletableFuture<Void> sendClose(CloseCode code, CharSequence reason);
+    CompletableFuture<WebSocket> sendClose(CloseCode code, CharSequence reason);
 
     /**
      * Sends an empty Close message.
      *
-     * <p> Returns immediately with a {@code CompletableFuture<Void>} which
-     * completes normally when the message has been sent, or completes
-     * exceptionally if an error occurs.
+     * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+     * normally when the message has been sent or completes exceptionally if an
+     * error occurs.
      *
      * <p> The returned {@code CompletableFuture} can complete exceptionally
      * with:
      * <ul>
      * <li> {@link IOException}
-     *          if an I/O error occurs during this operation or the
-     *          {@code WebSocket} closes while this operation is in progress
+     *          if an I/O error occurs during this operation
+     * <li> {@link IllegalStateException}
+     *          if the {@code WebSocket} closes while this operation is in progress;
+     *          or if a Close message has been sent already;
+     *          or if there is an outstanding send operation
      * </ul>
      *
-     * @return a CompletableFuture of Void
-     *
-     * @throws IllegalStateException
-     *         if the WebSocket is closed
-     * @throws IllegalStateException
-     *         if a Close message has been already sent
-     * @throws IllegalStateException
-     *         if there is an outstanding send operation
+     * @return a CompletableFuture with this WebSocket
      */
-    CompletableFuture<Void> sendClose();
+    CompletableFuture<WebSocket> sendClose();
 
     /**
      * Requests {@code n} more messages to be received by the {@link Listener
@@ -1001,6 +926,7 @@
      * @implNote This implementation does not distinguish between partial and
      * whole messages, because it's not known beforehand how a message will be
      * received.
+     *
      * <p> If a server sends more messages than requested, the implementation
      * queues up these messages on the TCP connection and may eventually force
      * the sender to stop sending through TCP flow control.
@@ -1242,47 +1168,4 @@
             return Map.entry(cc.getCode(), cc);
         }
     }
-
-    /**
-     * A character sequence that provides access to the characters UTF-8 decoded
-     * from a message in a {@code ByteBuffer}.
-     *
-     * @since 9
-     */
-    interface Text extends CharSequence {
-
-        // Methods from the CharSequence below are mentioned explicitly for the
-        // purpose of documentation, so when looking at javadoc it immediately
-        // obvious what methods Text has
-
-        @Override
-        int length();
-
-        @Override
-        char charAt(int index);
-
-        @Override
-        CharSequence subSequence(int start, int end);
-
-        /**
-         * Returns a string containing the characters in this sequence in the
-         * same order as this sequence. The length of the string will be the
-         * length of this sequence.
-         *
-         * @return a string consisting of exactly this sequence of characters
-         */
-        @Override
-        // TODO: remove the explicit javadoc above when:
-        // (JDK-8144034 has been resolved) AND (the comment is still identical
-        // to CharSequence#toString)
-        String toString();
-
-        /**
-         * Returns a read-only {@code ByteBuffer} containing the message encoded
-         * in UTF-8.
-         *
-         * @return a read-only ByteBuffer
-         */
-        ByteBuffer asByteBuffer();
-    }
 }
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java	Thu Jun 09 19:07:27 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -128,7 +128,7 @@
      * of &quot;MULTITHREADED&quot;, and also, the engine maintains independent values
      * for symbols in scripts executing on different threads.
      * <li><code>&quot;STATELESS&quot;</code> - The implementation satisfies the requirements of
-     * <li><code>&quot;THREAD-ISOLATED&quot;</code>.  In addition, script executions do not alter the
+     * <code>&quot;THREAD-ISOLATED&quot;</code>.  In addition, script executions do not alter the
      * mappings in the <code>Bindings</code> which is the engine scope of the
      * <code>ScriptEngine</code>.  In particular, the keys in the <code>Bindings</code>
      * and their associated values are the same before and after the execution of the script.
--- a/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/extra/EditingHistory.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/extra/EditingHistory.java	Thu Jun 09 19:07:27 2016 +0000
@@ -54,7 +54,9 @@
              (Runnable) () -> moveHistoryToSnippet(in, ((EditingHistory) in.getHistory())::previousSnippet));
         bind(in, CTRL_DOWN,
              (Runnable) () -> moveHistoryToSnippet(in, ((EditingHistory) in.getHistory())::nextSnippet));
-        load(originalHistory);
+        if (originalHistory != null) {
+            load(originalHistory);
+        }
     }
 
     private void moveHistoryToSnippet(ConsoleReader in, Supplier<Boolean> action) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java	Thu Jun 09 19:07:27 2016 +0000
@@ -28,19 +28,16 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
+import java.nio.file.FileSystem;
 import java.nio.file.Files;
-import static java.nio.file.StandardOpenOption.READ;
-import static java.nio.file.StandardOpenOption.WRITE;
+import java.nio.file.PathMatcher;
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.MissingResourceException;
+import java.util.function.Predicate;
 import jdk.internal.jimage.BasicImageReader;
 import jdk.internal.jimage.ImageHeader;
-import static jdk.internal.jimage.ImageHeader.MAGIC;
-import static jdk.internal.jimage.ImageHeader.MAJOR_VERSION;
-import static jdk.internal.jimage.ImageHeader.MINOR_VERSION;
 import jdk.internal.jimage.ImageLocation;
 import jdk.tools.jlink.internal.ImageResourcesTree;
 import jdk.tools.jlink.internal.TaskHelper;
@@ -48,53 +45,71 @@
 import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
 import jdk.tools.jlink.internal.TaskHelper.Option;
 import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
+import jdk.tools.jlink.internal.Utils;
 
 class JImageTask {
-
-    static final Option<?>[] recognizedOptions = {
-        new Option<JImageTask>(true, (task, opt, arg) -> {
+    private static final Option<?>[] RECOGNIZED_OPTIONS = {
+        new Option<JImageTask>(true, (task, option, arg) -> {
             task.options.directory = arg;
         }, "--dir"),
-        new Option<JImageTask>(false, (task, opt, arg) -> {
+
+        new Option<JImageTask>(true, (task, option, arg) -> {
+            task.options.filters = arg;
+        }, "--filter"),
+
+        new Option<JImageTask>(false, (task, option, arg) -> {
             task.options.fullVersion = true;
         }, true, "--fullversion"),
-        new Option<JImageTask>(false, (task, opt, arg) -> {
+
+        new Option<JImageTask>(false, (task, option, arg) -> {
             task.options.help = true;
         }, "--help"),
-        new Option<JImageTask>(true, (task, opt, arg) -> {
-            task.options.flags = arg;
-        }, "--flags"),
-        new Option<JImageTask>(false, (task, opt, arg) -> {
+
+        new Option<JImageTask>(false, (task, option, arg) -> {
             task.options.verbose = true;
         }, "--verbose"),
-        new Option<JImageTask>(false, (task, opt, arg) -> {
+
+        new Option<JImageTask>(false, (task, option, arg) -> {
             task.options.version = true;
         }, "--version")
     };
-    private static final TaskHelper taskHelper
+    private static final TaskHelper TASK_HELPER
             = new TaskHelper(JIMAGE_BUNDLE);
-    private static final OptionsHelper<JImageTask> optionsHelper
-            = taskHelper.newOptionsHelper(JImageTask.class, recognizedOptions);
+    private static final OptionsHelper<JImageTask> OPTION_HELPER
+            = TASK_HELPER.newOptionsHelper(JImageTask.class, RECOGNIZED_OPTIONS);
+    private static final String PROGNAME = "jimage";
+    private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
+
+    private final OptionsValues options;
+    private final List<Predicate<String>> filterPredicates;
+    private PrintWriter log;
+
+    JImageTask() {
+        this.options = new OptionsValues();
+        this.filterPredicates = new ArrayList<>();
+        log = null;
+    }
+
+    void setLog(PrintWriter out) {
+        log = out;
+        TASK_HELPER.setLog(log);
+    }
 
     static class OptionsValues {
         Task task = Task.LIST;
         String directory = ".";
+        String filters = "";
         boolean fullVersion;
         boolean help;
-        String flags;
         boolean verbose;
         boolean version;
         List<File> jimages = new LinkedList<>();
     }
 
-    private static final String PROGNAME = "jimage";
-    private final OptionsValues options = new OptionsValues();
-
     enum Task {
         EXTRACT,
         INFO,
         LIST,
-        SET,
         VERIFY
     };
 
@@ -145,50 +160,97 @@
 
     int run(String[] args) {
         if (log == null) {
-            setLog(new PrintWriter(System.out));
+            setLog(new PrintWriter(System.out, true));
         }
 
         if (args.length == 0) {
-            log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
+            log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
             return EXIT_ABNORMAL;
         }
 
         try {
-            List<String> unhandled = optionsHelper.handleOptions(this, args);
+            List<String> unhandled = OPTION_HELPER.handleOptions(this, args);
+
             if(!unhandled.isEmpty()) {
                 try {
                     options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
                 } catch (IllegalArgumentException ex) {
-                    throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
+                    throw TASK_HELPER.newBadArgs("err.not.a.task", unhandled.get(0));
                 }
+
                 for(int i = 1; i < unhandled.size(); i++) {
                     options.jimages.add(new File(unhandled.get(i)));
                 }
-            } else {
-                throw taskHelper.newBadArgs("err.not.a.task", "<unspecified>");
+            } else if (!options.help && !options.version && !options.fullVersion) {
+                throw TASK_HELPER.newBadArgs("err.invalid.task", "<unspecified>");
             }
+
             if (options.help) {
-                optionsHelper.showHelp(PROGNAME);
+                if (unhandled.isEmpty()) {
+                    log.println(TASK_HELPER.getMessage("main.usage", PROGNAME));
+
+                    for (Option<?> o : RECOGNIZED_OPTIONS) {
+                        String name = o.aliases()[0];
+
+                        if (name.startsWith("--")) {
+                            name = name.substring(2);
+                        } else if (name.startsWith("-")) {
+                            name = name.substring(1);
+                        }
+
+                        log.println(TASK_HELPER.getMessage("main.opt." + name));
+                    }
+                } else {
+                    try {
+                        log.println(TASK_HELPER.getMessage("main.usage." +
+                                options.task.toString().toLowerCase()));
+                    } catch (MissingResourceException ex) {
+                        throw TASK_HELPER.newBadArgs("err.not.a.task", unhandled.get(0));
+                    }
+                }
+                return EXIT_OK;
             }
+
             if (options.version || options.fullVersion) {
-                taskHelper.showVersion(options.fullVersion);
+                TASK_HELPER.showVersion(options.fullVersion);
+
+                if (unhandled.isEmpty()) {
+                    return EXIT_OK;
+                }
             }
-            boolean ok = run();
-            return ok ? EXIT_OK : EXIT_ERROR;
+
+            processFilter(options.filters);
+
+            return run() ? EXIT_OK : EXIT_ERROR;
         } catch (BadArgs e) {
-            taskHelper.reportError(e.key, e.args);
+            TASK_HELPER.reportError(e.key, e.args);
+
             if (e.showUsage) {
-                log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
+                log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
             }
+
             return EXIT_CMDERR;
         } catch (Exception x) {
             x.printStackTrace();
+
             return EXIT_ABNORMAL;
         } finally {
             log.flush();
         }
     }
 
+    private void processFilter(String filters) {
+        if (filters.isEmpty()) {
+            return;
+        }
+
+        for (String filter : filters.split(",")) {
+            final PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, filter);
+            Predicate<String> predicate = (path) -> matcher.matches(JRT_FILE_SYSTEM.getPath(path));
+            filterPredicates.add(predicate);
+        }
+    }
+
     private void listTitle(File file, BasicImageReader reader) {
         log.println("jimage: " + file);
     }
@@ -216,10 +278,12 @@
 
         if (parent.exists()) {
             if (!parent.isDirectory()) {
-                throw taskHelper.newBadArgs("err.cannot.create.dir", parent.getAbsolutePath());
+                throw TASK_HELPER.newBadArgs("err.cannot.create.dir",
+                                            parent.getAbsolutePath());
             }
         } else if (!parent.mkdirs()) {
-            throw taskHelper.newBadArgs("err.cannot.create.dir", parent.getAbsolutePath());
+            throw TASK_HELPER.newBadArgs("err.cannot.create.dir",
+                                        parent.getAbsolutePath());
         }
 
         if (!ImageResourcesTree.isTreeInfoResource(name)) {
@@ -261,7 +325,7 @@
 
         log.println(" Major Version:  " + header.getMajorVersion());
         log.println(" Minor Version:  " + header.getMinorVersion());
-        log.println(" Flags:          " + Integer.toHexString(header.getMinorVersion()));
+        log.println(" Flags:          " + Integer.toHexString(header.getFlags()));
         log.println(" Resource Count: " + header.getResourceCount());
         log.println(" Table Length:   " + header.getTableLength());
         log.println(" Offsets Size:   " + header.getOffsetsSize());
@@ -287,36 +351,7 @@
         print(reader, name);
     }
 
-    void set(File file, BasicImageReader reader) throws BadArgs {
-        try {
-            ImageHeader oldHeader = reader.getHeader();
-
-            int value = 0;
-            try {
-                value = Integer.valueOf(options.flags);
-            } catch (NumberFormatException ex) {
-                throw taskHelper.newBadArgs("err.flags.not.int", options.flags);
-            }
-
-            ImageHeader newHeader = new ImageHeader(MAGIC, MAJOR_VERSION, MINOR_VERSION,
-                    value,
-                    oldHeader.getResourceCount(), oldHeader.getTableLength(),
-                    oldHeader.getLocationsSize(), oldHeader.getStringsSize());
-
-            ByteBuffer buffer = ByteBuffer.allocate(ImageHeader.getHeaderSize());
-            buffer.order(ByteOrder.nativeOrder());
-            newHeader.writeTo(buffer);
-            buffer.rewind();
-
-            try (FileChannel channel = FileChannel.open(file.toPath(), READ, WRITE)) {
-                channel.write(buffer, 0);
-            }
-        } catch (IOException ex) {
-            throw taskHelper.newBadArgs("err.cannot.update.file", file.getName());
-        }
-    }
-
-     void verify(BasicImageReader reader, String name, ImageLocation location) {
+      void verify(BasicImageReader reader, String name, ImageLocation location) {
         if (name.endsWith(".class")) {
             byte[] bytes = reader.getResource(location);
 
@@ -335,12 +370,12 @@
             ModuleAction moduleAction,
             ResourceAction resourceAction) throws IOException, BadArgs {
         if (options.jimages.isEmpty()) {
-            throw taskHelper.newBadArgs("err.no.jimage");
+            throw TASK_HELPER.newBadArgs("err.no.jimage");
         }
 
         for (File file : options.jimages) {
             if (!file.exists() || !file.isFile()) {
-                throw taskHelper.newBadArgs("err.not.a.jimage", file.getName());
+                throw TASK_HELPER.newBadArgs("err.not.a.jimage", file.getName());
             }
 
             try (BasicImageReader reader = BasicImageReader.open(file.toPath())) {
@@ -353,6 +388,19 @@
                     String oldModule = "";
 
                     for (String name : entryNames) {
+                        boolean match = filterPredicates.isEmpty();
+
+                        for (Predicate<String> predicate : filterPredicates) {
+                            if (predicate.test(name)) {
+                                match = true;
+                                break;
+                            }
+                        }
+
+                        if (!match) {
+                            continue;
+                        }
+
                         if (!ImageResourcesTree.isTreeInfoResource(name)) {
                             if (moduleAction != null) {
                                 int offset = name.indexOf('/', 1);
@@ -387,21 +435,13 @@
             case LIST:
                 iterate(this::listTitle, this::listModule, this::list);
                 break;
-            case SET:
-                iterate(this::set, null, null);
-                break;
             case VERIFY:
                 iterate(this::listTitle, null, this::verify);
                 break;
             default:
-                throw taskHelper.newBadArgs("err.invalid.task", options.task.name()).showUsage(true);
+                throw TASK_HELPER.newBadArgs("err.invalid.task",
+                        options.task.name()).showUsage(true);
         }
         return true;
     }
-
-    private PrintWriter log;
-    void setLog(PrintWriter out) {
-        log = out;
-        taskHelper.setLog(log);
-    }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties	Thu Jun 09 19:07:27 2016 +0000
@@ -24,54 +24,67 @@
 #
 
 main.usage.summary=\
-Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
-use --help for a list of possible options
+Usage: {0} <extract | info | list | verify> <options> jimage...\n\
+use --help for a list of possible options.
 
 main.usage=\
-Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
+Usage: {0} <extract | info | list | verify> <options> jimage...\n\
+\n\
+\  extract  - Extract all jimage entries and place in a directory specified\n\
+\             by the --dir=<directory> (default='.') option.\n\
 \n\
-\  extract  - Extract all jimage entries into separate files into the directory\n\
-\             specified by --dir=<directory> (default='.')\n\
-\  info     - Prints information specified in the jimage header.\n\
+\  info     - Prints detailed information contained in the jimage header.\n\
+\n\
 \  list     - Prints the names of all the entries in the jimage.  When used with\n\
-\             --verbose will also print entry attributes ex. size and offset.\n\
-\  set      - sets the value of specific jimage header entries\n\
-\  verify   - Reports errors on any .class entries that don't verify as classes.\n\
+\             --verbose, list will also print entry size and offset attributes.\n\
+\n\
+\  verify   - Reports on any .class entries that don't verify as classes.\n\
 \n\
 Possible options include:
 
+main.usage.extract=\
+\  extract  - Extract all jimage entries and place in a directory specified\n\
+\             by the --dir=<directory> (default='.') option.
+
+main.usage.info=\
+\  info     - Prints detailed information contained in the jimage header.
+
+main.usage.list=\
+\  list     - Prints the names of all the entries in the jimage.  When used with\n\
+\             --verbose, list will also print entry size and offset attributes.
+
+main.usage.verify=\
+\  verify   - Reports errors on any .class entries that don't verify as classes.
+
 error.prefix=Error:
 warn.prefix=Warning:
 
 main.opt.dir=\
-\  --dir                                Target directory for extract
+\  --dir                             Target directory for extract directive
 
-main.opt.flags=\
-\  --flags=value                        Set the jimage flags to value
+main.opt.filter=\
+\  --filter                          Filter entries for list or extract\n\
+\                                    Ex. /java.base/*, */module-info.class
+
+main.opt.fullversion=\
+\  --fullversion                     Print full version information
 
 main.opt.help=\
-\  --help                               Print this usage message
+\  --help                            Print usage message
 
 main.opt.verbose=\
-\  --verbose                            Verbose listing
+\  --verbose                         Listing prints entry size and offset attributes
 
 main.opt.version=\
-\  --version                            Version information
+\  --version                         Print version information
 
 main.command.files=\
-\  @<filename>                          Read options from file
-err.cannot.read.file=cannot read file: {0}
-err.cannot.update.file=cannot update file: {0}
-err.file.not.found=cannot find file: {0}
-err.file.error=cannot access file: {0}
-err.flags.not.int=--flags value not integer: {0}
-err.internal.error=internal error: {0} {1} {2}
-err.invalid.arg.for.option=invalid argument for option: {0}
-err.invalid.task=task must be extract|info|list|verify: {0}
+\  @<filename>                       Read options from file
+
+err.not.a.task=task must be one of <extract | info | list | verify>: {0}
 err.missing.arg=no value given for {0}
 err.not.a.dir=not a directory: {0}
 err.not.a.jimage=not a jimage file: {0}
 err.no.jimage=no jimage provided
-err.not.a.task=not a valid task: {0}
 err.option.unsupported={0} not supported: {1}
 err.unknown.option=unknown option: {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Thu Jun 09 19:07:27 2016 +0000
@@ -186,7 +186,7 @@
 
     int run(String[] args) {
         if (log == null) {
-            setLog(new PrintWriter(System.err));
+            setLog(new PrintWriter(System.err, true));
         }
         try {
             optionsHelper.handleOptions(this, args);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java	Thu Jun 09 19:07:27 2016 +0000
@@ -136,6 +136,10 @@
         void process(T task, String opt, String arg) throws BadArgs {
             processing.process(task, opt, arg);
         }
+
+        public String[] aliases() {
+            return aliases;
+        }
     }
 
     private static class PlugOption extends Option<PluginsOptions> {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java	Thu Jun 09 19:07:27 2016 +0000
@@ -25,6 +25,10 @@
 package jdk.tools.jlink.internal;
 
 import java.lang.reflect.Module;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.PathMatcher;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
@@ -155,4 +159,20 @@
     public static boolean isBuiltin(Plugin prov) {
         return THIS_MODULE.equals(prov.getClass().getModule());
     }
+
+    public static FileSystem jrtFileSystem() {
+        return FileSystems.getFileSystem(URI.create("jrt:/"));
+    }
+
+    public static PathMatcher getPathMatcher(FileSystem fs, String pattern) {
+        if (!pattern.startsWith("glob:") && !pattern.startsWith("regex:")) {
+            pattern = "glob:" + pattern;
+        }
+
+        return fs.getPathMatcher(pattern);
+    }
+
+    public static PathMatcher getPathMatcher(String pattern) {
+        return getPathMatcher(jrtFileSystem(), pattern);
+    }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java	Thu Jun 09 19:07:27 2016 +0000
@@ -26,7 +26,9 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.FileSystem;
 import java.nio.file.Files;
+import java.nio.file.PathMatcher;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -47,6 +49,8 @@
  */
 public final class OrderResourcesPlugin implements TransformerPlugin {
     public static final String NAME = "order-resources";
+    private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
+
     private final List<ToIntFunction<String>> filters;
     private final Map<String, Integer> orderedPaths;
 
@@ -187,27 +191,11 @@
                     }
                 }
             } else {
-                boolean endsWith = pattern.startsWith("*");
-                boolean startsWith = pattern.endsWith("*");
-                ToIntFunction<String> function;
                 final int result = ordinal++;
-
-                if (startsWith && endsWith) {
-                    final String string = pattern.substring(1, pattern.length() - 1);
-                    function = (path)-> path.contains(string) ? result : Integer.MAX_VALUE;
-                } else if (startsWith) {
-                    final String string = pattern.substring(0, pattern.length() - 1);
-                    function = (path)-> path.startsWith(string) ? result : Integer.MAX_VALUE;
-                } else if (endsWith) {
-                    final String string = pattern.substring(1);
-                    function = (path)-> path.endsWith(string) ? result : Integer.MAX_VALUE;
-                } else {
-                    final String string = pattern;
-                    function = (path)-> path.equals(string) ? result : Integer.MAX_VALUE;
-                }
-
+                final PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, pattern);
+                ToIntFunction<String> function = (path)-> matcher.matches(JRT_FILE_SYSTEM.getPath(path)) ? result : Integer.MAX_VALUE;
                 filters.add(function);
-            }
+             }
         }
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java	Thu Jun 09 19:07:27 2016 +0000
@@ -24,113 +24,71 @@
  */
 package jdk.tools.jlink.internal.plugins;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Predicate;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
+import jdk.tools.jlink.internal.Utils;
+import jdk.tools.jlink.plugin.PluginException;
 
 /**
  *
- * Filter in or out a resource
+ * Filter resource resources using path matcher.
  */
 public class ResourceFilter implements Predicate<String> {
+    private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
 
-    private final Pattern inPatterns;
-    private final Pattern outPatterns;
-
-    static final String NEG = "^";
+    final boolean negate;
+    final List<PathMatcher> matchers;
 
     public ResourceFilter(String[] patterns) throws IOException {
         this(patterns, false);
     }
 
-    public ResourceFilter(String[] patterns, boolean negateAll) throws IOException {
+    public ResourceFilter(String[] patterns, boolean negate) throws IOException {
+        this.negate = negate;
+        this.matchers = new ArrayList<>();
+
+        for (String pattern : patterns) {
+            if (pattern.startsWith("@")) {
+                File file = new File(pattern.substring(1));
+
+                if (file.exists()) {
+                    List<String> lines;
+
+                    try {
+                        lines = Files.readAllLines(file.toPath());
+                    } catch (IOException ex) {
+                        throw new PluginException(ex);
+                    }
 
-        // Get the patterns from a file
-        if (patterns != null && patterns.length == 1) {
-            String filePath = patterns[0];
-            File f = new File(filePath);
-            if (f.exists()) {
-                List<String> pats;
-                try (FileInputStream fis = new FileInputStream(f);
-                        InputStreamReader ins = new InputStreamReader(fis,
-                                StandardCharsets.UTF_8);
-                        BufferedReader reader = new BufferedReader(ins)) {
-                    pats = reader.lines().collect(Collectors.toList());
+                    for (String line : lines) {
+                        PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, line);
+                        matchers.add(matcher);
+                    }
                 }
-                patterns = new String[pats.size()];
-                pats.toArray(patterns);
+            } else {
+                PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, pattern);
+                matchers.add(matcher);
+            }
+        }
+    }
+
+    @Override
+    public boolean test(String name) {
+        Path path = JRT_FILE_SYSTEM.getPath(name);
+
+        for (PathMatcher matcher : matchers) {
+            if (matcher.matches(path)) {
+                return !negate;
             }
         }
 
-        if (patterns != null && negateAll) {
-            String[] excluded = new String[patterns.length];
-            for (int i = 0; i < patterns.length; i++) {
-                excluded[i] = ResourceFilter.NEG + patterns[i];
-            }
-            patterns = excluded;
-        }
-
-        StringBuilder inPatternsBuilder = new StringBuilder();
-        StringBuilder outPatternsBuilder = new StringBuilder();
-        if (patterns != null) {
-            for (int i = 0; i < patterns.length; i++) {
-                String p = patterns[i];
-                p = p.replaceAll(" ", "");
-                StringBuilder builder = p.startsWith(NEG)
-                        ? outPatternsBuilder : inPatternsBuilder;
-                String pat = p.startsWith(NEG) ? p.substring(NEG.length()) : p;
-                builder.append(escape(pat));
-                if (i < patterns.length - 1) {
-                    builder.append("|");
-                }
-            }
-        }
-        this.inPatterns = inPatternsBuilder.length() == 0 ? null
-                : Pattern.compile(inPatternsBuilder.toString());
-        this.outPatterns = outPatternsBuilder.length() == 0 ? null
-                : Pattern.compile(outPatternsBuilder.toString());
-    }
-
-    public static String escape(String s) {
-        s = s.replaceAll(" ", "");
-        s = s.replaceAll("\\$", Matcher.quoteReplacement("\\$"));
-        s = s.replaceAll("\\.", Matcher.quoteReplacement("\\."));
-        s = s.replaceAll("\\*", ".+");
-        return s;
-    }
-
-    private boolean accept(String path) {
-        if (outPatterns != null) {
-            Matcher mout = outPatterns.matcher(path);
-            if (mout.matches()) {
-                //System.out.println("Excluding file " + resource.getPath());
-                return false;
-            }
-        }
-        boolean accepted = false;
-        // If the inPatterns is null, means that all resources are accepted.
-        if (inPatterns == null) {
-            accepted = true;
-        } else {
-            Matcher m = inPatterns.matcher(path);
-            if (m.matches()) {
-                //System.out.println("Including file " + resource.getPath());
-                accepted = true;
-            }
-        }
-        return accepted;
-    }
-
-    @Override
-    public boolean test(String path) {
-        return accept(path);
+        return negate;
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Thu Jun 09 19:07:27 2016 +0000
@@ -1072,6 +1072,10 @@
         @Override
         public Pattern convert(String value) {
             try {
+                if (value.startsWith("regex:")) {
+                    value = value.substring("regex:".length()).trim();
+                }
+
                 return Pattern.compile(value);
             } catch (PatternSyntaxException e) {
                 throw new CommandException("err.bad.pattern", value);
@@ -1083,10 +1087,15 @@
         @Override public String valuePattern() { return "pattern"; }
     }
 
-    static class GlobConverter implements ValueConverter<PathMatcher> {
+    static class PathMatcherConverter implements ValueConverter<PathMatcher> {
         @Override
         public PathMatcher convert(String pattern) {
             try {
+                if (!pattern.startsWith("glob:") &&
+                    !pattern.startsWith("regex:")) {
+                    pattern = "glob:" + pattern;
+                }
+
                 return FileSystems.getDefault()
                                   .getPathMatcher("glob:" + pattern);
             } catch (PatternSyntaxException e) {
@@ -1194,7 +1203,7 @@
         OptionSpec<PathMatcher> excludes
                 = parser.accepts("exclude", getMessage("main.opt.exclude"))
                         .withRequiredArg()
-                        .withValuesConvertedBy(new GlobConverter());
+                        .withValuesConvertedBy(new PathMatcherConverter());
 
         OptionSpec<Pattern> hashModules
                 = parser.accepts("hash-modules", getMessage("main.opt.hash-modules"))
--- a/jdk/test/ProblemList.txt	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/ProblemList.txt	Thu Jun 09 19:07:27 2016 +0000
@@ -167,6 +167,8 @@
 
 java/net/DatagramSocket/SendDatagramToBadAddress.java           7143960 macosx-all
 
+sun/net/www/http/ChunkedOutputStream/checkError.java            8041924 linux-all
+
 ############################################################################
 
 # jdk_nio
@@ -199,6 +201,8 @@
 
 sun/rmi/rmic/newrmic/equivalence/run.sh                         8145980 generic-all
 
+java/rmi/transport/dgcDeadLock/DGCDeadLock.java                 8029360 macosx-all
+
 ############################################################################
 
 # jdk_security
--- a/jdk/test/com/sun/crypto/provider/Cipher/TestCipher.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/com/sun/crypto/provider/Cipher/TestCipher.java	Thu Jun 09 19:07:27 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -150,11 +150,6 @@
         }
 
         // Encryption
-        int PAD_LEN = 0;
-        if (pad.equalsIgnoreCase("PKCS5Padding")) {
-            // Need to consider pad bytes
-            PAD_LEN = 8;
-        }
 
         byte[] plainText = INPUT_TEXT.clone();
 
@@ -162,12 +157,13 @@
         byte[] cipherText = ci.doFinal(INPUT_TEXT, ENC_OFFSET, TEXT_LEN);
 
         // Generate cipher and save to same buffer
-        int offset = ci.update(
+        int enc_bytes = ci.update(
                 INPUT_TEXT, ENC_OFFSET, TEXT_LEN, INPUT_TEXT, STORAGE_OFFSET);
-        ci.doFinal(INPUT_TEXT, offset + STORAGE_OFFSET);
+        enc_bytes += ci.doFinal(INPUT_TEXT, enc_bytes + STORAGE_OFFSET);
 
         if (!equalsBlock(
-                INPUT_TEXT, STORAGE_OFFSET, cipherText, 0, cipherText.length)) {
+                INPUT_TEXT, STORAGE_OFFSET, enc_bytes,
+                cipherText, 0, cipherText.length)) {
             throw new RuntimeException(
                     "Different ciphers generated with same buffer");
         }
@@ -183,8 +179,8 @@
         byte[] recoveredText = ci.doFinal(cipherText, 0, cipherText.length);
 
         if (!equalsBlock(
-                plainText, ENC_OFFSET, recoveredText, 0,
-                recoveredText.length)) {
+                plainText, ENC_OFFSET, TEXT_LEN,
+                recoveredText, 0, recoveredText.length)) {
             throw new RuntimeException(
                     "Recovered text not same as plain text");
         } else {
@@ -192,13 +188,13 @@
         }
 
         // Recover text from cipher and save to same buffer
-        ci.update(INPUT_TEXT, STORAGE_OFFSET, TEXT_LEN + PAD_LEN, INPUT_TEXT,
-                ENC_OFFSET);
-        ci.doFinal(INPUT_TEXT, ENC_OFFSET);
+        int dec_bytes = ci.update(
+                INPUT_TEXT, STORAGE_OFFSET, enc_bytes, INPUT_TEXT, ENC_OFFSET);
+        dec_bytes += ci.doFinal(INPUT_TEXT, dec_bytes + ENC_OFFSET);
 
         if (!equalsBlock(
-                plainText, ENC_OFFSET, recoveredText, 0,
-                recoveredText.length)) {
+                plainText, ENC_OFFSET, TEXT_LEN,
+                INPUT_TEXT, ENC_OFFSET, dec_bytes)) {
             throw new RuntimeException(
                     "Recovered text not same as plain text with same buffer");
         } else {
@@ -208,9 +204,12 @@
         out.println("Test Passed.");
     }
 
-    private static boolean equalsBlock(byte[] b1, int off1, byte[] b2, int off2,
-            int len) {
-        for (int i = off1, j = off2, k = 0; k < len; i++, j++, k++) {
+    private static boolean equalsBlock(byte[] b1, int off1, int len1,
+            byte[] b2, int off2, int len2) {
+        if (len1 != len2) {
+            return false;
+        }
+        for (int i = off1, j = off2, k = 0; k < len1; i++, j++, k++) {
             if (b1[i] != b2[j]) {
                 return false;
             }
--- a/jdk/test/java/lang/String/concat/WithSecurityManager.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/java/lang/String/concat/WithSecurityManager.java	Thu Jun 09 19:07:27 2016 +0000
@@ -26,7 +26,7 @@
 /**
  * @test
  * @summary String concatenation fails with a custom SecurityManager that uses concatenation
- * @bug 8155090
+ * @bug 8155090 8158851
  *
  * @compile WithSecurityManager.java
  *
@@ -37,17 +37,43 @@
  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      WithSecurityManager
  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      WithSecurityManager
  * @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  WithSecurityManager
+ *
+ * @run main/othervm -Xverify:all -limitmods java.base WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB                  WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED            WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED            WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT      WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT      WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT  WithSecurityManager
 */
 public class WithSecurityManager {
     public static void main(String[] args) throws Throwable {
-        SecurityManager sm = new SecurityManager() {
-            @Override
-            public void checkPermission(Permission perm) {
-                String abc = "abc";
-                String full = abc + "def";
-            }
-        };
-        System.setSecurityManager(sm);
-        ClassLoader cl = new ClassLoader() {};
+        // First time should succeed to bootstrap everything
+        {
+            SecurityManager sm = new SecurityManager() {
+                @Override
+                public void checkPermission(Permission perm) {
+                    String abc = "abc";
+                    String full = abc + "def";
+                }
+            };
+            System.setSecurityManager(sm);
+            ClassLoader cl = new ClassLoader() {
+            };
+        }
+
+        // Second time should succeed to run after bootstrapping
+        {
+            SecurityManager sm = new SecurityManager() {
+                @Override
+                public void checkPermission(Permission perm) {
+                    String abc = "abc";
+                    String full = abc + "def";
+                }
+            };
+            System.setSecurityManager(sm);
+            ClassLoader cl = new ClassLoader() {
+            };
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/AnnotationWithLambda.java	Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8147585
+ * @summary Check Annotation with Lambda, with or without parameter
+ * @run testng AnnotationWithLambda
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.function.Consumer;
+
+import org.testng.annotations.*;
+import static org.testng.Assert.*;
+
+public class AnnotationWithLambda {
+
+    @Test
+    void testAnnotationWithLambda() {
+        Method[] methods = AnnotationWithLambda.MethodsWithAnnotations.class.getDeclaredMethods();
+        for (Method method : methods) {
+            assertTrue((method.isAnnotationPresent(LambdaWithParameter.class)) &&
+                       (method.isAnnotationPresent(LambdaWithoutParameter.class)));
+
+        }
+    }
+
+    static class MethodsWithAnnotations {
+
+        @LambdaWithParameter
+        @LambdaWithoutParameter
+        public void testAnnotationLambda() {
+        }
+    }
+}
+
+@Target(value = ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface LambdaWithParameter {
+    Consumer<Integer> f1 = a -> {
+        System.out.println("lambda has parameter");
+    };
+}
+
+@Target(value = ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface LambdaWithoutParameter {
+    Runnable r = () -> System.out.println("lambda without parameter");
+}
+
--- a/jdk/test/java/net/httpclient/BasicWebSocketAPITest.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/java/net/httpclient/BasicWebSocketAPITest.java	Thu Jun 09 19:07:27 2016 +0000
@@ -30,6 +30,7 @@
 import java.net.http.WebSocket;
 import java.net.http.WebSocket.CloseCode;
 import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
 import java.nio.channels.SocketChannel;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
@@ -92,12 +93,24 @@
         );
         checkAndClose(
                 (ws) ->
+                        TestKit.assertThrows(IllegalArgumentException.class,
+                                ".*message.*",
+                                () -> ws.sendPing(ByteBuffer.allocate(126)))
+        );
+        checkAndClose(
+                (ws) ->
                         TestKit.assertThrows(NullPointerException.class,
                                 "message",
                                 () -> ws.sendPing(null))
         );
         checkAndClose(
                 (ws) ->
+                        TestKit.assertThrows(IllegalArgumentException.class,
+                                ".*message.*",
+                                () -> ws.sendPong(ByteBuffer.allocate(126)))
+        );
+        checkAndClose(
+                (ws) ->
                         TestKit.assertThrows(NullPointerException.class,
                                 "message",
                                 () -> ws.sendPong(null))
@@ -106,7 +119,7 @@
                 (ws) ->
                         TestKit.assertThrows(NullPointerException.class,
                                 "message",
-                                () -> ws.sendText((CharSequence) null, true))
+                                () -> ws.sendText(null, true))
         );
         checkAndClose(
                 (ws) ->
@@ -122,6 +135,12 @@
         );
         checkAndClose(
                 (ws) ->
+                        TestKit.assertThrows(IllegalArgumentException.class,
+                                "(?i).*reason.*",
+                                () -> ws.sendClose(CloseCode.NORMAL_CLOSURE, CharBuffer.allocate(124)))
+        );
+        checkAndClose(
+                (ws) ->
                         TestKit.assertThrows(NullPointerException.class,
                                 "code",
                                 () -> ws.sendClose(null, ""))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/ALPN/SSLServerSocketAlpnTest.java	Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8051498 8145849 8158978
+ * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @compile MyX509ExtendedKeyManager.java
+ * @run main/othervm SSLServerSocketAlpnTest h2          h2          h2
+ * @run main/othervm SSLServerSocketAlpnTest h2          h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest h2,http/1.1 h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest http/1.1,h2 h2,http/1.1 http/1.1
+ * @run main/othervm SSLServerSocketAlpnTest h4,h3,h2    h1,h2       h2
+ * @run main/othervm SSLServerSocketAlpnTest EMPTY       h2,http/1.1 NONE
+ * @run main/othervm SSLServerSocketAlpnTest h2          EMPTY       NONE
+ * @run main/othervm SSLServerSocketAlpnTest H2          h2          ERROR
+ * @run main/othervm SSLServerSocketAlpnTest h2          http/1.1    ERROR
+ * @author Brad Wetmore
+ */
+import java.io.*;
+import java.security.KeyStore;
+
+import javax.net.ssl.*;
+
+public class SSLServerSocketAlpnTest {
+
+    /*
+     * =============================================================
+     * 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 = false;
+
+    /*
+     * Where do we find the keystores?
+     */
+    static String pathToStores = "../etc";
+    static String keyStoreFile = "keystore";
+    static String trustStoreFile = "truststore";
+    static String passwd = "passphrase";
+
+    static String keyFilename = System.getProperty("test.src", ".") + "/"
+            + pathToStores + "/" + keyStoreFile;
+    static String trustFilename = System.getProperty("test.src", ".") + "/"
+            + pathToStores + "/" + trustStoreFile;
+
+    /*
+     * SSLContext
+     */
+    SSLContext mySSLContext = null;
+
+    /*
+     * Is the server ready to serve?
+     */
+    volatile static boolean serverReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    static boolean debug = false;
+
+    static String[] serverAPs;
+    static String[] clientAPs;
+    static String expectedAP;
+
+    /*
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang. The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
+
+    /*
+     * 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 = mySSLContext.getServerSocketFactory();
+        SSLServerSocket sslServerSocket
+                = (SSLServerSocket) sslssf.createServerSocket(serverPort);
+        sslServerSocket.setNeedClientAuth(true);
+
+        SSLParameters sslp = sslServerSocket.getSSLParameters();
+
+        // for both client/server to call into X509KM
+        sslp.setNeedClientAuth(true);
+
+        /*
+         * The default ciphersuite ordering from the SSLContext may not
+         * reflect "h2" ciphersuites as being preferred, additionally the
+         * client may not send them in an appropriate order. We could resort
+         * the suite list if so desired.
+         */
+        String[] suites = sslp.getCipherSuites();
+        sslp.setCipherSuites(suites);
+        sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+        // Set the ALPN selection.
+        sslp.setApplicationProtocols(serverAPs);
+        sslServerSocket.setSSLParameters(sslp);
+
+        serverPort = sslServerSocket.getLocalPort();
+
+        /*
+         * Signal Client, we're ready for his connect.
+         */
+        serverReady = true;
+
+        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+
+        if (sslSocket.getHandshakeApplicationProtocol() != null) {
+            throw new Exception ("getHandshakeApplicationProtocol() should "
+                    + "return null before the handshake starts");
+        }
+
+        sslSocket.startHandshake();
+
+        if (sslSocket.getHandshakeApplicationProtocol() != null) {
+            throw new Exception ("getHandshakeApplicationProtocol() should "
+                    + "return null after the handshake is completed");
+        }
+
+        String ap = sslSocket.getApplicationProtocol();
+        System.out.println("Application Protocol: \"" + ap + "\"");
+
+        if (ap == null) {
+            throw new Exception(
+                    "Handshake was completed but null was received");
+        }
+        if (expectedAP.equals("NONE")) {
+            if (!ap.isEmpty()) {
+                throw new Exception("Expected no ALPN value");
+            } else {
+                System.out.println("No ALPN value negotiated, as expected");
+            }
+        } else if (!expectedAP.equals(ap)) {
+            throw new Exception(expectedAP
+                    + " ALPN value not available on negotiated connection");
+        }
+
+        InputStream sslIS = sslSocket.getInputStream();
+        OutputStream sslOS = sslSocket.getOutputStream();
+
+        sslIS.read();
+        sslOS.write(85);
+        sslOS.flush();
+
+        sslSocket.close();
+    }
+
+    /*
+     * 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);
+        }
+
+        SSLSocketFactory sslsf = mySSLContext.getSocketFactory();
+        SSLSocket sslSocket
+                = (SSLSocket) sslsf.createSocket("localhost", serverPort);
+
+        SSLParameters sslp = sslSocket.getSSLParameters();
+
+        /*
+         * The default ciphersuite ordering from the SSLContext may not
+         * reflect "h2" ciphersuites as being preferred, additionally the
+         * client may not send them in an appropriate order. We could resort
+         * the suite list if so desired.
+         */
+        String[] suites = sslp.getCipherSuites();
+        sslp.setCipherSuites(suites);
+        sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+        // Set the ALPN selection.
+        sslp.setApplicationProtocols(clientAPs);
+        sslSocket.setSSLParameters(sslp);
+
+        if (sslSocket.getHandshakeApplicationProtocol() != null) {
+            throw new Exception ("getHandshakeApplicationProtocol() should "
+                    + "return null before the handshake starts");
+        }
+
+        sslSocket.startHandshake();
+
+        if (sslSocket.getHandshakeApplicationProtocol() != null) {
+            throw new Exception ("getHandshakeApplicationProtocol() should "
+                    + "return null after the handshake is completed");
+        }
+
+        /*
+         * Check that the resulting connection meets our defined ALPN
+         * criteria.  If we were connecting to a non-JSSE implementation,
+         * the server might have negotiated something we shouldn't accept.
+         */
+        String ap = sslSocket.getApplicationProtocol();
+        System.out.println("Application Protocol: \"" + ap + "\"");
+
+        if (ap == null) {
+            throw new Exception(
+                    "Handshake was completed but null was received");
+        }
+        if (expectedAP.equals("NONE")) {
+            if (!ap.isEmpty()) {
+                throw new Exception("Expected no ALPN value");
+            } else {
+                System.out.println("No ALPN value negotiated, as expected");
+            }
+        } else if (!expectedAP.equals(ap)) {
+            throw new Exception(expectedAP
+                    + " ALPN value not available on negotiated connection");
+        }
+
+        InputStream sslIS = sslSocket.getInputStream();
+        OutputStream sslOS = sslSocket.getOutputStream();
+
+        sslOS.write(280);
+        sslOS.flush();
+        sslIS.read();
+
+        sslSocket.close();
+    }
+
+    /*
+     * =============================================================
+     * 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 {
+
+        if (debug) {
+            System.setProperty("javax.net.debug", "all");
+        }
+
+        // Validate parameters
+        if (args.length != 3) {
+            throw new Exception("Invalid number of test parameters");
+        }
+        serverAPs = convert(args[0]);
+        clientAPs = convert(args[1]);
+        expectedAP = args[2];
+
+        /*
+         * Start the tests.
+         */
+        try {
+            new SSLServerSocketAlpnTest();
+        } catch (SSLHandshakeException she) {
+            if (args[2].equals("ERROR")) {
+                System.out.println("Caught the expected exception: " + she);
+            } else {
+                throw she;
+            }
+        }
+
+        System.out.println("Test Passed.");
+    }
+
+    SSLContext getSSLContext(String keyFilename, String trustFilename)
+            throws Exception {
+        SSLContext ctx = SSLContext.getInstance("TLS");
+
+        // Keystores
+        KeyStore keyKS = KeyStore.getInstance("JKS");
+        keyKS.load(new FileInputStream(keyFilename), passwd.toCharArray());
+
+        KeyStore trustKS = KeyStore.getInstance("JKS");
+        trustKS.load(new FileInputStream(trustFilename), passwd.toCharArray());
+
+        // Generate KeyManager and TrustManager
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+        kmf.init(keyKS, passwd.toCharArray());
+
+        KeyManager[] kms = kmf.getKeyManagers();
+        if (!(kms[0] instanceof X509ExtendedKeyManager)) {
+            throw new Exception("kms[0] not X509ExtendedKeyManager");
+        }
+
+        kms = new KeyManager[] { new MyX509ExtendedKeyManager(
+                (X509ExtendedKeyManager) kms[0], expectedAP) };
+
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+        tmf.init(trustKS);
+        TrustManager[] tms = tmf.getTrustManagers();
+
+        // initial SSLContext
+        ctx.init(kms, tms, null);
+
+        return ctx;
+    }
+
+    /*
+     * Convert a comma-separated list into an array of strings.
+     */
+    private static String[] convert(String list) {
+        String[] strings;
+
+        if (list.equals("EMPTY")) {
+            return new String[0];
+        }
+
+        if (list.indexOf(',') > 0) {
+            strings = list.split(",");
+        } else {
+            strings = new String[]{ list };
+        }
+
+        return strings;
+    }
+
+    Thread clientThread = null;
+    Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    SSLServerSocketAlpnTest() throws Exception {
+        Exception startException = null;
+        mySSLContext = getSSLContext(keyFilename, trustFilename);
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            startException = e;
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            if (serverThread != null) {
+                serverThread.join();
+            }
+        } else {
+            if (clientThread != null) {
+                clientThread.join();
+            }
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+        } else {
+            remote = clientException;
+            local = serverException;
+        }
+
+        Exception exception = null;
+
+        /*
+         * Check various exception conditions.
+         */
+        if ((local != null) && (remote != null)) {
+            // If both failed, return the curthread's exception.
+            local.initCause(remote);
+            exception = local;
+        } else if (local != null) {
+            exception = local;
+        } else if (remote != null) {
+            exception = remote;
+        } else if (startException != null) {
+            exception = startException;
+        }
+
+        /*
+         * If there was an exception *AND* a startException,
+         * output it.
+         */
+        if (exception != null) {
+            if (exception != startException && startException != null) {
+                exception.addSuppressed(startException);
+            }
+            throw exception;
+        }
+
+        // Fall-through: no exception to throw!
+    }
+
+    void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                @Override
+                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 {
+            try {
+                doServerSide();
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = true;
+            }
+        }
+    }
+
+    void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.err.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
+        }
+    }
+}
--- a/jdk/test/sun/security/provider/DSA/SupportedDSAParamGen.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/sun/security/provider/DSA/SupportedDSAParamGen.java	Thu Jun 09 19:07:27 2016 +0000
@@ -28,7 +28,7 @@
  * @run main/timeout=300 SupportedDSAParamGen 1024 160
  * @run main/timeout=300 SupportedDSAParamGen 2048 224
  * @run main/timeout=300 SupportedDSAParamGen 2048 256
- * @run main/timeout=450 SupportedDSAParamGen 3072 256
+ * @run main/timeout=700 SupportedDSAParamGen 3072 256
  */
 import java.security.*;
 import java.security.spec.*;
--- a/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java	Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java	Thu Jun 09 19:07:27 2016 +0000
@@ -31,9 +31,6 @@
 import java.security.spec.DSAGenParameterSpec;
 import java.security.spec.DSAParameterSpec;
 import java.security.spec.InvalidParameterSpecException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
 
 /*
  * @test
@@ -43,8 +40,15 @@
  *          DSA within some certain range of key sizes as described in the class
  *          specification (L, N) as (1024, 160), (2048, 224), (2048, 256) and
  *          (3072, 256) should be OK for DSAGenParameterSpec.
- * @run main TestDSAGenParameterSpec 2048,256,true 2048,224,true 1024,160,true 4096,256 3072,224 2048,160 1024,224 512,160
- * @run main TestDSAGenParameterSpec 3072,256,true
+ * @run main TestDSAGenParameterSpec 512 160
+ * @run main TestDSAGenParameterSpec 1024 160 true
+ * @run main TestDSAGenParameterSpec 1024 224
+ * @run main TestDSAGenParameterSpec 2048 160
+ * @run main/timeout=300 TestDSAGenParameterSpec 2048 224 true
+ * @run main/timeout=300 TestDSAGenParameterSpec 2048 256 true
+ * @run main TestDSAGenParameterSpec 3072 224
+ * @run main/timeout=700 TestDSAGenParameterSpec 3072 256 true
+ * @run main TestDSAGenParameterSpec 4096 256
  */
 public class TestDSAGenParameterSpec {
 
@@ -57,8 +61,8 @@
         System.out.printf("Test case: primePLen=%d, " + "subprimeQLen=%d%n",
                 dataTuple.primePLen, dataTuple.subprimeQLen);
 
-        AlgorithmParameterGenerator apg =
-                AlgorithmParameterGenerator.getInstance(ALGORITHM_NAME,
+        AlgorithmParameterGenerator apg
+                = AlgorithmParameterGenerator.getInstance(ALGORITHM_NAME,
                         PROVIDER_NAME);
 
         DSAGenParameterSpec genParamSpec = createGenParameterSpec(dataTuple);
@@ -80,8 +84,8 @@
 
     private static void checkParam(AlgorithmParameters param,
             DSAGenParameterSpec genParam) throws InvalidParameterSpecException,
-                    NoSuchAlgorithmException, NoSuchProviderException,
-                    InvalidAlgorithmParameterException {
+            NoSuchAlgorithmException, NoSuchProviderException,
+            InvalidAlgorithmParameterException {
         String algorithm = param.getAlgorithm();
         if (!algorithm.equalsIgnoreCase(ALGORITHM_NAME)) {
             throw new RuntimeException(
@@ -139,21 +143,25 @@
     }
 
     public static void main(String[] args) throws Exception {
-        List<DataTuple> dataTuples = Arrays.stream(args)
-                .map(arg -> arg.split(",")).map(params -> {
-                    int primePLen = Integer.valueOf(params[0]);
-                    int subprimeQLen = Integer.valueOf(params[1]);
-                    boolean isDSASpecSupported = false;
-                    if (params.length == 3) {
-                        isDSASpecSupported = Boolean.valueOf(params[2]);
-                    }
-                    return new DataTuple(primePLen, subprimeQLen,
-                            isDSASpecSupported);
-                }).collect(Collectors.toList());
+        if (args == null || args.length < 2) {
+            throw new RuntimeException("Invalid number of arguments to generate"
+                    + " DSA parameter.");
+        }
+        DataTuple dataTuple = null;
+        switch (args.length) {
+            case 3:
+                dataTuple = new DataTuple(Integer.valueOf(args[0]),
+                        Integer.valueOf(args[1]), Boolean.valueOf(args[2]));
+                break;
+            case 2:
+                dataTuple = new DataTuple(Integer.valueOf(args[0]),
+                        Integer.valueOf(args[1]), false);
+                break;
+            default:
+                throw new RuntimeException("Unsupported arguments found.");
+        }
+        testDSAGenParameterSpec(dataTuple);
 
-        for (DataTuple dataTuple : dataTuples) {
-            testDSAGenParameterSpec(dataTuple);
-        }
     }
 
     private static class DataTuple {
@@ -170,4 +178,3 @@
         }
     }
 }
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/SpecTest.java	Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8051408 8157308
+ * @modules java.base/sun.security.provider
+ * @build java.base/sun.security.provider.S
+ * @run main SpecTest
+ * @summary check the AbstractDrbg API etc
+ */
+
+import java.security.*;
+import sun.security.provider.S;
+import static java.security.DrbgParameters.Capability.*;
+
+/**
+ * This test makes sure the AbstractDrbg API works as specified. It also
+ * checks the SecureRandom API.
+ *
+ * The implementations must be patched into java.base/sun.security.provider
+ * because AbstractDrbg is not a public interface.
+ */
+public class SpecTest {
+
+    public static void main(String args[]) throws Exception {
+
+        // getInstance from a provider.
+
+        Provider p = new All("A", 0, "");
+        byte[] bytes = new byte[100];
+
+        // A non-DRBG
+        iae(() -> SecureRandom.getInstance("S1", null, p));
+        nsae(() -> SecureRandom.getInstance("S1",
+                new SecureRandomParameters() {}, p));
+
+        SecureRandom s1 = SecureRandom.getInstance("S1", p);
+        if (s1.getParameters() != null) {
+            throw new Exception();
+        }
+
+        iae(() -> s1.nextBytes(bytes, null));
+        uoe(() -> s1.nextBytes(bytes, new SecureRandomParameters() {}));
+        uoe(() -> s1.reseed());
+        iae(() -> s1.reseed(null));
+        uoe(() -> s1.reseed(new SecureRandomParameters() {}));
+
+        // A weak DRBG
+        iae(() -> SecureRandom.getInstance("S2", null, p));
+        nsae(() -> SecureRandom.getInstance("S2",
+                new SecureRandomParameters() {}, p));
+        nsae(() -> SecureRandom.getInstance("S2",
+                DrbgParameters.instantiation(256, NONE, null), p));
+        nsae(() -> SecureRandom.getInstance("S2",
+                DrbgParameters.instantiation(-1, PR_AND_RESEED, null), p));
+        nsae(() -> SecureRandom.getInstance("S2",
+                DrbgParameters.instantiation(-1, RESEED_ONLY, null), p));
+
+        SecureRandom s2 = SecureRandom.getInstance("S2",
+                DrbgParameters.instantiation(-1, NONE, null), p);
+        equals(s2, "S2,SQUEEZE,128,none");
+        equals(s2.getParameters(), "128,none,null");
+
+        npe(() -> s2.nextBytes(null));
+        iae(() -> s2.nextBytes(bytes, null));
+        iae(() -> s2.nextBytes(bytes, new SecureRandomParameters() {}));
+        uoe(() -> s2.reseed());
+        iae(() -> s2.reseed(null));
+
+        iae(() -> s2.nextBytes(bytes,
+                DrbgParameters.nextBytes(-1, false, new byte[101])));
+        s2.nextBytes(new byte[101],
+                DrbgParameters.nextBytes(-1, false, new byte[100]));
+        s2.nextBytes(bytes,
+                DrbgParameters.nextBytes(-1, false, new byte[100]));
+
+        // A strong DRBG
+        iae(() -> SecureRandom.getInstance("S3", null, p));
+        nsae(() -> SecureRandom.getInstance("S3",
+                new SecureRandomParameters() {}, p));
+        SecureRandom.getInstance("S3",
+                DrbgParameters.instantiation(192, PR_AND_RESEED, null), p);
+
+        SecureRandom s3 = SecureRandom.getInstance("S3", p);
+        equals(s3, "S3,SQUEEZE,128,reseed_only");
+        equals(s3.getParameters(), "128,reseed_only,null");
+
+        iae(() -> s3.nextBytes(bytes,
+                DrbgParameters.nextBytes(192, false, null)));
+        iae(() -> s3.nextBytes(bytes,
+                DrbgParameters.nextBytes(112, true, null)));
+        iae(() -> s3.reseed(new SecureRandomParameters() {}));
+
+        SecureRandom s32 = SecureRandom.getInstance(
+                "S3", DrbgParameters.instantiation(192, PR_AND_RESEED, null), p);
+        equals(s32, "S3,SQUEEZE,192,pr_and_reseed");
+        equals(s32.getParameters(), "192,pr_and_reseed,null");
+
+        s32.nextBytes(bytes, DrbgParameters.nextBytes(192, false, null));
+        s32.nextBytes(bytes, DrbgParameters.nextBytes(112, true, null));
+        s32.reseed();
+        s32.reseed(DrbgParameters.reseed(true, new byte[100]));
+
+        // getInstance from competitive providers.
+
+        Provider l = new Legacy("L", 0, "");
+        Provider w = new Weak("W", 0, "");
+        Provider s = new Strong("S", 0, "");
+
+        Security.addProvider(l);
+        Security.addProvider(w);
+        Security.addProvider(s);
+
+        SecureRandom s4;
+
+        try {
+            s4 = SecureRandom.getInstance("S");
+            if (s4.getProvider() != l) {
+                throw new Exception();
+            }
+
+            nsae(() -> SecureRandom.getInstance(
+                    "S", DrbgParameters.instantiation(256, NONE, null)));
+
+            s4 = SecureRandom.getInstance(
+                    "S", DrbgParameters.instantiation(192, NONE, null));
+            if (s4.getProvider() != s) {
+                throw new Exception();
+            }
+
+            s4 = SecureRandom.getInstance(
+                    "S", DrbgParameters.instantiation(128, PR_AND_RESEED, null));
+            if (s4.getProvider() != s) {
+                throw new Exception();
+            }
+
+            s4 = SecureRandom.getInstance(
+                    "S", DrbgParameters.instantiation(128, RESEED_ONLY, null));
+            if (s4.getProvider() != s) {
+                throw new Exception();
+            }
+
+            s4 = SecureRandom.getInstance(
+                    "S", DrbgParameters.instantiation(128, NONE, null));
+            if (s4.getProvider() != w) {
+                throw new Exception();
+            }
+        } finally {
+            Security.removeProvider("L");
+            Security.removeProvider("W");
+            Security.removeProvider("S");
+        }
+    }
+
+    public static class All extends Provider {
+        protected All(String name, double version, String info) {
+            super(name, version, info);
+            put("SecureRandom.S1", S.S1.class.getName());
+            put("SecureRandom.S2", S.S2.class.getName());
+            put("SecureRandom.S3", S.S3.class.getName());
+        }
+    }
+
+    // Providing S with no params support
+    public static class Legacy extends Provider {
+        protected Legacy(String name, double version, String info) {
+            super(name, version, info);
+            put("SecureRandom.S", S.S1.class.getName());
+        }
+    }
+
+    public static class Weak extends Provider {
+        protected Weak(String name, double version, String info) {
+            super(name, version, info);
+            put("SecureRandom.S", S.S2.class.getName());
+        }
+    }
+
+    public static class Strong extends Provider {
+        protected Strong(String name, double version, String info) {
+            super(name, version, info);
+            put("SecureRandom.S", S.S3.class.getName());
+        }
+    }
+
+    static void nsae(RunnableWithException r) throws Exception {
+        checkException(r, NoSuchAlgorithmException.class);
+    }
+
+    static void iae(RunnableWithException r) throws Exception {
+        checkException(r, IllegalArgumentException.class);
+    }
+
+    static void uoe(RunnableWithException r) throws Exception {
+        checkException(r, UnsupportedOperationException.class);
+    }
+
+    static void npe(RunnableWithException r) throws Exception {
+        checkException(r, NullPointerException.class);
+    }
+
+    interface RunnableWithException {
+        void run() throws Exception;
+    }
+
+    static void checkException(RunnableWithException r, Class ex)
+            throws Exception {
+        try {
+            r.run();
+        } catch (Exception e) {
+            if (ex.isAssignableFrom(e.getClass())) {
+                return;
+            }
+            throw e;
+        }
+        throw new Exception("No exception thrown");
+    }
+
+    static void equals(Object o, String s) throws Exception {
+        if (!o.toString().equals(s)) {
+            throw new Exception(o.toString() + " is not " + s);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/java.base/sun/security/provider/S.java	Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.provider;
+
+import java.security.SecureRandomParameters;
+import java.security.SecureRandomSpi;
+
+/**
+ * Read ../../../../SpecTest.java for details.
+ */
+public class S extends SecureRandomSpi {
+
+    protected AbstractDrbg impl;
+
+    // This is not a DRBG.
+    public static class S1 extends SecureRandomSpi {
+        @Override
+        protected void engineSetSeed(byte[] seed) {
+        }
+
+        @Override
+        protected void engineNextBytes(byte[] bytes) {
+        }
+
+        @Override
+        protected byte[] engineGenerateSeed(int numBytes) {
+            return new byte[numBytes];
+        }
+    }
+
+    // This is a weak DRBG. maximum strength is 128 and does
+    // not support prediction resistance or reseed.
+    public static class S2 extends S {
+        public S2(SecureRandomParameters params) {
+            impl = new Impl2(params);
+        }
+    }
+
+    // This is a strong DRBG.
+    public static class S3 extends S {
+        public S3(SecureRandomParameters params) {
+            impl = new Impl3(params);
+        }
+    }
+
+    // AbstractDrbg Implementations
+
+    static class Impl3 extends AbstractDrbg {
+
+        public Impl3(SecureRandomParameters params) {
+            supportPredictionResistance = true;
+            supportReseeding = true;
+            highestSupportedSecurityStrength = 192;
+            mechName = "S3";
+            algorithm = "SQUEEZE";
+            configure(params);
+        }
+
+        protected void chooseAlgorithmAndStrength() {
+            if (requestedInstantiationSecurityStrength < 0) {
+                securityStrength = DEFAULT_STRENGTH;
+            } else {
+                securityStrength = requestedInstantiationSecurityStrength;
+            }
+            minLength = securityStrength / 8;
+            maxAdditionalInputLength = maxPersonalizationStringLength = 100;
+        }
+
+        @Override
+        protected void initEngine() {
+        }
+
+        @Override
+        protected void instantiateAlgorithm(byte[] ei) {
+        }
+
+        @Override
+        protected void generateAlgorithm(byte[] result, byte[] additionalInput) {
+        }
+
+        @Override
+        protected void reseedAlgorithm(byte[] ei, byte[] additionalInput) {
+        }
+    }
+
+    static class Impl2 extends Impl3 {
+        public Impl2(SecureRandomParameters params) {
+            super(null);
+            mechName = "S2";
+            highestSupportedSecurityStrength = 128;
+            supportPredictionResistance = false;
+            supportReseeding = false;
+            configure(params);
+        }
+    }
+
+    // Overridden SecureRandomSpi methods
+
+    @Override
+    protected void engineSetSeed(byte[] seed) {
+        impl.engineSetSeed(seed);
+    }
+
+    @Override
+    protected void engineNextBytes(byte[] bytes) {
+        impl.engineNextBytes(bytes);
+    }
+
+    @Override
+    protected byte[] engineGenerateSeed(int numBytes) {
+        return impl.engineGenerateSeed(numBytes);
+    }
+
+    @Override
+    protected void engineNextBytes(
+            byte[] bytes, SecureRandomParameters params) {
+        impl.engineNextBytes(bytes, params);
+    }
+
+    @Override
+    protected void engineReseed(SecureRandomParameters params) {
+        impl.engineReseed(params);
+    }
+
+    @Override
+    protected SecureRandomParameters engineGetParameters() {
+        return impl.engineGetParameters();
+    }
+
+    @Override
+    public String toString() {
+        return impl.toString();
+    }
+}
--- a/jdk/test/sun/security/provider/SecureRandom/AbstractDrbgSpec.java	Thu Jun 09 17:28:37 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 8051408
- * @modules java.base/sun.security.provider
- * @summary check the AbstractDrbg API etc
- */
-
-import java.security.*;
-import sun.security.provider.AbstractDrbg;
-import static java.security.DrbgParameters.Capability.*;
-
-/**
- * This test makes sure the AbstractDrbg API works as specified. It also
- * checks the SecureRandom API.
- */
-public class AbstractDrbgSpec {
-
-    public static void main(String args[]) throws Exception {
-
-        // getInstance from a provider.
-
-        Provider p = new All("A", 0, "");
-        byte[] bytes = new byte[100];
-
-        // A non-DRBG
-        iae(() -> SecureRandom.getInstance("S1", null, p));
-        nsae(() -> SecureRandom.getInstance("S1",
-                new SecureRandomParameters() {}, p));
-
-        SecureRandom s1 = SecureRandom.getInstance("S1", p);
-        if (s1.getParameters() != null) {
-            throw new Exception();
-        }
-
-        iae(() -> s1.nextBytes(bytes, null));
-        uoe(() -> s1.nextBytes(bytes, new SecureRandomParameters() {}));
-        uoe(() -> s1.reseed());
-        iae(() -> s1.reseed(null));
-        uoe(() -> s1.reseed(new SecureRandomParameters() {}));
-
-        // A weak DRBG
-        iae(() -> SecureRandom.getInstance("S2", null, p));
-        nsae(() -> SecureRandom.getInstance("S2",
-                new SecureRandomParameters() {}, p));
-        nsae(() -> SecureRandom.getInstance("S2",
-                DrbgParameters.instantiation(256, NONE, null), p));
-        nsae(() -> SecureRandom.getInstance("S2",
-                DrbgParameters.instantiation(-1, PR_AND_RESEED, null), p));
-        nsae(() -> SecureRandom.getInstance("S2",
-                DrbgParameters.instantiation(-1, RESEED_ONLY, null), p));
-
-        SecureRandom s2 = SecureRandom.getInstance("S2",
-                DrbgParameters.instantiation(-1, NONE, null), p);
-        equals(s2, "S2,SQUEEZE,128,none");
-        equals(s2.getParameters(), "128,none,null");
-
-        npe(() -> s2.nextBytes(null));
-        iae(() -> s2.nextBytes(bytes, null));
-        iae(() -> s2.nextBytes(bytes, new SecureRandomParameters() {}));
-        uoe(() -> s2.reseed());
-        iae(() -> s2.reseed(null));
-
-        iae(() -> s2.nextBytes(bytes,
-                DrbgParameters.nextBytes(-1, false, new byte[101])));
-        s2.nextBytes(new byte[101],
-                DrbgParameters.nextBytes(-1, false, new byte[100]));
-        s2.nextBytes(bytes,
-                DrbgParameters.nextBytes(-1, false, new byte[100]));
-
-        // A strong DRBG
-        iae(() -> SecureRandom.getInstance("S3", null, p));
-        nsae(() -> SecureRandom.getInstance("S3",
-                new SecureRandomParameters() {}, p));
-        SecureRandom.getInstance("S3",
-                DrbgParameters.instantiation(192, PR_AND_RESEED, null), p);
-
-        SecureRandom s3 = SecureRandom.getInstance("S3", p);
-        equals(s3, "S3,SQUEEZE,128,reseed_only");
-        equals(s3.getParameters(), "128,reseed_only,null");
-
-        iae(() -> s3.nextBytes(bytes,
-                DrbgParameters.nextBytes(192, false, null)));
-        iae(() -> s3.nextBytes(bytes,
-                DrbgParameters.nextBytes(112, true, null)));
-        iae(() -> s3.reseed(new SecureRandomParameters() {}));
-
-        SecureRandom s32 = SecureRandom.getInstance(
-                "S3", DrbgParameters.instantiation(192, PR_AND_RESEED, null), p);
-        equals(s32, "S3,SQUEEZE,192,pr_and_reseed");
-        equals(s32.getParameters(), "192,pr_and_reseed,null");
-
-        s32.nextBytes(bytes, DrbgParameters.nextBytes(192, false, null));
-        s32.nextBytes(bytes, DrbgParameters.nextBytes(112, true, null));
-        s32.reseed();
-        s32.reseed(DrbgParameters.reseed(true, new byte[100]));
-
-        // getInstance from competitive providers.
-
-        Provider l = new Legacy("L", 0, "");
-        Provider w = new Weak("W", 0, "");
-        Provider s = new Strong("S", 0, "");
-
-        Security.addProvider(l);
-        Security.addProvider(w);
-        Security.addProvider(s);
-
-        SecureRandom s4;
-
-        try {
-            s4 = SecureRandom.getInstance("S");
-            if (s4.getProvider() != l) {
-                throw new Exception();
-            }
-
-            nsae(() -> SecureRandom.getInstance(
-                    "S", DrbgParameters.instantiation(256, NONE, null)));
-
-            s4 = SecureRandom.getInstance(
-                    "S", DrbgParameters.instantiation(192, NONE, null));
-            if (s4.getProvider() != s) {
-                throw new Exception();
-            }
-
-            s4 = SecureRandom.getInstance(
-                    "S", DrbgParameters.instantiation(128, PR_AND_RESEED, null));
-            if (s4.getProvider() != s) {
-                throw new Exception();
-            }
-
-            s4 = SecureRandom.getInstance(
-                    "S", DrbgParameters.instantiation(128, RESEED_ONLY, null));
-            if (s4.getProvider() != s) {
-                throw new Exception();
-            }
-
-            s4 = SecureRandom.getInstance(
-                    "S", DrbgParameters.instantiation(128, NONE, null));
-            if (s4.getProvider() != w) {
-                throw new Exception();
-            }
-        } finally {
-            Security.removeProvider("L");
-            Security.removeProvider("W");
-            Security.removeProvider("S");
-        }
-    }
-
-    public static class All extends Provider {
-        protected All(String name, double version, String info) {
-            super(name, version, info);
-            put("SecureRandom.S1", S1.class.getName());
-            put("SecureRandom.S2", S2.class.getName());
-            put("SecureRandom.S3", S3.class.getName());
-        }
-    }
-
-    // Providing S with no params support
-    public static class Legacy extends Provider {
-        protected Legacy(String name, double version, String info) {
-            super(name, version, info);
-            put("SecureRandom.S", S1.class.getName());
-        }
-    }
-
-    public static class Weak extends Provider {
-        protected Weak(String name, double version, String info) {
-            super(name, version, info);
-            put("SecureRandom.S", S2.class.getName());
-        }
-    }
-
-    public static class Strong extends Provider {
-        protected Strong(String name, double version, String info) {
-            super(name, version, info);
-            put("SecureRandom.S", S3.class.getName());
-        }
-    }
-
-    // This is not a DRBG.
-    public static class S1 extends SecureRandomSpi {
-        @Override
-        protected void engineSetSeed(byte[] seed) {
-        }
-
-        @Override
-        protected void engineNextBytes(byte[] bytes) {
-        }
-
-        @Override
-        protected byte[] engineGenerateSeed(int numBytes) {
-            return new byte[numBytes];
-        }
-    }
-
-    // This is a strong DRBG.
-    public static class S3 extends AbstractDrbg {
-
-        public S3(SecureRandomParameters params) {
-            supportPredictionResistance = true;
-            supportReseeding = true;
-            highestSupportedSecurityStrength = 192;
-            mechName = "S3";
-            algorithm = "SQUEEZE";
-            configure(params);
-        }
-        protected void chooseAlgorithmAndStrength() {
-            if (requestedInstantiationSecurityStrength < 0) {
-                securityStrength = DEFAULT_STRENGTH;
-            } else {
-                securityStrength = requestedInstantiationSecurityStrength;
-            }
-            minLength = securityStrength / 8;
-            maxAdditionalInputLength = maxPersonalizationStringLength = 100;
-        }
-
-        @Override
-        protected void initEngine() {
-
-        }
-
-        @Override
-        protected void instantiateAlgorithm(byte[] ei) {
-
-        }
-
-        @Override
-        protected void generateAlgorithm(byte[] result, byte[] additionalInput) {
-
-        }
-
-        @Override
-        protected void reseedAlgorithm(byte[] ei, byte[] additionalInput) {
-
-        }
-    }
-
-    // This is a weak DRBG. maximum strength is 128 and does
-    // not support prediction resistance or reseed.
-    public static class S2 extends S3 {
-        public S2(SecureRandomParameters params) {
-            super(null);
-            mechName = "S2";
-            highestSupportedSecurityStrength = 128;
-            supportPredictionResistance = false;
-            supportReseeding = false;
-            configure(params);
-        }
-    }
-
-    static void nsae(RunnableWithException r) throws Exception {
-        checkException(r, NoSuchAlgorithmException.class);
-    }
-
-    static void iae(RunnableWithException r) throws Exception {
-        checkException(r, IllegalArgumentException.class);
-    }
-
-    static void uoe(RunnableWithException r) throws Exception {
-        checkException(r, UnsupportedOperationException.class);
-    }
-
-    static void npe(RunnableWithException r) throws Exception {
-        checkException(r, NullPointerException.class);
-    }
-
-    interface RunnableWithException {
-        void run() throws Exception;
-    }
-
-    static void checkException(RunnableWithException r, Class ex)
-            throws Exception {
-        try {
-            r.run();
-        } catch (Exception e) {
-            if (ex.isAssignableFrom(e.getClass())) {
-                return;
-            }
-            throw e;
-        }
-        throw new Exception("No exception thrown");
-    }
-
-    static void equals(Object o, String s) throws Exception {
-        if (!o.toString().equals(s)) {
-            throw new Exception(o.toString() + " is not " + s);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/SecureRandom/DRBGS11n.java	Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import sun.security.provider.DRBG;
+import sun.security.provider.MoreDrbgParameters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+
+/**
+ * @test
+ * @bug 8157308
+ * @modules java.base/sun.security.provider
+ * @summary Make AbstractDrbg non-Serializable
+ * @run main DRBGS11n mech
+ * @run main DRBGS11n capability
+ */
+public class DRBGS11n {
+
+    public static void main(String[] args) throws Exception {
+
+        DRBG d = new DRBG(null);
+        Field f = DRBG.class.getDeclaredField("mdp");
+        f.setAccessible(true);
+        MoreDrbgParameters mdp = (MoreDrbgParameters)f.get(d);
+
+        // Corrupt the mech or capability fields inside DRBG#mdp.
+        f = MoreDrbgParameters.class.getDeclaredField(args[0]);
+        f.setAccessible(true);
+        f.set(mdp, null);
+
+        try {
+            revive(d);
+        } catch (IllegalArgumentException iae) {
+            // Expected
+            return;
+        }
+
+        throw new Exception("revive should fail");
+    }
+
+    static <T> T revive(T in) throws Exception {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        new ObjectOutputStream(bout).writeObject(in);
+        return (T) new ObjectInputStream(
+                new ByteArrayInputStream(bout.toByteArray())).readObject();
+    }
+}