Merge
authorlana
Thu, 22 Dec 2016 18:48:53 +0000
changeset 42943 51ece443d1cc
parent 42917 22bc450920ec (current diff)
parent 42942 ca9965624c3b (diff)
child 42944 641db7ce5057
child 43080 24abeeafc01f
Merge
--- a/jdk/make/gensrc/GensrcLocaleData.gmk	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/make/gensrc/GensrcLocaleData.gmk	Thu Dec 22 18:48:53 2016 +0000
@@ -64,7 +64,7 @@
 BASE_LOCALES := en en-US
 
 # Locales that don't have any resource files should be included here.
-ALL_NON_BASE_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
+ALL_NON_BASE_LOCALES := ja-JP-JP th-TH-TH
 
 SED_BASEARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
 SED_NONBASEARGS := $(SED_BASEARGS)
@@ -89,6 +89,10 @@
   $1_NON_BASE_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_BASE_LOCALES))
   $1_NON_BASE_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_BASE_LOCALES))
 
+# Adding implict locales nn-NO and nb-NO
+  $1_NON_BASE_LOCALES += nn-NO  nb-NO
+  $1_NON_BASE_LOCALES := $$(sort $$($1_NON_BASE_LOCALES))
+
   ALL_BASE_LOCALES += $$($1_BASE_LOCALES)
   ALL_NON_BASE_LOCALES += $$($1_NON_BASE_LOCALES)
 
--- a/jdk/make/src/classes/build/tools/cldrconverter/CLDRConverter.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/make/src/classes/build/tools/cldrconverter/CLDRConverter.java	Thu Dec 22 18:48:53 2016 +0000
@@ -487,10 +487,43 @@
             metaInfo.get("AvailableLocales").add(toLanguageTag(bundle.getID()));
             addLikelySubtags(metaInfo, "AvailableLocales", bundle.getID());
         }
-
+        addCldrImplicitLocales(metaInfo);
         bundleGenerator.generateMetaInfo(metaInfo);
     }
 
+    /**
+     * These are the Locales that are implicitly supported by CLDR.
+     * Adding them explicitly as likelySubtags here, will ensure that
+     * COMPAT locales do not precede them during ResourceBundle search path.
+     */
+    private static void addCldrImplicitLocales(Map<String, SortedSet<String>> metaInfo) {
+        metaInfo.get("LocaleNames").add("zh-Hans-CN");
+        metaInfo.get("LocaleNames").add("zh-Hans-SG");
+        metaInfo.get("LocaleNames").add("zh-Hant-HK");
+        metaInfo.get("LocaleNames").add("zh-Hant-MO");
+        metaInfo.get("LocaleNames").add("zh-Hant-TW");
+        metaInfo.get("CurrencyNames").add("zh-Hans-CN");
+        metaInfo.get("CurrencyNames").add("zh-Hans-SG");
+        metaInfo.get("CurrencyNames").add("zh-Hant-HK");
+        metaInfo.get("CurrencyNames").add("zh-Hant-MO");
+        metaInfo.get("CurrencyNames").add("zh-Hant-TW");
+        metaInfo.get("TimeZoneNames").add("zh-Hans-CN");
+        metaInfo.get("TimeZoneNames").add("zh-Hans-SG");
+        metaInfo.get("TimeZoneNames").add("zh-Hant-HK");
+        metaInfo.get("TimeZoneNames").add("zh-Hant-MO");
+        metaInfo.get("TimeZoneNames").add("zh-Hant-TW");
+        metaInfo.get("TimeZoneNames").add("zh-HK");
+        metaInfo.get("CalendarData").add("zh-Hans-CN");
+        metaInfo.get("CalendarData").add("zh-Hans-SG");
+        metaInfo.get("CalendarData").add("zh-Hant-HK");
+        metaInfo.get("CalendarData").add("zh-Hant-MO");
+        metaInfo.get("CalendarData").add("zh-Hant-TW");
+        metaInfo.get("FormatData").add("zh-Hans-CN");
+        metaInfo.get("FormatData").add("zh-Hans-SG");
+        metaInfo.get("FormatData").add("zh-Hant-HK");
+        metaInfo.get("FormatData").add("zh-Hant-MO");
+        metaInfo.get("FormatData").add("zh-Hant-TW");
+    }
     static final Map<String, String> aliases = new HashMap<>();
 
     /**
--- a/jdk/src/java.base/share/classes/java/nio/file/FileTreeWalker.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/nio/file/FileTreeWalker.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -353,12 +353,13 @@
                 }
             }
 
-            // no next entry so close and pop directory, creating corresponding event
+            // no next entry so close and pop directory,
+            // creating corresponding event
             if (entry == null) {
                 try {
                     top.stream().close();
                 } catch (IOException e) {
-                    if (ioe != null) {
+                    if (ioe == null) {
                         ioe = e;
                     } else {
                         ioe.addSuppressed(e);
--- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java	Thu Dec 22 18:48:53 2016 +0000
@@ -758,16 +758,6 @@
                     dfs = y;
                 }
             }
-            // If the bundle's locale isn't the target locale, put another cache
-            // entry for the bundle's locale.
-            Locale bundleLocale = resource.getLocale();
-            if (!bundleLocale.equals(locale)) {
-                SoftReference<DateFormatSymbols> z
-                    = cachedInstances.putIfAbsent(bundleLocale, ref);
-                if (z != null && z.get() == null) {
-                    cachedInstances.replace(bundleLocale, z, ref);
-                }
-            }
         }
 
         // Copy the field values from dfs to this instance.
--- a/jdk/src/java.base/share/classes/java/time/LocalDateTime.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/time/LocalDateTime.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1407,8 +1407,8 @@
      * </ol>
      * <p>
      * For example, 2008-02-29 (leap year) minus one year would result in the
-     * invalid date 2009-02-29 (standard year). Instead of returning an invalid
-     * result, the last valid day of the month, 2009-02-28, is selected instead.
+     * invalid date 2007-02-29 (standard year). Instead of returning an invalid
+     * result, the last valid day of the month, 2007-02-28, is selected instead.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -1431,8 +1431,8 @@
      * </ol>
      * <p>
      * For example, 2007-03-31 minus one month would result in the invalid date
-     * 2007-04-31. Instead of returning an invalid result, the last valid day
-     * of the month, 2007-04-30, is selected instead.
+     * 2007-02-31. Instead of returning an invalid result, the last valid day
+     * of the month, 2007-02-28, is selected instead.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
--- a/jdk/src/java.base/share/classes/java/time/OffsetDateTime.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/time/OffsetDateTime.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -1393,8 +1393,8 @@
      * </ol>
      * <p>
      * For example, 2008-02-29 (leap year) minus one year would result in the
-     * invalid date 2009-02-29 (standard year). Instead of returning an invalid
-     * result, the last valid day of the month, 2009-02-28, is selected instead.
+     * invalid date 2007-02-29 (standard year). Instead of returning an invalid
+     * result, the last valid day of the month, 2007-02-28, is selected instead.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -1417,8 +1417,8 @@
      * </ol>
      * <p>
      * For example, 2007-03-31 minus one month would result in the invalid date
-     * 2007-04-31. Instead of returning an invalid result, the last valid day
-     * of the month, 2007-04-30, is selected instead.
+     * 2007-02-31. Instead of returning an invalid result, the last valid day
+     * of the month, 2007-02-28, is selected instead.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -1437,7 +1437,7 @@
      * the month and year fields as necessary to ensure the result remains valid.
      * The result is only invalid if the maximum/minimum year is exceeded.
      * <p>
-     * For example, 2008-12-31 minus one week would result in 2009-01-07.
+     * For example, 2009-01-07 minus one week would result in 2008-12-31.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -1456,7 +1456,7 @@
      * month and year fields as necessary to ensure the result remains valid.
      * The result is only invalid if the maximum/minimum year is exceeded.
      * <p>
-     * For example, 2008-12-31 minus one day would result in 2009-01-01.
+     * For example, 2009-01-01 minus one day would result in 2008-12-31.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1774,16 +1774,20 @@
                     if (count > 1) {
                         throw new IllegalArgumentException("Too many pattern letters: " + cur);
                     }
-                    appendInternal(new WeekBasedFieldPrinterParser(cur, count));
+                    appendValue(new WeekBasedFieldPrinterParser(cur, count, count, count));
                 } else if (cur == 'w') {
                     // Fields defined by Locale
                     if (count > 2) {
                         throw new IllegalArgumentException("Too many pattern letters: " + cur);
                     }
-                    appendInternal(new WeekBasedFieldPrinterParser(cur, count));
+                    appendValue(new WeekBasedFieldPrinterParser(cur, count, count, 2));
                 } else if (cur == 'Y') {
                     // Fields defined by Locale
-                    appendInternal(new WeekBasedFieldPrinterParser(cur, count));
+                    if (count == 2) {
+                        appendValue(new WeekBasedFieldPrinterParser(cur, count, count, 2));
+                    } else {
+                        appendValue(new WeekBasedFieldPrinterParser(cur, count, count, 19));
+                    }
                 } else {
                     throw new IllegalArgumentException("Unknown pattern letter: " + cur);
                 }
@@ -1843,7 +1847,10 @@
                 }
                 break;
             case 'c':
-                if (count == 2) {
+                if (count == 1) {
+                    appendValue(new WeekBasedFieldPrinterParser(cur, count, count, count));
+                    break;
+                } else if (count == 2) {
                     throw new IllegalArgumentException("Invalid pattern \"cc\"");
                 }
                 /*fallthrough*/
@@ -1858,8 +1865,8 @@
                 switch (count) {
                     case 1:
                     case 2:
-                        if (cur == 'c' || cur == 'e') {
-                            appendInternal(new WeekBasedFieldPrinterParser(cur, count));
+                        if (cur == 'e') {
+                            appendValue(new WeekBasedFieldPrinterParser(cur, count, count, count));
                         } else if (cur == 'E') {
                             appendText(field, TextStyle.SHORT);
                         } else {
@@ -4770,8 +4777,9 @@
      * the field is to be printed or parsed.
      * The locale is needed to select the proper WeekFields from which
      * the field for day-of-week, week-of-month, or week-of-year is selected.
+     * Hence the inherited field NumberPrinterParser.field is unused.
      */
-    static final class WeekBasedFieldPrinterParser implements DateTimePrinterParser {
+    static final class WeekBasedFieldPrinterParser extends NumberPrinterParser {
         private char chr;
         private int count;
 
@@ -4780,12 +4788,55 @@
          *
          * @param chr the pattern format letter that added this PrinterParser.
          * @param count the repeat count of the format letter
+         * @param minWidth  the minimum field width, from 1 to 19
+         * @param maxWidth  the maximum field width, from minWidth to 19
          */
-        WeekBasedFieldPrinterParser(char chr, int count) {
+        WeekBasedFieldPrinterParser(char chr, int count, int minWidth, int maxWidth) {
+            this(chr, count, minWidth, maxWidth, 0);
+        }
+
+        /**
+         * Constructor.
+         *
+         * @param chr the pattern format letter that added this PrinterParser.
+         * @param count the repeat count of the format letter
+         * @param minWidth  the minimum field width, from 1 to 19
+         * @param maxWidth  the maximum field width, from minWidth to 19
+         * @param subsequentWidth  the width of subsequent non-negative numbers, 0 or greater,
+         * -1 if fixed width due to active adjacent parsing
+         */
+        WeekBasedFieldPrinterParser(char chr, int count, int minWidth, int maxWidth,
+                int subsequentWidth) {
+            super(null, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth);
             this.chr = chr;
             this.count = count;
         }
 
+        /**
+         * Returns a new instance with fixed width flag set.
+         *
+         * @return a new updated printer-parser, not null
+         */
+        @Override
+        WeekBasedFieldPrinterParser withFixedWidth() {
+            if (subsequentWidth == -1) {
+                return this;
+            }
+            return new WeekBasedFieldPrinterParser(chr, count, minWidth, maxWidth, -1);
+        }
+
+        /**
+         * Returns a new instance with an updated subsequent width.
+         *
+         * @param subsequentWidth  the width of subsequent non-negative numbers, 0 or greater
+         * @return a new updated printer-parser, not null
+         */
+        @Override
+        WeekBasedFieldPrinterParser withSubsequentWidth(int subsequentWidth) {
+            return new WeekBasedFieldPrinterParser(chr, count, minWidth, maxWidth,
+                    this.subsequentWidth + subsequentWidth);
+        }
+
         @Override
         public boolean format(DateTimePrintContext context, StringBuilder buf) {
             return printerParser(context.getLocale()).format(context, buf);
@@ -4810,10 +4861,12 @@
                 case 'Y':
                     field = weekDef.weekBasedYear();
                     if (count == 2) {
-                        return new ReducedPrinterParser(field, 2, 2, 0, ReducedPrinterParser.BASE_DATE, 0);
+                        return new ReducedPrinterParser(field, 2, 2, 0, ReducedPrinterParser.BASE_DATE,
+                                this.subsequentWidth);
                     } else {
                         return new NumberPrinterParser(field, count, 19,
-                                (count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD, -1);
+                                (count < 4) ? SignStyle.NORMAL : SignStyle.EXCEEDS_PAD,
+                                this.subsequentWidth);
                     }
                 case 'e':
                 case 'c':
@@ -4828,7 +4881,8 @@
                 default:
                     throw new IllegalStateException("unreachable");
             }
-            return new NumberPrinterParser(field, (count == 2 ? 2 : 1), 2, SignStyle.NOT_NEGATIVE);
+            return new NumberPrinterParser(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE,
+                    this.subsequentWidth);
         }
 
         @Override
--- a/jdk/src/java.base/share/classes/java/util/ArrayDeque.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ArrayDeque.java	Thu Dec 22 18:48:53 2016 +0000
@@ -146,16 +146,16 @@
         if (jump < needed
             || (newCapacity = (oldCapacity + jump)) - MAX_ARRAY_SIZE > 0)
             newCapacity = newCapacity(needed, jump);
-        elements = Arrays.copyOf(elements, newCapacity);
+        final Object[] es = elements = Arrays.copyOf(elements, newCapacity);
         // Exceptionally, here tail == head needs to be disambiguated
-        if (tail < head || (tail == head && elements[head] != null)) {
+        if (tail < head || (tail == head && es[head] != null)) {
             // wrap around; slide first leg forward to end of array
             int newSpace = newCapacity - oldCapacity;
-            System.arraycopy(elements, head,
-                             elements, head + newSpace,
+            System.arraycopy(es, head,
+                             es, head + newSpace,
                              oldCapacity - head);
-            Arrays.fill(elements, head, head + newSpace, null);
-            head += newSpace;
+            for (int i = head, to = (head += newSpace); i < to; i++)
+                es[i] = null;
         }
     }
 
@@ -873,6 +873,9 @@
         }
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     public void forEach(Consumer<? super E> action) {
         Objects.requireNonNull(action);
         final Object[] es = elements;
@@ -1035,11 +1038,14 @@
 
     /**
      * Nulls out slots starting at array index i, upto index end.
+     * Condition i == end means "empty" - nothing to do.
      */
     private static void circularClear(Object[] es, int i, int end) {
+        // assert 0 <= i && i < es.length;
+        // assert 0 <= end && end < es.length;
         for (int to = (i <= end) ? end : es.length;
              ; i = 0, to = end) {
-            Arrays.fill(es, i, to, null);
+            for (; i < to; i++) es[i] = null;
             if (to == end) break;
         }
     }
--- a/jdk/src/java.base/share/classes/java/util/ArrayList.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ArrayList.java	Thu Dec 22 18:48:53 2016 +0000
@@ -576,8 +576,9 @@
      */
     public void clear() {
         modCount++;
-        Arrays.fill(elementData, 0, size, null);
-        size = 0;
+        final Object[] es = elementData;
+        for (int to = size, i = size = 0; i < to; i++)
+            es[i] = null;
     }
 
     /**
@@ -665,10 +666,14 @@
                     outOfBoundsMsg(fromIndex, toIndex));
         }
         modCount++;
-        final Object[] es = elementData;
-        final int oldSize = size;
-        System.arraycopy(es, toIndex, es, fromIndex, oldSize - toIndex);
-        Arrays.fill(es, size -= (toIndex - fromIndex), oldSize, null);
+        shiftTailOverGap(elementData, fromIndex, toIndex);
+    }
+
+    /** Erases the gap from lo to hi, by sliding down following elements. */
+    private void shiftTailOverGap(Object[] es, int lo, int hi) {
+        System.arraycopy(es, hi, es, lo, size - hi);
+        for (int to = size, i = (size -= hi - lo); i < to; i++)
+            es[i] = null;
     }
 
     /**
@@ -756,25 +761,25 @@
                 w += end - r;
                 throw ex;
             } finally {
-                final int oldSize = size, deleted = end - w;
-                modCount += deleted;
-                System.arraycopy(es, end, es, w, oldSize - end);
-                Arrays.fill(es, size -= deleted, oldSize, null);
+                modCount += end - w;
+                shiftTailOverGap(es, w, end);
             }
         }
         return modified;
     }
 
     /**
-     * Save the state of the {@code ArrayList} instance to a stream (that
-     * is, serialize it).
+     * Saves the state of the {@code ArrayList} instance to a stream
+     * (that is, serializes it).
      *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      * @serialData The length of the array backing the {@code ArrayList}
      *             instance is emitted (int), followed by all of its elements
      *             (each an {@code Object}) in the proper order.
      */
     private void writeObject(java.io.ObjectOutputStream s)
-        throws java.io.IOException{
+        throws java.io.IOException {
         // Write out element count, and any hidden stuff
         int expectedModCount = modCount;
         s.defaultWriteObject();
@@ -793,8 +798,12 @@
     }
 
     /**
-     * Reconstitute the {@code ArrayList} instance from a stream (that is,
-     * deserialize it).
+     * Reconstitutes the {@code ArrayList} instance from a stream (that is,
+     * deserializes it).
+     * @param s the stream
+     * @throws ClassNotFoundException if the class of a serialized object
+     *         could not be found
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
@@ -1285,9 +1294,8 @@
         public Spliterator<E> spliterator() {
             checkForComodification();
 
-            // ArrayListSpliterator is not used because late-binding logic
-            // is different here
-            return new Spliterator<>() {
+            // ArrayListSpliterator not used here due to late-binding
+            return new Spliterator<E>() {
                 private int index = offset; // current index, modified on advance/split
                 private int fence = -1; // -1 until used; then one past last index
                 private int expectedModCount; // initialized when fence set
@@ -1301,12 +1309,11 @@
                     return hi;
                 }
 
-                public ArrayListSpliterator<E> trySplit() {
+                public ArrayList<E>.ArrayListSpliterator trySplit() {
                     int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
-                    // ArrayListSpliterator could be used here as the source is already bound
+                    // ArrayListSpliterator can be used here as the source is already bound
                     return (lo >= mid) ? null : // divide range in half unless too small
-                        new ArrayListSpliterator<>(root, lo, index = mid,
-                                                   expectedModCount);
+                        root.new ArrayListSpliterator(lo, index = mid, expectedModCount);
                 }
 
                 public boolean tryAdvance(Consumer<? super E> action) {
@@ -1348,7 +1355,7 @@
                 }
 
                 public long estimateSize() {
-                    return (long) (getFence() - index);
+                    return getFence() - index;
                 }
 
                 public int characteristics() {
@@ -1358,6 +1365,9 @@
         }
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     @Override
     public void forEach(Consumer<? super E> action) {
         Objects.requireNonNull(action);
@@ -1385,11 +1395,11 @@
      */
     @Override
     public Spliterator<E> spliterator() {
-        return new ArrayListSpliterator<>(this, 0, -1, 0);
+        return new ArrayListSpliterator(0, -1, 0);
     }
 
     /** Index-based split-by-two, lazily initialized Spliterator */
-    static final class ArrayListSpliterator<E> implements Spliterator<E> {
+    final class ArrayListSpliterator implements Spliterator<E> {
 
         /*
          * If ArrayLists were immutable, or structurally immutable (no
@@ -1423,15 +1433,12 @@
          * these streamlinings.
          */
 
-        private final ArrayList<E> list;
         private int index; // current index, modified on advance/split
         private int fence; // -1 until used; then one past last index
         private int expectedModCount; // initialized when fence set
 
-        /** Create new spliterator covering the given range */
-        ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
-                             int expectedModCount) {
-            this.list = list; // OK if null unless traversed
+        /** Creates new spliterator covering the given range. */
+        ArrayListSpliterator(int origin, int fence, int expectedModCount) {
             this.index = origin;
             this.fence = fence;
             this.expectedModCount = expectedModCount;
@@ -1439,23 +1446,17 @@
 
         private int getFence() { // initialize fence to size on first use
             int hi; // (a specialized variant appears in method forEach)
-            ArrayList<E> lst;
             if ((hi = fence) < 0) {
-                if ((lst = list) == null)
-                    hi = fence = 0;
-                else {
-                    expectedModCount = lst.modCount;
-                    hi = fence = lst.size;
-                }
+                expectedModCount = modCount;
+                hi = fence = size;
             }
             return hi;
         }
 
-        public ArrayListSpliterator<E> trySplit() {
+        public ArrayListSpliterator trySplit() {
             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
             return (lo >= mid) ? null : // divide range in half unless too small
-                new ArrayListSpliterator<>(list, lo, index = mid,
-                                           expectedModCount);
+                new ArrayListSpliterator(lo, index = mid, expectedModCount);
         }
 
         public boolean tryAdvance(Consumer<? super E> action) {
@@ -1464,9 +1465,9 @@
             int hi = getFence(), i = index;
             if (i < hi) {
                 index = i + 1;
-                @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
+                @SuppressWarnings("unchecked") E e = (E)elementData[i];
                 action.accept(e);
-                if (list.modCount != expectedModCount)
+                if (modCount != expectedModCount)
                     throw new ConcurrentModificationException();
                 return true;
             }
@@ -1475,13 +1476,13 @@
 
         public void forEachRemaining(Consumer<? super E> action) {
             int i, hi, mc; // hoist accesses and checks from loop
-            ArrayList<E> lst; Object[] a;
+            Object[] a;
             if (action == null)
                 throw new NullPointerException();
-            if ((lst = list) != null && (a = lst.elementData) != null) {
+            if ((a = elementData) != null) {
                 if ((hi = fence) < 0) {
-                    mc = lst.modCount;
-                    hi = lst.size;
+                    mc = modCount;
+                    hi = size;
                 }
                 else
                     mc = expectedModCount;
@@ -1490,7 +1491,7 @@
                         @SuppressWarnings("unchecked") E e = (E) a[i];
                         action.accept(e);
                     }
-                    if (lst.modCount == mc)
+                    if (modCount == mc)
                         return;
                 }
             }
@@ -1498,7 +1499,7 @@
         }
 
         public long estimateSize() {
-            return (long) (getFence() - index);
+            return getFence() - index;
         }
 
         public int characteristics() {
@@ -1518,6 +1519,9 @@
         return (bits[i >> 6] & (1L << i)) == 0;
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     @Override
     public boolean removeIf(Predicate<? super E> filter) {
         return removeIf(filter, 0, size);
@@ -1552,9 +1556,7 @@
             for (i = beg; i < end; i++)
                 if (isClear(deathRow, i - beg))
                     es[w++] = es[i];
-            final int oldSize = size;
-            System.arraycopy(es, end, es, w, oldSize - end);
-            Arrays.fill(es, size -= (end - w), oldSize, null);
+            shiftTailOverGap(es, w, end);
             return true;
         } else {
             if (modCount != expectedModCount)
--- a/jdk/src/java.base/share/classes/java/util/PriorityQueue.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/PriorityQueue.java	Thu Dec 22 18:48:53 2016 +0000
@@ -522,6 +522,8 @@
          */
         private int expectedModCount = modCount;
 
+        Itr() {}                        // prevent access constructor creation
+
         public boolean hasNext() {
             return cursor < size ||
                 (forgetMeNot != null && !forgetMeNot.isEmpty());
@@ -631,7 +633,7 @@
      * promoting x up the tree until it is greater than or equal to
      * its parent, or is the root.
      *
-     * To simplify and speed up coercions and comparisons. the
+     * To simplify and speed up coercions and comparisons, the
      * Comparable and Comparator versions are separated into different
      * methods that are otherwise identical. (Similarly for siftDown.)
      *
@@ -727,11 +729,18 @@
     /**
      * Establishes the heap invariant (described above) in the entire tree,
      * assuming nothing about the order of the elements prior to the call.
+     * This classic algorithm due to Floyd (1964) is known to be O(size).
      */
     @SuppressWarnings("unchecked")
     private void heapify() {
-        for (int i = (size >>> 1) - 1; i >= 0; i--)
-            siftDown(i, (E) queue[i]);
+        final Object[] es = queue;
+        final int half = (size >>> 1) - 1;
+        if (comparator == null)
+            for (int i = half; i >= 0; i--)
+                siftDownComparable(i, (E) es[i]);
+        else
+            for (int i = half; i >= 0; i--)
+                siftDownUsingComparator(i, (E) es[i]);
     }
 
     /**
@@ -812,23 +821,16 @@
      * @since 1.8
      */
     public final Spliterator<E> spliterator() {
-        return new PriorityQueueSpliterator<>(this, 0, -1, 0);
+        return new PriorityQueueSpliterator(0, -1, 0);
     }
 
-    static final class PriorityQueueSpliterator<E> implements Spliterator<E> {
-        /*
-         * This is very similar to ArrayList Spliterator, except for
-         * extra null checks.
-         */
-        private final PriorityQueue<E> pq;
+    final class PriorityQueueSpliterator implements Spliterator<E> {
         private int index;            // current index, modified on advance/split
         private int fence;            // -1 until first use
         private int expectedModCount; // initialized when fence set
 
         /** Creates new spliterator covering the given range. */
-        PriorityQueueSpliterator(PriorityQueue<E> pq, int origin, int fence,
-                                 int expectedModCount) {
-            this.pq = pq;
+        PriorityQueueSpliterator(int origin, int fence, int expectedModCount) {
             this.index = origin;
             this.fence = fence;
             this.expectedModCount = expectedModCount;
@@ -837,68 +839,54 @@
         private int getFence() { // initialize fence to size on first use
             int hi;
             if ((hi = fence) < 0) {
-                expectedModCount = pq.modCount;
-                hi = fence = pq.size;
+                expectedModCount = modCount;
+                hi = fence = size;
             }
             return hi;
         }
 
-        public PriorityQueueSpliterator<E> trySplit() {
+        public PriorityQueueSpliterator trySplit() {
             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
             return (lo >= mid) ? null :
-                new PriorityQueueSpliterator<>(pq, lo, index = mid,
-                                               expectedModCount);
+                new PriorityQueueSpliterator(lo, index = mid, expectedModCount);
         }
 
         @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
-            int i, hi, mc; // hoist accesses and checks from loop
-            PriorityQueue<E> q; Object[] a;
             if (action == null)
                 throw new NullPointerException();
-            if ((q = pq) != null && (a = q.queue) != null) {
-                if ((hi = fence) < 0) {
-                    mc = q.modCount;
-                    hi = q.size;
-                }
-                else
-                    mc = expectedModCount;
-                if ((i = index) >= 0 && (index = hi) <= a.length) {
-                    for (E e;; ++i) {
-                        if (i < hi) {
-                            if ((e = (E) a[i]) == null) // must be CME
-                                break;
-                            action.accept(e);
-                        }
-                        else if (q.modCount != mc)
-                            break;
-                        else
-                            return;
-                    }
-                }
+            if (fence < 0) { fence = size; expectedModCount = modCount; }
+            final Object[] a = queue;
+            int i, hi; E e;
+            for (i = index, index = hi = fence; i < hi; i++) {
+                if ((e = (E) a[i]) == null)
+                    break;      // must be CME
+                action.accept(e);
             }
-            throw new ConcurrentModificationException();
+            if (modCount != expectedModCount)
+                throw new ConcurrentModificationException();
         }
 
+        @SuppressWarnings("unchecked")
         public boolean tryAdvance(Consumer<? super E> action) {
             if (action == null)
                 throw new NullPointerException();
-            int hi = getFence(), lo = index;
-            if (lo >= 0 && lo < hi) {
-                index = lo + 1;
-                @SuppressWarnings("unchecked") E e = (E)pq.queue[lo];
-                if (e == null)
+            if (fence < 0) { fence = size; expectedModCount = modCount; }
+            int i;
+            if ((i = index) < fence) {
+                index = i + 1;
+                E e;
+                if ((e = (E) queue[i]) == null
+                    || modCount != expectedModCount)
                     throw new ConcurrentModificationException();
                 action.accept(e);
-                if (pq.modCount != expectedModCount)
-                    throw new ConcurrentModificationException();
                 return true;
             }
             return false;
         }
 
         public long estimateSize() {
-            return (long) (getFence() - index);
+            return getFence() - index;
         }
 
         public int characteristics() {
--- a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java	Thu Dec 22 18:48:53 2016 +0000
@@ -2942,17 +2942,6 @@
                             script = "Hans";
                             break;
                         }
-                    } else if (script.length() > 0 && region.length() == 0) {
-                        // Supply region(country) for users who still package Chinese
-                        // bundles using old convension.
-                        switch (script) {
-                        case "Hans":
-                            region = "CN";
-                            break;
-                        case "Hant":
-                            region = "TW";
-                            break;
-                        }
                     }
                 }
 
@@ -2983,6 +2972,21 @@
                 }
                 if (script.length() > 0) {
                     list.add(Locale.getInstance(language, script, "", "", null));
+                    // Special handling for Chinese
+                    if (language.equals("zh")) {
+                        if (region.length() == 0) {
+                            // Supply region(country) for users who still package Chinese
+                            // bundles using old convension.
+                            switch (script) {
+                                case "Hans":
+                                    region = "CN";
+                                    break;
+                                case "Hant":
+                                    region = "TW";
+                                    break;
+                            }
+                        }
+                    }
 
                     // With script, after truncating variant, region and script,
                     // start over without script.
--- a/jdk/src/java.base/share/classes/java/util/SplittableRandom.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/SplittableRandom.java	Thu Dec 22 18:48:53 2016 +0000
@@ -375,7 +375,7 @@
      * may, and typically does, vary across program invocations.
      */
     public SplittableRandom() { // emulate defaultGen.split()
-        long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
+        long s = defaultGen.getAndAdd(GOLDEN_GAMMA << 1);
         this.seed = mix64(s);
         this.gamma = mixGamma(s + GOLDEN_GAMMA);
     }
--- a/jdk/src/java.base/share/classes/java/util/Vector.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Vector.java	Thu Dec 22 18:48:53 2016 +0000
@@ -306,9 +306,9 @@
         modCount++;
         if (newSize > elementData.length)
             grow(newSize);
-        for (int i = newSize; i < elementCount; i++)
-            elementData[i] = null;
-        elementCount = newSize;
+        final Object[] es = elementData;
+        for (int to = elementCount, i = elementCount = newSize; i < to; i++)
+            es[i] = null;
     }
 
     /**
@@ -675,9 +675,10 @@
      * method (which is part of the {@link List} interface).
      */
     public synchronized void removeAllElements() {
-        Arrays.fill(elementData, 0, elementCount, null);
+        final Object[] es = elementData;
+        for (int to = elementCount, i = elementCount = 0; i < to; i++)
+            es[i] = null;
         modCount++;
-        elementCount = 0;
     }
 
     /**
@@ -980,6 +981,9 @@
         return bulkRemove(e -> !c.contains(e));
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     @Override
     public boolean removeIf(Predicate<? super E> filter) {
         Objects.requireNonNull(filter);
@@ -1024,7 +1028,8 @@
             for (i = beg; i < end; i++)
                 if (isClear(deathRow, i - beg))
                     es[w++] = es[i];
-            Arrays.fill(es, elementCount = w, end, null);
+            for (i = elementCount = w; i < end; i++)
+                es[i] = null;
             return true;
         } else {
             if (modCount != expectedModCount)
@@ -1152,19 +1157,25 @@
      * (If {@code toIndex==fromIndex}, this operation has no effect.)
      */
     protected synchronized void removeRange(int fromIndex, int toIndex) {
-        final Object[] es = elementData;
-        final int oldSize = elementCount;
-        System.arraycopy(es, toIndex, es, fromIndex, oldSize - toIndex);
+        modCount++;
+        shiftTailOverGap(elementData, fromIndex, toIndex);
+    }
 
-        modCount++;
-        Arrays.fill(es, elementCount -= (toIndex - fromIndex), oldSize, null);
+    /** Erases the gap from lo to hi, by sliding down following elements. */
+    private void shiftTailOverGap(Object[] es, int lo, int hi) {
+        System.arraycopy(es, hi, es, lo, elementCount - hi);
+        for (int to = elementCount, i = (elementCount -= hi - lo); i < to; i++)
+            es[i] = null;
     }
 
     /**
-     * Save the state of the {@code Vector} instance to a stream (that
-     * is, serialize it).
+     * Saves the state of the {@code Vector} instance to a stream
+     * (that is, serializes it).
      * This method performs synchronization to ensure the consistency
      * of the serialized data.
+     *
+     * @param s the stream
+     * @throws java.io.IOException if an I/O error occurs
      */
     private void writeObject(java.io.ObjectOutputStream s)
             throws java.io.IOException {
@@ -1337,6 +1348,9 @@
         }
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     @Override
     public synchronized void forEach(Consumer<? super E> action) {
         Objects.requireNonNull(action);
@@ -1349,6 +1363,9 @@
             throw new ConcurrentModificationException();
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     @Override
     public synchronized void replaceAll(UnaryOperator<E> operator) {
         Objects.requireNonNull(operator);
@@ -1387,21 +1404,19 @@
      */
     @Override
     public Spliterator<E> spliterator() {
-        return new VectorSpliterator<>(this, null, 0, -1, 0);
+        return new VectorSpliterator(null, 0, -1, 0);
     }
 
     /** Similar to ArrayList Spliterator */
-    static final class VectorSpliterator<E> implements Spliterator<E> {
-        private final Vector<E> list;
+    final class VectorSpliterator implements Spliterator<E> {
         private Object[] array;
         private int index; // current index, modified on advance/split
         private int fence; // -1 until used; then one past last index
         private int expectedModCount; // initialized when fence set
 
-        /** Create new spliterator covering the given range */
-        VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,
+        /** Creates new spliterator covering the given range. */
+        VectorSpliterator(Object[] array, int origin, int fence,
                           int expectedModCount) {
-            this.list = list;
             this.array = array;
             this.index = origin;
             this.fence = fence;
@@ -1411,10 +1426,10 @@
         private int getFence() { // initialize on first use
             int hi;
             if ((hi = fence) < 0) {
-                synchronized (list) {
-                    array = list.elementData;
-                    expectedModCount = list.modCount;
-                    hi = fence = list.elementCount;
+                synchronized (Vector.this) {
+                    array = elementData;
+                    expectedModCount = modCount;
+                    hi = fence = elementCount;
                 }
             }
             return hi;
@@ -1423,8 +1438,7 @@
         public Spliterator<E> trySplit() {
             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
             return (lo >= mid) ? null :
-                new VectorSpliterator<>(list, array, lo, index = mid,
-                                        expectedModCount);
+                new VectorSpliterator(array, lo, index = mid, expectedModCount);
         }
 
         @SuppressWarnings("unchecked")
@@ -1435,7 +1449,7 @@
             if (getFence() > (i = index)) {
                 index = i + 1;
                 action.accept((E)array[i]);
-                if (list.modCount != expectedModCount)
+                if (modCount != expectedModCount)
                     throw new ConcurrentModificationException();
                 return true;
             }
@@ -1444,28 +1458,15 @@
 
         @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
-            int i, hi; // hoist accesses and checks from loop
-            Vector<E> lst; Object[] a;
             if (action == null)
                 throw new NullPointerException();
-            if ((lst = list) != null) {
-                if ((hi = fence) < 0) {
-                    synchronized (lst) {
-                        expectedModCount = lst.modCount;
-                        a = array = lst.elementData;
-                        hi = fence = lst.elementCount;
-                    }
-                }
-                else
-                    a = array;
-                if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {
-                    while (i < hi)
-                        action.accept((E) a[i++]);
-                    if (lst.modCount == expectedModCount)
-                        return;
-                }
-            }
-            throw new ConcurrentModificationException();
+            final int hi = getFence();
+            final Object[] a = array;
+            int i;
+            for (i = index, index = hi; i < hi; i++)
+                action.accept((E) a[i]);
+            if (modCount != expectedModCount)
+                throw new ConcurrentModificationException();
         }
 
         public long estimateSize() {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java	Thu Dec 22 18:48:53 2016 +0000
@@ -675,12 +675,14 @@
 
     /**
      * Nulls out slots starting at array index i, upto index end.
-     * If i == end, the entire array is cleared!
+     * Condition i == end means "full" - the entire array is cleared.
      */
     private static void circularClear(Object[] items, int i, int end) {
+        // assert 0 <= i && i < items.length;
+        // assert 0 <= end && end < items.length;
         for (int to = (i < end) ? end : items.length;
              ; i = 0, to = end) {
-            Arrays.fill(items, i, to, null);
+            for (; i < to; i++) items[i] = null;
             if (to == end) break;
         }
     }
@@ -1011,6 +1013,11 @@
      * expected element to remove, in lastItem.  Yes, we may fail to
      * remove lastItem from the queue if it moved due to an interleaved
      * interior remove while in detached mode.
+     *
+     * Method forEachRemaining, added in Java 8, is treated similarly
+     * to hasNext returning false, in that we switch to detached mode,
+     * but we regard it as an even stronger request to "close" this
+     * iteration, and don't bother supporting subsequent remove().
      */
     private class Itr implements Iterator<E> {
         /** Index to look for new nextItem; NONE at end */
@@ -1432,6 +1439,9 @@
                     Spliterator.CONCURRENT));
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     public void forEach(Consumer<? super E> action) {
         Objects.requireNonNull(action);
         final ReentrantLock lock = this.lock;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java	Thu Dec 22 18:48:53 2016 +0000
@@ -48,6 +48,7 @@
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * An unbounded concurrent {@linkplain Deque deque} based on linked nodes.
@@ -864,8 +865,8 @@
 
     public E peekFirst() {
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null)
+            final E item;
+            if ((item = p.item) != null)
                 return item;
         }
         return null;
@@ -873,8 +874,8 @@
 
     public E peekLast() {
         for (Node<E> p = last(); p != null; p = pred(p)) {
-            E item = p.item;
-            if (item != null)
+            final E item;
+            if ((item = p.item) != null)
                 return item;
         }
         return null;
@@ -896,8 +897,9 @@
 
     public E pollFirst() {
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null && ITEM.compareAndSet(p, item, null)) {
+            final E item;
+            if ((item = p.item) != null
+                && ITEM.compareAndSet(p, item, null)) {
                 unlink(p);
                 return item;
             }
@@ -907,8 +909,9 @@
 
     public E pollLast() {
         for (Node<E> p = last(); p != null; p = pred(p)) {
-            E item = p.item;
-            if (item != null && ITEM.compareAndSet(p, item, null)) {
+            final E item;
+            if ((item = p.item) != null
+                && ITEM.compareAndSet(p, item, null)) {
                 unlink(p);
                 return item;
             }
@@ -993,9 +996,10 @@
     public boolean removeFirstOccurrence(Object o) {
         Objects.requireNonNull(o);
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null && o.equals(item) &&
-                ITEM.compareAndSet(p, item, null)) {
+            final E item;
+            if ((item = p.item) != null
+                && o.equals(item)
+                && ITEM.compareAndSet(p, item, null)) {
                 unlink(p);
                 return true;
             }
@@ -1018,9 +1022,10 @@
     public boolean removeLastOccurrence(Object o) {
         Objects.requireNonNull(o);
         for (Node<E> p = last(); p != null; p = pred(p)) {
-            E item = p.item;
-            if (item != null && o.equals(item) &&
-                ITEM.compareAndSet(p, item, null)) {
+            final E item;
+            if ((item = p.item) != null
+                && o.equals(item)
+                && ITEM.compareAndSet(p, item, null)) {
                 unlink(p);
                 return true;
             }
@@ -1039,8 +1044,8 @@
     public boolean contains(Object o) {
         if (o != null) {
             for (Node<E> p = first(); p != null; p = succ(p)) {
-                E item = p.item;
-                if (item != null && o.equals(item))
+                final E item;
+                if ((item = p.item) != null && o.equals(item))
                     return true;
             }
         }
@@ -1181,8 +1186,8 @@
             int charLength = 0;
             int size = 0;
             for (Node<E> p = first(); p != null;) {
-                E item = p.item;
-                if (item != null) {
+                final E item;
+                if ((item = p.item) != null) {
                     if (a == null)
                         a = new String[4];
                     else if (size == a.length)
@@ -1207,8 +1212,8 @@
         restartFromHead: for (;;) {
             int size = 0;
             for (Node<E> p = first(); p != null;) {
-                E item = p.item;
-                if (item != null) {
+                final E item;
+                if ((item = p.item) != null) {
                     if (x == null)
                         x = new Object[4];
                     else if (size == x.length)
@@ -1360,8 +1365,8 @@
                     nextItem = null;
                     break;
                 }
-                E item = p.item;
-                if (item != null) {
+                final E item;
+                if ((item = p.item) != null) {
                     nextNode = p;
                     nextItem = item;
                     break;
@@ -1391,36 +1396,33 @@
 
     /** Forward iterator */
     private class Itr extends AbstractItr {
+        Itr() {}                        // prevent access constructor creation
         Node<E> startNode() { return first(); }
         Node<E> nextNode(Node<E> p) { return succ(p); }
     }
 
     /** Descending iterator */
     private class DescendingItr extends AbstractItr {
+        DescendingItr() {}              // prevent access constructor creation
         Node<E> startNode() { return last(); }
         Node<E> nextNode(Node<E> p) { return pred(p); }
     }
 
     /** A customized variant of Spliterators.IteratorSpliterator */
-    static final class CLDSpliterator<E> implements Spliterator<E> {
+    final class CLDSpliterator implements Spliterator<E> {
         static final int MAX_BATCH = 1 << 25;  // max batch array size;
-        final ConcurrentLinkedDeque<E> queue;
         Node<E> current;    // current node; null until initialized
         int batch;          // batch size for splits
         boolean exhausted;  // true when no more nodes
-        CLDSpliterator(ConcurrentLinkedDeque<E> queue) {
-            this.queue = queue;
-        }
 
         public Spliterator<E> trySplit() {
             Node<E> p;
-            final ConcurrentLinkedDeque<E> q = this.queue;
             int b = batch;
             int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
             if (!exhausted &&
-                ((p = current) != null || (p = q.first()) != null)) {
+                ((p = current) != null || (p = first()) != null)) {
                 if (p.item == null && p == (p = p.next))
-                    current = p = q.first();
+                    current = p = first();
                 if (p != null && p.next != null) {
                     Object[] a = new Object[n];
                     int i = 0;
@@ -1428,7 +1430,7 @@
                         if ((a[i] = p.item) != null)
                             ++i;
                         if (p == (p = p.next))
-                            p = q.first();
+                            p = first();
                     } while (p != null && i < n);
                     if ((current = p) == null)
                         exhausted = true;
@@ -1447,14 +1449,13 @@
         public void forEachRemaining(Consumer<? super E> action) {
             Node<E> p;
             if (action == null) throw new NullPointerException();
-            final ConcurrentLinkedDeque<E> q = this.queue;
             if (!exhausted &&
-                ((p = current) != null || (p = q.first()) != null)) {
+                ((p = current) != null || (p = first()) != null)) {
                 exhausted = true;
                 do {
                     E e = p.item;
                     if (p == (p = p.next))
-                        p = q.first();
+                        p = first();
                     if (e != null)
                         action.accept(e);
                 } while (p != null);
@@ -1464,14 +1465,13 @@
         public boolean tryAdvance(Consumer<? super E> action) {
             Node<E> p;
             if (action == null) throw new NullPointerException();
-            final ConcurrentLinkedDeque<E> q = this.queue;
             if (!exhausted &&
-                ((p = current) != null || (p = q.first()) != null)) {
+                ((p = current) != null || (p = first()) != null)) {
                 E e;
                 do {
                     e = p.item;
                     if (p == (p = p.next))
-                        p = q.first();
+                        p = first();
                 } while (e == null && p != null);
                 if ((current = p) == null)
                     exhausted = true;
@@ -1508,7 +1508,7 @@
      * @since 1.8
      */
     public Spliterator<E> spliterator() {
-        return new CLDSpliterator<E>(this);
+        return new CLDSpliterator();
     }
 
     /**
@@ -1527,8 +1527,8 @@
 
         // Write out all elements in the proper order.
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            E item = p.item;
-            if (item != null)
+            final E item;
+            if ((item = p.item) != null)
                 s.writeObject(item);
         }
 
@@ -1563,6 +1563,57 @@
         initHeadTail(h, t);
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        return bulkRemove(filter);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> c.contains(e));
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> !c.contains(e));
+    }
+
+    /** Implementation of bulk remove methods. */
+    private boolean bulkRemove(Predicate<? super E> filter) {
+        boolean removed = false;
+        for (Node<E> p = first(), succ; p != null; p = succ) {
+            succ = succ(p);
+            final E item;
+            if ((item = p.item) != null
+                && filter.test(item)
+                && ITEM.compareAndSet(p, item, null)) {
+                unlink(p);
+                removed = true;
+            }
+        }
+        return removed;
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        E item;
+        for (Node<E> p = first(); p != null; p = succ(p))
+            if ((item = p.item) != null)
+                action.accept(item);
+    }
+
     // VarHandle mechanics
     private static final VarHandle HEAD;
     private static final VarHandle TAIL;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java	Thu Dec 22 18:48:53 2016 +0000
@@ -47,6 +47,7 @@
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 /**
  * An unbounded thread-safe {@linkplain Queue queue} based on linked nodes.
@@ -112,7 +113,7 @@
     /*
      * This is a modification of the Michael & Scott algorithm,
      * adapted for a garbage-collected environment, with support for
-     * interior node deletion (to support remove(Object)).  For
+     * interior node deletion (to support e.g. remove(Object)).  For
      * explanation, read the paper.
      *
      * Note that like most non-blocking algorithms in this package,
@@ -160,12 +161,13 @@
      * it is possible for tail to lag behind head (why not)?
      *
      * CASing a Node's item reference to null atomically removes the
-     * element from the queue.  Iterators skip over Nodes with null
-     * items.  Prior implementations of this class had a race between
-     * poll() and remove(Object) where the same element would appear
-     * to be successfully removed by two concurrent operations.  The
-     * method remove(Object) also lazily unlinks deleted Nodes, but
-     * this is merely an optimization.
+     * element from the queue, leaving a "dead" node that should later
+     * be unlinked (but unlinking is merely an optimization).
+     * Interior element removal methods (other than Iterator.remove())
+     * keep track of the predecessor node during traversal so that the
+     * node can be CAS-unlinked.  Some traversal methods try to unlink
+     * any deleted nodes encountered during traversal.  See comments
+     * in bulkRemove.
      *
      * When constructing a Node (before enqueuing it) we avoid paying
      * for a volatile write to item.  This allows the cost of enqueue
@@ -290,6 +292,21 @@
     }
 
     /**
+     * Tries to CAS pred.next (or head, if pred is null) from c to p.
+     */
+    private boolean tryCasSuccessor(Node<E> pred, Node<E> c, Node<E> p) {
+        // assert c.item == null;
+        // assert c != p;
+        if (pred != null)
+            return NEXT.compareAndSet(pred, c, p);
+        if (HEAD.compareAndSet(this, c, p)) {
+            NEXT.setRelease(c, c);
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Inserts the specified element at the tail of this queue.
      * As the queue is unbounded, this method will never return {@code false}.
      *
@@ -326,12 +343,11 @@
     }
 
     public E poll() {
-        restartFromHead:
-        for (;;) {
-            for (Node<E> h = head, p = h, q;;) {
-                E item = p.item;
-
-                if (item != null && ITEM.compareAndSet(p, item, null)) {
+        restartFromHead: for (;;) {
+            for (Node<E> h = head, p = h, q;; p = q) {
+                final E item;
+                if ((item = p.item) != null
+                    && ITEM.compareAndSet(p, item, null)) {
                     // Successful CAS is the linearization point
                     // for item to be removed from this queue.
                     if (p != h) // hop two nodes at a time
@@ -344,25 +360,21 @@
                 }
                 else if (p == q)
                     continue restartFromHead;
-                else
-                    p = q;
             }
         }
     }
 
     public E peek() {
-        restartFromHead:
-        for (;;) {
-            for (Node<E> h = head, p = h, q;;) {
-                E item = p.item;
-                if (item != null || (q = p.next) == null) {
+        restartFromHead: for (;;) {
+            for (Node<E> h = head, p = h, q;; p = q) {
+                final E item;
+                if ((item = p.item) != null
+                    || (q = p.next) == null) {
                     updateHead(h, p);
                     return item;
                 }
                 else if (p == q)
                     continue restartFromHead;
-                else
-                    p = q;
             }
         }
     }
@@ -376,9 +388,8 @@
      * of losing a race to a concurrent poll().
      */
     Node<E> first() {
-        restartFromHead:
-        for (;;) {
-            for (Node<E> h = head, p = h, q;;) {
+        restartFromHead: for (;;) {
+            for (Node<E> h = head, p = h, q;; p = q) {
                 boolean hasItem = (p.item != null);
                 if (hasItem || (q = p.next) == null) {
                     updateHead(h, p);
@@ -386,8 +397,6 @@
                 }
                 else if (p == q)
                     continue restartFromHead;
-                else
-                    p = q;
             }
         }
     }
@@ -440,14 +449,24 @@
      * @return {@code true} if this queue contains the specified element
      */
     public boolean contains(Object o) {
-        if (o != null) {
-            for (Node<E> p = first(); p != null; p = succ(p)) {
-                E item = p.item;
-                if (item != null && o.equals(item))
+        if (o == null) return false;
+        restartFromHead: for (;;) {
+            for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
+                final E item;
+                if ((item = p.item) != null && o.equals(item))
                     return true;
+                if (c != p && tryCasSuccessor(pred, c, p))
+                    c = p;
+                q = p.next;
+                if (item != null || c != p) {
+                    pred = p;
+                    c = q;
+                }
+                else if (p == q)
+                    continue restartFromHead;
             }
+            return false;
         }
-        return false;
     }
 
     /**
@@ -462,27 +481,28 @@
      * @return {@code true} if this queue changed as a result of the call
      */
     public boolean remove(Object o) {
-        if (o != null) {
-            Node<E> next, pred = null;
-            for (Node<E> p = first(); p != null; pred = p, p = next) {
-                boolean removed = false;
-                E item = p.item;
-                if (item != null) {
-                    if (!o.equals(item)) {
-                        next = succ(p);
-                        continue;
-                    }
-                    removed = ITEM.compareAndSet(p, item, null);
-                }
-
-                next = succ(p);
-                if (pred != null && next != null) // unlink
-                    NEXT.weakCompareAndSet(pred, p, next);
+        if (o == null) return false;
+        restartFromHead: for (;;) {
+            for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
+                final E item;
+                final boolean removed =
+                    (item = p.item) != null
+                    && o.equals(item)
+                    && ITEM.compareAndSet(p, item, null);
+                if (c != p && tryCasSuccessor(pred, c, p))
+                    c = p;
                 if (removed)
                     return true;
+                q = p.next;
+                if (item != null || c != p) {
+                    pred = p;
+                    c = q;
+                }
+                else if (p == q)
+                    continue restartFromHead;
             }
+            return false;
         }
-        return false;
     }
 
     /**
@@ -553,8 +573,8 @@
             int charLength = 0;
             int size = 0;
             for (Node<E> p = first(); p != null;) {
-                E item = p.item;
-                if (item != null) {
+                final E item;
+                if ((item = p.item) != null) {
                     if (a == null)
                         a = new String[4];
                     else if (size == a.length)
@@ -579,8 +599,8 @@
         restartFromHead: for (;;) {
             int size = 0;
             for (Node<E> p = first(); p != null;) {
-                E item = p.item;
-                if (item != null) {
+                final E item;
+                if ((item = p.item) != null) {
                     if (x == null)
                         x = new Object[4];
                     else if (size == x.length)
@@ -697,7 +717,7 @@
             restartFromHead: for (;;) {
                 Node<E> h, p, q;
                 for (p = h = head;; p = q) {
-                    E item;
+                    final E item;
                     if ((item = p.item) != null) {
                         nextNode = p;
                         nextItem = item;
@@ -762,8 +782,8 @@
 
         // Write out all elements in the proper order.
         for (Node<E> p = first(); p != null; p = succ(p)) {
-            Object item = p.item;
-            if (item != null)
+            final E item;
+            if ((item = p.item) != null)
                 s.writeObject(item);
         }
 
@@ -801,23 +821,18 @@
     }
 
     /** A customized variant of Spliterators.IteratorSpliterator */
-    static final class CLQSpliterator<E> implements Spliterator<E> {
+    final class CLQSpliterator implements Spliterator<E> {
         static final int MAX_BATCH = 1 << 25;  // max batch array size;
-        final ConcurrentLinkedQueue<E> queue;
         Node<E> current;    // current node; null until initialized
         int batch;          // batch size for splits
         boolean exhausted;  // true when no more nodes
-        CLQSpliterator(ConcurrentLinkedQueue<E> queue) {
-            this.queue = queue;
-        }
 
         public Spliterator<E> trySplit() {
             Node<E> p;
-            final ConcurrentLinkedQueue<E> q = this.queue;
             int b = batch;
             int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
             if (!exhausted &&
-                ((p = current) != null || (p = q.first()) != null) &&
+                ((p = current) != null || (p = first()) != null) &&
                 p.next != null) {
                 Object[] a = new Object[n];
                 int i = 0;
@@ -825,7 +840,7 @@
                     if ((a[i] = p.item) != null)
                         ++i;
                     if (p == (p = p.next))
-                        p = q.first();
+                        p = first();
                 } while (p != null && i < n);
                 if ((current = p) == null)
                     exhausted = true;
@@ -843,14 +858,13 @@
         public void forEachRemaining(Consumer<? super E> action) {
             Node<E> p;
             if (action == null) throw new NullPointerException();
-            final ConcurrentLinkedQueue<E> q = this.queue;
             if (!exhausted &&
-                ((p = current) != null || (p = q.first()) != null)) {
+                ((p = current) != null || (p = first()) != null)) {
                 exhausted = true;
                 do {
                     E e = p.item;
                     if (p == (p = p.next))
-                        p = q.first();
+                        p = first();
                     if (e != null)
                         action.accept(e);
                 } while (p != null);
@@ -860,14 +874,13 @@
         public boolean tryAdvance(Consumer<? super E> action) {
             Node<E> p;
             if (action == null) throw new NullPointerException();
-            final ConcurrentLinkedQueue<E> q = this.queue;
             if (!exhausted &&
-                ((p = current) != null || (p = q.first()) != null)) {
+                ((p = current) != null || (p = first()) != null)) {
                 E e;
                 do {
                     e = p.item;
                     if (p == (p = p.next))
-                        p = q.first();
+                        p = first();
                 } while (e == null && p != null);
                 if ((current = p) == null)
                     exhausted = true;
@@ -905,7 +918,100 @@
      */
     @Override
     public Spliterator<E> spliterator() {
-        return new CLQSpliterator<E>(this);
+        return new CLQSpliterator();
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        return bulkRemove(filter);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> c.contains(e));
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> !c.contains(e));
+    }
+
+    public void clear() {
+        bulkRemove(e -> true);
+    }
+
+    /**
+     * Tolerate this many consecutive dead nodes before CAS-collapsing.
+     * Amortized cost of clear() is (1 + 1/MAX_HOPS) CASes per element.
+     */
+    private static final int MAX_HOPS = 8;
+
+    /** Implementation of bulk remove methods. */
+    private boolean bulkRemove(Predicate<? super E> filter) {
+        boolean removed = false;
+        restartFromHead: for (;;) {
+            int hops = MAX_HOPS;
+            // c will be CASed to collapse intervening dead nodes between
+            // pred (or head if null) and p.
+            for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
+                final E item; boolean pAlive;
+                if (pAlive = ((item = p.item) != null)) {
+                    if (filter.test(item)) {
+                        if (ITEM.compareAndSet(p, item, null))
+                            removed = true;
+                        pAlive = false;
+                    }
+                }
+                if ((q = p.next) == null || pAlive || --hops == 0) {
+                    // p might already be self-linked here, but if so:
+                    // - CASing head will surely fail
+                    // - CASing pred's next will be useless but harmless.
+                    if (c != p && tryCasSuccessor(pred, c, p))
+                        c = p;
+                    // if c != p, CAS failed, so abandon old pred
+                    if (pAlive || c != p) {
+                        hops = MAX_HOPS;
+                        pred = p;
+                        c = q;
+                    }
+                } else if (p == q)
+                    continue restartFromHead;
+            }
+            return removed;
+        }
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        restartFromHead: for (;;) {
+            for (Node<E> p = head, c = p, pred = null, q; p != null; p = q) {
+                final E item;
+                if ((item = p.item) != null)
+                    action.accept(item);
+                if (c != p && tryCasSuccessor(pred, c, p))
+                    c = p;
+                q = p.next;
+                if (item != null || c != p) {
+                    pred = p;
+                    c = q;
+                }
+                else if (p == q)
+                    continue restartFromHead;
+            }
+            return;
+        }
     }
 
     // VarHandle mechanics
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Thu Dec 22 18:48:53 2016 +0000
@@ -793,6 +793,9 @@
         }
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     public void forEach(Consumer<? super E> action) {
         if (action == null) throw new NullPointerException();
         for (Object x : getArray()) {
@@ -801,6 +804,9 @@
         }
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     public boolean removeIf(Predicate<? super E> filter) {
         if (filter == null) throw new NullPointerException();
         return bulkRemove(filter);
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java	Thu Dec 22 18:48:53 2016 +0000
@@ -411,10 +411,16 @@
                 && compareSets(al.getArray(), (Set<?>) o) == 0);
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     public boolean removeIf(Predicate<? super E> filter) {
         return al.removeIf(filter);
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
     public void forEach(Consumer<? super E> action) {
         al.forEach(action);
     }
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java	Thu Dec 22 18:48:53 2016 +0000
@@ -149,7 +149,8 @@
      * but no subsequent reset.
      */
     private static class Generation {
-        boolean broken;         // initially false
+        Generation() {}                 // prevent access constructor creation
+        boolean broken;                 // initially false
     }
 
     /** The lock for guarding barrier entry */
--- a/jdk/src/java.base/share/classes/java/util/concurrent/DelayQueue.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/DelayQueue.java	Thu Dec 22 18:48:53 2016 +0000
@@ -547,8 +547,7 @@
         public E next() {
             if (cursor >= array.length)
                 throw new NoSuchElementException();
-            lastRet = cursor;
-            return (E)array[cursor++];
+            return (E)array[lastRet = cursor++];
         }
 
         public void remove() {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java	Thu Dec 22 18:48:53 2016 +0000
@@ -39,6 +39,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.concurrent.locks.Condition;
@@ -740,8 +741,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c, int maxElements) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         if (maxElements <= 0)
@@ -986,6 +986,16 @@
     }
 
     /**
+     * Used for any element traversal that is not entirely under lock.
+     * Such traversals must handle both:
+     * - dequeued nodes (p.next == p)
+     * - (possibly multiple) interior removed nodes (p.item == null)
+     */
+    Node<E> succ(Node<E> p) {
+        return (p == (p = p.next)) ? first : p;
+    }
+
+    /**
      * Returns an iterator over the elements in this deque in proper sequence.
      * The elements will be returned in order from first (head) to last (tail).
      *
@@ -1024,8 +1034,8 @@
         /**
          * nextItem holds on to item fields because once we claim that
          * an element exists in hasNext(), we must return item read
-         * under lock (in advance()) even if it was in the process of
-         * being removed when hasNext() was called.
+         * under lock even if it was in the process of being removed
+         * when hasNext() was called.
          */
         E nextItem;
 
@@ -1038,48 +1048,17 @@
         abstract Node<E> firstNode();
         abstract Node<E> nextNode(Node<E> n);
 
+        private Node<E> succ(Node<E> p) {
+            return (p == (p = nextNode(p))) ? firstNode() : p;
+        }
+
         AbstractItr() {
             // set to initial position
             final ReentrantLock lock = LinkedBlockingDeque.this.lock;
             lock.lock();
             try {
-                next = firstNode();
-                nextItem = (next == null) ? null : next.item;
-            } finally {
-                lock.unlock();
-            }
-        }
-
-        /**
-         * Returns the successor node of the given non-null, but
-         * possibly previously deleted, node.
-         */
-        private Node<E> succ(Node<E> n) {
-            // Chains of deleted nodes ending in null or self-links
-            // are possible if multiple interior nodes are removed.
-            for (;;) {
-                Node<E> s = nextNode(n);
-                if (s == null)
-                    return null;
-                else if (s.item != null)
-                    return s;
-                else if (s == n)
-                    return firstNode();
-                else
-                    n = s;
-            }
-        }
-
-        /**
-         * Advances next.
-         */
-        void advance() {
-            final ReentrantLock lock = LinkedBlockingDeque.this.lock;
-            lock.lock();
-            try {
-                // assert next != null;
-                next = succ(next);
-                nextItem = (next == null) ? null : next.item;
+                if ((next = firstNode()) != null)
+                    nextItem = next.item;
             } finally {
                 lock.unlock();
             }
@@ -1090,14 +1069,65 @@
         }
 
         public E next() {
-            if (next == null)
+            Node<E> p;
+            if ((p = next) == null)
                 throw new NoSuchElementException();
-            lastRet = next;
+            lastRet = p;
             E x = nextItem;
-            advance();
+            final ReentrantLock lock = LinkedBlockingDeque.this.lock;
+            lock.lock();
+            try {
+                E e = null;
+                for (p = nextNode(p); p != null && (e = p.item) == null; )
+                    p = succ(p);
+                next = p;
+                nextItem = e;
+            } finally {
+                lock.unlock();
+            }
             return x;
         }
 
+        public void forEachRemaining(Consumer<? super E> action) {
+            // A variant of forEachFrom
+            Objects.requireNonNull(action);
+            Node<E> p;
+            if ((p = next) == null) return;
+            lastRet = p;
+            next = null;
+            final ReentrantLock lock = LinkedBlockingDeque.this.lock;
+            final int batchSize = 32;
+            Object[] es = null;
+            int n, len = 1;
+            do {
+                lock.lock();
+                try {
+                    if (es == null) {
+                        p = nextNode(p);
+                        for (Node<E> q = p; q != null; q = succ(q))
+                            if (q.item != null && ++len == batchSize)
+                                break;
+                        es = new Object[len];
+                        es[0] = nextItem;
+                        nextItem = null;
+                        n = 1;
+                    } else
+                        n = 0;
+                    for (; p != null && n < len; p = succ(p))
+                        if ((es[n] = p.item) != null) {
+                            lastRet = p;
+                            n++;
+                        }
+                } finally {
+                    lock.unlock();
+                }
+                for (int i = 0; i < n; i++) {
+                    @SuppressWarnings("unchecked") E e = (E) es[i];
+                    action.accept(e);
+                }
+            } while (n > 0 && p != null);
+        }
+
         public void remove() {
             Node<E> n = lastRet;
             if (n == null)
@@ -1116,25 +1146,30 @@
 
     /** Forward iterator */
     private class Itr extends AbstractItr {
+        Itr() {}                        // prevent access constructor creation
         Node<E> firstNode() { return first; }
         Node<E> nextNode(Node<E> n) { return n.next; }
     }
 
     /** Descending iterator */
     private class DescendingItr extends AbstractItr {
+        DescendingItr() {}              // prevent access constructor creation
         Node<E> firstNode() { return last; }
         Node<E> nextNode(Node<E> n) { return n.prev; }
     }
 
-    /** A customized variant of Spliterators.IteratorSpliterator */
+    /**
+     * A customized variant of Spliterators.IteratorSpliterator.
+     * Keep this class in sync with (very similar) LBQSpliterator.
+     */
     private final class LBDSpliterator implements Spliterator<E> {
         static final int MAX_BATCH = 1 << 25;  // max batch array size;
         Node<E> current;    // current node; null until initialized
         int batch;          // batch size for splits
         boolean exhausted;  // true when no more nodes
-        long est;           // size estimate
+        long est = size();  // size estimate
 
-        LBDSpliterator() { est = size(); }
+        LBDSpliterator() {}
 
         public long estimateSize() { return est; }
 
@@ -1143,8 +1178,7 @@
             int b = batch;
             int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
             if (!exhausted &&
-                (((h = current) != null && h != h.next)
-                 || (h = first) != null)
+                ((h = current) != null || (h = first) != null)
                 && h.next != null) {
                 Object[] a = new Object[n];
                 final ReentrantLock lock = LinkedBlockingDeque.this.lock;
@@ -1152,10 +1186,10 @@
                 Node<E> p = current;
                 lock.lock();
                 try {
-                    if (((p != null && p != p.next) || (p = first) != null)
-                        && p.item != null)
-                        for (; p != null && i < n; p = p.next)
-                            a[i++] = p.item;
+                    if (p != null || (p = first) != null)
+                        for (; p != null && i < n; p = succ(p))
+                            if ((a[i] = p.item) != null)
+                                i++;
                 } finally {
                     lock.unlock();
                 }
@@ -1176,51 +1210,39 @@
             return null;
         }
 
-        public void forEachRemaining(Consumer<? super E> action) {
-            if (action == null) throw new NullPointerException();
-            if (exhausted)
-                return;
-            exhausted = true;
-            final ReentrantLock lock = LinkedBlockingDeque.this.lock;
-            Node<E> p = current;
-            current = null;
-            do {
+        public boolean tryAdvance(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            if (!exhausted) {
                 E e = null;
+                final ReentrantLock lock = LinkedBlockingDeque.this.lock;
                 lock.lock();
                 try {
-                    if ((p != null && p != p.next) || (p = first) != null) {
-                        e = p.item;
-                        p = p.next;
-                    }
+                    Node<E> p;
+                    if ((p = current) != null || (p = first) != null)
+                        do {
+                            e = p.item;
+                            p = succ(p);
+                        } while (e == null && p != null);
+                    exhausted = ((current = p) == null);
                 } finally {
                     lock.unlock();
                 }
-                if (e != null)
+                if (e != null) {
                     action.accept(e);
-            } while (p != null);
+                    return true;
+                }
+            }
+            return false;
         }
 
-        public boolean tryAdvance(Consumer<? super E> action) {
-            if (action == null) throw new NullPointerException();
-            if (exhausted)
-                return false;
-            final ReentrantLock lock = LinkedBlockingDeque.this.lock;
-            Node<E> p = current;
-            E e = null;
-            lock.lock();
-            try {
-                if ((p != null && p != p.next) || (p = first) != null) {
-                    e = p.item;
-                    p = p.next;
-                }
-            } finally {
-                lock.unlock();
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            if (!exhausted) {
+                exhausted = true;
+                Node<E> p = current;
+                current = null;
+                forEachFrom(action, p);
             }
-            exhausted = ((current = p) == null);
-            if (e == null)
-                return false;
-            action.accept(e);
-            return true;
         }
 
         public int characteristics() {
@@ -1251,6 +1273,48 @@
     }
 
     /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        forEachFrom(action, null);
+    }
+
+    /**
+     * Runs action on each element found during a traversal starting at p.
+     * If p is null, traversal starts at head.
+     */
+    void forEachFrom(Consumer<? super E> action, Node<E> p) {
+        // Extract batches of elements while holding the lock; then
+        // run the action on the elements while not
+        final ReentrantLock lock = this.lock;
+        final int batchSize = 32;       // max number of elements per batch
+        Object[] es = null;             // container for batch of elements
+        int n, len = 0;
+        do {
+            lock.lock();
+            try {
+                if (es == null) {
+                    if (p == null) p = first;
+                    for (Node<E> q = p; q != null; q = succ(q))
+                        if (q.item != null && ++len == batchSize)
+                            break;
+                    es = new Object[len];
+                }
+                for (n = 0; p != null && n < len; p = succ(p))
+                    if ((es[n] = p.item) != null)
+                        n++;
+            } finally {
+                lock.unlock();
+            }
+            for (int i = 0; i < n; i++) {
+                @SuppressWarnings("unchecked") E e = (E) es[i];
+                action.accept(e);
+            }
+        } while (n > 0 && p != null);
+    }
+
+    /**
      * Saves this deque to a stream (that is, serializes it).
      *
      * @param s the stream
@@ -1290,8 +1354,7 @@
         last = null;
         // Read in all elements and place in queue
         for (;;) {
-            @SuppressWarnings("unchecked")
-            E item = (E)s.readObject();
+            @SuppressWarnings("unchecked") E item = (E)s.readObject();
             if (item == null)
                 break;
             add(item);
--- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java	Thu Dec 22 18:48:53 2016 +0000
@@ -39,6 +39,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Objects;
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -234,14 +235,6 @@
         putLock.unlock();
     }
 
-//     /**
-//      * Tells whether both locks are held by current thread.
-//      */
-//     boolean isFullyLocked() {
-//         return (putLock.isHeldByCurrentThread() &&
-//                 takeLock.isHeldByCurrentThread());
-//     }
-
     /**
      * Creates a {@code LinkedBlockingQueue} with a capacity of
      * {@link Integer#MAX_VALUE}.
@@ -517,7 +510,8 @@
      * Unlinks interior Node p with predecessor trail.
      */
     void unlink(Node<E> p, Node<E> trail) {
-        // assert isFullyLocked();
+        // assert putLock.isHeldByCurrentThread();
+        // assert takeLock.isHeldByCurrentThread();
         // p.next is not changed, to allow iterators that are
         // traversing p to maintain their weak-consistency guarantee.
         p.item = null;
@@ -701,8 +695,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c, int maxElements) {
-        if (c == null)
-            throw new NullPointerException();
+        Objects.requireNonNull(c);
         if (c == this)
             throw new IllegalArgumentException();
         if (maxElements <= 0)
@@ -741,6 +734,16 @@
     }
 
     /**
+     * Used for any element traversal that is not entirely under lock.
+     * Such traversals must handle both:
+     * - dequeued nodes (p.next == p)
+     * - (possibly multiple) interior removed nodes (p.item == null)
+     */
+    Node<E> succ(Node<E> p) {
+        return (p == (p = p.next)) ? head.next : p;
+    }
+
+    /**
      * Returns an iterator over the elements in this queue in proper sequence.
      * The elements will be returned in order from first (head) to last (tail).
      *
@@ -760,48 +763,80 @@
          * still have it to return even if lost race with a take etc.
          */
 
-        private Node<E> current;
+        private Node<E> next;
+        private E nextItem;
         private Node<E> lastRet;
-        private E currentElement;
 
         Itr() {
             fullyLock();
             try {
-                current = head.next;
-                if (current != null)
-                    currentElement = current.item;
+                if ((next = head.next) != null)
+                    nextItem = next.item;
             } finally {
                 fullyUnlock();
             }
         }
 
         public boolean hasNext() {
-            return current != null;
+            return next != null;
         }
 
         public E next() {
+            Node<E> p;
+            if ((p = next) == null)
+                throw new NoSuchElementException();
+            lastRet = p;
+            E x = nextItem;
             fullyLock();
             try {
-                if (current == null)
-                    throw new NoSuchElementException();
-                lastRet = current;
-                E item = null;
-                // Unlike other traversal methods, iterators must handle both:
-                // - dequeued nodes (p.next == p)
-                // - (possibly multiple) interior removed nodes (p.item == null)
-                for (Node<E> p = current, q;; p = q) {
-                    if ((q = p.next) == p)
-                        q = head.next;
-                    if (q == null || (item = q.item) != null) {
-                        current = q;
-                        E x = currentElement;
-                        currentElement = item;
-                        return x;
-                    }
-                }
+                E e = null;
+                for (p = p.next; p != null && (e = p.item) == null; )
+                    p = succ(p);
+                next = p;
+                nextItem = e;
             } finally {
                 fullyUnlock();
             }
+            return x;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            // A variant of forEachFrom
+            Objects.requireNonNull(action);
+            Node<E> p;
+            if ((p = next) == null) return;
+            lastRet = p;
+            next = null;
+            final int batchSize = 32;
+            Object[] es = null;
+            int n, len = 1;
+            do {
+                fullyLock();
+                try {
+                    if (es == null) {
+                        p = p.next;
+                        for (Node<E> q = p; q != null; q = succ(q))
+                            if (q.item != null && ++len == batchSize)
+                                break;
+                        es = new Object[len];
+                        es[0] = nextItem;
+                        nextItem = null;
+                        n = 1;
+                    } else
+                        n = 0;
+                    for (; p != null && n < len; p = succ(p))
+                        if ((es[n] = p.item) != null) {
+                            lastRet = p;
+                            n++;
+                        }
+                } finally {
+                    fullyUnlock();
+                }
+                for (int i = 0; i < n; i++) {
+                    @SuppressWarnings("unchecked") E e = (E) es[i];
+                    action.accept(e);
+                }
+            } while (n > 0 && p != null);
         }
 
         public void remove() {
@@ -825,42 +860,39 @@
         }
     }
 
-    /** A customized variant of Spliterators.IteratorSpliterator */
-    static final class LBQSpliterator<E> implements Spliterator<E> {
+    /**
+     * A customized variant of Spliterators.IteratorSpliterator.
+     * Keep this class in sync with (very similar) LBDSpliterator.
+     */
+    private final class LBQSpliterator implements Spliterator<E> {
         static final int MAX_BATCH = 1 << 25;  // max batch array size;
-        final LinkedBlockingQueue<E> queue;
         Node<E> current;    // current node; null until initialized
         int batch;          // batch size for splits
         boolean exhausted;  // true when no more nodes
-        long est;           // size estimate
-        LBQSpliterator(LinkedBlockingQueue<E> queue) {
-            this.queue = queue;
-            this.est = queue.size();
-        }
+        long est = size();  // size estimate
+
+        LBQSpliterator() {}
 
         public long estimateSize() { return est; }
 
         public Spliterator<E> trySplit() {
             Node<E> h;
-            final LinkedBlockingQueue<E> q = this.queue;
             int b = batch;
             int n = (b <= 0) ? 1 : (b >= MAX_BATCH) ? MAX_BATCH : b + 1;
             if (!exhausted &&
-                ((h = current) != null || (h = q.head.next) != null) &&
-                h.next != null) {
+                ((h = current) != null || (h = head.next) != null)
+                && h.next != null) {
                 Object[] a = new Object[n];
                 int i = 0;
                 Node<E> p = current;
-                q.fullyLock();
+                fullyLock();
                 try {
-                    if (p != null || (p = q.head.next) != null) {
-                        do {
+                    if (p != null || (p = head.next) != null)
+                        for (; p != null && i < n; p = succ(p))
                             if ((a[i] = p.item) != null)
-                                ++i;
-                        } while ((p = p.next) != null && i < n);
-                    }
+                                i++;
                 } finally {
-                    q.fullyUnlock();
+                    fullyUnlock();
                 }
                 if ((current = p) == null) {
                     est = 0L;
@@ -879,53 +911,22 @@
             return null;
         }
 
-        public void forEachRemaining(Consumer<? super E> action) {
-            if (action == null) throw new NullPointerException();
-            final LinkedBlockingQueue<E> q = this.queue;
-            if (!exhausted) {
-                exhausted = true;
-                Node<E> p = current;
-                do {
-                    E e = null;
-                    q.fullyLock();
-                    try {
-                        if (p == null)
-                            p = q.head.next;
-                        while (p != null) {
-                            e = p.item;
-                            p = p.next;
-                            if (e != null)
-                                break;
-                        }
-                    } finally {
-                        q.fullyUnlock();
-                    }
-                    if (e != null)
-                        action.accept(e);
-                } while (p != null);
-            }
-        }
-
         public boolean tryAdvance(Consumer<? super E> action) {
-            if (action == null) throw new NullPointerException();
-            final LinkedBlockingQueue<E> q = this.queue;
+            Objects.requireNonNull(action);
             if (!exhausted) {
                 E e = null;
-                q.fullyLock();
+                fullyLock();
                 try {
-                    if (current == null)
-                        current = q.head.next;
-                    while (current != null) {
-                        e = current.item;
-                        current = current.next;
-                        if (e != null)
-                            break;
-                    }
+                    Node<E> p;
+                    if ((p = current) != null || (p = head.next) != null)
+                        do {
+                            e = p.item;
+                            p = succ(p);
+                        } while (e == null && p != null);
+                    exhausted = ((current = p) == null);
                 } finally {
-                    q.fullyUnlock();
+                    fullyUnlock();
                 }
-                if (current == null)
-                    exhausted = true;
                 if (e != null) {
                     action.accept(e);
                     return true;
@@ -934,9 +935,20 @@
             return false;
         }
 
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            if (!exhausted) {
+                exhausted = true;
+                Node<E> p = current;
+                current = null;
+                forEachFrom(action, p);
+            }
+        }
+
         public int characteristics() {
-            return Spliterator.ORDERED | Spliterator.NONNULL |
-                Spliterator.CONCURRENT;
+            return (Spliterator.ORDERED |
+                    Spliterator.NONNULL |
+                    Spliterator.CONCURRENT);
         }
     }
 
@@ -957,7 +969,48 @@
      * @since 1.8
      */
     public Spliterator<E> spliterator() {
-        return new LBQSpliterator<E>(this);
+        return new LBQSpliterator();
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        forEachFrom(action, null);
+    }
+
+    /**
+     * Runs action on each element found during a traversal starting at p.
+     * If p is null, traversal starts at head.
+     */
+    void forEachFrom(Consumer<? super E> action, Node<E> p) {
+        // Extract batches of elements while holding the lock; then
+        // run the action on the elements while not
+        final int batchSize = 32;       // max number of elements per batch
+        Object[] es = null;             // container for batch of elements
+        int n, len = 0;
+        do {
+            fullyLock();
+            try {
+                if (es == null) {
+                    if (p == null) p = head.next;
+                    for (Node<E> q = p; q != null; q = succ(q))
+                        if (q.item != null && ++len == batchSize)
+                            break;
+                    es = new Object[len];
+                }
+                for (n = 0; p != null && n < len; p = succ(p))
+                    if ((es[n] = p.item) != null)
+                        n++;
+            } finally {
+                fullyUnlock();
+            }
+            for (int i = 0; i < n; i++) {
+                @SuppressWarnings("unchecked") E e = (E) es[i];
+                action.accept(e);
+            }
+        } while (n > 0 && p != null);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java	Thu Dec 22 18:48:53 2016 +0000
@@ -179,7 +179,7 @@
  * void startTasks(List<Runnable> tasks, int iterations) {
  *   Phaser phaser = new Phaser() {
  *     protected boolean onAdvance(int phase, int registeredParties) {
- *       return phase >= iterations || registeredParties == 0;
+ *       return phase >= iterations - 1 || registeredParties == 0;
  *     }
  *   };
  *   phaser.register();
--- a/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Thu Dec 22 18:48:53 2016 +0000
@@ -345,11 +345,9 @@
      * promoting x up the tree until it is greater than or equal to
      * its parent, or is the root.
      *
-     * To simplify and speed up coercions and comparisons. the
+     * To simplify and speed up coercions and comparisons, the
      * Comparable and Comparator versions are separated into different
      * methods that are otherwise identical. (Similarly for siftDown.)
-     * These methods are static, with heap state as arguments, to
-     * simplify use in light of possible comparator exceptions.
      *
      * @param k the position to fill
      * @param x the item to insert
@@ -435,6 +433,7 @@
     /**
      * Establishes the heap invariant (described above) in the entire tree,
      * assuming nothing about the order of the elements prior to the call.
+     * This classic algorithm due to Floyd (1964) is known to be O(size).
      */
     private void heapify() {
         Object[] array = queue;
@@ -878,8 +877,7 @@
         public E next() {
             if (cursor >= array.length)
                 throw new NoSuchElementException();
-            lastRet = cursor;
-            return (E)array[cursor++];
+            return (E)array[lastRet = cursor++];
         }
 
         public void remove() {
@@ -936,15 +934,12 @@
     /**
      * Immutable snapshot spliterator that binds to elements "late".
      */
-    static final class PBQSpliterator<E> implements Spliterator<E> {
-        final PriorityBlockingQueue<E> queue;
+    final class PBQSpliterator implements Spliterator<E> {
         Object[] array;
         int index;
         int fence;
 
-        PBQSpliterator(PriorityBlockingQueue<E> queue, Object[] array,
-                       int index, int fence) {
-            this.queue = queue;
+        PBQSpliterator(Object[] array, int index, int fence) {
             this.array = array;
             this.index = index;
             this.fence = fence;
@@ -953,14 +948,14 @@
         final int getFence() {
             int hi;
             if ((hi = fence) < 0)
-                hi = fence = (array = queue.toArray()).length;
+                hi = fence = (array = toArray()).length;
             return hi;
         }
 
-        public PBQSpliterator<E> trySplit() {
+        public PBQSpliterator trySplit() {
             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
             return (lo >= mid) ? null :
-                new PBQSpliterator<E>(queue, array, lo, index = mid);
+                new PBQSpliterator(array, lo, index = mid);
         }
 
         @SuppressWarnings("unchecked")
@@ -969,7 +964,7 @@
             if (action == null)
                 throw new NullPointerException();
             if ((a = array) == null)
-                fence = (a = queue.toArray()).length;
+                fence = (a = toArray()).length;
             if ((hi = fence) <= a.length &&
                 (i = index) >= 0 && i < (index = hi)) {
                 do { action.accept((E)a[i]); } while (++i < hi);
@@ -987,7 +982,7 @@
             return false;
         }
 
-        public long estimateSize() { return (long)(getFence() - index); }
+        public long estimateSize() { return getFence() - index; }
 
         public int characteristics() {
             return Spliterator.NONNULL | Spliterator.SIZED | Spliterator.SUBSIZED;
@@ -1012,7 +1007,7 @@
      * @since 1.8
      */
     public Spliterator<E> spliterator() {
-        return new PBQSpliterator<E>(this, null, 0, -1);
+        return new PBQSpliterator(null, 0, -1);
     }
 
     // VarHandle mechanics
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1306,8 +1306,7 @@
             public Runnable next() {
                 if (cursor >= array.length)
                     throw new NoSuchElementException();
-                lastRet = cursor;
-                return array[cursor++];
+                return array[lastRet = cursor++];
             }
 
             public void remove() {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java	Thu Dec 22 18:48:53 2016 +0000
@@ -195,6 +195,7 @@
 
     /** Fallback if ForkJoinPool.commonPool() cannot support parallelism */
     private static final class ThreadPerTaskExecutor implements Executor {
+        ThreadPerTaskExecutor() {}      // prevent access constructor creation
         public void execute(Runnable r) { new Thread(r).start(); }
     }
 
@@ -1454,7 +1455,17 @@
          */
         private boolean checkControl(Flow.Subscriber<? super T> s, int c) {
             boolean stat = true;
-            if ((c & ERROR) != 0) {
+            if ((c & SUBSCRIBE) != 0) {
+                if (CTL.compareAndSet(this, c, c & ~SUBSCRIBE)) {
+                    try {
+                        if (s != null)
+                            s.onSubscribe(this);
+                    } catch (Throwable ex) {
+                        onError(ex);
+                    }
+                }
+            }
+            else if ((c & ERROR) != 0) {
                 Throwable ex = pendingError;
                 ctl = DISABLED;           // no need for CAS
                 if (ex != null) {         // null if errorless cancel
@@ -1465,16 +1476,6 @@
                     }
                 }
             }
-            else if ((c & SUBSCRIBE) != 0) {
-                if (CTL.compareAndSet(this, c, c & ~SUBSCRIBE)) {
-                    try {
-                        if (s != null)
-                            s.onSubscribe(this);
-                    } catch (Throwable ex) {
-                        onError(ex);
-                    }
-                }
-            }
             else {
                 detach();
                 stat = false;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java	Thu Dec 22 18:48:53 2016 +0000
@@ -138,7 +138,7 @@
  * <pre> {@code
  * class CachedData {
  *   Object data;
- *   volatile boolean cacheValid;
+ *   boolean cacheValid;
  *   final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  *
  *   void processCachedData() {
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLEngine.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1338,7 +1338,7 @@
     /**
      * Registers a callback function that selects an application protocol
      * value for a SSL/TLS/DTLS handshake.
-     * The function overrides any values set using
+     * The function overrides any values supplied using
      * {@link SSLParameters#setApplicationProtocols
      * SSLParameters.setApplicationProtocols} and it supports the following
      * type parameters:
@@ -1354,6 +1354,8 @@
      * <dt> {@code String}
      * <dd> The function's result is an application protocol name, or null to
      *      indicate that none of the advertised names are acceptable.
+     *      If the return value is an empty {@code String} then application
+     *      protocol indications will not be used.
      *      If the return value is null (no value chosen) or is a value that
      *      was not advertised by the peer, the underlying protocol will
      *      determine what action to take. (For example, ALPN will send a
--- a/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/javax/net/ssl/SSLSocket.java	Thu Dec 22 18:48:53 2016 +0000
@@ -749,7 +749,7 @@
     /**
      * Registers a callback function that selects an application protocol
      * value for a SSL/TLS/DTLS handshake.
-     * The function overrides any values set using
+     * The function overrides any values supplied using
      * {@link SSLParameters#setApplicationProtocols
      * SSLParameters.setApplicationProtocols} and it supports the following
      * type parameters:
@@ -765,6 +765,8 @@
      * <dt> {@code String}
      * <dd> The function's result is an application protocol name, or null to
      *      indicate that none of the advertised names are acceptable.
+     *      If the return value is an empty {@code String} then application
+     *      protocol indications will not be used.
      *      If the return value is null (no value chosen) or is a value that
      *      was not advertised by the peer, the underlying protocol will
      *      determine what action to take. (For example, ALPN will send a
--- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, 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
@@ -31,7 +31,7 @@
 import java.nio.channels.*;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
-
+import java.util.concurrent.TimeUnit;
 
 // Make a socket channel look like a socket.
 //
@@ -99,17 +99,19 @@
                 try {
                     if (sc.connect(remote))
                         return;
-                    long to = timeout;
+                    long timeoutNanos =
+                        TimeUnit.NANOSECONDS.convert(timeout,
+                            TimeUnit.MILLISECONDS);
                     for (;;) {
                         if (!sc.isOpen())
                             throw new ClosedChannelException();
-                        long st = System.currentTimeMillis();
+                        long startTime = System.nanoTime();
 
-                        int result = sc.poll(Net.POLLCONN, to);
+                        int result = sc.poll(Net.POLLCONN, timeout);
                         if (result > 0 && sc.finishConnect())
                             break;
-                        to -= System.currentTimeMillis() - st;
-                        if (to <= 0) {
+                        timeoutNanos -= System.nanoTime() - startTime;
+                        if (timeoutNanos <= 0) {
                             try {
                                 sc.close();
                             } catch (IOException x) { }
@@ -194,18 +196,20 @@
                     int n;
                     if ((n = sc.read(bb)) != 0)
                         return n;
-                    long to = timeout;
+                    long timeoutNanos =
+                        TimeUnit.NANOSECONDS.convert(timeout,
+                            TimeUnit.MILLISECONDS);
                     for (;;) {
                         if (!sc.isOpen())
                             throw new ClosedChannelException();
-                        long st = System.currentTimeMillis();
-                        int result = sc.poll(Net.POLLIN, to);
+                        long startTime = System.nanoTime();
+                        int result = sc.poll(Net.POLLIN, timeout);
                         if (result > 0) {
                             if ((n = sc.read(bb)) != 0)
                                 return n;
                         }
-                        to -= System.currentTimeMillis() - st;
-                        if (to <= 0)
+                        timeoutNanos -= System.nanoTime() - startTime;
+                        if (timeoutNanos <= 0)
                             throw new SocketTimeoutException();
                     }
                 } finally {
--- a/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java	Thu Dec 22 18:48:53 2016 +0000
@@ -80,7 +80,7 @@
     @Override
     protected void chooseAlgorithmAndStrength() {
         if (requestedAlgorithm != null) {
-            algorithm = requestedAlgorithm.toUpperCase();
+            algorithm = requestedAlgorithm.toUpperCase(Locale.ROOT);
             int supportedStrength = alg2strength(algorithm);
             if (requestedInstantiationSecurityStrength >= 0) {
                 int tryStrength = getStandardStrength(
--- a/jdk/src/java.base/share/classes/sun/security/x509/AlgorithmId.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/x509/AlgorithmId.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, 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
@@ -1009,7 +1009,7 @@
      * @return the default alg, might be null if unsupported
      */
     public static String getDefaultSigAlgForKey(PrivateKey k) {
-        switch (k.getAlgorithm().toUpperCase()) {
+        switch (k.getAlgorithm().toUpperCase(Locale.ROOT)) {
             case "EC":
                 return ecStrength(KeyUtil.getKeySize(k))
                     + "withECDSA";
--- a/jdk/src/java.desktop/share/classes/java/beans/PropertyDescriptor.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/java/beans/PropertyDescriptor.java	Thu Dec 22 18:48:53 2016 +0000
@@ -183,9 +183,10 @@
             setShortDescription(description.toString());
         }
         Object values = info.get(PropertyInfo.Name.enumerationValues);
-        if (values != null) {
-            setValue(PropertyInfo.Name.enumerationValues.name(), values);
+        if (values == null) {
+            values = new Object[0];
         }
+        setValue(PropertyInfo.Name.enumerationValues.name(), values);
         this.baseName = base;
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/JToggleButton.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JToggleButton.java	Thu Dec 22 18:48:53 2016 +0000
@@ -34,6 +34,7 @@
 
 import java.io.ObjectOutputStream;
 import java.io.IOException;
+import java.util.Iterator;
 
 /**
  * An implementation of a two-state button.
@@ -208,6 +209,96 @@
         return true;
     }
 
+    private JToggleButton getGroupSelection(FocusEvent.Cause cause) {
+        switch (cause) {
+          case ACTIVATION:
+          case TRAVERSAL:
+          case TRAVERSAL_UP:
+          case TRAVERSAL_DOWN:
+          case TRAVERSAL_FORWARD:
+          case TRAVERSAL_BACKWARD:
+            ButtonModel model = getModel();
+            JToggleButton selection = this;
+            if (model instanceof DefaultButtonModel) {
+                ButtonGroup group = ((DefaultButtonModel) model).getGroup();
+                if (group != null && group.getSelection() != null
+                                                  && !group.isSelected(model)) {
+                    Iterator<AbstractButton> iterator =
+                                               group.getElements().asIterator();
+                    while (iterator.hasNext()) {
+                        AbstractButton member = iterator.next();
+                        if (group.isSelected(member.getModel())) {
+                            if (member instanceof JToggleButton &&
+                                member.isVisible() && member.isDisplayable() &&
+                                member.isEnabled() && member.isFocusable()) {
+                                selection = (JToggleButton) member;
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+            return selection;
+          default:
+            return this;
+        }
+    }
+
+    /**
+     * If this toggle button is a member of the {@link ButtonGroup} which has
+     * another toggle button which is selected and can be the focus owner,
+     * and the focus cause argument denotes window activation or focus
+     * traversal action of any direction the result of the method execution
+     * is the same as calling
+     * {@link Component#requestFocus(FocusEvent.Cause)} on the toggle button
+     * selected in the group.
+     * In all other cases the result of the method is the same as calling
+     * {@link Component#requestFocus(FocusEvent.Cause)} on this toggle button.
+     *
+     * @param  cause the cause why the focus is requested
+     * @see ButtonGroup
+     * @see Component#requestFocus(FocusEvent.Cause)
+     * @see FocusEvent.Cause
+     *
+     * @since 9
+     */
+    @Override
+    public void requestFocus(FocusEvent.Cause cause) {
+        getGroupSelection(cause).requestFocusUnconditionally(cause);
+    }
+
+    private void requestFocusUnconditionally(FocusEvent.Cause cause) {
+        super.requestFocus(cause);
+    }
+
+    /**
+     * If this toggle button is a member of the {@link ButtonGroup} which has
+     * another toggle button which is selected and can be the focus owner,
+     * and the focus cause argument denotes window activation or focus
+     * traversal action of any direction the result of the method execution
+     * is the same as calling
+     * {@link Component#requestFocusInWindow(FocusEvent.Cause)} on the toggle
+     * button selected in the group.
+     * In all other cases the result of the method is the same as calling
+     * {@link Component#requestFocusInWindow(FocusEvent.Cause)} on this toggle
+     * button.
+     *
+     * @param  cause the cause why the focus is requested
+     * @see ButtonGroup
+     * @see Component#requestFocusInWindow(FocusEvent.Cause)
+     * @see FocusEvent.Cause
+     *
+     * @since 9
+     */
+    public boolean requestFocusInWindow(FocusEvent.Cause cause) {
+        return getGroupSelection(cause)
+                                    .requestFocusInWindowUnconditionally(cause);
+    }
+
+    private boolean requestFocusInWindowUnconditionally(FocusEvent.Cause cause) {
+        return super.requestFocusInWindow(cause);
+    }
+
     // *********************************************************************
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/UIManager.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/UIManager.java	Thu Dec 22 18:48:53 2016 +0000
@@ -629,16 +629,7 @@
         }
         else {
             Class<?> lnfClass = SwingUtilities.loadSystemClass(className);
-            try {
-                LookAndFeel laf =
-                    (LookAndFeel)lnfClass.newInstance();
-                setLookAndFeel(laf);
-            } catch (ReflectiveOperationException | IllegalArgumentException e) {
-                InstantiationException ex =
-                    new InstantiationException("Wrapped Exception");
-                ex.initCause(e);
-                throw ex;
-            }
+            setLookAndFeel((LookAndFeel)(lnfClass.newInstance()));
         }
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/awt/FontConfiguration.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/FontConfiguration.java	Thu Dec 22 18:48:53 2016 +0000
@@ -182,11 +182,17 @@
             throw new Error("java.home property not set");
         }
         javaLib = javaHome + File.separator + "lib";
+        String javaConfFonts = javaHome +
+                               File.separator + "conf" +
+                               File.separator + "fonts";
         String userConfigFile = System.getProperty("sun.awt.fontconfig");
         if (userConfigFile != null) {
             fontConfigFile = new File(userConfigFile);
         } else {
-            fontConfigFile = findFontConfigFile(javaLib);
+            fontConfigFile = findFontConfigFile(javaConfFonts);
+            if (fontConfigFile == null) {
+                fontConfigFile = findFontConfigFile(javaLib);
+            }
         }
     }
 
@@ -275,8 +281,11 @@
         return null;
     }
 
-    private File findFontConfigFile(String javaLib) {
-        String baseName = javaLib + File.separator + "fontconfig";
+    private File findFontConfigFile(String dir) {
+        if (!(new File(dir)).exists()) {
+            return null;
+        }
+        String baseName = dir + File.separator + "fontconfig";
         File configFile;
         String osMajorVersion = null;
         if (osVersion != null && osName != null) {
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ScriptAndLanguageTags.cpp	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ScriptAndLanguageTags.cpp	Thu Dec 22 18:48:53 2016 +0000
@@ -33,13 +33,14 @@
  * Generated on: 10/26/2010 02:53:33 PM PDT
  */
 
+#include "LEScripts.h"
 #include "LETypes.h"
 #include "ScriptAndLanguageTags.h"
 #include "OpenTypeLayoutEngine.h"
 
 U_NAMESPACE_BEGIN
 
-const LETag OpenTypeLayoutEngine::scriptTags[] = {
+const LETag OpenTypeLayoutEngine::scriptTags[scriptCodeCount] = {
     zyyyScriptTag, /* 'zyyy' (COMMON) */
     zinhScriptTag, /* 'zinh' (INHERITED) */
     arabScriptTag, /* 'arab' (ARABIC) */
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ThaiShaping.cpp	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ThaiShaping.cpp	Thu Dec 22 18:48:53 2016 +0000
@@ -302,7 +302,7 @@
         le_uint8 charClass;
 
         // Decompose SARA AM into NIKHAHIT + SARA AA
-        if (ch == CH_SARA_AM && isLegalHere(ch, state)) {
+        if (ch == CH_SARA_AM && isLegalHere(ch, state) && conState < stateCount) {
             outputIndex = conOutput;
             state = getNextState(CH_NIKHAHIT, conState, inputIndex, glyphSet, errorChar, charClass,
                 output, glyphStorage, outputIndex);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ThaiShaping.h	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ThaiShaping.h	Thu Dec 22 18:48:53 2016 +0000
@@ -80,7 +80,8 @@
         tG  =  5,
         tH  =  6,
         tR  =  7,
-        tS  =  8
+        tS  =  8,
+        stateCount = 52
     };
 
     struct StateTransition
@@ -100,7 +101,7 @@
     ThaiShaping();
 
     static const le_uint8 classTable[];
-    static const StateTransition thaiStateTable[][classCount];
+    static const StateTransition thaiStateTable[stateCount][classCount];
 
     inline static StateTransition getTransition(le_uint8 state, le_uint8 currClass);
 
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ThaiStateTables.cpp	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ThaiStateTables.cpp	Thu Dec 22 18:48:53 2016 +0000
@@ -49,7 +49,7 @@
     /*0E50*/ NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON, NON
 };
 
-const ThaiShaping::StateTransition ThaiShaping::thaiStateTable[][ThaiShaping::classCount] = {
+const ThaiShaping::StateTransition ThaiShaping::thaiStateTable[ThaiShaping::stateCount][ThaiShaping::classCount] = {
     //+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
     //|         N         C         C         C         L         F         F         F         B         B         B         T         A         A         A         N         A         A         A    |
     //|         O         O         O         O         V         V         V         V         V         V         D         O         D         D         D         I         V         V         V    |
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_Ports.c	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_Ports.c	Thu Dec 22 18:48:53 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
@@ -385,6 +385,7 @@
     int isStereo;
     char* type;
     snd_mixer_selem_channel_id_t channel;
+    memset(controls, 0, sizeof(controls));
 
     TRACE0("> PORT_GetControls\n");
     if (id == NULL) {
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_Ports.c	Thu Dec 22 18:48:53 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
@@ -385,6 +385,7 @@
     int isStereo;
     char* type;
     snd_mixer_selem_channel_id_t channel;
+    memset(controls, 0, sizeof(controls));
 
     TRACE0("> PORT_GetControls\n");
     if (id == NULL) {
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Ports.c	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_Ports.c	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -390,6 +390,7 @@
     int controlCount = 0;
     INT32 type;
     int selectable = 1;
+    memset(controls, 0, sizeof(controls));
 
     TRACE4(">PORT_GetControls(id=%p, portIndex=%d). controlIDs=%p, maxControlCount=%d\n",
            id, portIndex, info->controlIDs, info->maxControlCount);
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeCipherWithJavaPadding.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeCipherWithJavaPadding.java	Thu Dec 22 18:48:53 2016 +0000
@@ -28,6 +28,7 @@
 import java.nio.ByteBuffer;
 import java.util.Set;
 import java.util.Arrays;
+import java.util.Locale;
 import java.util.concurrent.ConcurrentSkipListSet;
 import java.lang.ref.*;
 
@@ -262,7 +263,7 @@
         throws NoSuchAlgorithmException, NoSuchPaddingException {
         this.nc = nc;
         this.blockSize = nc.engineGetBlockSize();
-        if (paddingScheme.toUpperCase().equals("PKCS5PADDING")) {
+        if (paddingScheme.toUpperCase(Locale.ROOT).equals("PKCS5PADDING")) {
             padding = new PKCS5Padding(blockSize);
         } else {
             throw new NoSuchAlgorithmException("Unsupported padding scheme: " + paddingScheme);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Thu Dec 22 18:48:53 2016 +0000
@@ -74,6 +74,7 @@
 import java.util.Optional;
 import java.util.ResourceBundle;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -497,6 +498,7 @@
 
                 // Add (or replace) the Packages attribute
                 if (packages != null) {
+                    validatePackages(descriptor, packages);
                     extender.packages(packages);
                 }
 
@@ -530,6 +532,24 @@
             }
         }
 
+        private void validatePackages(ModuleDescriptor descriptor, Set<String> packages) {
+            Set<String> nonExistPackages = new TreeSet<>();
+            descriptor.exports().stream()
+                .map(Exports::source)
+                .filter(pn -> !packages.contains(pn))
+                .forEach(nonExistPackages::add);
+
+            descriptor.opens().stream()
+                .map(Opens::source)
+                .filter(pn -> !packages.contains(pn))
+                .forEach(nonExistPackages::add);
+
+            if (!nonExistPackages.isEmpty()) {
+                throw new CommandException("err.missing.export.or.open.packages",
+                    descriptor.name(), nonExistPackages);
+            }
+        }
+
         /*
          * Hasher resolves a module graph using the --hash-modules PATTERN
          * as the roots.
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties	Thu Dec 22 18:48:53 2016 +0000
@@ -107,6 +107,7 @@
 err.internal.error=internal error: {0} {1} {2}
 err.invalid.dryrun.option=--dry-run can only be used with hash mode
 err.module.descriptor.not.found=Module descriptor not found
+err.missing.export.or.open.packages=Packages that are exported or open in {0} are not present: {1}
 warn.invalid.arg=Invalid classname or pathname not exist: {0}
 warn.no.module.hashes=No hashes recorded: no module specified for hashing depends on {0}
 warn.module.resolution.fail=No hashes recorded: {0}
--- a/jdk/test/ProblemList.txt	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/ProblemList.txt	Thu Dec 22 18:48:53 2016 +0000
@@ -203,8 +203,6 @@
 
 sun/rmi/rmic/newrmic/equivalence/run.sh                         8145980 generic-all
 
-java/rmi/transport/dgcDeadLock/DGCDeadLock.java                 8029360 macosx-all
-
 java/rmi/registry/readTest/readTest.sh                          7146543 generic-all
 
 ############################################################################
@@ -217,10 +215,6 @@
 
 sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java      8026393 generic-all
 
-sun/security/ssl/SSLSocketImpl/AsyncSSLSocketClose.java         8161232 macosx-all
-
-sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java  8171043 windows-all
-
 javax/net/ssl/DTLS/PacketLossRetransmission.java                8169086 macosx-x64
 
 ############################################################################
@@ -234,8 +228,6 @@
 
 javax/sound/sampled/Mixers/DisabledAssertionCrash.java 7067310 generic-all
 
-javax/sound/sampled/Clip/OpenNonIntegralNumberOfSampleframes.java 8168881 generic-all
-
 ############################################################################
 
 # jdk_imageio
--- a/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/awt/EmbeddedFrame/DisplayChangedTest/DisplayChangedTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -23,12 +23,12 @@
 
 /*
  @test
- @bug 4980592
+ @bug 4980592 8171363
  @summary   switching user in XP causes an NPE in
             sun.awt.windows.WWindowPeer.displayChanged
  @requires (os.family == "windows")
  @modules java.desktop/java.awt.peer
- @modules java.desktop/sun.awt.windows
+ @modules java.desktop/sun.awt.windows:open
  @modules java.desktop/sun.awt
  @author son@sparc.spb.su: area=embedded
  @run main DisplayChangedTest
--- a/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -23,12 +23,12 @@
 
 /*
  @test
- @bug 6345002
+ @bug 6345003 8171363
  @summary grab problems with EmbeddedFrame
  @requires (os.family == "windows")
  @modules java.desktop/java.awt.peer
  @modules java.desktop/sun.awt
- @modules java.desktop/sun.awt.windows
+ @modules java.desktop/sun.awt.windows:open
  @author Oleg.Semenov@sun.com area=EmbeddedFrame
  @run main EmbeddedFrameGrabTest
  */
--- a/jdk/test/java/awt/datatransfer/ConstructFlavoredObjectTest/ConstructFlavoredObjectTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/awt/datatransfer/ConstructFlavoredObjectTest/ConstructFlavoredObjectTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -31,34 +31,57 @@
 /*
  * @test
  * @key headful
- * @bug 8130329
+ * @bug 8130329 8134612 8133719
  * @summary  Audit Core Reflection in module java.desktop AWT/Miscellaneous area
  *           for places that will require changes to work with modules
  * @author Alexander Scherbatiy
+ * @run main/othervm ConstructFlavoredObjectTest COPY
+ * @run main/othervm ConstructFlavoredObjectTest PASTE
  */
 public class ConstructFlavoredObjectTest {
 
-    private static final String TEST_MIME_TYPE = "text/plain;class="
-            + MyStringReader.class.getName();
-
     public static void main(String[] args) throws Exception {
 
-        final DataFlavor dataFlavor = new DataFlavor(TEST_MIME_TYPE);
-        SystemFlavorMap systemFlavorMap = (SystemFlavorMap) SystemFlavorMap.
-                getDefaultFlavorMap();
-        systemFlavorMap.addUnencodedNativeForFlavor(dataFlavor, "TEXT");
-        systemFlavorMap.addFlavorForUnencodedNative("TEXT", dataFlavor);
+        if (args[0].equals("COPY")) {
+
+            // Copy a simple text string on to the System clipboard
+
+            final String TEXT_MIME_TYPE = DataFlavor.javaJVMLocalObjectMimeType +
+                    ";class=" + String.class.getName();
 
-        TransferHandler transferHandler = new TransferHandler("Test Handler");
+            final DataFlavor dataFlavor = new DataFlavor(TEXT_MIME_TYPE);
+            SystemFlavorMap systemFlavorMap =
+                   (SystemFlavorMap) SystemFlavorMap.getDefaultFlavorMap();
+            systemFlavorMap.addUnencodedNativeForFlavor(dataFlavor, "TEXT");
+            systemFlavorMap.addFlavorForUnencodedNative("TEXT", dataFlavor);
+
+            TransferHandler transferHandler = new TransferHandler("text");
 
-        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
-        transferHandler.exportToClipboard(new JLabel("Test"), clipboard,
-                TransferHandler.COPY);
+            String text = "This is sample export text";
+            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+            transferHandler.exportToClipboard(new JLabel(text), clipboard,
+                    TransferHandler.COPY);
+        }
+        else if (args[0].equals("PASTE")) {
+
+            // Try to read text data from the System clipboard
+
+            final String TEST_MIME_TYPE = "text/plain;class=" +
+                    MyStringReader.class.getName();
 
-        Object clipboardData = clipboard.getData(dataFlavor);
+            final DataFlavor dataFlavor = new DataFlavor(TEST_MIME_TYPE);
+            SystemFlavorMap systemFlavorMap = (SystemFlavorMap) SystemFlavorMap.
+                    getDefaultFlavorMap();
+            systemFlavorMap.addUnencodedNativeForFlavor(dataFlavor, "TEXT");
+            systemFlavorMap.addFlavorForUnencodedNative("TEXT", dataFlavor);
 
-        if (!(clipboardData instanceof MyStringReader)) {
-            throw new RuntimeException("Wrong clipboard data!");
+            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+
+            Object clipboardData = clipboard.getData(dataFlavor);
+
+            if (!(clipboardData instanceof MyStringReader)) {
+                throw new RuntimeException("Wrong clipboard data!");
+            }
         }
     }
 
@@ -78,3 +101,4 @@
         }
     }
 }
+
--- a/jdk/test/java/beans/Introspector/8130937/TestBooleanBeanProperties.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/beans/Introspector/8130937/TestBooleanBeanProperties.java	Thu Dec 22 18:48:53 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
@@ -28,7 +28,7 @@
 
 /**
  * @test
- * @bug 8130937
+ * @bug 8130937 8131347
  * @summary Tests the booleans properties of the BeanProperty annotation
  * @library ..
  */
@@ -76,6 +76,9 @@
         if (getValue(pd, "visualUpdate") != isVS) {
             throw new RuntimeException("required should be: " + isVS);
         }
+        if (pd.getValue("enumerationValues") == null) {
+            throw new RuntimeException("enumerationValues should be empty array");
+        }
     }
 
     private static boolean getValue(PropertyDescriptor pd, String value) {
@@ -107,7 +110,8 @@
         }
 
         @BeanProperty(bound = true, expert = true, hidden = true,
-                      preferred = true, required = true, visualUpdate = true)
+                      preferred = true, required = true, visualUpdate = true,
+                      enumerationValues = {})
         public void setValue(int value) {
             this.value = value;
         }
--- a/jdk/test/java/rmi/testlibrary/REGISTRY.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/rmi/testlibrary/REGISTRY.java	Thu Dec 22 18:48:53 2016 +0000
@@ -33,28 +33,48 @@
  */
 public class REGISTRY extends JavaVM {
 
-    private static double startTimeout = 20_000 * TestLibrary.getTimeoutFactor();
+    private static final double START_TIMEOUT =
+            20_000 * TestLibrary.getTimeoutFactor();
+    private static final String DEFAULT_RUNNER = "RegistryRunner";
 
     private int port = -1;
 
-    private REGISTRY(OutputStream out, OutputStream err,
+    private REGISTRY(String runner, OutputStream out, OutputStream err,
                     String options, int port) {
-        super("RegistryRunner", options, Integer.toString(port), out, err);
+        super(runner, options, Integer.toString(port), out, err);
+        try {
+            Class runnerClass = Class.forName(runner);
+            if (!RegistryRunner.class.isAssignableFrom(runnerClass)) {
+                throw new RuntimeException("runner class must be RegistryRunner"
+                        + " or its sub class");
+            }
+        } catch (ClassNotFoundException ex) {
+            throw new RuntimeException(ex);
+        }
         this.port = port;
     }
 
     public static REGISTRY createREGISTRY() {
-        return createREGISTRY(System.out, System.err, "", 0);
+        return createREGISTRYWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
     }
 
     public static REGISTRY createREGISTRY(OutputStream out, OutputStream err,
                                     String options, int port) {
+        return createREGISTRYWithRunner(DEFAULT_RUNNER, out, err, options, port);
+    }
+
+    public static REGISTRY createREGISTRYWithRunner(String runner, String options) {
+        return createREGISTRYWithRunner(runner, System.out, System.err, options, 0);
+    }
+
+    public static REGISTRY createREGISTRYWithRunner(String runner, OutputStream out,
+                                        OutputStream err, String options, int port) {
         options += " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
-                 + " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
-                 + " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
-                 + " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
-        REGISTRY reg = new REGISTRY(out, err, options, port);
-        return reg;
+                + " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
+                + " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
+                + " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
+       REGISTRY reg = new REGISTRY(runner, out, err, options, port);
+       return reg;
     }
 
     /**
@@ -65,7 +85,7 @@
     public void start() throws IOException {
         super.start();
         long startTime = System.currentTimeMillis();
-        long deadline = TestLibrary.computeDeadline(startTime, (long)startTimeout);
+        long deadline = TestLibrary.computeDeadline(startTime, (long)START_TIMEOUT);
         while (true) {
             try {
                 Thread.sleep(1000);
--- a/jdk/test/java/rmi/testlibrary/RegistryRunner.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/rmi/testlibrary/RegistryRunner.java	Thu Dec 22 18:48:53 2016 +0000
@@ -36,7 +36,7 @@
     implements RemoteExiter
 {
     private static final String PORT_LABEL_START = "RegistryRunner.port.start:";
-    private static final String PORT_LABEL_END = "RegistryRunner.port.end";
+    private static final String PORT_LABEL_END = ":RegistryRunner.port.end";
 
     private static Registry registry = null;
     private static RemoteExiter exiter = null;
@@ -95,17 +95,17 @@
         return port;
     }
 
-    public static void main(String[] args) {
-
+    /**
+     * port 0 means to use ephemeral port to start registry.
+     */
+    protected static int init(String[] args) {
         try {
             if (args.length == 0) {
                 System.err.println("Usage: <port>");
                 System.exit(0);
             }
             int port = -1;
-            try {
-                port = Integer.parseInt(args[0]);
-            } catch (NumberFormatException ignore) { }
+            port = Integer.parseInt(args[0]);
 
             // create a registry
             registry = LocateRegistry.createRegistry(port);
@@ -118,14 +118,30 @@
             Naming.rebind("rmi://localhost:" + port +
                           "/RemoteExiter", exiter);
 
-            // this output is important for REGISTRY to get the port
-            // where rmiregistry is serving
-            System.out.println(PORT_LABEL_START + port + PORT_LABEL_END);
-
+            return port;
         } catch (Exception e) {
             System.err.println(e.getMessage());
             e.printStackTrace();
             System.exit(-1);
         }
+        return -1;
+    }
+
+    /**
+     * REGISTRY.start() will filter the output of registry subprocess,
+     * when valid port is detected, REGISTRY.start() returns.
+     * So, for subclass, it's important to call this method after registry
+     * is initialized and necessary remote objects have been bound.
+     */
+    protected static void notify(int port) {
+        // this output is important for REGISTRY to get the port
+        // where rmiregistry is serving
+        System.out.println(PORT_LABEL_START + port + PORT_LABEL_END);
+        System.out.flush();
+    }
+
+    public static void main(String[] args) {
+        int port = init(args);
+        notify(port);
     }
 }
--- a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -33,7 +33,7 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary Test TestImpl TestImpl_Stub
+ * @build TestLibrary Test TestImpl REGISTRY RegistryRunner
  * @run main/othervm/policy=security.policy/timeout=360 DGCDeadLock
  */
 
@@ -55,11 +55,12 @@
 import java.io.*;
 
 public class DGCDeadLock implements Runnable {
-    private static final int REGISTRY_PORT = TestLibrary.getUnusedRandomPort();
     final static public int HOLD_TARGET_TIME = 25000;
-    public static int TEST_FAIL_TIME = HOLD_TARGET_TIME + 30000;
-    public static boolean finished = false;
-    static DGCDeadLock test = new DGCDeadLock();
+    public static final double TEST_FAIL_TIME =
+            (HOLD_TARGET_TIME + 30000) * TestLibrary.getTimeoutFactor();
+    public static volatile boolean finished = false;
+    static final DGCDeadLock test = new DGCDeadLock();
+    static volatile int registryPort = -1;
 
     static {
         System.setProperty("sun.rmi.transport.cleanInterval", "50");
@@ -67,7 +68,7 @@
 
     static public void main(String[] args) {
 
-        JavaVM testImplVM = null;
+        REGISTRY testImplVM = null;
 
         System.err.println("\nregression test for 4118056\n");
         TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
@@ -75,18 +76,15 @@
         try {
             String options = " -Djava.security.policy=" +
                 TestParams.defaultPolicy +
-                " --add-exports java.rmi/sun.rmi.registry=ALL-UNNAMED" +
-                " --add-exports java.rmi/sun.rmi.server=ALL-UNNAMED" +
                 " --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED" +
-                " --add-exports java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" +
                 " -Djava.rmi.dgc.leaseValue=500000" +
-                "  -Dsun.rmi.dgc.checkInterval=" +
+                " -Dsun.rmi.dgc.checkInterval=" +
                 (HOLD_TARGET_TIME - 5000) +
-                "   -Drmi.registry.port=" + REGISTRY_PORT +
                 "" ;
 
-            testImplVM = new JavaVM("TestImpl", options, "");
+            testImplVM = REGISTRY.createREGISTRYWithRunner("TestImpl", options);
             testImplVM.start();
+            registryPort = testImplVM.getPort();
 
             synchronized (test) {
                 Thread t = new Thread(test);
@@ -94,7 +92,7 @@
                 t.start();
 
                 // wait for the remote calls to take place
-                test.wait(TEST_FAIL_TIME);
+                test.wait((long)TEST_FAIL_TIME);
             }
 
             if (!finished) {
@@ -106,8 +104,12 @@
                                "finished in time.");
 
         } catch (Exception e) {
-            testImplVM = null;
-            TestLibrary.bomb("test failed", e);
+            TestLibrary.bomb("test failed in main()", e);
+        } finally {
+            if (testImplVM != null) {
+                testImplVM.shutdown();
+                testImplVM = null;
+            }
         }
     }
 
@@ -115,12 +117,9 @@
         try {
             String echo = null;
 
-            // give the test remote object time to initialize.
-            Thread.currentThread().sleep(8000);
-
             // create a test client
             Test foo = (Test) Naming.lookup("rmi://:" +
-                                            REGISTRY_PORT +
+                                            registryPort +
                                             "/Foo");
             echo = foo.echo("Hello world");
             System.err.println("Test object created.");
@@ -139,7 +138,7 @@
 
             //import "Bar"
             Test bar = (Test) Naming.lookup("rmi://:" +
-                                            REGISTRY_PORT +
+                                            registryPort +
                                             "/Bar");
 
             /* infinite loop to show the liveness of Client,
@@ -155,11 +154,16 @@
                 finished = true;
 
             } catch (RemoteException e) {
+                System.err.println("catch RemoteException");
+                e.printStackTrace();
             }
 
         } catch (Exception e) {
-            TestLibrary.bomb("test failed", e);
+            TestLibrary.bomb("test failed in run()", e);
         } finally {
+            synchronized(this) {
+                notify();
+            }
         }
     }
 }
--- a/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -34,7 +34,7 @@
 import java.rmi.registry.*;
 import java.rmi.server.*;
 
-public class TestImpl extends UnicastRemoteObject
+public class TestImpl extends RegistryRunner
     implements Test {
     static Thread locker = null;
     static TestImpl foo = null;
@@ -53,12 +53,8 @@
     }
 
     static public void main(String[] args) {
-        Registry registry = null;
-
         try {
-            int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
-            registry = java.rmi.registry.LocateRegistry.
-                createRegistry(registryPort);
+            int registryPort = RegistryRunner.init(args);
 
             //export "Foo"
             foo = new TestImpl();
@@ -75,16 +71,11 @@
             } catch (Exception e) {
                 throw new RemoteException(e.getMessage());
             }
-            Thread.sleep(DGCDeadLock.TEST_FAIL_TIME);
-            System.err.println("object vm exiting...");
-            System.exit(0);
 
+            RegistryRunner.notify(registryPort);
         } catch (Exception e) {
             System.err.println(e.getMessage());
             e.printStackTrace();
-        } finally {
-            TestLibrary.unexport(registry);
-            registry = null;
         }
     }
 
--- a/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldParser.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/time/tck/java/time/format/TCKLocalizedFieldParser.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -66,9 +66,11 @@
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.DateTimeParseException;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.WeekFields;
+import java.util.Locale;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -79,12 +81,17 @@
  */
 @Test
 public class TCKLocalizedFieldParser extends AbstractTestPrinterParser {
-
+    public static final WeekFields WEEKDEF = WeekFields.of(Locale.US);
+    public static final TemporalField WEEK_BASED_YEAR = WEEKDEF.weekBasedYear();
+    public static final TemporalField WEEK_OF_WEEK_BASED_YEAR = WEEKDEF.weekOfWeekBasedYear();
+    public static final TemporalField DAY_OF_WEEK = WEEKDEF.dayOfWeek();
     //-----------------------------------------------------------------------
     @DataProvider(name="FieldPatterns")
     Object[][] provider_fieldPatterns() {
         return new Object[][] {
-            {"e",  "6", 0, 1, 6},
+            {"e", "6", 0, 1, 6},
+            {"ee", "06", 0, 2, 6},
+            {"c",  "6", 0, 1 , 6},
             {"W",  "3", 0, 1, 3},
             {"w",  "29", 0, 2, 29},
             {"ww", "29", 0, 2, 29},
@@ -99,6 +106,7 @@
         WeekFields weekDef = WeekFields.of(locale);
         TemporalField field = null;
         switch(pattern.charAt(0)) {
+            case 'c' :
             case 'e' :
                 field = weekDef.dayOfWeek();
                 break;
@@ -176,9 +184,9 @@
             {"Y-w-e",  "2008-01-1", 0, 9, LocalDate.of(2007, 12, 30)},
             {"Y-w-e",  "2008-52-1", 0, 9, LocalDate.of(2008, 12, 21)},
             {"Y-w-e",  "2008-52-7", 0, 9, LocalDate.of(2008, 12, 27)},
-            {"Y-w-e",  "2009-01-01", 0, 10, LocalDate.of(2008, 12, 28)},
-            {"Y-w-e",  "2009-01-04", 0, 10, LocalDate.of(2008, 12, 31)},
-            {"Y-w-e",  "2009-01-05", 0, 10, LocalDate.of(2009, 1, 1)},
+            {"Y-w-e",  "2009-01-1", 0, 9, LocalDate.of(2008, 12, 28)},
+            {"Y-w-e",  "2009-01-4", 0, 9, LocalDate.of(2008, 12, 31)},
+            {"Y-w-e",  "2009-01-5", 0, 9, LocalDate.of(2009, 1, 1)},
        };
     }
 
@@ -202,4 +210,77 @@
         }
     }
 
+    //-----------------------------------------------------------------------
+    @DataProvider(name = "adjacentValuePatterns1")
+    Object[][] provider_adjacentValuePatterns1() {
+        return new Object[][] {
+                {"YYww", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, "1612", 2016, 12},
+                {"YYYYww", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, "201612", 2016, 12},
+        };
+    }
+
+    @Test(dataProvider = "adjacentValuePatterns1")
+    public void test_adjacentValuePatterns1(String pattern, TemporalField field1, TemporalField field2,
+            String text, int expected1, int expected2) {
+        DateTimeFormatter df = new DateTimeFormatterBuilder()
+                .appendPattern(pattern).toFormatter(Locale.US);
+        ParsePosition ppos = new ParsePosition(0);
+        TemporalAccessor parsed = df.parseUnresolved(text, ppos);
+        assertEquals(parsed.get(field1), expected1);
+        assertEquals(parsed.get(field2), expected2);
+    }
+
+    @DataProvider(name = "adjacentValuePatterns2")
+    Object[][] provider_adjacentValuePatterns2() {
+        return new Object[][] {
+                {"YYYYwwc", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, DAY_OF_WEEK,
+                        "2016121", 2016, 12, 1},
+                {"YYYYwwee", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, DAY_OF_WEEK,
+                        "20161201", 2016, 12, 1},
+                {"YYYYwwe", WEEK_BASED_YEAR, WEEK_OF_WEEK_BASED_YEAR, DAY_OF_WEEK,
+                        "2016121", 2016, 12, 1},
+        };
+    }
+
+    @Test(dataProvider = "adjacentValuePatterns2")
+    public void test_adjacentValuePatterns2(String pattern, TemporalField field1, TemporalField field2,
+            TemporalField field3, String text, int expected1, int expected2, int expected3) {
+        DateTimeFormatter df = new DateTimeFormatterBuilder()
+                .appendPattern(pattern).toFormatter(Locale.US);
+        ParsePosition ppos = new ParsePosition(0);
+        TemporalAccessor parsed = df.parseUnresolved(text, ppos);
+        assertEquals(parsed.get(field1), expected1);
+        assertEquals(parsed.get(field2), expected2);
+        assertEquals(parsed.get(field3), expected3);
+    }
+
+    @Test
+    public void test_adjacentValuePatterns3() {
+        String pattern = "yyyyMMddwwc";
+        String text =  "20120720296";
+        DateTimeFormatter df = new DateTimeFormatterBuilder()
+                .appendPattern(pattern).toFormatter(Locale.US);
+        ParsePosition ppos = new ParsePosition(0);
+        TemporalAccessor parsed = df.parseUnresolved(text, ppos);
+        assertEquals(parsed.get(DAY_OF_WEEK), 6);
+        assertEquals(parsed.get(WEEK_OF_WEEK_BASED_YEAR), 29);
+        LocalDate result = LocalDate.parse(text, df);
+        LocalDate expectedValue = LocalDate.of(2012, 07, 20);
+        assertEquals(result, expectedValue, "LocalDate incorrect for " + pattern);
+    }
+
+    @DataProvider(name = "invalidPatterns")
+    Object[][] provider_invalidPatterns() {
+        return new Object[][] {
+            {"W", "01"},
+            {"c", "01"},
+            {"e", "01"},
+            {"yyyyMMddwwc", "201207202906"}, //  1 extra digit in the input
+        };
+    }
+
+    @Test(dataProvider = "invalidPatterns", expectedExceptions = DateTimeParseException.class)
+    public void test_invalidPatterns(String pattern, String value) {
+        DateTimeFormatter.ofPattern(pattern).parse(value);
+    }
 }
--- a/jdk/test/java/util/Currency/CurrencyTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/util/Currency/CurrencyTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -23,7 +23,7 @@
 /*
  * @test
  * @bug 4290801 4692419 4693631 5101540 5104960 6296410 6336600 6371531
- *    6488442 7036905 8008577 8039317 8074350 8074351 8150324
+ *    6488442 7036905 8008577 8039317 8074350 8074351 8150324 8167143
  * @summary Basic tests for Currency class.
  * @modules java.base/java.util:open
  *          jdk.localedata
@@ -188,7 +188,7 @@
     static void testSymbols() {
         testSymbol("USD", Locale.US, "$");
         testSymbol("EUR", Locale.GERMANY, "\u20AC");
-        testSymbol("USD", Locale.PRC, "USD");
+        testSymbol("USD", Locale.PRC, "US$");
     }
 
     static void testSymbol(String currencyCode, Locale locale, String expectedSymbol) {
@@ -262,7 +262,7 @@
         testDisplayName("KRW", Locale.KOREAN, "\ub300\ud55c\ubbfc\uad6d \uc6d0");
         testDisplayName("SEK", new Locale("sv"), "svensk krona");
         testDisplayName("CNY", Locale.SIMPLIFIED_CHINESE, "\u4eba\u6c11\u5e01");
-        testDisplayName("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u81fa\u5e63");
+        testDisplayName("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u53f0\u5e63");
     }
 
     static void testDisplayName(String currencyCode, Locale locale, String expectedName) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/TimeZone/Bug8167143.java	Thu Dec 22 18:48:53 2016 +0000
@@ -0,0 +1,279 @@
+/*
+ * 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 8167143
+ * @summary Test
+ * Timezone parsing works for all locales for default providers prefernce
+ * as well as when  prefernce list is [COMPAT, CLDR],
+ * CLDR implict locales are correctly reflected,
+ * th_TH bundle is not wrongly cached in DateFormatSymbols,
+ * correct candidate locale list is retrieved for
+ * zh_Hant and zh_Hans and
+ * Implict COMPAT Locales nn-NO, nb-NO are reflected in available locales
+ * for all Providers for COMPAT.
+ * @modules java.base/sun.util.locale.provider
+ *          java.base/sun.util.spi
+ *          jdk.localedata
+ * @run main/othervm -Djava.locale.providers=COMPAT,CLDR Bug8167143 testTimeZone
+ * @run main/othervm  Bug8167143 testTimeZone
+ * @run main/othervm -Djava.locale.providers=CLDR Bug8167143 testCldr
+ * @run main/othervm  Bug8167143 testCache
+ * @run main/othervm  Bug8167143 testCandidateLocales
+ * @run main/othervm  -Djava.locale.providers=COMPAT Bug8167143 testCompat
+ */
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.TimeZone;
+
+import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.LocaleProviderAdapter.Type;
+
+public class Bug8167143 {
+
+    private static final TimeZone REYKJAVIK = TimeZone.getTimeZone("Atlantic/Reykjavik");
+    private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York");
+    private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
+    private static final List<Locale> CLDR_IMPLICIT_LOCS = List.of(Locale.forLanguageTag("zh-Hans-CN"),
+            Locale.forLanguageTag("zh-Hans-SG"),
+            Locale.forLanguageTag("zh-Hant-HK"),
+            Locale.forLanguageTag("zh-Hant-TW"),
+            Locale.forLanguageTag("zh-Hant-MO"));
+
+    private static final List<Locale> COMPAT_IMPLICIT_LOCS = List.of(Locale.forLanguageTag("nn-NO"),
+            Locale.forLanguageTag("nb-NO"));
+    /**
+     * List of candidate locales for zh_Hant
+     */
+    private static final List<Locale> ZH_HANT_CANDLOCS = List.of(
+            Locale.forLanguageTag("zh-Hant"),
+            Locale.forLanguageTag("zh-TW"),
+            Locale.forLanguageTag("zh"),
+            Locale.ROOT);
+    /**
+     * List of candidate locales for zh_Hans
+     */
+    private static final List<Locale> ZH_HANS_CANDLOCS = List.of(
+            Locale.forLanguageTag("zh-Hans"),
+            Locale.forLanguageTag("zh-CN"),
+            Locale.forLanguageTag("zh"),
+            Locale.ROOT);
+
+    public static void main(String[] args) {
+        switch (args[0]) {
+            case "testTimeZone":
+                testTimeZoneParsing();
+                break;
+            case "testCldr":
+                testImplicitCldrLocales();
+                break;
+            case "testCache":
+                testDateFormatSymbolsCache();
+                break;
+            case "testCandidateLocales":
+                testCandidateLocales();
+                break;
+            case "testCompat":
+                testImplicitCompatLocales();
+                break;
+            default:
+                throw new RuntimeException("no test was specified.");
+        }
+    }
+
+    /**
+     * Check that if Locale Provider Preference list is Default, or if Locale
+     * Provider Preference List is COMPAT,CLDR SimplDateFormat parsing works for
+     * all Available Locales.
+     */
+    private static void testTimeZoneParsing() {
+        Set<Locale> locales = Set.of(Locale.forLanguageTag("zh-hant"), new Locale("no", "NO", "NY"));
+        // Set<Locale> locales = Set.of(Locale.getAvailableLocales());
+        locales.forEach((locale) -> {
+            final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd z", locale);
+            for (final TimeZone tz : new TimeZone[]{REYKJAVIK, GMT, NEW_YORK}) {
+                try {
+                    sdf.parse("2000/02/10 " + tz.getDisplayName(locale));
+                } catch (ParseException e) {
+                    throw new RuntimeException("TimeZone Parsing failed with Locale "
+                            + locale + " for TimeZone  " + tz.getDisplayName(), e);
+                }
+            }
+        });
+    }
+
+    /**
+     * Check that locales implicitly supported from CLDR are reflected in output
+     * from getAvailbleLocales() for each bundle.
+     *
+     */
+    private static void testImplicitCldrLocales() {
+        LocaleProviderAdapter cldr = LocaleProviderAdapter.forType(Type.CLDR);
+        checkPresenceCldr("CurrencyNameProvider",
+                cldr.getCurrencyNameProvider().getAvailableLocales());
+        checkPresenceCldr("LocaleNameProvider",
+                cldr.getLocaleNameProvider().getAvailableLocales());
+        checkPresenceCldr("TimeZoneNameProvider",
+                cldr.getTimeZoneNameProvider().getAvailableLocales());
+        checkPresenceCldr("CalendarDataProvider",
+                cldr.getCalendarDataProvider().getAvailableLocales());
+        checkPresenceCldr("CalendarNameProvider",
+                cldr.getCalendarProvider().getAvailableLocales());
+    }
+
+    private static void checkPresenceCldr(String testName, Locale[] got) {
+        List<Locale> gotLocalesList = Arrays.asList(got);
+        List<Locale> gotList = new ArrayList<>(gotLocalesList);
+        if (!testName.equals("TimeZoneNameProvider")) {
+            if (!gotList.removeAll(CLDR_IMPLICIT_LOCS)) {
+                // check which locale are not present in retrievedLocales List.
+                List<Locale> expectedLocales = new ArrayList<>(CLDR_IMPLICIT_LOCS);
+                expectedLocales.removeAll(gotList);
+                throw new RuntimeException("Locales those not correctly reflected are "
+                        + expectedLocales + " for test " + testName);
+            }
+        } else {
+            // check one extra locale zh_HK for TimeZoneNameProvider
+            Locale zh_HK = Locale.forLanguageTag("zh-HK");
+            if (!gotList.removeAll(CLDR_IMPLICIT_LOCS) && gotList.remove(zh_HK)) {
+                //check which locale are not present in retrievedLocales List
+                List<Locale> expectedLocales = new ArrayList<>(CLDR_IMPLICIT_LOCS);
+                expectedLocales.add(zh_HK);
+                expectedLocales.removeAll(gotList);
+                throw new RuntimeException("Locales those not correctly reflected are "
+                        + expectedLocales + " for test " + testName);
+            }
+        }
+    }
+
+    /**
+     * Check that if Locale Provider Preference list is default and if
+     * SimpleDateFormat instance for th-TH-TH is created first, then JRE bundle
+     * for th-TH should not be cached in cache of DateFormatSymbols class.
+     */
+    private static void testDateFormatSymbolsCache() {
+        Locale th_TH_TH = new Locale("th", "TH", "TH");
+        Locale th_TH = new Locale("th", "TH");
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd z", th_TH_TH);
+        String[][] thTHTHZoneStrings = sdf.getDateFormatSymbols().getZoneStrings();
+        String[][] thTHZoneStrings = sdf.getDateFormatSymbols().getZoneStrings();
+        if (Arrays.equals(thTHTHZoneStrings, thTHZoneStrings)) {
+            throw new RuntimeException("th_TH bundle still cached with DateFormatSymbols"
+                    + "cache for locale  " + th_TH
+            );
+        }
+    }
+
+    /**
+     * Check that candidate locales list retrieved for zh__Hant and for zh__Hans
+     * do not have first candidate locale as zh_TW_Hant and zh_CN_Hans
+     * respectively.
+     */
+    private static void testCandidateLocales() {
+        ResourceBundle.Control Control = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
+        Locale zh_Hant = Locale.forLanguageTag("zh-Hant");
+        Locale zh_Hans = Locale.forLanguageTag("zh-Hans");
+        List<Locale> zhHantCandidateLocs = Control.getCandidateLocales("", zh_Hant);
+        List<Locale> zhHansCandidateLocs = Control.getCandidateLocales("", zh_Hans);
+        if (!zhHantCandidateLocs.equals(ZH_HANT_CANDLOCS)) {
+            reportDifference(zhHantCandidateLocs, ZH_HANT_CANDLOCS, "zh_Hant");
+
+        }
+        if (!zhHansCandidateLocs.equals(ZH_HANS_CANDLOCS)) {
+            reportDifference(zhHansCandidateLocs, ZH_HANS_CANDLOCS, "zh_Hans");
+
+        }
+    }
+
+    private static void reportDifference(List<Locale> got, List<Locale> expected, String locale) {
+        List<Locale> retrievedList = new ArrayList<>(got);
+        List<Locale> expectedList = new ArrayList<>(expected);
+        retrievedList.removeAll(expectedList);
+        expectedList.removeAll(retrievedList);
+        if ((retrievedList.size() > 0) && (expectedList.size() > 0)) {
+            throw new RuntimeException(" retrievedList contain extra candidate locales " + retrievedList
+                    + " and missing candidate locales " + expectedList
+                    + "for locale " + locale);
+        }
+        if ((retrievedList.size() > 0)) {
+            throw new RuntimeException(" retrievedList contain extra candidate locales " + retrievedList
+                    + "for locale " + locale);
+        }
+        if ((expectedList.size() > 0)) {
+            throw new RuntimeException(" retrievedList contain extra candidate locales " + expectedList
+                    + "for locale " + locale);
+        }
+    }
+
+    /**
+     * checks that locales nn-NO  and nb-NO should be present in list of supported locales for
+     * all Providers for COMPAT.
+     */
+    private static void testImplicitCompatLocales() {
+        LocaleProviderAdapter jre = LocaleProviderAdapter.forJRE();
+        checkPresenceCompat("BreakIteratorProvider",
+            jre.getBreakIteratorProvider().getAvailableLocales());
+        checkPresenceCompat("CollatorProvider",
+            jre.getCollatorProvider().getAvailableLocales());
+        checkPresenceCompat("DateFormatProvider",
+            jre.getDateFormatProvider().getAvailableLocales());
+        checkPresenceCompat("DateFormatSymbolsProvider",
+            jre.getDateFormatSymbolsProvider().getAvailableLocales());
+        checkPresenceCompat("DecimalFormatSymbolsProvider",
+            jre.getDecimalFormatSymbolsProvider().getAvailableLocales());
+        checkPresenceCompat("NumberFormatProvider",
+            jre.getNumberFormatProvider().getAvailableLocales());
+        checkPresenceCompat("CurrencyNameProvider",
+            jre.getCurrencyNameProvider().getAvailableLocales());
+        checkPresenceCompat("LocaleNameProvider",
+            jre.getLocaleNameProvider().getAvailableLocales());
+        checkPresenceCompat("TimeZoneNameProvider",
+            jre.getTimeZoneNameProvider().getAvailableLocales());
+        checkPresenceCompat("CalendarDataProvider",
+            jre.getCalendarDataProvider().getAvailableLocales());
+        checkPresenceCompat("CalendarNameProvider",
+            jre.getCalendarNameProvider().getAvailableLocales());
+        checkPresenceCompat("CalendarProvider",
+            jre.getCalendarProvider().getAvailableLocales());
+    }
+
+    private static void checkPresenceCompat(String testName, Locale[] got) {
+        List<Locale> gotLocalesList = Arrays.asList(got);
+        List<Locale> gotList = new ArrayList<>(gotLocalesList);
+            if (!gotList.removeAll(COMPAT_IMPLICIT_LOCS)) {
+                // check which Implicit locale are not present in retrievedLocales List.
+                List<Locale> implicitLocales = new ArrayList<>(COMPAT_IMPLICIT_LOCS);
+                implicitLocales.removeAll(gotList);
+                throw new RuntimeException("Locales those not correctly reflected are "
+                        + implicitLocales + " for test " + testName);
+            }
+    }
+}
--- a/jdk/test/java/util/concurrent/tck/Collection8Test.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/util/concurrent/tck/Collection8Test.java	Thu Dec 22 18:48:53 2016 +0000
@@ -39,6 +39,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.ConcurrentModificationException;
 import java.util.Deque;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -369,9 +370,112 @@
     }
 
     /**
+     * All elements removed in the middle of CONCURRENT traversal.
+     */
+    public void testElementRemovalDuringTraversal() {
+        Collection c = impl.emptyCollection();
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = rnd.nextInt(6);
+        ArrayList copy = new ArrayList();
+        for (int i = 0; i < n; i++) {
+            Object x = impl.makeElement(i);
+            copy.add(x);
+            c.add(x);
+        }
+        ArrayList iterated = new ArrayList();
+        ArrayList spliterated = new ArrayList();
+        Spliterator s = c.spliterator();
+        Iterator it = c.iterator();
+        for (int i = rnd.nextInt(n + 1); --i >= 0; ) {
+            assertTrue(s.tryAdvance(spliterated::add));
+            if (rnd.nextBoolean()) assertTrue(it.hasNext());
+            iterated.add(it.next());
+        }
+        Consumer alwaysThrows = e -> { throw new AssertionError(); };
+        if (s.hasCharacteristics(Spliterator.CONCURRENT)) {
+            c.clear();          // TODO: many more removal methods
+            if (testImplementationDetails
+                && !(c instanceof java.util.concurrent.ArrayBlockingQueue)) {
+                if (rnd.nextBoolean())
+                    assertFalse(s.tryAdvance(alwaysThrows));
+                else
+                    s.forEachRemaining(alwaysThrows);
+            }
+            if (it.hasNext()) iterated.add(it.next());
+            if (rnd.nextBoolean()) assertIteratorExhausted(it);
+        }
+        assertTrue(copy.containsAll(iterated));
+        assertTrue(copy.containsAll(spliterated));
+    }
+
+    /**
+     * Some elements randomly disappear in the middle of traversal.
+     */
+    public void testRandomElementRemovalDuringTraversal() {
+        Collection c = impl.emptyCollection();
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = rnd.nextInt(6);
+        ArrayList copy = new ArrayList();
+        for (int i = 0; i < n; i++) {
+            Object x = impl.makeElement(i);
+            copy.add(x);
+            c.add(x);
+        }
+        ArrayList iterated = new ArrayList();
+        ArrayList spliterated = new ArrayList();
+        ArrayList removed = new ArrayList();
+        Spliterator s = c.spliterator();
+        Iterator it = c.iterator();
+        if (! (s.hasCharacteristics(Spliterator.CONCURRENT) ||
+               s.hasCharacteristics(Spliterator.IMMUTABLE)))
+            return;
+        for (int i = rnd.nextInt(n + 1); --i >= 0; ) {
+            assertTrue(s.tryAdvance(e -> {}));
+            if (rnd.nextBoolean()) assertTrue(it.hasNext());
+            it.next();
+        }
+        Consumer alwaysThrows = e -> { throw new AssertionError(); };
+        // TODO: many more removal methods
+        if (rnd.nextBoolean()) {
+            for (Iterator z = c.iterator(); z.hasNext(); ) {
+                Object e = z.next();
+                if (rnd.nextBoolean()) {
+                    try {
+                        z.remove();
+                    } catch (UnsupportedOperationException ok) { return; }
+                    removed.add(e);
+                }
+            }
+        } else {
+            Predicate randomlyRemove = e -> {
+                if (rnd.nextBoolean()) { removed.add(e); return true; }
+                else return false;
+            };
+            c.removeIf(randomlyRemove);
+        }
+        s.forEachRemaining(spliterated::add);
+        while (it.hasNext())
+            iterated.add(it.next());
+        assertTrue(copy.containsAll(iterated));
+        assertTrue(copy.containsAll(spliterated));
+        assertTrue(copy.containsAll(removed));
+        if (s.hasCharacteristics(Spliterator.CONCURRENT)) {
+            ArrayList iteratedAndRemoved = new ArrayList(iterated);
+            ArrayList spliteratedAndRemoved = new ArrayList(spliterated);
+            iteratedAndRemoved.retainAll(removed);
+            spliteratedAndRemoved.retainAll(removed);
+            assertTrue(iteratedAndRemoved.size() <= 1);
+            assertTrue(spliteratedAndRemoved.size() <= 1);
+            if (testImplementationDetails
+                && !(c instanceof java.util.concurrent.ArrayBlockingQueue))
+                assertTrue(spliteratedAndRemoved.isEmpty());
+        }
+    }
+
+    /**
      * Various ways of traversing a collection yield same elements
      */
-    public void testIteratorEquivalence() {
+    public void testTraversalEquivalence() {
         Collection c = impl.emptyCollection();
         ThreadLocalRandom rnd = ThreadLocalRandom.current();
         int n = rnd.nextInt(6);
@@ -439,6 +543,43 @@
     }
 
     /**
+     * Iterator.forEachRemaining has same behavior as Iterator's
+     * default implementation.
+     */
+    public void testForEachRemainingConsistentWithDefaultImplementation() {
+        Collection c = impl.emptyCollection();
+        if (!testImplementationDetails
+            || c.getClass() == java.util.LinkedList.class)
+            return;
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = 1 + rnd.nextInt(3);
+        for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
+        ArrayList iterated = new ArrayList();
+        ArrayList iteratedForEachRemaining = new ArrayList();
+        Iterator it1 = c.iterator();
+        Iterator it2 = c.iterator();
+        assertTrue(it1.hasNext());
+        assertTrue(it2.hasNext());
+        c.clear();
+        Object r1, r2;
+        try {
+            while (it1.hasNext()) iterated.add(it1.next());
+            r1 = iterated;
+        } catch (ConcurrentModificationException ex) {
+            r1 = ConcurrentModificationException.class;
+            assertFalse(impl.isConcurrent());
+        }
+        try {
+            it2.forEachRemaining(iteratedForEachRemaining::add);
+            r2 = iteratedForEachRemaining;
+        } catch (ConcurrentModificationException ex) {
+            r2 = ConcurrentModificationException.class;
+            assertFalse(impl.isConcurrent());
+        }
+        assertEquals(r1, r2);
+    }
+
+    /**
      * Calling Iterator#remove() after Iterator#forEachRemaining
      * should (maybe) remove last element
      */
@@ -577,6 +718,41 @@
         assertTrue(found.isEmpty());
     }
 
+    /** TODO: promote to a common utility */
+    static <T> T chooseOne(T ... ts) {
+        return ts[ThreadLocalRandom.current().nextInt(ts.length)];
+    }
+
+    /** TODO: more random adders and removers */
+    static <E> Runnable adderRemover(Collection<E> c, E e) {
+        return chooseOne(
+            () -> {
+                assertTrue(c.add(e));
+                assertTrue(c.contains(e));
+                assertTrue(c.remove(e));
+                assertFalse(c.contains(e));
+            },
+            () -> {
+                assertTrue(c.add(e));
+                assertTrue(c.contains(e));
+                assertTrue(c.removeIf(x -> x == e));
+                assertFalse(c.contains(e));
+            },
+            () -> {
+                assertTrue(c.add(e));
+                assertTrue(c.contains(e));
+                for (Iterator it = c.iterator();; )
+                    if (it.next() == e) {
+                        try { it.remove(); }
+                        catch (UnsupportedOperationException ok) {
+                            c.remove(e);
+                        }
+                        break;
+                    }
+                assertFalse(c.contains(e));
+            });
+    }
+
     /**
      * Motley crew of threads concurrently randomly hammer the collection.
      */
@@ -616,17 +792,20 @@
             () -> checkArraySanity.accept(c.toArray()),
             () -> checkArraySanity.accept(c.toArray(emptyArray)),
             () -> {
-                assertTrue(c.add(one));
-                assertTrue(c.contains(one));
-                assertTrue(c.remove(one));
-                assertFalse(c.contains(one));
-            },
-            () -> {
-                assertTrue(c.add(two));
-                assertTrue(c.contains(two));
-                assertTrue(c.remove(two));
-                assertFalse(c.contains(two));
-            },
+                Object[] a = new Object[5];
+                Object three = impl.makeElement(3);
+                Arrays.fill(a, 0, a.length, three);
+                Object[] x = c.toArray(a);
+                if (x == a)
+                    for (int i = 0; i < a.length && a[i] != null; i++)
+                        checkSanity.accept(a[i]);
+                    // A careful reading of the spec does not support:
+                    // for (i++; i < a.length; i++) assertSame(three, a[i]);
+                else
+                    checkArraySanity.accept(x);
+                },
+            adderRemover(c, one),
+            adderRemover(c, two),
         };
         final List<Runnable> tasks =
             Arrays.stream(frobbers)
@@ -684,6 +863,22 @@
         }
     }
 
+    /**
+     * Spliterator.getComparator throws IllegalStateException iff the
+     * spliterator does not report SORTED.
+     */
+    public void testGetComparator_IllegalStateException() {
+        Collection c = impl.emptyCollection();
+        Spliterator s = c.spliterator();
+        boolean reportsSorted = s.hasCharacteristics(Spliterator.SORTED);
+        try {
+            s.getComparator();
+            assertTrue(reportsSorted);
+        } catch (IllegalStateException ex) {
+            assertFalse(reportsSorted);
+        }
+    }
+
 //     public void testCollection8DebugFail() {
 //         fail(impl.klazz().getSimpleName());
 //     }
--- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java	Thu Dec 22 18:48:53 2016 +0000
@@ -35,13 +35,30 @@
 
 /*
  * @test
- * @summary JSR-166 tck tests
+ * @summary JSR-166 tck tests (conformance testing mode)
+ * @build *
+ * @modules java.management
+ * @run junit/othervm/timeout=1000 JSR166TestCase
+ */
+
+/*
+ * @test
+ * @summary JSR-166 tck tests (whitebox tests allowed)
+ * @build *
  * @modules java.base/java.util.concurrent:open
  *          java.management
- * @build *
- * @run junit/othervm/timeout=1000 -Djsr166.testImplementationDetails=true JSR166TestCase
- * @run junit/othervm/timeout=1000 -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 -Djsr166.testImplementationDetails=true JSR166TestCase
- * @run junit/othervm/timeout=1000 -Djava.util.concurrent.ForkJoinPool.common.parallelism=1 -Djava.util.secureRandomSeed=true JSR166TestCase
+ * @run junit/othervm/timeout=1000
+ *      -Djsr166.testImplementationDetails=true
+ *      JSR166TestCase
+ * @run junit/othervm/timeout=1000
+ *      -Djsr166.testImplementationDetails=true
+ *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=0
+ *      JSR166TestCase
+ * @run junit/othervm/timeout=1000
+ *      -Djsr166.testImplementationDetails=true
+ *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=1
+ *      -Djava.util.secureRandomSeed=true
+ *      JSR166TestCase
  */
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -543,6 +560,8 @@
                 "DoubleAdderTest",
                 "ForkJoinPool8Test",
                 "ForkJoinTask8Test",
+                "LinkedBlockingDeque8Test",
+                "LinkedBlockingQueue8Test",
                 "LongAccumulatorTest",
                 "LongAdderTest",
                 "SplittableRandomTest",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/tck/LinkedBlockingDeque8Test.java	Thu Dec 22 18:48:53 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Martin Buchholz with assistance from
+ * members of JCP JSR-166 Expert Group and released to the public
+ * domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.Spliterator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LinkedBlockingDeque8Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return newTestSuite(LinkedBlockingDeque8Test.class);
+    }
+
+    /**
+     * Spliterator.getComparator always throws IllegalStateException
+     */
+    public void testSpliterator_getComparator() {
+        assertThrows(IllegalStateException.class,
+                     () -> new LinkedBlockingDeque().spliterator().getComparator());
+    }
+
+    /**
+     * Spliterator characteristics are as advertised
+     */
+    public void testSpliterator_characteristics() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        Spliterator s = q.spliterator();
+        int characteristics = s.characteristics();
+        int required = Spliterator.CONCURRENT
+            | Spliterator.NONNULL
+            | Spliterator.ORDERED;
+        assertEquals(required, characteristics & required);
+        assertTrue(s.hasCharacteristics(required));
+        assertEquals(0, characteristics
+                     & (Spliterator.DISTINCT
+                        | Spliterator.IMMUTABLE
+                        | Spliterator.SORTED));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/tck/LinkedBlockingQueue8Test.java	Thu Dec 22 18:48:53 2016 +0000
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Martin Buchholz with assistance from
+ * members of JCP JSR-166 Expert Group and released to the public
+ * domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.Spliterator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LinkedBlockingQueue8Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return newTestSuite(LinkedBlockingQueue8Test.class);
+    }
+
+    /**
+     * Spliterator.getComparator always throws IllegalStateException
+     */
+    public void testSpliterator_getComparator() {
+        assertThrows(IllegalStateException.class,
+                     () -> new LinkedBlockingQueue().spliterator().getComparator());
+    }
+
+    /**
+     * Spliterator characteristics are as advertised
+     */
+    public void testSpliterator_characteristics() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue();
+        Spliterator s = q.spliterator();
+        int characteristics = s.characteristics();
+        int required = Spliterator.CONCURRENT
+            | Spliterator.NONNULL
+            | Spliterator.ORDERED;
+        assertEquals(required, characteristics & required);
+        assertTrue(s.hasCharacteristics(required));
+        assertEquals(0, characteristics
+                     & (Spliterator.DISTINCT
+                        | Spliterator.IMMUTABLE
+                        | Spliterator.SORTED));
+    }
+
+}
--- a/jdk/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -71,9 +71,9 @@
     }
 
     static class CustomTask<V> implements RunnableScheduledFuture<V> {
-        RunnableScheduledFuture<V> task;
+        private final RunnableScheduledFuture<V> task;
         volatile boolean ran;
-        CustomTask(RunnableScheduledFuture<V> t) { task = t; }
+        CustomTask(RunnableScheduledFuture<V> task) { this.task = task; }
         public boolean isPeriodic() { return task.isPeriodic(); }
         public void run() {
             ran = true;
--- a/jdk/test/java/util/concurrent/tck/SubmissionPublisherTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/util/concurrent/tck/SubmissionPublisherTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -402,6 +402,7 @@
 
     /**
      * Closing a publisher exceptionally causes onError to subscribers
+     * after they are subscribed
      */
     public void testCloseExceptionallyError() {
         SubmissionPublisher<Integer> p = basicPublisher();
@@ -412,9 +413,11 @@
         p.submit(1);
         p.closeExceptionally(new SPException());
         assertTrue(p.isClosed());
+        s1.awaitSubscribe();
         s1.awaitError();
         assertTrue(s1.nexts <= 1);
         assertEquals(1, s1.errors);
+        s2.awaitSubscribe();
         s2.awaitError();
         assertTrue(s2.nexts <= 1);
         assertEquals(1, s2.errors);
--- a/jdk/test/java/util/concurrent/tck/ThreadLocalRandomTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/util/concurrent/tck/ThreadLocalRandomTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -85,32 +85,41 @@
      */
     public void testNext() throws ReflectiveOperationException {
         ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final java.lang.reflect.Method m;
         try {
-            java.lang.reflect.Method m
-                = ThreadLocalRandom.class.getDeclaredMethod(
+            m = ThreadLocalRandom.class.getDeclaredMethod(
                     "next", new Class[] { int.class });
             m.setAccessible(true);
-
-            int i;
-            {
-                int val = new java.util.Random().nextInt(4);
-                for (i = 0; i < NCALLS; i++) {
-                    int q = (int) m.invoke(rnd, new Object[] { 2 });
-                    if (val == q) break;
-                }
-                assertTrue(i < NCALLS);
-            }
+        } catch (SecurityException acceptable) {
+            // Security manager may deny access
+            return;
+        } catch (Exception ex) {
+            // jdk9 module system may deny access
+            if (ex.getClass().getSimpleName()
+                .equals("InaccessibleObjectException"))
+                return;
+            throw ex;
+        }
 
-            {
-                int r = (int) m.invoke(rnd, new Object[] { 3 });
-                for (i = 0; i < NCALLS; i++) {
-                    int q = (int) m.invoke(rnd, new Object[] { 3 });
-                    assertTrue(q < (1<<3));
-                    if (r != q) break;
-                }
-                assertTrue(i < NCALLS);
+        int i;
+        {
+            int val = new java.util.Random().nextInt(4);
+            for (i = 0; i < NCALLS; i++) {
+                int q = (int) m.invoke(rnd, new Object[] { 2 });
+                if (val == q) break;
             }
-        } catch (SecurityException acceptable) {}
+            assertTrue(i < NCALLS);
+        }
+
+        {
+            int r = (int) m.invoke(rnd, new Object[] { 3 });
+            for (i = 0; i < NCALLS; i++) {
+                int q = (int) m.invoke(rnd, new Object[] { 3 });
+                assertTrue(q < (1<<3));
+                if (r != q) break;
+            }
+            assertTrue(i < NCALLS);
+        }
     }
 
     /**
--- a/jdk/test/java/util/concurrent/tck/VectorTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/java/util/concurrent/tck/VectorTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -58,9 +58,22 @@
             }
         }
         return newTestSuite(
-                // VectorTest.class,
+                VectorTest.class,
                 CollectionTest.testSuite(new Implementation()),
                 CollectionTest.testSuite(new SubListImplementation()));
     }
 
+    /**
+     * tests for setSize()
+     */
+    public void testSetSize() {
+        Vector v = new Vector();
+        for (int n : new int[] { 100, 5, 50 }) {
+            v.setSize(n);
+            assertEquals(n, v.size());
+            assertNull(v.get(0));
+            assertNull(v.get(n - 1));
+        }
+    }
+
 }
--- a/jdk/test/javax/net/ssl/templates/SSLSocketTemplate.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/javax/net/ssl/templates/SSLSocketTemplate.java	Thu Dec 22 18:48:53 2016 +0000
@@ -176,6 +176,13 @@
     }
 
     /*
+     * Configure the server side socket.
+     */
+    protected void configureServerSocket(SSLServerSocket socket) {
+
+    }
+
+    /*
      * =============================================
      * Define the client and server side operations.
      *
@@ -211,6 +218,7 @@
         SSLServerSocketFactory sslssf = context.getServerSocketFactory();
         SSLServerSocket sslServerSocket =
                 (SSLServerSocket)sslssf.createServerSocket(serverPort);
+        configureServerSocket(sslServerSocket);
         serverPort = sslServerSocket.getLocalPort();
 
         // Signal the client, the server is ready to accept connection.
--- a/jdk/test/javax/swing/JFileChooser/4847375/bug4847375.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/javax/swing/JFileChooser/4847375/bug4847375.java	Thu Dec 22 18:48:53 2016 +0000
@@ -23,11 +23,11 @@
 
 /*
  * @test
- * @bug 4847375
+ * @bug 4847375 8171363
  * @summary JFileChooser Create New Folder button is disabled incorrectly
  * @author Pavel Porvatov
  * @modules java.desktop/sun.awt
- *          java.desktop/sun.awt.shell
+ *          java.desktop/sun.awt.shell:+open
  */
 
 import sun.awt.OSInfo;
--- a/jdk/test/javax/swing/JFileChooser/6741890/bug6741890.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/javax/swing/JFileChooser/6741890/bug6741890.java	Thu Dec 22 18:48:53 2016 +0000
@@ -22,11 +22,11 @@
  */
 
 /* @test
-   @bug 6741890
+   @bug 6741890 8171363
    @summary Deadlock in Win32ShellFolderManager2
    @author Pavel Porvatov
    @modules java.desktop/sun.awt
-            java.desktop/sun.awt.shell
+            java.desktop/sun.awt.shell:+open
    @run main bug6741890
 */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -0,0 +1,119 @@
+/*
+ * 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 8074883
+ * @summary Tab key should move to focused button in a button group
+ * @run main ButtonGroupFocusTest
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.KeyEvent;
+
+public class ButtonGroupFocusTest {
+
+    private static JRadioButton button1;
+    private static JRadioButton button2;
+    private static JRadioButton button3;
+    private static JRadioButton button4;
+    private static JRadioButton button5;
+    private static Robot robot;
+    private static JFrame frame;
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        robot.setAutoDelay(100);
+
+        SwingUtilities.invokeAndWait(() -> {
+            frame = new JFrame();
+            Container contentPane = frame.getContentPane();
+            contentPane.setLayout(new FlowLayout());
+            button1 = new JRadioButton("Button 1");
+            contentPane.add(button1);
+            button2 = new JRadioButton("Button 2");
+            contentPane.add(button2);
+            button3 = new JRadioButton("Button 3");
+            contentPane.add(button3);
+            button4 = new JRadioButton("Button 4");
+            contentPane.add(button4);
+            button5 = new JRadioButton("Button 5");
+            contentPane.add(button5);
+            ButtonGroup group = new ButtonGroup();
+            group.add(button1);
+            group.add(button2);
+            group.add(button3);
+
+            group = new ButtonGroup();
+            group.add(button4);
+            group.add(button5);
+
+            button2.setSelected(true);
+
+            frame.pack();
+            frame.setVisible(true);
+        });
+
+        robot.waitForIdle();
+        robot.delay(200);
+
+        SwingUtilities.invokeAndWait(() -> {
+            if( !button2.hasFocus() ) {
+                frame.dispose();
+                throw new RuntimeException(
+                        "Button 2 should get focus after activation");
+            }
+        });
+
+        robot.keyPress(KeyEvent.VK_TAB);
+        robot.keyRelease(KeyEvent.VK_TAB);
+
+        robot.waitForIdle();
+        robot.delay(200);
+
+        SwingUtilities.invokeAndWait(() -> {
+            if( !button4.hasFocus() ) {
+                frame.dispose();
+                throw new RuntimeException(
+                        "Button 4 should get focus");
+            }
+            button3.setSelected(true);
+        });
+
+        robot.keyPress(KeyEvent.VK_TAB);
+        robot.keyRelease(KeyEvent.VK_TAB);
+
+        robot.waitForIdle();
+        robot.delay(200);
+
+        SwingUtilities.invokeAndWait(() -> {
+            if( !button3.hasFocus() ) {
+                frame.dispose();
+                throw new RuntimeException(
+                        "selected Button 3 should get focus");
+            }
+        });
+
+        SwingUtilities.invokeLater(frame::dispose);
+    }
+}
--- a/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java	Thu Dec 22 18:48:53 2016 +0000
@@ -29,7 +29,7 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary JavaVM
+ * @build TestLibrary REGISTRY RegistryRunner
  * @run main/othervm DeadCachedConnection
  */
 
@@ -60,73 +60,65 @@
 import java.rmi.server.*;
 
 public class DeadCachedConnection {
-    static public final int regport = TestLibrary.getUnusedRandomPort();
 
     static public void main(String[] argv)
         throws Exception {
-        // establish the registry (we hope)
-        System.err.println ("Starting registry on port " + regport);
-        DeadCachedConnection.makeRegistry(regport);
+        try {
+            Registry reg = null;
+            int port = makeRegistry(0);
 
-        // Get a handle to the registry
-        Registry reg = null;
-        System.err.println ("Locating just-started registry...");
-        try {
-            reg = LocateRegistry.getRegistry(regport);
-        } catch (RemoteException e) {
-            throw new InternalError ("Can't find registry after starting it.");
-        }
+            // Get a handle to the registry
+            System.err.println ("Locating just-started registry...");
+            try {
+                reg = LocateRegistry.getRegistry(port);
+            } catch (RemoteException e) {
+                throw new InternalError ("Can't find registry after starting it.");
+            }
+
+            // Contact the registry by invoking something on it.
+            System.err.println ("Connecting to registry...");
+            String[] junk = reg.list();
 
-        // Contact the registry by invoking something on it.
-        System.err.println ("Connecting to registry...");
-        String[] junk = reg.list();
-
-        // Kill and restart the registry
-        System.err.println("Killing registry...");
-        DeadCachedConnection.killRegistry();
-        System.err.println("Restarting registry...");
-        DeadCachedConnection.makeRegistry(regport);
+            // Kill and restart the registry
+            System.err.println("Killing registry...");
+            killRegistry();
+            System.err.println("Restarting registry...");
+            makeRegistry(port);
 
-        // Try again (this is the test)
-        System.err.println("Trying to use registry in spite of stale cache...");
-        junk = reg.list();
+            // Try again (this is the test)
+            System.err.println("Trying to use registry in spite of stale cache...");
+            junk = reg.list();
 
-        // we're happy
-        System.err.println("Test succeeded.");
-        try {
-            DeadCachedConnection.killRegistry();
-        } catch (Exception foo) {
+            System.err.println("Test succeeded.");
+        } catch (Exception e) {
+            TestLibrary.bomb(e);
+        } finally {
+            // dont leave the registry around to affect other tests.
+            killRegistry();
         }
     }
 
-    public static void makeRegistry(int p) {
-        // sadly, we can't kill a registry if we have too-close control
-        // over it.  We must make it in a subprocess, and then kill the
-        // subprocess when it has served our needs.
-
+    public static int makeRegistry(int port) {
         try {
-            JavaVM jvm =
-                new JavaVM("sun.rmi.registry.RegistryImpl", "", Integer.toString(p));
-            jvm.start();
-            DeadCachedConnection.subreg = jvm;
-
+            subreg = REGISTRY.createREGISTRY(System.out, System.err, "", port);
+            subreg.start();
+            int regPort = subreg.getPort();
+            System.out.println("Starting registry on port " + regPort);
+            return regPort;
         } catch (IOException e) {
             // one of these is summarily dropped, can't remember which one
             System.out.println ("Test setup failed - cannot run rmiregistry");
             TestLibrary.bomb("Test setup failed - cannot run test", e);
         }
-        // Slop - wait for registry to come up.  This is stupid.
-        try {
-            Thread.sleep (5000);
-        } catch (Exception whatever) {
+        return -1;
+    }
+
+    private static REGISTRY subreg = null;
+
+    public static void killRegistry() throws InterruptedException {
+        if (subreg != null) {
+            subreg.shutdown();
+            subreg = null;
         }
     }
-    private static JavaVM subreg = null;
-
-    public static void killRegistry() throws InterruptedException {
-        if (DeadCachedConnection.subreg != null) {
-            DeadCachedConnection.subreg.terminate();
-        }
-        DeadCachedConnection.subreg = null;
-    }
 }
--- a/jdk/test/sun/security/ssl/SSLContextImpl/TrustTrustedCert.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/TrustTrustedCert.java	Thu Dec 22 18:48:53 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -32,6 +32,7 @@
  * @test
  * @bug 7113275 8164846
  * @summary compatibility issue with MD2 trust anchor and old X509TrustManager
+ * @library /javax/net/ssl/templates
  * @run main/othervm TrustTrustedCert PKIX TLSv1.1 true
  * @run main/othervm TrustTrustedCert PKIX TLSv1.1 false
  * @run main/othervm TrustTrustedCert SunX509 TLSv1.1 false
@@ -40,7 +41,6 @@
  */
 
 import java.net.*;
-import java.util.*;
 import java.io.*;
 import javax.net.ssl.*;
 import java.security.*;
@@ -49,21 +49,7 @@
 import java.security.interfaces.*;
 import java.util.Base64;
 
-
-public class TrustTrustedCert {
-
-    /*
-     * =============================================================
-     * 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;
+public class TrustTrustedCert extends SSLSocketTemplate {
 
     /*
      * Certificates and key used in the test.
@@ -124,89 +110,61 @@
         "A5kokFb+E3Gplu29tJvCUpfwgBFRS+wmkvtiaU/tiyDcVgDO+An5DwedxxdVzqiE\n" +
         "njWHoKY3axDQ8OU=\n";
 
-
     static char passphrase[] = "passphrase".toCharArray();
 
-    /*
-     * Is the server ready to serve?
-     */
-    volatile static boolean serverReady = false;
-
-    /*
-     * Turn on SSL debugging?
-     */
-    static boolean debug = false;
+    @Override
+    protected SSLContext createServerSSLContext() throws Exception {
+        return generateSSLContext();
+    }
 
-    /*
-     * 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 {
-        SSLContext context = generateSSLContext();
-        SSLServerSocketFactory sslssf = context.getServerSocketFactory();
-        SSLServerSocket sslServerSocket =
-            (SSLServerSocket)sslssf.createServerSocket(serverPort);
-        sslServerSocket.setNeedClientAuth(true);
-        serverPort = sslServerSocket.getLocalPort();
-
-        /*
-         * Signal Client, we're ready for his connect.
-         */
-        serverReady = true;
-
-        SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept();
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
-
-        sslIS.read();
-        sslOS.write('A');
-        sslOS.flush();
-
-        sslSocket.close();
+    @Override
+    protected void configureServerSocket(SSLServerSocket socket) {
+        socket.setNeedClientAuth(true);
     }
 
-    /*
-     * 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 {
+    @Override
+    protected void runServerApplication(SSLSocket socket) throws Exception {
+        InputStream sslIS = socket.getInputStream();
+        OutputStream sslOS = socket.getOutputStream();
 
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
+        try {
+            sslIS.read();
+            sslOS.write('A');
+            sslOS.flush();
+        } catch (SSLHandshakeException e) {
+            if (expectFail && !e.toString().contains("certificate_unknown")) {
+                throw new RuntimeException(
+                        "Expected to see certificate_unknown in exception output",
+                        e);
+            }
         }
+    }
 
-        SSLSocket sslSocket = null;
-        try {
-            SSLContext context = generateSSLContext();
-            SSLSocketFactory sslsf = context.getSocketFactory();
+    @Override
+    protected SSLContext createClientSSLContext() throws Exception {
+        return generateSSLContext();
+    }
 
-            sslSocket = (SSLSocket)sslsf.createSocket("localhost", serverPort);
+    @Override
+    protected void runClientApplication(SSLSocket socket) throws Exception {
+        // enable the specified TLS protocol
+        socket.setEnabledProtocols(new String[] { tlsProtocol });
 
-            // enable the specified TLS protocol
-            sslSocket.setEnabledProtocols(new String[] {tlsProtocol});
+        InputStream sslIS = socket.getInputStream();
+        OutputStream sslOS = socket.getOutputStream();
 
-            InputStream sslIS = sslSocket.getInputStream();
-            OutputStream sslOS = sslSocket.getOutputStream();
+        try {
             sslOS.write('B');
             sslOS.flush();
             sslIS.read();
         } catch (SSLHandshakeException e) {
-            // focus in on the CertPathValidatorException
+            // focus on the CertPathValidatorException
             Throwable t = e.getCause().getCause();
-            if ((t == null) || (expectFail &&
-                !t.toString().contains("MD5withRSA"))) {
+            if ((t == null)
+                    || (expectFail && !t.toString().contains("MD5withRSA"))) {
                 throw new RuntimeException(
-                    "Expected to see MD5withRSA in exception output " + t);
+                        "Expected to see MD5withRSA in exception output", t);
             }
-        } finally {
-            if (sslSocket != null) sslSocket.close();
         }
     }
 
@@ -343,13 +301,6 @@
         }
     }
 
-
-    // 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 {
         /*
          * Get the customized arguments.
@@ -367,144 +318,9 @@
         Security.setProperty("jdk.tls.disabledAlgorithms",
                 "SSLv3, RC4, DH keySize < 768");
 
-        if (debug)
-            System.setProperty("javax.net.debug", "all");
-
         /*
          * Start the tests.
          */
-        new TrustTrustedCert();
-    }
-
-    Thread clientThread = null;
-    Thread serverThread = null;
-
-    /*
-     * Primary constructor, used to drive remainder of the test.
-     *
-     * Fork off the other side, then do your work.
-     */
-    TrustTrustedCert() throws Exception {
-        try {
-            if (separateServerThread) {
-                startServer(true);
-                startClient(false);
-            } else {
-                startClient(true);
-                startServer(false);
-            }
-        } catch (Exception e) {
-            System.out.println("Unexpected exception: ");
-            e.printStackTrace();
-        }
-
-        /*
-         * Wait for other side to close down.
-         */
-        if (separateServerThread) {
-            serverThread.join();
-        } else {
-            clientThread.join();
-        }
-
-        /*
-         * When we get here, the test is pretty much over.
-         * Which side threw the error?
-         */
-        Exception local;
-        Exception remote;
-        String whichRemote;
-
-        if (separateServerThread) {
-            remote = serverException;
-            local = clientException;
-            whichRemote = "server";
-        } else {
-            remote = clientException;
-            local = serverException;
-            whichRemote = "client";
-        }
-
-        /*
-         * If both failed, return the curthread's exception, but also
-         * print the remote side Exception
-         */
-        if ((local != null) && (remote != null)) {
-            System.out.println(whichRemote + " also threw:");
-            remote.printStackTrace();
-            System.out.println();
-            throw local;
-        }
-
-        if (remote != null) {
-            throw remote;
-        }
-
-        if (local != null) {
-            throw local;
-        }
-    }
-
-    void startServer(boolean newThread) throws Exception {
-        if (newThread) {
-            serverThread = new Thread() {
-                public void run() {
-                    try {
-                        doServerSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our server thread just died.
-                         *
-                         * Release the client, if not active already...
-                         */
-                        System.err.println("Server died...");
-                        serverReady = true;
-                        if (!expectFail) {
-                            // only record if we weren't expecting.
-                            // client side will record exception
-                            serverException = e;
-                        }
-                    }
-                }
-            };
-            serverThread.start();
-        } else {
-            try {
-                doServerSide();
-            } catch (Exception e) {
-                // only record if we weren't expecting.
-                // client side will record exception
-                if (!expectFail) {
-                    serverException = e;
-                }
-            } finally {
-                serverReady = true;
-            }
-        }
-    }
-
-    void startClient(boolean newThread) throws Exception {
-        if (newThread) {
-            clientThread = new Thread() {
-                public void run() {
-                    try {
-                        doClientSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our client thread just died.
-                         */
-                        System.err.println("Client died...");
-                        clientException = e;
-                    }
-                }
-            };
-            clientThread.start();
-        } else {
-            try {
-                doClientSide();
-            } catch (Exception e) {
-                clientException = e;
-            }
-        }
+        new TrustTrustedCert().run();
     }
 }
--- a/jdk/test/sun/util/locale/provider/Bug8038436.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/sun/util/locale/provider/Bug8038436.java	Thu Dec 22 18:48:53 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8038436 8158504 8065555
+ * @bug 8038436 8158504 8065555 8167143
  * @summary Test for changes in 8038436
  * @modules java.base/sun.util.locale.provider
  *          java.base/sun.util.spi
@@ -120,7 +120,7 @@
         "fi, fi-FI, fr, fr-BE, fr-CA, fr-CH, fr-FR, ga, ga-IE, he, he-IL, " +
         "hi-IN, hr, hr-HR, hu, hu-HU, id, id-ID, is, is-IS, it, it-CH, it-IT, " +
         "ja, ja-JP, ko, ko-KR, lt, lt-LT, lv, lv-LV, mk, mk-MK, ms, ms-MY, mt, " +
-        "mt-MT, nl, nl-BE, nl-NL, no, no-NO, no-NO, pl, pl-PL, pt, pt-BR, " +
+        "mt-MT, nb-NO, nl, nl-BE, nl-NL, nn-NO, no, no-NO, no-NO, pl, pl-PL, pt, pt-BR, " +
         "pt-PT, ro, ro-RO, ru, ru-RU, sk, sk-SK, sl, sl-SI, sq, sq-AL, sr, " +
         "sr-BA, sr-CS, sr-Latn, sr-Latn-ME, sr-ME, sr-RS, sv, sv-SE, th, th-TH, " +
         "tr, tr-TR, uk, uk-UA, und, vi, vi-VN, zh, zh-CN, zh-HK, zh-Hans-CN, " +
@@ -130,7 +130,7 @@
     static final String[] decimalfspLocs = bipLocs;
     static final String[] calnpLocs = bipLocs;
     static final String[] cpLocs = ("ar, be, bg, ca, cs, da, el, es, et, fi, " +
-        "fr, he, hi, hr, hu, is, ja, ko, lt, lv, mk, no, pl, ro, ru, sk, sl, " +
+        "fr, he, hi, hr, hu, is, ja, ko, lt, lv, mk, nb-NO, nn-NO, no, pl, ro, ru, sk, sl, " +
         "sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, zh-HK, zh-Hant-HK, " +
         "zh-Hant-TW, zh-TW, ").split(",\\s*");
     static final String[] nfpLocs = ("ar, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, " +
@@ -160,22 +160,22 @@
         "es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et-EE, fi-FI, " +
         "fr, fr-BE, fr-CA, fr-CH, fr-FR, fr-LU, ga-IE, he-IL, hi-IN, hr-HR, " +
         "hu-HU, id-ID, is-IS, it, it-CH, it-IT, ja, ja-JP, ko, ko-KR, lt-LT, " +
-        "lv-LV, mk-MK, ms-MY, mt-MT, nl-BE, nl-NL, no-NO, pl-PL, pt, pt-BR, " +
+        "lv-LV, mk-MK, ms-MY, mt-MT, nb-NO, nl-BE, nl-NL, nn-NO, no-NO, pl-PL, pt, pt-BR, " +
         "pt-PT, ro-RO, ru-RU, sk-SK, sl-SI, sq-AL, sr-BA, sr-CS, sr-Latn-BA, " +
         "sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, sv, sv-SE, th-TH, tr-TR, uk-UA, " +
         "und, vi-VN, zh-CN, zh-HK, zh-Hans-CN, zh-Hans-SG, zh-Hant-HK, " +
         "zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
     static final String[] lnpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " +
         "en, en-MT, en-PH, en-SG, es, es-US, et, fi, fr, ga, he, hi, hr, hu, " +
-        "id, is, it, ja, ko, lt, lv, mk, ms, mt, nl, no, no-NO, pl, pt, pt-BR, " +
+        "id, is, it, ja, ko, lt, lv, mk, ms, mt, nb-NO, nl, nn-NO, no, no-NO, pl, pt, pt-BR, " +
         "pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, " +
         "zh-HK, zh-Hans-SG, zh-Hant-HK, zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
     static final String[] tznpLocs = ("de, en, en-CA, en-GB, en-IE, es, fr, hi, " +
-        "it, ja, ko, pt-BR, sv, und, zh-CN, zh-HK, zh-Hans-CN, zh-Hant-HK, " +
+        "it, ja, ko, nb-NO, nn-NO, pt-BR, sv, und, zh-CN, zh-HK, zh-Hans-CN, zh-Hant-HK, " +
         "zh-Hant-TW, zh-TW, ").split(",\\s*");
     static final String[] caldpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " +
         "en, en-GB, en-IE, en-MT, es, es-ES, es-US, et, fi, fr, fr-CA, he, hi, " +
-        "hr, hu, id-ID, is, it, ja, ko, lt, lv, mk, ms-MY, mt, mt-MT, nl, no, " +
+        "hr, hu, id-ID, is, it, ja, ko, lt, lv, mk, ms-MY, mt, mt-MT, nb-NO, nl, nn-NO, no, " +
         "pl, pt, pt-BR, pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn-BA, sr-Latn-ME, " +
         "sr-Latn-RS, sv, th, tr, uk, und, vi, zh, ").split(",\\s*");
     static final String[] calpLocs = caldpLocs;
--- a/jdk/test/tools/jmod/JmodTest.java	Thu Dec 22 08:26:02 2016 +0000
+++ b/jdk/test/tools/jmod/JmodTest.java	Thu Dec 22 18:48:53 2016 +0000
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8142968 8166568
+ * @bug 8142968 8166568 8166286 8170618
  * @summary Basic test for jmod
  * @library /lib/testlibrary
  * @modules jdk.compiler
@@ -114,6 +114,27 @@
             .assertSuccess();
     }
 
+    // JDK-8170618 - jmod should validate if any exported or open package is missing
+    @Test
+    public void testMissingPackages() throws IOException {
+        Path apaDir = EXPLODED_DIR.resolve("apa");
+        Path classesDir = EXPLODED_DIR.resolve("apa").resolve("classes");
+        if (Files.exists(classesDir))
+            FileUtils.deleteFileTreeWithRetry(classesDir);
+        assertTrue(compileModule("apa", classesDir));
+        FileUtils.deleteFileTreeWithRetry(classesDir.resolve("jdk"));
+        Path jmod = MODS_DIR.resolve("apa.jmod");
+        jmod("create",
+             "--class-path", classesDir.toString(),
+             jmod.toString())
+            .assertFailure()
+            .resultChecker(r -> {
+                assertContains(r.output, "Packages that are exported or open in apa are not present: [jdk.test.apa]");
+            });
+        if (Files.exists(classesDir))
+            FileUtils.deleteFileTreeWithRetry(classesDir);
+    }
+
     @Test
     public void testList() throws IOException {
         String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();