Import test.java.util.Collections from jdk-17.0.6-ga

List of files:
  ojluni/src/test/java/util/Collections/AddAll.java
  ojluni/src/test/java/util/Collections/AsLifoQueue.java
  ojluni/src/test/java/util/Collections/BigBinarySearch.java
  ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java
  ojluni/src/test/java/util/Collections/CheckedIdentityMap.java
  ojluni/src/test/java/util/Collections/CheckedListBash.java
  ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java
  ojluni/src/test/java/util/Collections/CheckedMapBash.java
  ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java
  ojluni/src/test/java/util/Collections/CheckedNull.java
  ojluni/src/test/java/util/Collections/CheckedQueue.java
  ojluni/src/test/java/util/Collections/CheckedSetBash.java
  ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java
  ojluni/src/test/java/util/Collections/Disjoint.java
  ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java
  ojluni/src/test/java/util/Collections/EmptyIterator.java
  ojluni/src/test/java/util/Collections/EmptyNavigableMap.java
  ojluni/src/test/java/util/Collections/EmptyNavigableSet.java
  ojluni/src/test/java/util/Collections/Enum.java
  ojluni/src/test/java/util/Collections/EnumerationAsIterator.java
  ojluni/src/test/java/util/Collections/EqualsTest.java
  ojluni/src/test/java/util/Collections/FindSubList.java
  ojluni/src/test/java/util/Collections/Frequency.java
  ojluni/src/test/java/util/Collections/MinMax.java
  ojluni/src/test/java/util/Collections/NullComparator.java
  ojluni/src/test/java/util/Collections/RacingCollections.java
  ojluni/src/test/java/util/Collections/ReplaceAll.java
  ojluni/src/test/java/util/Collections/ReverseOrder.java
  ojluni/src/test/java/util/Collections/ReverseOrder2.java
  ojluni/src/test/java/util/Collections/Rotate.java
  ojluni/src/test/java/util/Collections/RotateEmpty.java
  ojluni/src/test/java/util/Collections/Ser.java
  ojluni/src/test/java/util/Collections/SetFromMap.java
  ojluni/src/test/java/util/Collections/SingletonIterator.java
  ojluni/src/test/java/util/Collections/Swap.java
  ojluni/src/test/java/util/Collections/SyncSubMutexes.java
  ojluni/src/test/java/util/Collections/T6433170.java
  ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java
  ojluni/src/test/java/util/Collections/ViewSynch.java
  ojluni/src/test/java/util/Collections/WrappedNull.java
  ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java
  ojluni/src/test/java/util/Collections/Wrappers.java

Generated by tools/expected_upstream/ojluni_merge_to_master.py

Bug: 283957281
Test: N/A
Change-Id: I4c06f7acccb1c862fa12db8702944eb3bfecca0d
diff --git a/EXPECTED_UPSTREAM b/EXPECTED_UPSTREAM
index f441f2f..f6e4e1d 100644
--- a/EXPECTED_UPSTREAM
+++ b/EXPECTED_UPSTREAM
@@ -2266,7 +2266,49 @@
 ojluni/src/test/java/util/BitSet/PreviousBits.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/BitSet/PreviousBits.java
 ojluni/src/test/java/util/BitSet/StickySize.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/BitSet/StickySize.java
 ojluni/src/test/java/util/BitSet/stream/BitSetStreamTest.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/BitSet/stream/BitSetStreamTest.java
+ojluni/src/test/java/util/Collections/AddAll.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/AddAll.java
+ojluni/src/test/java/util/Collections/AsLifoQueue.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/AsLifoQueue.java
+ojluni/src/test/java/util/Collections/BigBinarySearch.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/BigBinarySearch.java
+ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/BinarySearchNullComparator.java
+ojluni/src/test/java/util/Collections/CheckedIdentityMap.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/CheckedIdentityMap.java
+ojluni/src/test/java/util/Collections/CheckedListBash.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/CheckedListBash.java
+ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/CheckedListReplaceAll.java
+ojluni/src/test/java/util/Collections/CheckedMapBash.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/CheckedMapBash.java
+ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/CheckedMapReplaceAll.java
+ojluni/src/test/java/util/Collections/CheckedNull.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/CheckedNull.java
+ojluni/src/test/java/util/Collections/CheckedQueue.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/CheckedQueue.java
+ojluni/src/test/java/util/Collections/CheckedSetBash.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/CheckedSetBash.java
+ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/DelegatingIteratorForEachRemaining.java
+ojluni/src/test/java/util/Collections/Disjoint.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/Disjoint.java
+ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/EmptyCollectionSerialization.java
+ojluni/src/test/java/util/Collections/EmptyIterator.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/EmptyIterator.java
+ojluni/src/test/java/util/Collections/EmptyNavigableMap.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/EmptyNavigableMap.java
+ojluni/src/test/java/util/Collections/EmptyNavigableSet.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/EmptyNavigableSet.java
+ojluni/src/test/java/util/Collections/Enum.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/Enum.java
+ojluni/src/test/java/util/Collections/EnumerationAsIterator.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/EnumerationAsIterator.java
+ojluni/src/test/java/util/Collections/EqualsTest.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/EqualsTest.java
+ojluni/src/test/java/util/Collections/FindSubList.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/FindSubList.java
+ojluni/src/test/java/util/Collections/Frequency.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/Frequency.java
+ojluni/src/test/java/util/Collections/MinMax.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/MinMax.java
 ojluni/src/test/java/util/Collections/NCopies.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/NCopies.java
+ojluni/src/test/java/util/Collections/NullComparator.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/NullComparator.java
+ojluni/src/test/java/util/Collections/RacingCollections.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/RacingCollections.java
+ojluni/src/test/java/util/Collections/ReplaceAll.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/ReplaceAll.java
+ojluni/src/test/java/util/Collections/ReverseOrder.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/ReverseOrder.java
+ojluni/src/test/java/util/Collections/ReverseOrder2.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/ReverseOrder2.java
+ojluni/src/test/java/util/Collections/Rotate.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/Rotate.java
+ojluni/src/test/java/util/Collections/RotateEmpty.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/RotateEmpty.java
+ojluni/src/test/java/util/Collections/Ser.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/Ser.java
+ojluni/src/test/java/util/Collections/SetFromMap.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/SetFromMap.java
+ojluni/src/test/java/util/Collections/SingletonIterator.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/SingletonIterator.java
+ojluni/src/test/java/util/Collections/Swap.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/Swap.java
+ojluni/src/test/java/util/Collections/SyncSubMutexes.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/SyncSubMutexes.java
+ojluni/src/test/java/util/Collections/T6433170.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/T6433170.java
+ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/UnmodifiableMapEntrySet.java
+ojluni/src/test/java/util/Collections/ViewSynch.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/ViewSynch.java
+ojluni/src/test/java/util/Collections/WrappedNull.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/WrappedNull.java
+ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/WrappedUnmodifiableCollections.java
+ojluni/src/test/java/util/Collections/Wrappers.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/Collections/Wrappers.java
 ojluni/src/test/java/util/DoubleStreamSums/CompensatedSums.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/DoubleStreamSums/CompensatedSums.java
 ojluni/src/test/java/util/DoubleSummaryStatistics/NegativeCompensation.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/DoubleSummaryStatistics/NegativeCompensation.java
 ojluni/src/test/java/util/HashMap/HashMapCloneLeak.java,jdk17u/jdk-17.0.6-ga,test/jdk/java/util/HashMap/HashMapCloneLeak.java
diff --git a/ojluni/src/test/java/util/Collections/AddAll.java b/ojluni/src/test/java/util/Collections/AddAll.java
new file mode 100644
index 0000000..99341d0
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/AddAll.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2003, 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     4822887
+ * @summary Basic test for Collections.addAll
+ * @author  Josh Bloch
+ * @key randomness
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+public class AddAll {
+    static final int N = 100;
+    public static void main(String[] args) {
+        test(new ArrayList<Integer>());
+        test(new LinkedList<Integer>());
+        test(new HashSet<Integer>());
+        test(new LinkedHashSet<Integer>());
+    }
+
+    private static Random rnd = new Random();
+
+    static void test(Collection<Integer> c) {
+        int x = 0;
+        for (int i = 0; i < N; i++) {
+            int rangeLen = rnd.nextInt(10);
+            if (Collections.addAll(c, range(x, x + rangeLen)) !=
+                (rangeLen != 0))
+                throw new RuntimeException("" + rangeLen);
+            x += rangeLen;
+        }
+        if (c instanceof List) {
+            if (!c.equals(Arrays.asList(range(0, x))))
+                throw new RuntimeException(x +": "+c);
+        } else {
+            if (!c.equals(new HashSet<Integer>(Arrays.asList(range(0, x)))))
+                throw new RuntimeException(x +": "+c);
+        }
+    }
+
+    private static Integer[] range(int from, int to) {
+        Integer[] result = new Integer[to - from];
+        for (int i = from, j=0; i < to; i++, j++)
+            result[j] = new Integer(i);
+        return result;
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/AsLifoQueue.java b/ojluni/src/test/java/util/Collections/AsLifoQueue.java
new file mode 100644
index 0000000..c573e32
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/AsLifoQueue.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2005, 2014, 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     6301085 6192552 6365601
+ * @summary Basic tests for asLifoQueue
+ * @author  Martin Buchholz
+ */
+
+import java.util.*;
+import java.util.concurrent.*;
+
+public class AsLifoQueue {
+
+    private static void realMain(String[] args) throws Throwable {
+        try {
+            Deque<String> deq = new ArrayDeque<String>();
+            check(deq.addAll(Arrays.asList("b", "a", "c")));
+            equal(deq.toString(), "[b, a, c]");
+            check(deq.add("d"));
+            equal(deq.toString(), "[b, a, c, d]");
+            Queue<String> q = Collections.asLifoQueue(deq);
+            check(q.add("e"));
+            equal(deq.toString(),"[e, b, a, c, d]");
+        } catch (Throwable t) { unexpected(t); }
+
+        // Inspired by an excellent bug report by Jason Mehrens
+        try {
+            final Queue<String> q =
+                Collections.asLifoQueue(new LinkedBlockingDeque<String>(3));
+            check(q.isEmpty()); equal(q.size(), 0);
+            check(q.add("a")); check(! q.isEmpty()); equal(q.size(), 1);
+            check(q.offer("b"));
+            check(q.add("c"));
+            equal(q.size(), 3);
+            check(! q.offer("d"));
+            equal(q.size(), 3);
+            THROWS(IllegalStateException.class, () -> q.add("d"));
+            equal(q.size(), 3);
+            equal(q.toString(), "[c, b, a]");
+            equal(q.peek(), "c");
+            equal(q.element(), "c");
+            equal(q.remove(), "c");
+            equal(q.poll(), "b");
+            equal(q.peek(), "a");
+            equal(q.remove(), "a");
+            THROWS(NoSuchElementException.class, () -> q.remove());
+            equal(q.poll(), null);
+            check(q.isEmpty());
+            equal(q.size(), 0);
+        } catch (Throwable t) { unexpected(t); }
+
+        THROWS(NullPointerException.class, () -> Collections.asLifoQueue(null));
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void check(boolean cond) {if (cond) pass(); else fail();}
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+    interface Fun {void f() throws Throwable;}
+    private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
+        for (Fun f : fs)
+            try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
+            catch (Throwable t) {
+                if (k.isAssignableFrom(t.getClass())) pass();
+                else unexpected(t);}}
+}
diff --git a/ojluni/src/test/java/util/Collections/BigBinarySearch.java b/ojluni/src/test/java/util/Collections/BigBinarySearch.java
new file mode 100644
index 0000000..b10081c
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/BigBinarySearch.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2006, 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 5045582
+ * @summary binarySearch of Collections larger than 1<<30
+ * @author Martin Buchholz
+ */
+
+import java.util.AbstractList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.RandomAccess;
+
+public class BigBinarySearch {
+
+    // Allows creation of very "big" collections without using too
+    // many real resources
+    static class SparseIntegerList
+        extends AbstractList<Integer>
+        implements RandomAccess
+    {
+        private Map<Integer,Integer> m = new HashMap<>();
+
+        public Integer get(int i) {
+            if (i < 0) throw new IndexOutOfBoundsException(""+i);
+            Integer v = m.get(i);
+            return (v == null) ? Integer.valueOf(0) : v;
+        }
+
+        public int size() {
+            return Collections.max(m.keySet()) + 1;
+        }
+
+        public Integer set(int i, Integer v) {
+            if (i < 0) throw new IndexOutOfBoundsException(""+i);
+            Integer ret = get(i);
+            if (v == 0)
+                m.remove(i);
+            else
+                m.put(i, v);
+            return ret;
+        }
+    }
+
+    /** Checks that binarySearch finds an element where we got it. */
+    private static void checkBinarySearch(List<Integer> l, int i) {
+        try { equal(i, Collections.binarySearch(l, l.get(i))); }
+        catch (Throwable t) { unexpected(t); }
+    }
+
+    /** Checks that binarySearch finds an element where we got it. */
+    private static void checkBinarySearch(List<Integer> l, int i,
+                                          Comparator<Integer> comparator) {
+        try { equal(i, Collections.binarySearch(l, l.get(i), comparator)); }
+        catch (Throwable t) { unexpected(t); }
+    }
+
+    private static void realMain(String[] args) throws Throwable {
+        final int n = (1<<30) + 47;
+
+        System.out.println("binarySearch(List<Integer>, Integer)");
+        List<Integer> big = new SparseIntegerList();
+        big.set(  0, -44);
+        big.set(  1, -43);
+        big.set(n-2,  43);
+        big.set(n-1,  44);
+        int[] ints = { 0, 1, n-2, n-1 };
+        Comparator<Integer> reverse = Collections.reverseOrder();
+        Comparator<Integer> natural = Collections.reverseOrder(reverse);
+
+        for (int i : ints) {
+            checkBinarySearch(big, i);
+            checkBinarySearch(big, i, null);
+            checkBinarySearch(big, i, natural);
+        }
+        for (int i : ints)
+            big.set(i, - big.get(i));
+        for (int i : ints)
+            checkBinarySearch(big, i, reverse);
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void check(boolean cond) {if (cond) pass(); else fail();}
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java b/ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java
new file mode 100644
index 0000000..62bf55f
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/BinarySearchNullComparator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001, 2004, 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 4528331 5006032
+ * @summary Test Collections.binarySearch() with a null comparator
+ */
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class BinarySearchNullComparator {
+    public static void main(String[] args) throws Exception {
+        List list = Arrays.asList(new String[] {"I", "Love", "You"});
+
+        int result = Collections.binarySearch(list, "You", null);
+        if (result != 2)
+            throw new Exception("Result: " + result);
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedIdentityMap.java b/ojluni/src/test/java/util/Collections/CheckedIdentityMap.java
new file mode 100644
index 0000000..d51f5b4
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedIdentityMap.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007, 2013, 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 6585904
+ * @run testng CheckedIdentityMap
+ * @summary Checked collections with underlying maps with identity comparisons
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import static java.util.Collections.checkedMap;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+
+public class CheckedIdentityMap {
+
+    @Test
+    public void testHashCode() {
+        Map<Integer, Integer> m1 = checkedMap(
+            new IdentityHashMap<Integer, Integer>(),
+            Integer.class, Integer.class);
+        Map<Integer, Integer> m2 = checkedMap(
+            new IdentityHashMap<Integer, Integer>(),
+            Integer.class, Integer.class);
+        // NB: these are unique instances. Compare vs. Integer.valueOf(1)
+        m1.put(new Integer(1), new Integer(1));
+        m2.put(new Integer(1), new Integer(1));
+
+        Map.Entry<Integer, Integer> e1 = m1.entrySet().iterator().next();
+        Map.Entry<Integer, Integer> e2 = m2.entrySet().iterator().next();
+
+        assertNotEquals(e1, e2);
+        assertEquals(e1.hashCode(), hashCode(e1));
+        assertEquals(e2.hashCode(), hashCode(e2));
+    }
+
+    static int hashCode(Map.Entry<?,?> e) {
+        return (System.identityHashCode(e.getKey()) ^
+                System.identityHashCode(e.getValue()));
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedListBash.java b/ojluni/src/test/java/util/Collections/CheckedListBash.java
new file mode 100644
index 0000000..b65504b
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedListBash.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2003, 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     4904067
+ * @summary Unit test for Collections.checkedList
+ * @author  Josh Bloch
+ * @key randomness
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Random;
+
+public class CheckedListBash {
+    static Random rnd = new Random();
+
+    public static void main(String[] args) {
+        int numItr = 100;
+        int listSize = 100;
+
+        for (int i=0; i<numItr; i++) {
+            List s1 = newList();
+            AddRandoms(s1, listSize);
+
+            List s2 = newList();
+            AddRandoms(s2, listSize);
+
+            List intersection = clone(s1); intersection.retainAll(s2);
+            List diff1 = clone(s1); diff1.removeAll(s2);
+            List diff2 = clone(s2); diff2.removeAll(s1);
+            List union = clone(s1); union.addAll(s2);
+
+            if (diff1.removeAll(diff2))
+                fail("List algebra identity 2 failed");
+            if (diff1.removeAll(intersection))
+                fail("List algebra identity 3 failed");
+            if (diff2.removeAll(diff1))
+                fail("List algebra identity 4 failed");
+            if (diff2.removeAll(intersection))
+                fail("List algebra identity 5 failed");
+            if (intersection.removeAll(diff1))
+                fail("List algebra identity 6 failed");
+            if (intersection.removeAll(diff1))
+                fail("List algebra identity 7 failed");
+
+            intersection.addAll(diff1); intersection.addAll(diff2);
+            if (!(intersection.containsAll(union) &&
+                  union.containsAll(intersection)))
+                fail("List algebra identity 1 failed");
+
+            Iterator e = union.iterator();
+            while (e.hasNext())
+                intersection.remove(e.next());
+            if (!intersection.isEmpty())
+                fail("Copy nonempty after deleting all elements.");
+
+            e = union.iterator();
+            while (e.hasNext()) {
+                Object o = e.next();
+                if (!union.contains(o))
+                    fail("List doesn't contain one of its elements.");
+                e.remove();
+            }
+            if (!union.isEmpty())
+                fail("List nonempty after deleting all elements.");
+
+            s1.clear();
+            if (s1.size() != 0)
+                fail("Clear didn't reduce size to zero.");
+
+            s1.addAll(0, s2);
+            if (!(s1.equals(s2) && s2.equals(s1)))
+                fail("addAll(int, Collection) doesn't work.");
+            // Reverse List
+            for (int j=0, n=s1.size(); j<n; j++)
+                s1.set(j, s1.set(n-j-1, s1.get(j)));
+            // Reverse it again
+            for (int j=0, n=s1.size(); j<n; j++)
+                s1.set(j, s1.set(n-j-1, s1.get(j)));
+            if (!(s1.equals(s2) && s2.equals(s1)))
+                fail("set(int, Object) doesn't work");
+        }
+
+        List s = newList();
+        for (int i=0; i<listSize; i++)
+            s.add(new Integer(i));
+        if (s.size() != listSize)
+            fail("Size of [0..n-1] != n");
+
+        List even = clone(s);
+        Iterator it = even.iterator();
+        while (it.hasNext())
+            if (((Integer)it.next()).intValue() % 2 == 1)
+                it.remove();
+        it = even.iterator();
+        while (it.hasNext())
+            if (((Integer)it.next()).intValue() % 2 == 1)
+                fail("Failed to remove all odd nubmers.");
+
+        List odd = clone(s);
+        for (int i=0; i<(listSize/2); i++)
+            odd.remove(i);
+        for (int i=0; i<(listSize/2); i++)
+            if (((Integer)odd.get(i)).intValue() % 2 != 1)
+                fail("Failed to remove all even nubmers.");
+
+        List all = clone(odd);
+        for (int i=0; i<(listSize/2); i++)
+            all.add(2*i, even.get(i));
+        if (!all.equals(s))
+            fail("Failed to reconstruct ints from odds and evens.");
+
+        all = clone(odd);
+        ListIterator itAll = all.listIterator(all.size());
+        ListIterator itEven = even.listIterator(even.size());
+        while (itEven.hasPrevious()) {
+            itAll.previous();
+            itAll.add(itEven.previous());
+            itAll.previous(); // ???
+        }
+        itAll = all.listIterator();
+        while (itAll.hasNext()) {
+            Integer i = (Integer)itAll.next();
+            itAll.set(new Integer(i.intValue()));
+        }
+        itAll = all.listIterator();
+        it = s.iterator();
+        while (it.hasNext())
+            if (it.next()==itAll.next())
+                fail("Iterator.set failed to change value.");
+        if (!all.equals(s))
+            fail("Failed to reconstruct ints with ListIterator.");
+
+        it = all.listIterator();
+        int i=0;
+        while (it.hasNext()) {
+            Object o = it.next();
+            if (all.indexOf(o) != all.lastIndexOf(o))
+                fail("Apparent duplicate detected.");
+            if (all.subList(i,   all.size()).indexOf(o) != 0 ||
+                all.subList(i+1, all.size()).indexOf(o) != -1)
+                fail("subList/indexOf is screwy.");
+            if (all.subList(0,i+1).lastIndexOf(o) != i)
+                fail("subList/lastIndexOf is screwy.");
+            i++;
+        }
+
+        List l = newList();
+        AddRandoms(l, listSize);
+        Integer[] ia = (Integer[]) l.toArray(new Integer[0]);
+        if (!l.equals(Arrays.asList(ia)))
+            fail("toArray(Object[]) is hosed (1)");
+        ia = new Integer[listSize];
+        Integer[] ib = (Integer[]) l.toArray(ia);
+        if (ia != ib || !l.equals(Arrays.asList(ia)))
+            fail("toArray(Object[]) is hosed (2)");
+        ia = new Integer[listSize+1];
+        ia[listSize] = new Integer(69);
+        ib = (Integer[]) l.toArray(ia);
+        if (ia != ib || ia[listSize] != null
+            || !l.equals(Arrays.asList(ia).subList(0, listSize)))
+            fail("toArray(Object[]) is hosed (3)");
+
+    }
+
+    // Done inefficiently so as to exercise toArray
+    static List clone(List s) {
+        List a = Arrays.asList(s.toArray());
+        if (s.hashCode() != a.hashCode())
+            fail("Incorrect hashCode computation.");
+
+        List clone = newList();
+        clone.addAll(a);
+        if (!s.equals(clone))
+            fail("List not equal to copy.");
+        if (!s.containsAll(clone))
+            fail("List does not contain copy.");
+        if (!clone.containsAll(s))
+            fail("Copy does not contain list.");
+
+        return clone;
+    }
+
+    static List newList() {
+        List s =  Collections.checkedList(new ArrayList(), Integer.class);
+        if (!s.isEmpty())
+            fail("New instance non empty.");
+        return s;
+    }
+
+    static void AddRandoms(List s, int n) {
+        for (int i = 0; i < n; i++) {
+            Integer e = rnd.nextInt(n);
+
+            int preSize = s.size();
+            if (!s.add(e))
+                fail("Add failed.");
+            int postSize = s.size();
+            if (postSize - preSize != 1)
+                fail("Add didn't increase size by 1.");
+        }
+    }
+
+    static void fail(String s) {
+        throw new RuntimeException(s);
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java b/ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java
new file mode 100644
index 0000000..19042db
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedListReplaceAll.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014, 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     8047795 8053938
+ * @summary Ensure that replaceAll operator cannot add bad elements
+ * @author  Mike Duigou
+ */
+
+import java.util.*;
+import java.util.function.UnaryOperator;
+
+public class CheckedListReplaceAll {
+    public static void main(String[] args) {
+        List unwrapped = Arrays.asList(new Object[]{1, 2, 3});
+        List<Object> wrapped = Collections.checkedList(unwrapped, Integer.class);
+
+        UnaryOperator evil = e -> (((int) e) % 2 != 0) ? e : "evil";
+
+        try {
+            wrapped.replaceAll(evil);
+            System.out.printf("Bwahaha! I have defeated you! %s\n", wrapped);
+            throw new RuntimeException("String added to checked List<Integer>");
+        } catch (ClassCastException thwarted) {
+            thwarted.printStackTrace(System.out);
+            System.out.println("Curses! Foiled again!");
+        }
+
+        unwrapped = Arrays.asList(new Object[]{});  // Empty list
+        wrapped = Collections.checkedList(unwrapped, Integer.class);
+        try {
+            wrapped.replaceAll((UnaryOperator)null);
+            System.out.printf("Bwahaha! I have defeated you! %s\n", wrapped);
+            throw new RuntimeException("NPE not thrown when passed a null operator");
+        } catch (NullPointerException thwarted) {
+            thwarted.printStackTrace(System.out);
+            System.out.println("Curses! Foiled again!");
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedMapBash.java b/ojluni/src/test/java/util/Collections/CheckedMapBash.java
new file mode 100644
index 0000000..240ce64
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedMapBash.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2003, 2013, 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     4904067 5023830 7129185 8072015
+ * @summary Unit test for Collections.checkedMap
+ * @author  Josh Bloch
+ * @run testng CheckedMapBash
+ * @key randomness
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.fail;
+
+public class CheckedMapBash {
+    static final Random rnd = new Random();
+    static final Object nil = new Integer(0);
+    static final int numItr = 100;
+    static final int mapSize = 100;
+
+    @Test(dataProvider = "Bash.Supplier<Map<Integer,Integer>>")
+    public static void testCheckedMap(String description, Supplier<Map<Integer,Integer>> supplier) {
+        Map m = supplier.get();
+        Object head = nil;
+
+        for (int j=0; j<mapSize; j++) {
+            Object newHead;
+            do {
+                newHead = new Integer(rnd.nextInt());
+            } while (m.containsKey(newHead) || newHead.equals(nil));
+            m.put(newHead, head);
+            head = newHead;
+        }
+        if (m.size() != mapSize)
+            fail("Size not as expected.");
+
+        {
+            HashMap hm = new HashMap(m);
+            if (! (hm.hashCode() == m.hashCode() &&
+                   hm.entrySet().hashCode() == m.entrySet().hashCode() &&
+                   hm.keySet().hashCode() == m.keySet().hashCode()))
+                fail("Incorrect hashCode computation.");
+
+            if (! (hm.equals(m) &&
+                   hm.entrySet().equals(m.entrySet()) &&
+                   hm.keySet().equals(m.keySet()) &&
+                   m.equals(hm) &&
+                   m.entrySet().equals(hm.entrySet()) &&
+                   m.keySet().equals(hm.keySet())))
+                fail("Incorrect equals computation.");
+        }
+
+        Map m2 = supplier.get(); m2.putAll(m);
+        m2.values().removeAll(m.keySet());
+        if (m2.size()!= 1 || !m2.containsValue(nil))
+            fail("Collection views test failed.");
+
+        int j=0;
+        while (head != nil) {
+            if (!m.containsKey(head))
+                fail("Linked list doesn't contain a link.");
+            Object newHead = m.get(head);
+            if (newHead == null)
+                fail("Could not retrieve a link.");
+            m.remove(head);
+            head = newHead;
+            j++;
+        }
+        if (!m.isEmpty())
+            fail("Map nonempty after removing all links.");
+        if (j != mapSize)
+            fail("Linked list size not as expected.");
+    }
+
+    @Test(dataProvider = "Supplier<Map<Integer,Integer>>")
+    public static void testCheckedMap2(String description, Supplier<Map<Integer,Integer>> supplier) {
+        Map m = supplier.get();
+        for (int i=0; i<mapSize; i++)
+            if (m.put(new Integer(i), new Integer(2*i)) != null)
+                fail("put returns a non-null value erroneously.");
+        for (int i=0; i<2*mapSize; i++)
+            if (m.containsValue(new Integer(i)) != (i%2==0))
+                fail("contains value "+i);
+        if (m.put(nil, nil) == null)
+            fail("put returns a null value erroneously.");
+        Map m2 = supplier.get(); m2.putAll(m);
+        if (!m.equals(m2))
+            fail("Clone not equal to original. (1)");
+        if (!m2.equals(m))
+            fail("Clone not equal to original. (2)");
+        Set s = m.entrySet(), s2 = m2.entrySet();
+        if (!s.equals(s2))
+            fail("Clone not equal to original. (3)");
+        if (!s2.equals(s))
+            fail("Clone not equal to original. (4)");
+        if (!s.containsAll(s2))
+            fail("Original doesn't contain clone!");
+        if (!s2.containsAll(s))
+            fail("Clone doesn't contain original!");
+
+        s2.removeAll(s);
+        if (!m2.isEmpty())
+            fail("entrySet().removeAll failed.");
+
+        m2.putAll(m);
+        m2.clear();
+        if (!m2.isEmpty())
+            fail("clear failed.");
+
+        Iterator i = m.entrySet().iterator();
+        while (i.hasNext()) {
+            i.next();
+            i.remove();
+        }
+        if (!m.isEmpty())
+            fail("Iterator.remove() failed");
+    }
+
+    @DataProvider(name = "Bash.Supplier<Map<Integer,Integer>>", parallel = true)
+    public static Iterator<Object[]> bashNavigableMapProvider() {
+        ArrayList<Object[]> iters = new ArrayList<>(makeCheckedMaps());
+        iters.ensureCapacity(numItr * iters.size());
+        for (int each=1; each < numItr; each++) {
+            iters.addAll(makeCheckedMaps());
+        }
+        return iters.iterator();
+    }
+
+    @DataProvider(name = "Supplier<Map<Integer,Integer>>", parallel = true)
+    public static Iterator<Object[]> navigableMapProvider() {
+        return makeCheckedMaps().iterator();
+    }
+
+    public static Collection<Object[]> makeCheckedMaps() {
+        Object[][] params = {
+            {"Collections.checkedMap(HashMap)",
+             (Supplier) () -> Collections.checkedMap(new HashMap(), Integer.class, Integer.class)},
+            {"Collections.checkedMap(TreeMap(reverseOrder))",
+             (Supplier) () -> Collections.checkedMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)},
+            {"Collections.checkedMap(TreeMap.descendingMap())",
+             (Supplier) () -> Collections.checkedMap(new TreeMap().descendingMap(), Integer.class, Integer.class)},
+            {"Collections.checkedNavigableMap(TreeMap)",
+             (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(), Integer.class, Integer.class)},
+            {"Collections.checkedNavigableMap(TreeMap(reverseOrder))",
+             (Supplier) () -> Collections.checkedNavigableMap(new TreeMap(Collections.reverseOrder()), Integer.class, Integer.class)},
+            {"Collections.checkedNavigableMap(TreeMap.descendingMap())",
+             (Supplier) () -> Collections.checkedNavigableMap(new TreeMap().descendingMap(), Integer.class, Integer.class)},
+        };
+        return Arrays.asList(params);
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java b/ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java
new file mode 100644
index 0000000..05c4da3
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedMapReplaceAll.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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     8047795
+ * @summary Ensure that replaceAll operator cannot add bad elements
+ * @author  Mike Duigou
+ */
+
+import java.util.*;
+import java.util.function.BiFunction;
+
+public class CheckedMapReplaceAll {
+    public static void main(String[] args) {
+        Map<Integer,Double> unwrapped = new HashMap<>();
+        unwrapped.put(1, 1.0);
+        unwrapped.put(2, 2.0);
+        unwrapped.put(3, 3.0);
+
+        Map<Integer,Double> wrapped = Collections.checkedMap(unwrapped, Integer.class, Double.class);
+
+        BiFunction evil = (k, v) -> (((int)k) % 2 != 0) ? v : "evil";
+
+        try {
+            wrapped.replaceAll(evil);
+            System.out.printf("Bwahaha! I have defeated you! %s\n", wrapped);
+            throw new RuntimeException("String added to checked Map<Integer,Double>");
+        } catch (ClassCastException thwarted) {
+            thwarted.printStackTrace(System.out);
+            System.out.println("Curses! Foiled again!");
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedNull.java b/ojluni/src/test/java/util/Collections/CheckedNull.java
new file mode 100644
index 0000000..c298cab
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedNull.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 6409434
+ * @summary Test behavior of nulls in checked collections
+ */
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.TreeSet;
+
+import static java.util.Collections.singleton;
+import static java.util.Collections.singletonMap;
+
+@SuppressWarnings({"unchecked","serial"})
+public class CheckedNull {
+
+    void test(String[] args) throws Throwable {
+        testCollection(Collections.checkedCollection(
+                           new ArrayList<String>(), String.class));
+        testCollection(Collections.checkedList(
+                           new ArrayList<String>(), String.class));
+        testCollection(Collections.checkedSet(
+                           new HashSet<String>(), String.class));
+
+        final Comparator nullLow = new Comparator() {
+                public int compare(Object x, Object y) {
+                    return x == y ?  0 :
+                        x == null ? -1 :
+                        y == null ?  1 :
+                        ((Comparable)x).compareTo(y); }};
+        testCollection(Collections.checkedSortedSet(
+                           new TreeSet<String>(nullLow), String.class));
+
+        testMap(Collections.checkedMap(
+                    new HashMap<String, String>(),
+                    String.class, String.class));
+    }
+
+    ClassCastException cce(F f) {
+        try { f.f(); fail(); return null; }
+        catch (ClassCastException cce) { pass(); return cce; }
+        catch (Throwable t) { unexpected(t); return null; }
+    }
+
+    void equalCCE(F ... fs) {
+        String detailMessage = null;
+        for (F f : fs)
+            if (detailMessage == null)
+                detailMessage = cce(f).getMessage();
+            else
+                equal(detailMessage, cce(f).getMessage());
+    }
+
+    void add(Collection c, Object o) {
+        int s = c.size();
+        check(! c.contains(o));
+        check(c.add(o));
+        check(c.contains(o));
+        equal(c.size(), s+1);
+        check(c.remove(o));
+        check(! c.contains(o));
+        check(c.addAll(singleton(o)));
+        check(c.contains(o));
+        equal(c.size(), s+1);
+        check(c.remove(o));
+        equal(c.size(), s);
+    }
+
+    void testCollection(final Collection c) {
+        try {
+            check(c.isEmpty());
+            add(c, null);
+            add(c, "foo");
+
+            check(c.add("bar"));
+            add(c, null);
+            add(c, "foo");
+
+            equalCCE(
+                new F(){void f(){ c.add(1); }},
+                new F(){void f(){ c.addAll(singleton(1)); }});
+
+        } catch (Throwable t) { unexpected(t); }
+    }
+
+    void put(Map m, Object k, Object v) {
+        int s = m.size();
+        check(! m.containsKey(k));
+        check(! m.containsValue(v));
+        equal(null, m.put(k, v));
+        check(m.containsKey(k));
+        check(m.containsValue(v));
+        equal(m.size(), s+1);
+        equal(v, m.remove(k));
+        check(! m.containsKey(k));
+        check(! m.containsValue(v));
+        m.putAll(singletonMap(k,v));
+        check(m.containsKey(k));
+        check(m.containsValue(v));
+        equal(m.size(), s+1);
+        equal(v,m.remove(k));
+        equal(m.size(), s);
+    }
+
+    void testMap(final Map m) {
+        try {
+            check(m.isEmpty());
+
+            put(m, "foo", null);
+            put(m, null, "foo");
+            put(m, null, null);
+            put(m, "foo", "bar");
+
+            m.put("a", "b");
+
+            put(m, "foo", null);
+            put(m, null, "foo");
+            put(m, null, null);
+            put(m, "foo", "bar");
+
+            equalCCE(
+                new F(){void f(){ m.put(1, "foo"); }},
+                new F(){void f(){ m.putAll(singletonMap(1, "foo")); }});
+
+            final Collection cheater = new ArrayList() {
+                    public boolean contains(Object o) {
+                        if (o instanceof Map.Entry)
+                            ((Map.Entry)o).setValue(1);
+                        return false; }};
+
+            equalCCE(
+                new F(){void f(){ m.put("foo", 1); }},
+                new F(){void f(){ m.putAll(singletonMap("foo", 1)); }},
+                new F(){void f(){
+                    ((Map.Entry)m.entrySet().iterator().next()).setValue(1); }},
+                new F(){void f(){
+                    m.entrySet().removeAll(cheater);}},
+                new F(){void f(){
+                    m.entrySet().retainAll(cheater);}});
+
+            equalCCE(
+                new F(){void f(){ m.put(3, 1); }},
+                new F(){void f(){ m.putAll(singletonMap(3, 1)); }});
+
+            equal(m.size(), 1);
+            equal(m.keySet(), singleton("a"));
+            equal(m.entrySet(),
+                  singleton(new AbstractMap.SimpleImmutableEntry("a","b")));
+
+        } catch (Throwable t) { unexpected(t); }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    volatile int passed = 0, failed = 0;
+    void pass() {passed++;}
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+    void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    void check(boolean cond) {if (cond) pass(); else fail();}
+    void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        new CheckedNull().instanceMain(args);}
+    void instanceMain(String[] args) throws Throwable {
+        try {test(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+    abstract class F {abstract void f() throws Throwable;}
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedQueue.java b/ojluni/src/test/java/util/Collections/CheckedQueue.java
new file mode 100644
index 0000000..fb47e2e
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedQueue.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2011, 2014, 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 5020931 8048207
+ * @summary Unit test for Collections.checkedQueue
+ * @run testng CheckedQueue
+ */
+
+import java.util.Collections;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.fail;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+
+
+public class CheckedQueue {
+
+    /**
+     * This test adds items to a queue.
+     */
+    @Test
+    public void testAdd() {
+        int arrayLength = 10;
+        Queue<String> abq = Collections.checkedQueue(new ArrayBlockingQueue<>(arrayLength), String.class);
+
+        for (int i = 0; i < arrayLength; i++) {
+            abq.add(Integer.toString(i));
+        }
+
+        try {
+            abq.add("full");
+        } catch (IllegalStateException full) {
+
+        }
+    }
+
+    /**
+     * This test tests the CheckedQueue.add method.  It creates a queue of
+     * {@code String}s gets the checked queue, and attempt to add an Integer to
+     * the checked queue.
+     */
+    @Test(expectedExceptions = ClassCastException.class)
+    public void testAddFail1() {
+        int arrayLength = 10;
+        ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(arrayLength + 1);
+
+        for (int i = 0; i < arrayLength; i++) {
+            abq.add(Integer.toString(i));
+        }
+
+        Queue q = Collections.checkedQueue(abq, String.class);
+        q.add(0);
+    }
+
+    /**
+     * This test tests the CheckedQueue.add method.  It creates a queue of one
+     * {@code String}, gets the checked queue, and attempt to add an Integer to
+     * the checked queue.
+     */
+    @Test(expectedExceptions = ClassCastException.class)
+    public void testAddFail2() {
+        ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(1);
+        Queue q = Collections.checkedQueue(abq, String.class);
+
+        q.add(0);
+    }
+
+    /**
+     * This test tests the Collections.checkedQueue method call for nulls in
+     * each and both of the parameters.
+     */
+    @Test
+    public void testArgs() {
+        ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(1);
+        Queue q;
+
+        try {
+            q = Collections.checkedQueue(null, String.class);
+            fail( "should throw NullPointerException.");
+        } catch(NullPointerException npe) {
+            // Do nothing
+        }
+
+        try {
+            q = Collections.checkedQueue(abq, null);
+            fail( "should throw NullPointerException.");
+        } catch(Exception e) {
+            // Do nothing
+        }
+
+        try {
+            q = Collections.checkedQueue(null, null);
+            fail( "should throw NullPointerException.");
+        } catch(Exception e) {
+            // Do nothing
+        }
+    }
+
+    /**
+     * This test tests the CheckedQueue.offer method.
+     */
+    @Test
+    public void testOffer() {
+        ArrayBlockingQueue<String> abq = new ArrayBlockingQueue(1);
+        Queue q = Collections.checkedQueue(abq, String.class);
+
+        try {
+            q.offer(null);
+            fail("should throw NullPointerException.");
+        } catch (NullPointerException npe) {
+            // Do nothing
+        }
+
+        try {
+            q.offer(0);
+            fail("should throw ClassCastException.");
+        } catch (ClassCastException cce) {
+            // Do nothing
+        }
+
+        assertTrue(q.offer("0"), "queue should have room");
+
+        // no room at the inn!
+        assertFalse(q.offer("1"), "queue should be full");
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/CheckedSetBash.java b/ojluni/src/test/java/util/Collections/CheckedSetBash.java
new file mode 100644
index 0000000..16dfb11
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/CheckedSetBash.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2003, 2013, 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     4904067 7129185
+ * @summary Unit test for Collections.checkedSet
+ * @author  Josh Bloch
+ * @run testng CheckedSetBash
+ * @key randomness
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+public class CheckedSetBash {
+    static final int numItr = 100;
+    static final int setSize = 100;
+    static final Random rnd = new Random();
+
+    @Test(dataProvider = "Supplier<Set<Integer>>")
+    public static void testCheckedSet(String description, Supplier<Set<Integer>> supplier) {
+
+        Set<Integer> s1 = supplier.get();
+        assertTrue(s1.isEmpty());
+
+        AddRandoms(s1, setSize);
+
+        Set<Integer> s2 = supplier.get();
+
+        assertTrue(s2.isEmpty());
+
+        AddRandoms(s2, setSize);
+
+        Set<Integer> intersection = clone(s1, supplier);
+        intersection.retainAll(s2);
+        Set<Integer> diff1 = clone(s1, supplier); diff1.removeAll(s2);
+        Set<Integer> diff2 = clone(s2, supplier); diff2.removeAll(s1);
+        Set<Integer> union = clone(s1, supplier); union.addAll(s2);
+
+        if (diff1.removeAll(diff2))
+            fail("Set algebra identity 2 failed");
+        if (diff1.removeAll(intersection))
+            fail("Set algebra identity 3 failed");
+        if (diff2.removeAll(diff1))
+            fail("Set algebra identity 4 failed");
+        if (diff2.removeAll(intersection))
+            fail("Set algebra identity 5 failed");
+        if (intersection.removeAll(diff1))
+            fail("Set algebra identity 6 failed");
+        if (intersection.removeAll(diff1))
+            fail("Set algebra identity 7 failed");
+
+        intersection.addAll(diff1); intersection.addAll(diff2);
+        if (!intersection.equals(union))
+            fail("Set algebra identity 1 failed");
+
+        if (new HashSet(union).hashCode() != union.hashCode())
+            fail("Incorrect hashCode computation.");
+
+        Iterator e = union.iterator();
+        while (e.hasNext())
+            if (!intersection.remove(e.next()))
+                fail("Couldn't remove element from copy.");
+        if (!intersection.isEmpty())
+            fail("Copy nonempty after deleting all elements.");
+
+        e = union.iterator();
+        while (e.hasNext()) {
+            Object o = e.next();
+            if (!union.contains(o))
+                fail("Set doesn't contain one of its elements.");
+            e.remove();
+            if (union.contains(o))
+                fail("Set contains element after deletion.");
+        }
+        if (!union.isEmpty())
+            fail("Set nonempty after deleting all elements.");
+
+        s1.clear();
+        if (!s1.isEmpty())
+            fail("Set nonempty after clear.");
+    }
+
+    // Done inefficiently so as to exercise toArray
+    static <T> Set<T> clone(Set<T> s, Supplier<Set<T>> supplier) {
+        Set<T> clone = supplier.get();
+        List<T> arrayList = Arrays.asList((T[]) s.toArray());
+        clone.addAll(arrayList);
+        if (!s.equals(clone))
+            fail("Set not equal to copy.");
+        if (!s.containsAll(clone))
+            fail("Set does not contain copy.");
+        if (!clone.containsAll(s))
+            fail("Copy does not contain set.");
+        return clone;
+    }
+
+    static void AddRandoms(Set s, int n) {
+        for (int i = 0; i < n; i++) {
+            Integer e = rnd.nextInt(n);
+
+            int preSize = s.size();
+            boolean prePresent = s.contains(e);
+            boolean added = s.add(e);
+            if (!s.contains(e))
+                fail("Element not present after addition.");
+            if (added == prePresent)
+                fail("added == alreadyPresent");
+            int postSize = s.size();
+            if (added && preSize == postSize)
+                fail("Add returned true, but size didn't change.");
+            if (!added && preSize != postSize)
+                fail("Add returned false, but size changed.");
+        }
+    }
+
+    @DataProvider(name = "Supplier<Set<Integer>>", parallel = true)
+    public static Iterator<Object[]> navigableSetsProvider() {
+        ArrayList<Object[]> iters = new ArrayList<>(makeCheckedSets());
+        iters.ensureCapacity(numItr * iters.size());
+        for (int each=1; each < numItr; each++) {
+            iters.addAll(makeCheckedSets());
+        }
+        return iters.iterator();
+    }
+
+    public static Collection<Object[]> makeCheckedSets() {
+        Object[][] params = {
+            {"Collections.checkedSet(HashSet)",
+             (Supplier) () -> Collections.checkedSet(new HashSet(), Integer.class)},
+            {"Collections.checkedSet(TreeSet(reverseOrder))",
+             (Supplier) () -> Collections.checkedSet(new TreeSet(Collections.reverseOrder()), Integer.class)},
+            {"Collections.checkedSet(TreeSet.descendingSet())",
+             (Supplier) () -> Collections.checkedSet(new TreeSet().descendingSet(), Integer.class)},
+            {"Collections.checkedNavigableSet(TreeSet)",
+             (Supplier) () -> Collections.checkedNavigableSet(new TreeSet(), Integer.class)},
+            {"Collections.checkedNavigableSet(TreeSet(reverseOrder))",
+             (Supplier) () -> Collections.checkedNavigableSet(new TreeSet(Collections.reverseOrder()), Integer.class)},
+            {"Collections.checkedNavigableSet(TreeSet.descendingSet())",
+             (Supplier) () -> Collections.checkedNavigableSet(new TreeSet().descendingSet(), Integer.class)},
+        };
+        return Arrays.asList(params);
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java b/ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java
new file mode 100644
index 0000000..65bd0b9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/DelegatingIteratorForEachRemaining.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2018 Google Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run junit DelegatingIteratorForEachRemaining
+ */
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+public class DelegatingIteratorForEachRemaining {
+
+    static abstract class ForwardingIterator<E> implements Iterator<E> {
+        private final Iterator<E> delegate;
+
+        protected ForwardingIterator(Iterator<E> delegate) {
+            this.delegate = Objects.requireNonNull(delegate);
+        }
+
+        @Override public boolean hasNext() { return delegate.hasNext(); }
+        @Override public E next() { return delegate.next(); }
+        @Override public void remove() { delegate.remove(); }
+        @Override public void forEachRemaining(Consumer<? super E> action) {
+            delegate.forEachRemaining(action);
+        }
+    }
+
+    static final class ThrowingIterator<E> extends ForwardingIterator<E> {
+        public ThrowingIterator(Iterator<E> delegate) {
+            super(delegate);
+        }
+
+        @Override
+        public void forEachRemaining(Consumer<? super E> action) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    static abstract class ForwardingSet<E> implements Set<E> {
+        private final Set<E> delegate;
+
+        protected ForwardingSet(Set<E> delegate) {
+            this.delegate = Objects.requireNonNull(delegate);
+        }
+
+        @Override public int size() { return delegate.size(); }
+        @Override public boolean isEmpty() { return delegate.isEmpty(); }
+        @Override public boolean contains(Object o) { return delegate.contains(o); }
+        @Override public Iterator<E> iterator() { return delegate.iterator(); }
+        @Override public Object[] toArray() { return delegate.toArray(); }
+        @Override public <T> T[] toArray( T[] ts) { return delegate.toArray(ts); }
+        @Override public boolean add(E e) { return delegate.add(e); }
+        @Override public boolean remove(Object o) { return delegate.remove(o); }
+        @Override public boolean containsAll( Collection<?> c) { return delegate.containsAll(c); }
+        @Override public boolean addAll( Collection<? extends E> c) { return delegate.addAll(c); }
+        @Override public boolean retainAll( Collection<?> c) { return delegate.retainAll(c); }
+        @Override public boolean removeAll( Collection<?> c) { return delegate.removeAll(c); }
+        @Override public void clear() { delegate.clear(); }
+        @Override public boolean equals(Object o) { return delegate.equals(o); }
+        @Override public int hashCode() { return delegate.hashCode(); }
+        @Override public Spliterator<E> spliterator() { return delegate.spliterator(); }
+        @Override public boolean removeIf(Predicate<? super E> filter) { return delegate.removeIf(filter); }
+        @Override public Stream<E> stream() { return delegate.stream(); }
+        @Override public Stream<E> parallelStream() { return delegate.parallelStream(); }
+        @Override public void forEach(Consumer<? super E> action) { delegate.forEach(action); }
+    }
+
+    static class ThrowingSet<E> extends ForwardingSet<E> {
+        public ThrowingSet(Set<E> delegate) {
+            super(delegate);
+        }
+
+        @Override
+        public ThrowingIterator<E> iterator() {
+            return new ThrowingIterator<>(super.iterator());
+        }
+    }
+
+    static abstract class ForwardingMap<K, V> implements Map<K, V> {
+        private final Map<K, V> delegate;
+
+        public ForwardingMap(Map<K, V> delegate) {
+            this.delegate = delegate;
+        }
+
+        @Override public int size() { return delegate.size(); }
+        @Override public boolean isEmpty() { return delegate.isEmpty(); }
+        @Override public boolean containsKey(Object o) { return delegate.containsKey(o); }
+        @Override public boolean containsValue(Object o) { return delegate.containsValue(o); }
+        @Override public V get(Object o) { return delegate.get(o); }
+        @Override public V put(K k, V v) { return delegate.put(k, v); }
+        @Override public V remove(Object o) { return delegate.remove(o); }
+        @Override public void putAll(Map<? extends K, ? extends V> map) { delegate.putAll(map); }
+        @Override public void clear() { delegate.clear(); }
+        @Override public Set<K> keySet() { return delegate.keySet(); }
+        @Override public Collection<V> values() { return delegate.values(); }
+        @Override public Set<Entry<K, V>> entrySet() { return delegate.entrySet(); }
+        @Override public boolean equals(Object o) { return delegate.equals(o); }
+        @Override public int hashCode() { return delegate.hashCode(); }
+        @Override public V getOrDefault(Object key, V defaultValue) { return delegate.getOrDefault(key, defaultValue); }
+        @Override public void forEach(BiConsumer<? super K, ? super V> action) { delegate.forEach(action); }
+        @Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { delegate.replaceAll(function); }
+        @Override public V putIfAbsent(K key, V value) { return delegate.putIfAbsent(key, value); }
+        @Override public boolean remove(Object key, Object value) { return delegate.remove(key, value); }
+        @Override public boolean replace(K key, V oldValue, V newValue) { return delegate.replace(key, oldValue, newValue); }
+        @Override public V replace(K key, V value) { return delegate.replace(key, value); }
+        @Override public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { return delegate.computeIfAbsent(key, mappingFunction); }
+        @Override public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { return delegate.computeIfPresent(key, remappingFunction); }
+        @Override public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { return delegate.compute(key, remappingFunction); }
+        @Override public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { return delegate.merge(key, value, remappingFunction); }
+    }
+
+    static class ThrowingMap<K, V> extends ForwardingMap<K, V> {
+        public ThrowingMap(Map<K, V> delegate) {
+            super(delegate);
+        }
+
+        @Override
+        public ThrowingSet<Entry<K, V>> entrySet() {
+            return new ThrowingSet<>(super.entrySet());
+        }
+
+        @Override
+        public Set<K> keySet() {
+            return new ThrowingSet(super.keySet());
+        }
+    }
+
+    static<E> void assertThrowingIterator(Iterator<E> iterator) {
+        try {
+            iterator.forEachRemaining((entry) -> {});
+            Assert.fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    private static Map<String, Object> map() {
+        Map<String, Object> map = new HashMap<>();
+        map.put("name", "Bill");
+        map.put("age", 23);
+        return new ThrowingMap<>(map);
+    }
+
+    @Test public void testUnwrapped() {
+        assertThrowingIterator(map().entrySet().iterator());
+        assertThrowingIterator(map().keySet().iterator());
+    }
+
+    @Test public void test_unmodifiableMap_entrySet() {
+        assertThrowingIterator(Collections.unmodifiableMap(map()).entrySet().iterator());
+    }
+
+    @Test public void test_checkedMap_entrySet() {
+        assertThrowingIterator(Collections.checkedMap(map(), String.class, Object.class).entrySet().iterator());
+    }
+
+    @Test public void test_entrySet_checkedSet() {
+        Set<Map.Entry<String, Object>> entrySet = map().entrySet();
+        Class clazz = entrySet.iterator().next().getClass();
+        assertThrowingIterator(Collections.checkedSet(entrySet, clazz).iterator());
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/Disjoint.java b/ojluni/src/test/java/util/Collections/Disjoint.java
new file mode 100644
index 0000000..13bdac8
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Disjoint.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2003, 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     4339792
+ * @summary Basic test for Collections.disjoint
+ * @author  Josh Bloch
+ * @key randomness
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+
+public class Disjoint {
+    static final int N = 20;
+
+    public static void main(String[] args) {
+        // Make an array of lists each of which shares a single element
+        // with its "neighbors," and no elements with other lists in the array
+        Random rnd = new Random();
+        List[] lists = new List[N];
+        int x = 0;
+        for (int i = 0; i < N; i++) {
+            int size = rnd.nextInt(10) + 2;
+            List<Integer> list = new ArrayList<>(size);
+            for (int j = 1; j < size; j++)
+                list.add(x++);
+            list.add(x);
+            Collections.shuffle(list);
+
+            lists[i] = list;
+        }
+
+        for (int i = 0; i < N; i++) {
+            for (int j = 0; j < N; j++) {
+                boolean disjoint = (Math.abs(i - j) > 1);
+                List<Integer> a = (List<Integer>) lists[i];
+                List<Integer> b = (List<Integer>) lists[j];
+
+                if (Collections.disjoint(a, b) != disjoint)
+                    throw new RuntimeException("A: " + i + ", " + j);
+                if (Collections.disjoint(new HashSet<Integer>(a), b)
+                    != disjoint)
+                    throw new RuntimeException("B: " + i + ", " + j);
+                if (Collections.disjoint(new HashSet<Integer>(a),
+                                         new HashSet<Integer>(b)) != disjoint)
+                    throw new RuntimeException("C: " + i + ", " + j);
+            }
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java b/ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java
new file mode 100644
index 0000000..7f8009f
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EmptyCollectionSerialization.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2002, 2013, 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     4684279 7129185
+ * @summary Empty utility collections should be singletons
+ * @author  Josh Bloch
+ * @run testng EmptyCollectionSerialization
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.fail;
+
+public class EmptyCollectionSerialization {
+    private static Object patheticDeepCopy(Object o) throws Exception {
+        // Serialize
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+        oos.writeObject(o);
+        byte[] serializedForm = bos.toByteArray();
+
+        // Deserialize
+        InputStream is = new ByteArrayInputStream(serializedForm);
+        ObjectInputStream ois = new ObjectInputStream(is);
+        return ois.readObject();
+    }
+
+    @Test(dataProvider="SerializableSingletons")
+    public static void serializableSingletons(String description, Supplier<Object> o) {
+        try {
+            Object singleton = o.get();
+            assertSame(o.get(), singleton, description + ": broken Supplier not returning singleton");
+            Object copy = patheticDeepCopy(singleton);
+            assertSame(copy, singleton, description + ": " +
+                copy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(copy)) +
+                " is not the singleton " +
+                singleton.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(singleton)));
+        } catch (Exception all) {
+            fail(description + ": Unexpected Exception", all);
+        }
+    }
+
+    @DataProvider(name = "SerializableSingletons", parallel = true)
+    public static Iterator<Object[]> navigableMapProvider() {
+        return makeSingletons().iterator();
+    }
+
+    public static Collection<Object[]> makeSingletons() {
+        Object[][] params = {
+            {"Collections.EMPTY_LIST",
+             (Supplier) () -> Collections.EMPTY_LIST},
+            {"Collections.EMPTY_MAP",
+             (Supplier) () -> Collections.EMPTY_MAP},
+            {"Collections.EMPTY_SET",
+             (Supplier) () -> Collections.EMPTY_SET},
+            {"Collections.emptyList()",
+             (Supplier) () -> Collections.emptyList()},
+            {"Collections.emptyMap()",
+             (Supplier) () -> Collections.emptyMap()},
+            {"Collections.emptySet()",
+             (Supplier) () -> Collections.emptySet()},
+            {"Collections.emptySortedSet()",
+             (Supplier) () -> Collections.emptySortedSet()},
+            {"Collections.emptySortedMap()",
+             (Supplier) () -> Collections.emptySortedMap()},
+            {"Collections.emptyNavigableSet()",
+             (Supplier) () -> Collections.emptyNavigableSet()},
+            {"Collections.emptyNavigableMap()",
+             (Supplier) () -> Collections.emptyNavigableMap()},
+        };
+        return Arrays.asList(params);
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/EmptyIterator.java b/ojluni/src/test/java/util/Collections/EmptyIterator.java
new file mode 100644
index 0000000..5f3a2b2
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EmptyIterator.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2007, 2014, 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 5017904 6356890 8004928
+ * @summary Test empty iterators, enumerations, and collections
+ */
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.concurrent.SynchronousQueue;
+
+import static java.util.Collections.emptyEnumeration;
+import static java.util.Collections.emptyIterator;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyListIterator;
+import static java.util.Collections.emptyMap;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.nCopies;
+import static java.util.Collections.unmodifiableMap;
+
+public class EmptyIterator {
+
+    void test(String[] args) throws Throwable {
+        testEmptyCollection(emptyList());
+        testEmptyCollection(emptySet());
+        testEmptyCollection(new SynchronousQueue<Object>());
+        testEmptyMap(emptyMap());
+
+        Hashtable<?,?> emptyTable = new Hashtable<>();
+        testEmptyEnumeration(emptyTable.keys());
+        testEmptyEnumeration(emptyTable.elements());
+        testEmptyIterator(emptyTable.keySet().iterator());
+        testEmptyIterator(emptyTable.values().iterator());
+        testEmptyIterator(emptyTable.entrySet().iterator());
+
+        final Enumeration<EmptyIterator> finalEmptyTyped = emptyEnumeration();
+        testEmptyEnumeration(finalEmptyTyped);
+
+        final Enumeration<?> finalEmptyAbstract = emptyEnumeration();
+        testEmptyEnumeration(finalEmptyAbstract);
+
+        testEmptyIterator(emptyIterator());
+    }
+
+    void testEmptyEnumeration(final Enumeration<?> e) {
+        check(e == emptyEnumeration());
+        check(!e.hasMoreElements());
+        THROWS(NoSuchElementException.class,
+               new F(){void f(){ e.nextElement(); }});
+    }
+
+    void testEmptyIterator(final Iterator<?> it) {
+        check(it == emptyIterator());
+        check(! it.hasNext());
+        THROWS(NoSuchElementException.class,
+               new F(){void f(){ it.next(); }});
+        THROWS(IllegalStateException.class,
+               new F(){void f(){ it.remove(); }});
+    }
+
+    void testEmptyMap(Map<?,?> m) {
+        check(m == emptyMap());
+        check(m.entrySet().iterator() ==
+              Collections.<Map.Entry<?,?>>emptyIterator());
+        check(m.values().iterator() == emptyIterator());
+        check(m.keySet().iterator() == emptyIterator());
+        equal(m, unmodifiableMap(m));
+
+        testEmptyCollection(m.keySet());
+        testEmptyCollection(m.entrySet());
+        testEmptyCollection(m.values());
+    }
+
+    void testToArray(final Collection<?> c) {
+        Object[] a = c.toArray();
+        equal(a.length, 0);
+        equal(a.getClass().getComponentType(), Object.class);
+        THROWS(NullPointerException.class,
+               new F(){void f(){ c.toArray((Object[])null); }});
+
+        {
+            String[] t = new String[0];
+            check(c.toArray(t) == t);
+        }
+
+        {
+            String[] t = nCopies(10, "").toArray(new String[0]);
+            check(c.toArray(t) == t);
+            check(t[0] == null);
+            for (int i=1; i<t.length; i++)
+                check(t[i] == "");
+        }
+    }
+
+    void testEmptyCollection(final Collection<?> c) {
+        testEmptyIterator(c.iterator());
+
+        check(c.iterator() == emptyIterator());
+        if (c instanceof List)
+            check(((List<?>)c).listIterator() == emptyListIterator());
+
+        testToArray(c);
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    volatile int passed = 0, failed = 0;
+    void pass() {passed++;}
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+    void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    void check(boolean cond) {if (cond) pass(); else fail();}
+    void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        new EmptyIterator().instanceMain(args);}
+    void instanceMain(String[] args) throws Throwable {
+        try {test(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+    abstract class F {abstract void f() throws Throwable;}
+    void THROWS(Class<? extends Throwable> k, F... fs) {
+        for (F f : fs)
+            try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+            catch (Throwable t) {
+                if (k.isAssignableFrom(t.getClass())) pass();
+                else unexpected(t);}}
+}
diff --git a/ojluni/src/test/java/util/Collections/EmptyNavigableMap.java b/ojluni/src/test/java/util/Collections/EmptyNavigableMap.java
new file mode 100644
index 0000000..fe0cec5
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EmptyNavigableMap.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2011, 2017, 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 4533691 7129185
+ * @summary Unit test for Collections.emptyNavigableMap
+ * @run testng EmptyNavigableMap
+ */
+
+import org.testng.Assert;
+import org.testng.Assert.ThrowingRunnable;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableMap;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+public class EmptyNavigableMap {
+
+    public static <T> void assertInstance(T actual, Class<? extends T> expected) {
+        assertInstance(actual, expected, null);
+    }
+
+    public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) {
+        assertTrue(expected.isInstance(actual), ((null != message) ? message : "")
+            + " " + (actual == null ? "<null>" : actual.getClass().getSimpleName()) + " != " + expected.getSimpleName() + ". ");
+    }
+
+    public static <T extends Throwable> void assertEmptyNavigableMap(Object obj) {
+        assertInstance(obj, NavigableMap.class);
+        assertTrue(((NavigableMap)obj).isEmpty() && (((NavigableMap)obj).size() == 0));
+    }
+
+    public static <T extends Throwable> void assertEmptyNavigableMap(Object obj, String message) {
+        assertInstance(obj, NavigableMap.class, message);
+        assertTrue(((NavigableMap)obj).isEmpty() && (((NavigableMap)obj).size() == 0),
+            ((null != message) ? message : "") + " Not empty. ");
+    }
+
+    private <T extends Throwable> void assertThrows(Class<T> throwableClass,
+                                                    ThrowingRunnable runnable,
+                                                    String message) {
+        try {
+            Assert.assertThrows(throwableClass, runnable);
+        } catch (AssertionError e) {
+            throw new AssertionError(String.format("%s%n%s",
+                    ((null != message) ? message : ""), e.getMessage()), e);
+        }
+    }
+
+    private void assertThrowsCCE(ThrowingRunnable r, String s) {
+        assertThrows(ClassCastException.class, r, s);
+    }
+
+    private void assertThrowsNPE(ThrowingRunnable r, String s) {
+        assertThrows(NullPointerException.class, r, s);
+    }
+
+    private void assertThrowsIAE(ThrowingRunnable r, String s) {
+        assertThrows(IllegalArgumentException.class, r, s);
+    }
+
+    public static final boolean isDescending(SortedMap<?,?> set) {
+        if (null == set.comparator()) {
+            // natural order
+            return false;
+        }
+
+        if (Collections.reverseOrder() == set.comparator()) {
+            // reverse natural order.
+            return true;
+        }
+
+        if (set.comparator().equals(Collections.reverseOrder(Collections.reverseOrder(set.comparator())))) {
+            // it's a Collections.reverseOrder(Comparator).
+            return true;
+        }
+
+        throw new IllegalStateException("can't determine ordering for " + set);
+    }
+
+    /**
+     * Tests that the comparator is {@code null}.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testComparatorIsNull(String description, NavigableMap<?,?> navigableMap) {
+        Comparator comparator = navigableMap.comparator();
+
+        assertTrue(comparator == null || comparator == Collections.reverseOrder(), description + ": Comparator (" + comparator + ") is not null.");
+    }
+
+    /**
+     * Tests that contains requires Comparable
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testContainsRequiresComparable(String description, NavigableMap<?,?> navigableMap) {
+        assertThrowsCCE(
+            () -> navigableMap.containsKey(new Object()),
+            description + ": Comparable should be required");
+    }
+
+    /**
+     * Tests that the contains method returns {@code false}.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testContains(String description, NavigableMap<?,?> navigableMap) {
+        assertFalse(navigableMap.containsKey(new Integer(1)),
+            description + ": Should not contain any elements.");
+        assertFalse(navigableMap.containsValue(new Integer(1)),
+            description + ": Should not contain any elements.");
+    }
+
+    /**
+     * Tests that the containsAll method returns {@code false}.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testContainsAll(String description, NavigableMap<?,?> navigableMap) {
+        TreeMap treeMap = new TreeMap();
+        treeMap.put("1", 1);
+        treeMap.put("2", 2);
+        treeMap.put("3", 3);
+
+        assertFalse(navigableMap.equals(treeMap), "Should not contain any elements.");
+    }
+
+    /**
+     * Tests that the iterator is empty.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testEmptyIterator(String description, NavigableMap<?,?> navigableMap) {
+        assertFalse(navigableMap.keySet().iterator().hasNext(), "The iterator is not empty.");
+        assertFalse(navigableMap.values().iterator().hasNext(), "The iterator is not empty.");
+        assertFalse(navigableMap.entrySet().iterator().hasNext(), "The iterator is not empty.");
+    }
+
+    /**
+     * Tests that the set is empty.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testIsEmpty(String description, NavigableMap<?,?> navigableMap) {
+        assertTrue(navigableMap.isEmpty(), "The set is not empty.");
+    }
+
+    /**
+     * Tests the headMap() method.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testHeadMap(String description, NavigableMap navigableMap) {
+        assertThrowsNPE(
+            () -> { NavigableMap ss = navigableMap.headMap(null, false); },
+            description + ": Must throw NullPointerException for null element");
+
+        assertThrowsCCE(
+            () -> { NavigableMap ss = navigableMap.headMap(new Object(), true); },
+            description + ": Must throw ClassCastException for non-Comparable element");
+
+        NavigableMap ss = navigableMap.headMap("1", false);
+
+        assertEmptyNavigableMap(ss, description + ": Returned value is not empty navigable set.");
+    }
+
+    /**
+     * Tests that the size is 0.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testSizeIsZero(String description, NavigableMap<?,?> navigableMap) {
+        assertTrue(0 == navigableMap.size(), "The size of the set is not 0.");
+    }
+
+    /**
+     * Tests the subMap() method.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testSubMap(String description, NavigableMap navigableMap) {
+        assertThrowsNPE(
+            () -> {
+                SortedMap ss = navigableMap.subMap(null, BigInteger.TEN);
+            },
+            description + ": Must throw NullPointerException for null element");
+
+        assertThrowsNPE(
+            () -> {
+                SortedMap ss = navigableMap.subMap(BigInteger.ZERO, null);
+            },
+            description + ": Must throw NullPointerException for null element");
+
+        assertThrowsNPE(
+            () -> {
+                SortedMap ss = navigableMap.subMap(null, null);
+            },
+            description + ": Must throw NullPointerException for null element");
+
+        Object obj1 = new Object();
+        Object obj2 = new Object();
+
+        assertThrowsCCE(
+            () -> {
+                SortedMap ss = navigableMap.subMap(obj1, BigInteger.TEN);
+            },
+            description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+        assertThrowsCCE(
+            () -> {
+                SortedMap ss = navigableMap.subMap(BigInteger.ZERO, obj2);
+            },
+            description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+        assertThrowsCCE(
+            () -> {
+                SortedMap ss = navigableMap.subMap(obj1, obj2);
+            },
+            description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+        // minimal range
+        navigableMap.subMap(BigInteger.ZERO, false, BigInteger.ZERO, false);
+        navigableMap.subMap(BigInteger.ZERO, false, BigInteger.ZERO, true);
+        navigableMap.subMap(BigInteger.ZERO, true, BigInteger.ZERO, false);
+        navigableMap.subMap(BigInteger.ZERO, true, BigInteger.ZERO, true);
+
+        Object first = isDescending(navigableMap) ? BigInteger.TEN : BigInteger.ZERO;
+        Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO;
+
+            assertThrowsIAE(
+                () -> navigableMap.subMap(last, true, first, false),
+                description + ": Must throw IllegalArgumentException when fromElement is not less than toElement.");
+
+        navigableMap.subMap(first, true, last, false);
+    }
+
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testSubMapRanges(String description, NavigableMap navigableMap) {
+        Object first = isDescending(navigableMap) ? BigInteger.TEN : BigInteger.ZERO;
+        Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO;
+
+        NavigableMap subMap = navigableMap.subMap(first, true, last, true);
+
+        // same subset
+        subMap.subMap(first, true, last, true);
+
+        // slightly smaller
+        NavigableMap ns = subMap.subMap(first, false, last, false);
+        // slight expansion
+        assertThrowsIAE(
+            () -> ns.subMap(first, true, last, true),
+            description + ": Expansion should not be allowed");
+
+        // much smaller
+        subMap.subMap(first, false, BigInteger.ONE, false);
+    }
+
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testheadMapRanges(String description, NavigableMap navigableMap) {
+        NavigableMap subMap = navigableMap.headMap(BigInteger.ONE, true);
+
+        // same subset
+        subMap.headMap(BigInteger.ONE, true);
+
+        // slightly smaller
+        NavigableMap ns = subMap.headMap(BigInteger.ONE, false);
+
+        // slight expansion
+        assertThrowsIAE(
+            () -> ns.headMap(BigInteger.ONE, true),
+            description + ": Expansion should not be allowed");
+
+        // much smaller
+        subMap.headMap(isDescending(subMap) ? BigInteger.TEN : BigInteger.ZERO, true);
+    }
+
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testTailMapRanges(String description, NavigableMap navigableMap) {
+        NavigableMap subMap = navigableMap.tailMap(BigInteger.ONE, true);
+
+        // same subset
+        subMap.tailMap(BigInteger.ONE, true);
+
+        // slightly smaller
+        NavigableMap ns = subMap.tailMap(BigInteger.ONE, false);
+
+        // slight expansion
+        assertThrowsIAE(
+            () -> ns.tailMap(BigInteger.ONE, true),
+            description + ": Expansion should not be allowed");
+
+        // much smaller
+        subMap.tailMap(isDescending(subMap) ? BigInteger.ZERO : BigInteger.TEN, false);
+    }
+
+    /**
+     * Tests the tailMap() method.
+     */
+    @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class)
+    public void testTailMap(String description, NavigableMap navigableMap) {
+        assertThrowsNPE(
+            () -> navigableMap.tailMap(null),
+            description + ": Must throw NullPointerException for null element");
+
+        assertThrowsCCE(
+            () -> navigableMap.tailMap(new Object()),
+            description);
+
+        NavigableMap ss = navigableMap.tailMap("1", true);
+
+        assertEmptyNavigableMap(ss, description + ": Returned value is not empty navigable set.");
+    }
+
+    @DataProvider(name = "NavigableMap<?,?>", parallel = true)
+    public static Iterator<Object[]> navigableMapsProvider() {
+        return makeNavigableMaps().iterator();
+    }
+
+    public static Collection<Object[]> makeNavigableMaps() {
+        return Arrays.asList(
+            new Object[]{"UnmodifiableNavigableMap(TreeMap)", Collections.unmodifiableNavigableMap(new TreeMap())},
+            new Object[]{"UnmodifiableNavigableMap(TreeMap.descendingMap()", Collections.unmodifiableNavigableMap(new TreeMap().descendingMap())},
+            new Object[]{"UnmodifiableNavigableMap(TreeMap.descendingMap().descendingMap()", Collections.unmodifiableNavigableMap(new TreeMap().descendingMap().descendingMap())},
+            new Object[]{"emptyNavigableMap()", Collections.emptyNavigableMap()},
+            new Object[]{"emptyNavigableMap().descendingMap()", Collections.emptyNavigableMap().descendingMap()},
+            new Object[]{"emptyNavigableMap().descendingMap().descendingMap()", Collections.emptyNavigableMap().descendingMap().descendingMap()}
+        );
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/EmptyNavigableSet.java b/ojluni/src/test/java/util/Collections/EmptyNavigableSet.java
new file mode 100644
index 0000000..52cdd9c
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EmptyNavigableSet.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2011, 2017, 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 4533691 7129185
+ * @summary Unit test for Collections.emptyNavigableSet
+ * @run testng EmptyNavigableSet
+ */
+
+import org.testng.Assert;
+import org.testng.Assert.ThrowingRunnable;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+public class EmptyNavigableSet {
+
+    public static <T> void assertInstance(T actual, Class<? extends T> expected) {
+        assertInstance(actual, expected, null);
+    }
+
+    public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) {
+        assertTrue(expected.isInstance(actual), ((null != message) ? message : "")
+            + " " + (actual == null ? "<null>" : actual.getClass().getSimpleName()) + " != " + expected.getSimpleName() + ". ");
+    }
+
+    public static <T extends Throwable> void assertEmptyNavigableSet(Object obj) {
+        assertInstance(obj, NavigableSet.class);
+        assertTrue(((NavigableSet)obj).isEmpty() && (((NavigableSet)obj).size() == 0));
+    }
+
+    public static <T extends Throwable> void assertEmptyNavigableSet(Object obj, String message) {
+        assertInstance(obj, NavigableSet.class, message);
+        assertTrue(((NavigableSet)obj).isEmpty() && (((NavigableSet)obj).size() == 0),
+            ((null != message) ? message : "") + " Not empty. ");
+    }
+
+    private <T extends Throwable> void assertThrows(Class<T> throwableClass,
+                                                    ThrowingRunnable runnable,
+                                                    String message) {
+        try {
+            Assert.assertThrows(throwableClass, runnable);
+        } catch (AssertionError e) {
+            throw new AssertionError(String.format("%s%n%s",
+                    ((null != message) ? message : ""), e.getMessage()), e);
+        }
+    }
+
+    private void assertThrowsCCE(ThrowingRunnable r, String s) {
+        assertThrows(ClassCastException.class, r, s);
+    }
+
+    private void assertThrowsNPE(ThrowingRunnable r, String s) {
+        assertThrows(NullPointerException.class, r, s);
+    }
+
+    private void assertThrowsIAE(ThrowingRunnable r, String s) {
+        assertThrows(IllegalArgumentException.class, r, s);
+    }
+
+    private void assertThrowsNSEE(ThrowingRunnable r, String s) {
+        assertThrows(NoSuchElementException.class, r, s);
+    }
+
+    public static final boolean isDescending(SortedSet<?> set) {
+        if (null == set.comparator()) {
+            // natural order
+            return false;
+        }
+
+        if (Collections.reverseOrder() == set.comparator()) {
+            // reverse natural order.
+            return true;
+        }
+
+        if (set.comparator().equals(Collections.reverseOrder(Collections.reverseOrder(set.comparator())))) {
+            // it's a Collections.reverseOrder(Comparator).
+            return true;
+        }
+
+        throw new IllegalStateException("can't determine ordering for " + set);
+    }
+
+    /**
+     * Tests that the comparator is {@code null}.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testComparatorIsNull(String description, NavigableSet<?> navigableSet) {
+        Comparator comparator = navigableSet.comparator();
+
+        assertTrue(comparator == null || comparator == Collections.reverseOrder(), description + ": Comparator (" + comparator + ") is not null.");
+    }
+
+    /**
+     * Tests that contains requires Comparable
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testContainsRequiresComparable(String description, NavigableSet<?> navigableSet) {
+        assertThrowsCCE(
+            () -> navigableSet.contains(new Object()),
+            description + ": Comparable should be required");
+    }
+
+    /**
+     * Tests that the contains method returns {@code false}.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testContains(String description, NavigableSet<?> navigableSet) {
+        assertFalse(navigableSet.contains(new Integer(1)),
+            description + ": Should not contain any elements.");
+    }
+
+    /**
+     * Tests that the containsAll method returns {@code false}.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testContainsAll(String description, NavigableSet<?> navigableSet) {
+        TreeSet treeSet = new TreeSet();
+        treeSet.add("1");
+        treeSet.add("2");
+        treeSet.add("3");
+
+        assertFalse(navigableSet.containsAll(treeSet), "Should not contain any elements.");
+    }
+
+    /**
+     * Tests that the iterator is empty.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testEmptyIterator(String description, NavigableSet<?> navigableSet) {
+        assertFalse(navigableSet.iterator().hasNext(), "The iterator is not empty.");
+    }
+
+    /**
+     * Tests that the set is empty.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testIsEmpty(String description, NavigableSet<?> navigableSet) {
+        assertTrue(navigableSet.isEmpty(), "The set is not empty.");
+    }
+
+    /**
+     * Tests that the first() method throws NoSuchElementException
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testFirst(String description, NavigableSet<?> navigableSet) {
+        assertThrowsNSEE(navigableSet::first, description);
+    }
+
+    /**
+     * Tests the headSet() method.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testHeadSet(String description, NavigableSet navigableSet) {
+        assertThrowsNPE(
+            () -> { NavigableSet ns = navigableSet.headSet(null, false); },
+            description + ": Must throw NullPointerException for null element");
+
+        assertThrowsCCE(
+            () -> { NavigableSet ns = navigableSet.headSet(new Object(), true); },
+            description + ": Must throw ClassCastException for non-Comparable element");
+
+        NavigableSet ns = navigableSet.headSet("1", false);
+
+        assertEmptyNavigableSet(ns, description + ": Returned value is not empty navigable set.");
+    }
+
+    /**
+     * Tests that the last() method throws NoSuchElementException
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testLast(String description, NavigableSet<?> navigableSet) {
+        assertThrowsNSEE(navigableSet::last, description);
+    }
+
+    /**
+     * Tests that the size is 0.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testSizeIsZero(String description, NavigableSet<?> navigableSet) {
+        assertTrue(0 == navigableSet.size(), "The size of the set is not 0.");
+    }
+
+    /**
+     * Tests the subSet() method.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testSubSet(String description, NavigableSet navigableSet) {
+        assertThrowsNPE(
+            () -> {
+                SortedSet ss = navigableSet.subSet(null, BigInteger.TEN);
+            },
+            description + ": Must throw NullPointerException for null element");
+
+        assertThrowsNPE(
+            () -> {
+                SortedSet ss = navigableSet.subSet(BigInteger.ZERO, null);
+            },
+            description + ": Must throw NullPointerException for null element");
+
+        assertThrowsNPE(
+            () -> {
+                SortedSet ss = navigableSet.subSet(null, null);
+            },
+            description + ": Must throw NullPointerException for null element");
+
+        Object obj1 = new Object();
+        Object obj2 = new Object();
+
+        assertThrowsCCE(
+            () -> {
+                SortedSet ss = navigableSet.subSet(obj1, BigInteger.TEN);
+            },
+            description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+        assertThrowsCCE(
+            () -> {
+                SortedSet ss = navigableSet.subSet(BigInteger.ZERO, obj2);
+            },
+            description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+        assertThrowsCCE(
+            () -> {
+                SortedSet ss = navigableSet.subSet(obj1, obj2);
+            },
+            description + ": Must throw ClassCastException for parameter which is not Comparable.");
+
+        // minimal range
+        navigableSet.subSet(BigInteger.ZERO, false, BigInteger.ZERO, false);
+        navigableSet.subSet(BigInteger.ZERO, false, BigInteger.ZERO, true);
+        navigableSet.subSet(BigInteger.ZERO, true, BigInteger.ZERO, false);
+        navigableSet.subSet(BigInteger.ZERO, true, BigInteger.ZERO, true);
+
+        Object first = isDescending(navigableSet) ? BigInteger.TEN : BigInteger.ZERO;
+        Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO;
+
+            assertThrowsIAE(
+                () -> navigableSet.subSet(last, true, first, false),
+                description
+                + ": Must throw IllegalArgumentException when fromElement is not less than toElement.");
+
+        navigableSet.subSet(first, true, last, false);
+    }
+
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testSubSetRanges(String description, NavigableSet navigableSet) {
+        Object first = isDescending(navigableSet) ? BigInteger.TEN : BigInteger.ZERO;
+        Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO;
+
+        NavigableSet subSet = navigableSet.subSet(first, true, last, true);
+
+        // same subset
+        subSet.subSet(first, true, last, true);
+
+        // slightly smaller
+        NavigableSet ns = subSet.subSet(first, false, last, false);
+        // slight expansion
+        assertThrowsIAE(
+            () -> ns.subSet(first, true, last, true),
+            description + ": Expansion should not be allowed");
+
+        // much smaller
+        subSet.subSet(first, false, BigInteger.ONE, false);
+    }
+
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testheadSetRanges(String description, NavigableSet navigableSet) {
+        NavigableSet subSet = navigableSet.headSet(BigInteger.ONE, true);
+
+        // same subset
+        subSet.headSet(BigInteger.ONE, true);
+
+        // slightly smaller
+        NavigableSet ns = subSet.headSet(BigInteger.ONE, false);
+
+        // slight expansion
+        assertThrowsIAE(
+            () -> ns.headSet(BigInteger.ONE, true),
+            description + ": Expansion should not be allowed");
+
+        // much smaller
+        subSet.headSet(isDescending(subSet) ? BigInteger.TEN : BigInteger.ZERO, true);
+    }
+
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testTailSetRanges(String description, NavigableSet navigableSet) {
+        NavigableSet subSet = navigableSet.tailSet(BigInteger.ONE, true);
+
+        // same subset
+        subSet.tailSet(BigInteger.ONE, true);
+
+        // slightly smaller
+        NavigableSet ns = subSet.tailSet(BigInteger.ONE, false);
+
+        // slight expansion
+        assertThrowsIAE(
+            () -> ns.tailSet(BigInteger.ONE, true),
+            description + ": Expansion should not be allowed");
+
+        // much smaller
+        subSet.tailSet(isDescending(subSet) ? BigInteger.ZERO : BigInteger.TEN, false);
+    }
+
+    /**
+     * Tests the tailSet() method.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testTailSet(String description, NavigableSet navigableSet) {
+        assertThrowsNPE(
+            () -> navigableSet.tailSet(null),
+            description + ": Must throw NullPointerException for null element");
+
+        assertThrowsCCE(
+            () -> navigableSet.tailSet(new Object()),
+            description);
+
+        NavigableSet ss = navigableSet.tailSet("1", true);
+
+        assertEmptyNavigableSet(ss, description + ": Returned value is not empty navigable set.");
+    }
+
+    /**
+     * Tests that the array has a size of 0.
+     */
+    @Test(dataProvider = "NavigableSet<?>", dataProviderClass = EmptyNavigableSet.class)
+    public void testToArray(String description, NavigableSet<?> navigableSet) {
+        Object[] emptyNavigableSetArray = navigableSet.toArray();
+
+        assertTrue(emptyNavigableSetArray.length == 0, "Returned non-empty Array.");
+
+        emptyNavigableSetArray = new Object[20];
+
+        Object[] result = navigableSet.toArray(emptyNavigableSetArray);
+
+        assertSame(emptyNavigableSetArray, result);
+
+        assertNull(result[0]);
+    }
+
+    @DataProvider(name = "NavigableSet<?>", parallel = true)
+    public static Iterator<Object[]> navigableSetsProvider() {
+        return makeNavigableSets().iterator();
+    }
+
+    public static Collection<Object[]> makeNavigableSets() {
+        return Arrays.asList(
+            new Object[]{"UnmodifiableNavigableSet(TreeSet)", Collections.unmodifiableNavigableSet(new TreeSet())},
+            new Object[]{"UnmodifiableNavigableSet(TreeSet.descendingSet()", Collections.unmodifiableNavigableSet(new TreeSet().descendingSet())},
+            new Object[]{"UnmodifiableNavigableSet(TreeSet.descendingSet().descendingSet()", Collections.unmodifiableNavigableSet(new TreeSet().descendingSet().descendingSet())},
+            new Object[]{"emptyNavigableSet()", Collections.emptyNavigableSet()},
+            new Object[]{"emptyNavigableSet().descendingSet()", Collections.emptyNavigableSet().descendingSet()},
+            new Object[]{"emptyNavigableSet().descendingSet().descendingSet()", Collections.emptyNavigableSet().descendingSet().descendingSet()}
+        );
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/Enum.java b/ojluni/src/test/java/util/Collections/Enum.java
new file mode 100644
index 0000000..432d226
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Enum.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2000, 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 4323074
+ * @summary Basic test for new Enumeration -> List converter
+ */
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Vector;
+
+public class Enum {
+    public static void main(String[] args) throws Exception {
+        int[] sizes = {0, 10, 100};
+        for (int i=0; i<sizes.length; i++) {
+            Vector v = new Vector();
+            int size = sizes[i];
+            for (int j=0; j<size; j++)
+                v.add(new Integer(j));
+            List l = Collections.list(v.elements());
+            if (!l.equals(v))
+                throw new Exception("Copy failed: "+size);
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/EnumerationAsIterator.java b/ojluni/src/test/java/util/Collections/EnumerationAsIterator.java
new file mode 100644
index 0000000..4901c40
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EnumerationAsIterator.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2015, 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 8072726
+ * @summary Tests for Enumeration-to-Iterator conversion.
+ * @run testng EnumerationAsIterator
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
+
+import static org.testng.Assert.*;
+
+@Test
+public class EnumerationAsIterator {
+    static Object[] of(String description, Supplier<Enumeration<?>> s, Collection<?> exp) {
+        return new Object[]{description, s, exp};
+    }
+
+    static Object[] of(String description, Collection<?> c, Collection<?> exp) {
+        return of(description, () -> Collections.enumeration(c), exp);
+    }
+
+    /**
+     * A wrapper Enumeration that doesn't override the
+     * default method on Enumeration.
+     */
+    static <T> Enumeration<T> wrapInDefault(Enumeration<T> e) {
+        return new Enumeration<>() {
+            @Override
+            public boolean hasMoreElements() {
+                return e.hasMoreElements();
+            }
+
+            @Override
+            public T nextElement() {
+                return e.nextElement();
+            }
+        };
+    }
+
+    @DataProvider
+    public static Iterator<Object[]> unmodifiable() {
+        return Arrays.asList(
+            of("Default-wrapped ArrayList",
+               () -> wrapInDefault(
+                   Collections.enumeration(new ArrayList<>(Arrays.asList("a")))),
+               Arrays.asList("a")),
+
+            of("Unmodifiable ArrayList",
+               Collections.unmodifiableList(new ArrayList<>(Arrays.asList("a"))),
+               Arrays.asList("a")),
+
+            of("Modifiable ArrayList",
+               new ArrayList<>(Arrays.asList("a")),
+               Arrays.asList("a"))
+        ).iterator();
+    }
+
+    @DataProvider
+    public static Iterator<Object[]> others() {
+        return Arrays.asList(
+            of("Default Collections.emptyEnumeration()",
+               () -> wrapInDefault(Collections.emptyEnumeration()),
+               Collections.emptyList()),
+
+            of("Collections.emptyEnumeration()",
+               Collections::emptyEnumeration,
+               Collections.emptyList()),
+
+            of("Collections.emptyList()",
+               Collections.emptyList(),
+               Collections.emptyList()),
+
+            of("Collections.singletonList()",
+               Collections.singletonList("a"),
+               Collections.singletonList("a")),
+
+            of("Arrays.asList(...)",
+               Arrays.asList("a", "b", "c"),
+               Arrays.asList("a", "b", "c"))
+        ).iterator();
+    }
+
+    @DataProvider
+    public static Iterator<Object[]> all() {
+        List<Object[]> all = new ArrayList<>();
+        unmodifiable().forEachRemaining(all::add);
+        others().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @Test(dataProvider = "all")
+    public void consumeByNext(String description, Supplier<Enumeration<?>> s, Collection<?> exp) {
+        Iterator<?> i = s.get().asIterator();
+        int count = 0;
+        while (i.hasNext()) {
+            assertTrue(i.hasNext());
+
+            i.next();
+            count++;
+        }
+        assertEquals(count, exp.size());
+
+        assertFalse(i.hasNext());
+
+        try {
+            i.next();
+            fail();
+        } catch (NoSuchElementException e) {
+        }
+    }
+
+    @Test(dataProvider = "all")
+    public void consumeByForEachRemaining(String description,
+                                          Supplier<Enumeration<?>> s,
+                                          Collection<?> exp) {
+        Iterator<?> i = s.get().asIterator();
+        AtomicInteger ai = new AtomicInteger();
+        i.forEachRemaining(e -> ai.getAndIncrement());
+        assertEquals(ai.get(), exp.size());
+        i.forEachRemaining(e -> ai.getAndIncrement());
+        assertEquals(ai.get(), exp.size());
+
+        assertFalse(i.hasNext());
+
+        try {
+            i.next();
+            fail();
+        } catch (NoSuchElementException e) {
+        }
+    }
+
+    @Test(dataProvider = "all")
+    public void consumeByNextThenForEachRemaining(String description,
+                                                  Supplier<Enumeration<?>> s,
+                                                  Collection<?> exp) {
+        Iterator<?> i = s.get().asIterator();
+        AtomicInteger ai = new AtomicInteger();
+        if (i.hasNext()) {
+            i.next();
+            ai.getAndIncrement();
+        }
+        i.forEachRemaining(e -> ai.getAndIncrement());
+        assertEquals(ai.get(), exp.size());
+        i.forEachRemaining(e -> ai.getAndIncrement());
+        assertEquals(ai.get(), exp.size());
+
+        assertFalse(i.hasNext());
+
+        try {
+            i.next();
+            fail();
+        } catch (NoSuchElementException e) {
+        }
+    }
+
+    @Test(dataProvider = "all")
+    public void contents(String description, Supplier<Enumeration<?>> s, Collection<?> exp) {
+        assertEquals(copy(s.get()), exp);
+    }
+
+    private List<?> copy(Enumeration<?> input) {
+        List<Object> output = new ArrayList<>();
+        input.asIterator().forEachRemaining(output::add);
+        return output;
+    }
+
+    @Test(dataProvider = "unmodifiable",
+          expectedExceptions=UnsupportedOperationException.class)
+    public void removeThrowsAfterAdvancingE(String description,
+                                            Supplier<Enumeration<?>> s,
+                                            Collection<?> exp) {
+        Enumeration<?> e = s.get();
+        e.nextElement();
+        e.asIterator().remove();
+    }
+
+    @Test(dataProvider = "unmodifiable",
+          expectedExceptions=UnsupportedOperationException.class)
+    public void removeThrowsAfterAdvancingI(String description,
+                                            Supplier<Enumeration<?>> s,
+                                            Collection<?> exp) {
+        Iterator<?> i = s.get().asIterator();
+        i.next();
+        i.remove();
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/EqualsTest.java b/ojluni/src/test/java/util/Collections/EqualsTest.java
new file mode 100644
index 0000000..2c76751
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/EqualsTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 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 7144488
+ * @summary Infinite recursion for some equals tests in Collections
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class EqualsTest {
+    public static void main(String[] args) {
+        boolean test;
+
+        /* synchronizedList test */
+        List list = Collections.synchronizedList(new ArrayList());
+        list.add(list);
+        test = list.equals(list);
+        assertTrue(test);
+        list.remove(list);
+
+        /* synchronizedSet test */
+        Set s = Collections.synchronizedSet(new HashSet());
+        s.add(s);
+        test = s.equals(s);
+        assertTrue(test);
+
+        /* synchronizedMap test */
+        Map m =  Collections.synchronizedMap(new HashMap());
+        test = m.equals(m);
+        assertTrue(test);
+
+    }
+
+    private static void assertTrue(boolean b) {
+        if (!b)
+            throw new RuntimeException("assertion failed");
+    }
+}
+
diff --git a/ojluni/src/test/java/util/Collections/FindSubList.java b/ojluni/src/test/java/util/Collections/FindSubList.java
new file mode 100644
index 0000000..31bfdc7
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/FindSubList.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2000, 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 4323074
+ * @summary Basic test for Collections.indexOfSubList/lastIndexOfSubList
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+
+public class FindSubList {
+    public static void main(String[] args) throws Exception {
+        int N = 500;
+        List source = new ArrayList(3 * N);
+        List[] target = new List[N+1];
+        int[] index = new int[N+1];
+        for (int i=0; i<=N; i++) {
+            List t = new ArrayList();
+            String s = Integer.toString(i, 2);
+            for (int j=0, len = s.length(); j<len; j++)
+                t.add(s.charAt(j)=='1' ? "1" : "0");
+            target[i] = t;
+            if (i == N) {
+                index[i] = -1;
+            } else {
+                index[i] = source.size();
+                source.addAll(t);
+                source.add("*");
+            }
+        }
+
+        List[] src = {
+            source,
+            new LinkedList(source),
+            new Vector(source),
+            Arrays.asList(source.toArray())
+        };
+        for (int j=0; j<src.length; j++) {
+            List s = src[j];
+
+            for (int i=0; i<=N; i++) {
+                int idx = Collections.indexOfSubList(s, target[i]);
+                if (idx != index[i])
+                    throw new Exception(s.getClass()+" indexOfSubList: " + i +
+                                        "is " + idx + ", should be "+index[i]);
+            }
+
+            if (Collections.indexOfSubList(s,Collections.nCopies(2*s.size(),
+                                                                 "0")) != -1)
+               throw new Exception(s.getClass()+" indexOfSubList: big target");
+
+        }
+
+        Collections.reverse(source);
+        int srcSize = source.size();
+        for (int i=0; i<=N; i++) {
+            Collections.reverse(target[i]);
+            if (i != N)
+                index[i] = srcSize - index[i] - target[i].size();
+        }
+        List[] src2 = {
+            source,
+            new LinkedList(source),
+            new Vector(source),
+            Arrays.asList(source.toArray())
+        };
+        for (int j=0; j<src2.length; j++) {
+            List s = src2[j];
+
+            for (int i=0; i<=N; i++) {
+                int idx = Collections.lastIndexOfSubList(s, target[i]);
+                if (idx != index[i])
+                    throw new Exception(s.getClass()+" lastIdexOfSubList: "+i +
+                                        "is " + idx + ", should be "+index[i]);
+            }
+            if (Collections.indexOfSubList(s,Collections.nCopies(2*s.size(),
+                                                                 "0")) != -1)
+              throw new Exception(s.getClass()+" lastIndexOfSubList: big tgt");
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/Frequency.java b/ojluni/src/test/java/util/Collections/Frequency.java
new file mode 100644
index 0000000..b10ecc6
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Frequency.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2003, 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     4193200
+ * @summary Basic test for Collections.frequency
+ * @author  Josh Bloch
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+public class Frequency {
+    static final int N = 100;
+    public static void main(String[] args) {
+        test(new ArrayList<Integer>());
+        test(new LinkedList<Integer>());
+    }
+
+    static void test(List<Integer> list) {
+        for (int i = 0; i < N; i++)
+            for (int j = 0; j < i; j++)
+                list.add(i);
+        Collections.shuffle(list);
+
+        for (int i = 0; i < N; i++)
+            if (Collections.frequency(list, i) != i)
+                throw new RuntimeException(list.getClass() + ": " + i);
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/MinMax.java b/ojluni/src/test/java/util/Collections/MinMax.java
new file mode 100644
index 0000000..5b07d1c
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/MinMax.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2001, 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 4486049
+ * @summary min and max methods fail if size changes in between a call to size
+ *           and an attempt to iterate.
+ * @author Josh Bloch
+ */
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+public class MinMax {
+    public static void main(String[] args) {
+        Set s = new LyingSet();
+        s.add("x");
+        if (!Collections.min(s).equals("x"))
+            throw new RuntimeException("1: " + Collections.min(s));
+        if (!Collections.max(s).equals("x"))
+            throw new RuntimeException("2: " + Collections.max(s));
+
+        s.add("y");
+        if (!Collections.min(s).equals("x"))
+            throw new RuntimeException("3: " + Collections.min(s));
+        if (!Collections.max(s).equals("y"))
+            throw new RuntimeException("4: " + Collections.max(s));
+
+        s.add("w");
+        if (!Collections.min(s).equals("w"))
+            throw new RuntimeException("5: " + Collections.min(s));
+        if (!Collections.max(s).equals("y"))
+            throw new RuntimeException("6: " + Collections.max(s));
+
+        s.clear();
+        s.add("x");
+        if (!Collections.min(s, Collections.reverseOrder()).equals("x"))
+            throw new RuntimeException("1a: " + Collections.min(s));
+        if (!Collections.max(s, Collections.reverseOrder()).equals("x"))
+            throw new RuntimeException("2a: " + Collections.max(s));
+
+        s.add("y");
+        if (!Collections.min(s, Collections.reverseOrder()).equals("y"))
+            throw new RuntimeException("3a: " + Collections.min(s));
+        if (!Collections.max(s, Collections.reverseOrder()).equals("x"))
+            throw new RuntimeException("4a: " + Collections.max(s));
+
+        s.add("w");
+        if (!Collections.min(s, Collections.reverseOrder()).equals("y"))
+            throw new RuntimeException("5a: " + Collections.min(s));
+        if (!Collections.max(s, Collections.reverseOrder()).equals("w"))
+            throw new RuntimeException("6a: " + Collections.max(s));
+    }
+}
+
+class LyingSet extends LinkedHashSet {
+    public int size() {
+        return super.size() + 1; // Lies, lies, all lies!
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/NullComparator.java b/ojluni/src/test/java/util/Collections/NullComparator.java
new file mode 100644
index 0000000..fd1134c
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/NullComparator.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1999, 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 4224271
+ * @summary A null Comparator is now specified to indicate natural ordering.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class NullComparator {
+    public static void main(String[] args) throws Exception {
+        List list = new ArrayList(100);
+        for (int i=0; i<100; i++)
+            list.add(new Integer(i));
+        List sorted = new ArrayList(list);
+        Collections.shuffle(list);
+
+        Object[] a = list.toArray();
+        Arrays.sort(a, null);
+        if (!Arrays.asList(a).equals(sorted))
+            throw new Exception("Arrays.sort");
+        a = list.toArray();
+        Arrays.sort(a, 0, 100, null);
+        if (!Arrays.asList(a).equals(sorted))
+            throw new Exception("Arrays.sort(from, to)");
+        if (Arrays.binarySearch(a, new Integer(69)) != 69)
+            throw new Exception("Arrays.binarySearch");
+
+        List tmp = new ArrayList(list);
+        Collections.sort(tmp, null);
+        if (!tmp.equals(sorted))
+            throw new Exception("Collections.sort");
+        if (Collections.binarySearch(tmp, new Integer(69)) != 69)
+            throw new Exception("Collections.binarySearch");
+        if (!Collections.min(list, null).equals(new Integer(0)))
+            throw new Exception("Collections.min");
+        if (!Collections.max(list, null).equals(new Integer(99)))
+            throw new Exception("Collections.max");
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/RacingCollections.java b/ojluni/src/test/java/util/Collections/RacingCollections.java
new file mode 100644
index 0000000..c6064b0
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/RacingCollections.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6360946 6360948
+ * @summary Test various operations on concurrently mutating collections
+ * @author Martin Buchholz
+ */
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.LinkedTransferQueue;
+
+import static java.util.Collections.asLifoQueue;
+import static java.util.Collections.checkedList;
+import static java.util.Collections.checkedMap;
+import static java.util.Collections.checkedSet;
+import static java.util.Collections.newSetFromMap;
+import static java.util.Collections.synchronizedList;
+import static java.util.Collections.synchronizedMap;
+import static java.util.Collections.synchronizedSet;
+import static java.util.Collections.unmodifiableList;
+import static java.util.Collections.unmodifiableMap;
+import static java.util.Collections.unmodifiableSet;
+
+public class RacingCollections {
+    /**
+     * How long to run each "race" (in milliseconds).
+     * Turn this up to some higher value like 1000 for stress testing:
+     * java -Dmillis=1000 RacingCollections
+     */
+    static final long defaultWorkTimeMillis = Long.getLong("millis", 10L);
+
+    /**
+     * Whether to print debug information.
+     */
+    static final boolean debug = Boolean.getBoolean("debug");
+
+    static final Integer one = 1;
+    static final Integer two = 2;
+
+    /**
+     * A thread that mutates an object forever, alternating between
+     * being empty and containing singleton "two"
+     */
+    static class Frobber extends CheckedThread {
+        volatile boolean done = false;
+        boolean keepGoing(int i) { return (i % 128 != 0) || ! done; }
+
+        final Object elLoco;
+        Frobber(Object elLoco) {
+            this.elLoco = elLoco;
+            this.start();
+        }
+
+        @SuppressWarnings("unchecked")
+        void clear(Object o) {
+            if (o instanceof Collection)
+                ((Collection<?>)o).clear();
+            else
+                ((Map<?,?>)o).clear();
+        }
+
+        @SuppressWarnings("unchecked")
+        void realRun() {
+            // Mutate elLoco wildly forever, checking occasionally for "done"
+            clear(elLoco);
+            if (elLoco instanceof List) {
+                List<Integer> l = (List<Integer>) elLoco;
+                for (int i = 0; keepGoing(i); i++) {
+                    switch (i%2) {
+                    case 0: l.add(two);    break;
+                    case 1: l.add(0, two); break;
+                    }
+                    switch (i%2) {
+                    case 0: l.remove(two); break;
+                    case 1: l.remove(0);   break;
+                    }}}
+            else if (elLoco instanceof Deque) {
+                Deque<Integer> q = (Deque<Integer>) elLoco;
+                for (int i = 0; keepGoing(i); i++) {
+                    switch (i%6) {
+                    case 0: q.add(two);        break;
+                    case 1: q.addFirst(two);   break;
+                    case 2: q.addLast(two);    break;
+                    case 3: q.offer(two);      break;
+                    case 4: q.offerFirst(two); break;
+                    case 5: q.offerLast(two);  break;
+                    }
+                    switch (i%6) {
+                    case 0: q.remove(two);     break;
+                    case 1: q.removeFirst();   break;
+                    case 2: q.removeLast();    break;
+                    case 3: q.poll();          break;
+                    case 4: q.pollFirst();     break;
+                    case 5: q.pollLast();      break;
+                    }}}
+            else if (elLoco instanceof Queue) {
+                Queue<Integer> q = (Queue<Integer>) elLoco;
+                for (int i = 0; keepGoing(i); i++) {
+                    switch (i%2) {
+                    case 0: q.add(two);    break;
+                    case 1: q.offer(two);  break;
+                    }
+                    switch (i%2) {
+                    case 0: q.remove(two); break;
+                    case 1: q.poll();      break;
+                    }}}
+            else if (elLoco instanceof Map) {
+                Map<Integer, Boolean> m = (Map<Integer, Boolean>) elLoco;
+                for (int i = 0; keepGoing(i); i++) {
+                    m.put(two, true);
+                    m.remove(two);
+                }}
+            else if (elLoco instanceof Collection) {
+                Collection<Integer> c = (Collection<Integer>) elLoco;
+                for (int i = 0; keepGoing(i); i++) {
+                    c.add(two);
+                    c.remove(two);
+                }}
+            else { throw new Error("Huh? " + elLoco); }
+        }
+
+        void enoughAlready() {
+            done = true;
+            try { join(); } catch (Throwable t) { unexpected(t); }
+        }
+    }
+
+    private static void checkEqualSanity(Object theRock, Object elLoco) {
+        //equal(theRock, theRock);
+        equal(elLoco, elLoco);
+
+        // It would be nice someday to have theRock and elLoco never "equal",
+        // although the meaning of "equal" for mutating collections
+        // is a bit fuzzy.  Uncomment when/if we fix:
+        // 6374942: Improve thread safety of collection .equals() methods
+        //notEqual(theRock, elLoco);
+        //notEqual(elLoco, theRock);
+
+        notEqual(theRock.toString(), elLoco.toString());
+    }
+
+    static class Looper {
+        final long quittingTime;
+        int i = 0;
+        Looper() { this(defaultWorkTimeMillis); }
+        Looper(long workTimeMillis) {
+            quittingTime = System.nanoTime() + workTimeMillis * 1024 * 1024;
+        }
+        boolean keepGoing() {
+            return (i++ % 128 != 0) || (System.nanoTime() - quittingTime < 0);
+        }
+    }
+
+    private static void frob(Object theRock, Object elLoco) {
+        Frobber frobber = new Frobber(elLoco);
+        try {
+            if (theRock instanceof Collection) {
+                @SuppressWarnings("unchecked")
+                Collection<Integer> c = (Collection<Integer>) theRock;
+                if (! c.contains(one))
+                    c.add(one);
+            } else {
+                @SuppressWarnings("unchecked")
+                Map<Integer, Boolean> m = (Map<Integer, Boolean>) theRock;
+                if (! m.containsKey(one))
+                    m.put(one, true);
+            }
+            for (Looper looper = new Looper(); looper.keepGoing(); )
+                checkEqualSanity(theRock, elLoco);
+        }
+        catch (Throwable t) { unexpected(t); }
+        finally { frobber.enoughAlready(); }
+    }
+
+    private static List<Map<Integer, Boolean>> newConcurrentMaps() {
+        List<Map<Integer, Boolean>> list = new ArrayList<>();
+        list.add(new ConcurrentHashMap<Integer, Boolean>());
+        list.add(new ConcurrentSkipListMap<Integer, Boolean>());
+        return list;
+    }
+
+    private static List<Map<Integer, Boolean>> maps() {
+        List<Map<Integer, Boolean>> list = newConcurrentMaps();
+        list.add(new Hashtable<Integer, Boolean>());
+        list.add(new HashMap<Integer, Boolean>());
+        list.add(new TreeMap<Integer, Boolean>());
+        Comparator<Integer> cmp = new Comparator<>() {
+            public int compare(Integer x, Integer y) {
+                return x - y;
+            }};
+        list.add(new TreeMap<Integer, Boolean>(Collections.reverseOrder(cmp)));
+        return list;
+    }
+
+    private static List<Set<Integer>> newConcurrentSets() {
+        List<Set<Integer>> list = new ArrayList<>();
+        list.add(new ConcurrentSkipListSet<Integer>());
+        list.add(new CopyOnWriteArraySet<Integer>());
+        return list;
+    }
+
+    private static List<Set<Integer>> newSets() {
+        List<Set<Integer>> list = newConcurrentSets();
+        list.add(new HashSet<Integer>());
+        list.add(new TreeSet<Integer>());
+        list.add(new TreeSet<Integer>(Collections.reverseOrder()));
+        return list;
+    }
+
+    private static List<List<Integer>> newConcurrentLists() {
+        List<List<Integer>> list = new ArrayList<>();
+        list.add(new CopyOnWriteArrayList<Integer>());
+        return list;
+    }
+
+    private static List<List<Integer>> newLists() {
+        List<List<Integer>> list = newConcurrentLists();
+        list.add(new Vector<Integer>());
+        list.add(new ArrayList<Integer>());
+        return list;
+    }
+
+    private static List<Queue<Integer>> newConcurrentQueues() {
+        List<Queue<Integer>> list = new ArrayList<>(newConcurrentDeques());
+        list.add(new ArrayBlockingQueue<Integer>(10));
+        list.add(new LinkedBlockingQueue<Integer>(10));
+        list.add(new LinkedTransferQueue<Integer>());
+        list.add(new ConcurrentLinkedQueue<Integer>());
+        return list;
+    }
+
+    private static List<Queue<Integer>> newQueues() {
+        List<Queue<Integer>> list = new ArrayList<>(newDeques());
+        list.add(new LinkedBlockingQueue<Integer>(10));
+        return list;
+    }
+
+    private static List<Deque<Integer>> newConcurrentDeques() {
+        List<Deque<Integer>> list = new ArrayList<>();
+        list.add(new LinkedBlockingDeque<Integer>(10));
+        list.add(new ConcurrentLinkedDeque<Integer>());
+        return list;
+    }
+
+    private static List<Deque<Integer>> newDeques() {
+        List<Deque<Integer>> list = newConcurrentDeques();
+        list.add(new ArrayDeque<Integer>());
+        list.add(new LinkedList<Integer>());
+        return list;
+    }
+
+    private static void describe(Class<?> k, Object x, Object y) {
+        if (debug)
+            System.out.printf("%s: %s, %s%n", k.getSimpleName(),
+                              x.getClass().getSimpleName(),
+                              y.getClass().getSimpleName());
+    }
+
+    private static void realMain(String[] args) {
+        for (Map<Integer, Boolean> x : maps())
+            for (Map<Integer, Boolean> y : newConcurrentMaps()) {
+                describe(Map.class, x, y);
+                x.put(one, true);
+                frob(x, y);
+                frob(unmodifiableMap(x), y);
+                frob(synchronizedMap(x), y);
+                frob(x, synchronizedMap(y));
+                frob(checkedMap(x, Integer.class, Boolean.class), y);
+                frob(x, checkedMap(y, Integer.class, Boolean.class));
+                x.clear();
+                frob(newSetFromMap(x), newSetFromMap(y));
+                frob(x.keySet(), newSetFromMap(y));
+            }
+
+        for (Set<Integer> x : newSets())
+            for (Set<Integer> y : newConcurrentSets()) {
+                describe(Set.class, x, y);
+                frob(x, y);
+                frob(unmodifiableSet(x), y);
+                frob(synchronizedSet(x), y);
+                frob(x, synchronizedSet(y));
+                frob(checkedSet(x, Integer.class), y);
+                frob(x, checkedSet(y, Integer.class));
+            }
+
+        for (List<Integer> x : newLists())
+            for (List<Integer> y : newConcurrentLists()) {
+                describe(List.class, x, y);
+                frob(x, y);
+                frob(unmodifiableList(x), y);
+                frob(synchronizedList(x), y);
+                frob(x, synchronizedList(y));
+                frob(checkedList(x, Integer.class), y);
+                frob(x, checkedList(y, Integer.class));
+            }
+
+        for (Queue<Integer> x : newQueues())
+            for (Queue<Integer> y : newConcurrentQueues()) {
+                describe(Queue.class, x, y);
+                frob(x, y);
+            }
+
+        for (Deque<Integer> x : newDeques())
+            for (Deque<Integer> y : newConcurrentDeques()) {
+                describe(Deque.class, x, y);
+                frob(asLifoQueue(x), y);
+                frob(x, asLifoQueue(y));
+            }
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void check(boolean cond) {if (cond) pass(); else fail();}
+    static String toString(Object x) {
+        return ((x instanceof Collection) || (x instanceof Map)) ?
+            x.getClass().getName() : x.toString();}
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(toString(x) + " not equal to " + toString(y));}
+    static void notEqual(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y))
+            fail(toString(x) + " equal to " + toString(y));
+        else pass();}
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+    private abstract static class CheckedThread extends Thread {
+        abstract void realRun() throws Throwable;
+        public void run() {
+            try { realRun(); } catch (Throwable t) { unexpected(t); }}}
+}
diff --git a/ojluni/src/test/java/util/Collections/ReplaceAll.java b/ojluni/src/test/java/util/Collections/ReplaceAll.java
new file mode 100644
index 0000000..498e4c2
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/ReplaceAll.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2000, 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 4323074
+ * @summary Basic test for new replaceAll algorithm
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+
+public class ReplaceAll {
+    static final int SIZE = 20;
+
+    public static void main(String[] args) throws Exception {
+        List[] a = {new ArrayList(), new LinkedList(), new Vector()};
+
+        for (int i=0; i<a.length; i++) {
+            List lst = a[i];
+            for (int j=1; j<=SIZE; j++)
+                lst.add(new Integer(j % 3));
+            List goal = Collections.nCopies(SIZE, "*");
+
+            for (int j=0; j<3; j++) {
+                List before = new ArrayList(lst);
+                if (!Collections.replaceAll(lst, new Integer(j), "*"))
+                    throw new Exception("False return value: "+i+", "+j);
+                if (lst.equals(before))
+                    throw new Exception("Unchanged: "+i+", "+j+", "+": "+lst);
+                if (lst.equals(goal) != (j==2))
+                    throw new Exception("Wrong change:"+i+", "+j);
+            }
+            if (Collections.replaceAll(lst, "love", "hate"))
+                throw new Exception("True return value: "+i);
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/ReverseOrder.java b/ojluni/src/test/java/util/Collections/ReverseOrder.java
new file mode 100644
index 0000000..ceaa544
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/ReverseOrder.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2002, 2013, 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 4593209 8001667
+ * @summary Reverse comparator was subtly broken
+ * @author Josh Bloch
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class ReverseOrder {
+    static byte[] serialBytes(Object o) {
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(o);
+            oos.flush();
+            oos.close();
+            return bos.toByteArray();
+        } catch (Throwable t) {
+            throw new Error(t);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T o) {
+        try {
+            ObjectInputStream ois = new ObjectInputStream
+                (new ByteArrayInputStream(serialBytes(o)));
+            T clone = (T) ois.readObject();
+            return clone;
+        } catch (Throwable t) {
+            throw new Error(t);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Foo[] a = { new Foo(2), new Foo(3), new Foo(1) };
+        List list = Arrays.asList(a);
+        Comparator cmp = Collections.reverseOrder();
+        Collections.sort(list, cmp);
+
+        Foo[] golden = { new Foo(3), new Foo(2), new Foo(1) };
+        List goldenList = Arrays.asList(golden);
+        if (!list.equals(goldenList))
+            throw new Exception(list.toString());
+
+        Comparator clone = serialClone(cmp);
+        List list2 = Arrays.asList(a);
+        Collections.sort(list2, clone);
+        if (!list2.equals(goldenList))
+            throw new Exception(list.toString());
+    }
+}
+
+class Foo implements Comparable {
+    int val;
+    Foo(int i) { val = i; }
+
+    public int compareTo(Object o) {
+        Foo f = (Foo)o;
+        return (val < f.val ? Integer.MIN_VALUE : (val == f.val ? 0 : 1));
+    }
+
+    public boolean equals(Object o) {
+        return o instanceof Foo && ((Foo)o).val == val;
+    }
+
+    public int hashCode()    { return val; }
+
+    public String toString() { return Integer.toString(val); }
+}
diff --git a/ojluni/src/test/java/util/Collections/ReverseOrder2.java b/ojluni/src/test/java/util/Collections/ReverseOrder2.java
new file mode 100644
index 0000000..0369b38
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/ReverseOrder2.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     4809442 6366832 4974878 6372554 4890211 6483125
+ * @summary Basic test for Collections.reverseOrder
+ * @author  Josh Bloch, Martin Buchholz
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ReverseOrder2 {
+    static final int N = 100;
+
+    static void realMain(String[] args) throws Throwable {
+        check(Collections.reverseOrder()
+              == Collections.reverseOrder(null));
+
+        check(Collections.reverseOrder()
+              == reincarnate(Collections.reverseOrder()));
+
+        check(Collections.reverseOrder(Collections.reverseOrder(cmp))
+              == cmp);
+
+        equal(Collections.reverseOrder(cmp),
+              Collections.reverseOrder(cmp));
+
+        equal(Collections.reverseOrder(cmp).hashCode(),
+              Collections.reverseOrder(cmp).hashCode());
+
+        check(Collections.reverseOrder(cmp).hashCode() !=
+              cmp.hashCode());
+
+        test(new ArrayList<String>());
+        test(new LinkedList<String>());
+        test2(new ArrayList<Integer>());
+        test2(new LinkedList<Integer>());
+    }
+
+    static void test(List<String> list) {
+        for (int i = 0; i < N; i++)
+            list.add(String.valueOf(i));
+        Collections.shuffle(list);
+        Collections.sort(list, Collections.reverseOrder(cmp));
+        equal(list, golden);
+    }
+
+    private static Comparator<String> cmp = new Comparator<>() {
+        public int compare(String s1, String s2) {
+            int i1 = Integer.parseInt(s1);
+            int i2 = Integer.parseInt(s2);
+            return (i1 < i2 ? Integer.MIN_VALUE : (i1 == i2 ? 0 : 1));
+        }
+    };
+
+    private static final List<String> golden = new ArrayList<>(N);
+    static {
+        for (int i = N-1; i >= 0; i--)
+            golden.add(String.valueOf(i));
+    }
+
+    static void test2(List<Integer> list) {
+        for (int i = 0; i < N; i++)
+            list.add(i);
+        Collections.shuffle(list);
+        Collections.sort(list, Collections.reverseOrder(null));
+        equal(list, golden2);
+    }
+
+    private static final List<Integer> golden2 = new ArrayList<>(N);
+    static {
+        for (int i = N-1; i >= 0; i--)
+            golden2.add(i);
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void check(boolean cond) {if (cond) pass(); else fail();}
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+    static byte[] serializedForm(Object obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            new ObjectOutputStream(baos).writeObject(obj);
+            return baos.toByteArray();
+        } catch (IOException e) {throw new RuntimeException(e);}}
+    static Object readObject(byte[] bytes)
+        throws IOException, ClassNotFoundException {
+        InputStream is = new ByteArrayInputStream(bytes);
+        return new ObjectInputStream(is).readObject();}
+    @SuppressWarnings("unchecked")
+    static <T> T reincarnate(T obj) {
+        try {return (T) readObject(serializedForm(obj));}
+        catch (Exception e) {throw new RuntimeException(e);}}
+}
diff --git a/ojluni/src/test/java/util/Collections/Rotate.java b/ojluni/src/test/java/util/Collections/Rotate.java
new file mode 100644
index 0000000..7ec42f9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Rotate.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2000, 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 4323074
+ * @summary Basic test for new rotate algorithm
+ * @key randomness
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Vector;
+
+public class Rotate {
+    // Should have lots of distinct factors and be > ROTATE_THRESHOLD
+    static final int SIZE = 120;
+
+    static Random rnd = new Random();
+
+    public static void main(String[] args) throws Exception {
+        List[] a = {new ArrayList(), new LinkedList(), new Vector()};
+
+        for (int i=0; i<a.length; i++) {
+            List lst = a[i];
+            for (int j=0; j<SIZE; j++)
+                lst.add(new Integer(j));
+            int totalDist = 0;
+
+            for (int j=0; j<10000; j++) {
+                int dist = rnd.nextInt(200) - 100;
+                Collections.rotate(lst, dist);
+
+                // Check that things are as they should be
+                totalDist = (totalDist + dist) % SIZE;
+                if (totalDist < 0)
+                    totalDist += SIZE;
+                int index =0;
+                for (int k=totalDist; k<SIZE; k++, index++)
+                    if (((Integer)lst.get(k)).intValue() != index)
+                        throw new Exception("j: "+j+", lst["+k+"]="+lst.get(k)+
+                                            ", should be "+index);
+                for (int k=0; k<totalDist; k++, index++)
+                    if (((Integer)lst.get(k)).intValue() != index)
+                        throw new Exception("j: "+j+", lst["+k+"]="+lst.get(k)+
+                                            ", should be "+index);
+            }
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/RotateEmpty.java b/ojluni/src/test/java/util/Collections/RotateEmpty.java
new file mode 100644
index 0000000..12b0d9c
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/RotateEmpty.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2000, 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 4389747
+ * @summary Collections.rotate(...) returns ArithmeticException
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class RotateEmpty {
+
+    public static void main(String[] args) throws Exception {
+            List l = new ArrayList();
+            Collections.rotate(l, 1);
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/Ser.java b/ojluni/src/test/java/util/Collections/Ser.java
new file mode 100644
index 0000000..554a8e7
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Ser.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999, 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 4190323
+ * @summary EMPTY_SET, EMPTY_LIST, and the collections returned by
+ *          nCopies and singleton were spec'd to be serializable, but weren't.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class Ser {
+    public static void main(String[] args) throws Exception {
+
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream(bos);
+            out.writeObject(Collections.EMPTY_SET);
+            out.flush();
+            ObjectInputStream in = new ObjectInputStream(
+                    new ByteArrayInputStream(bos.toByteArray()));
+
+            if (!Collections.EMPTY_SET.equals(in.readObject()))
+                throw new RuntimeException("empty set Ser/Deser failure.");
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to serialize empty set:" + e);
+        }
+
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream(bos);
+            out.writeObject(Collections.EMPTY_LIST);
+            out.flush();
+            ObjectInputStream in = new ObjectInputStream(
+                    new ByteArrayInputStream(bos.toByteArray()));
+
+            if (!Collections.EMPTY_LIST.equals(in.readObject()))
+                throw new RuntimeException("empty list Ser/Deser failure.");
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to serialize empty list:" + e);
+        }
+
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream(bos);
+            Set gumby = Collections.singleton("gumby");
+            out.writeObject(gumby);
+            out.flush();
+            ObjectInputStream in = new ObjectInputStream(
+                    new ByteArrayInputStream(bos.toByteArray()));
+
+            if (!gumby.equals(in.readObject()))
+                throw new RuntimeException("Singleton Ser/Deser failure.");
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to serialize singleton:" + e);
+        }
+
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream out = new ObjectOutputStream(bos);
+            List gumbies = Collections.nCopies(50, "gumby");
+            out.writeObject(gumbies);
+            out.flush();
+            ObjectInputStream in = new ObjectInputStream(
+                    new ByteArrayInputStream(bos.toByteArray()));
+
+            if (!gumbies.equals(in.readObject()))
+                throw new RuntimeException("nCopies Ser/Deser failure.");
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to serialize nCopies:" + e);
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/SetFromMap.java b/ojluni/src/test/java/util/Collections/SetFromMap.java
new file mode 100644
index 0000000..40fa9ff
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/SetFromMap.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2005, 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 6301089
+ * @summary test Collections.newSetFromMap
+ * @author Martin Buchholz
+ */
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class SetFromMap {
+    static volatile int passed = 0, failed = 0;
+    static void pass() { passed++; }
+    static void fail() { failed++; Thread.dumpStack(); }
+    static void unexpected(Throwable t) { failed++; t.printStackTrace(); }
+    static void check(boolean cond) { if (cond) pass(); else fail(); }
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else {System.out.println(x + " not equal to " + y); fail(); }}
+
+    public static void main(String[] args) throws Throwable {
+        try { realMain(); } catch (Throwable t) { unexpected(t); }
+
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new Exception("Some tests failed");
+    }
+
+    private static void realMain() throws Throwable {
+        try {
+            Map<String,Boolean> m = new IdentityHashMap<>();
+            Set<String> s = Collections.newSetFromMap(m);
+            String foo1 = new String("foo");
+            String foo2 = new String("foo");
+            String bar = new String("bar");
+            check(s.add(foo1));
+            check(s.add(foo2));
+            check(s.add(bar));
+            equal(s.size(), 3);
+            check(s.contains(foo1));
+            check(s.contains(foo2));
+            check(! s.contains(new String(foo1)));
+        } catch (Throwable t) { unexpected(t); }
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/SingletonIterator.java b/ojluni/src/test/java/util/Collections/SingletonIterator.java
new file mode 100644
index 0000000..0f7dfd1
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/SingletonIterator.java
@@ -0,0 +1,75 @@
+/*
+ * 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 8024500 8166446
+ * @run testng SingletonIterator
+ */
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+@Test(groups = "unit")
+public class SingletonIterator {
+    static void assertIteratorExhausted(Iterator<?> it) {
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            fail("should have thrown NoSuchElementException");
+        } catch (NoSuchElementException success) { }
+        it.forEachRemaining(e -> { throw new AssertionError("action called incorrectly"); });
+    }
+
+    public void testForEachRemaining() {
+        Iterator<String> it = Collections.singleton("TheOne").iterator();
+        AtomicInteger cnt = new AtomicInteger(0);
+
+        it.forEachRemaining(s -> {
+            assertEquals("TheOne", s);
+            cnt.incrementAndGet();
+        });
+
+        assertEquals(cnt.get(), 1);
+        assertIteratorExhausted(it);
+    }
+
+    static class SingletonException extends RuntimeException { }
+
+    public void testThrowFromForEachRemaining() {
+        Iterator<String> it = Collections.singleton("TheOne").iterator();
+
+        try {
+            it.forEachRemaining(s -> { throw new SingletonException(); });
+        } catch (SingletonException ignore) { }
+
+        assertIteratorExhausted(it);
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/Swap.java b/ojluni/src/test/java/util/Collections/Swap.java
new file mode 100644
index 0000000..488feed
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Swap.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2000, 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     4323074
+ * @summary Basic test for newly public swap algorithm
+ * @author  Josh Bloch
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class Swap {
+    static final int SIZE = 100;
+
+    public static void main(String[] args) throws Exception {
+        List l = new ArrayList(Collections.nCopies(100, Boolean.FALSE));
+        l.set(0, Boolean.TRUE);
+        for (int i=0; i < SIZE-1; i++)
+            Collections.swap(l, i, i+1);
+
+        List l2 = new ArrayList(Collections.nCopies(100, Boolean.FALSE));
+        l2.set(SIZE-1, Boolean.TRUE);
+        if (!l.equals(l2))
+            throw new RuntimeException("Wrong result");
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/SyncSubMutexes.java b/ojluni/src/test/java/util/Collections/SyncSubMutexes.java
new file mode 100644
index 0000000..dc2e7e3
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/SyncSubMutexes.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2014, 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 8048209
+ * @summary Check that Collections.synchronizedNavigableSet().tailSet() is using
+ * the same lock object as it's source.
+ * @modules java.base/java.util:open
+ * @run testng SyncSubMutexes
+ */
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.Set;
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.assertSame;
+
+public class SyncSubMutexes {
+
+    @Test(dataProvider = "Collections")
+    public void testCollections(Collection<String> instance) {
+        // nothing to test, no subset methods
+    }
+
+    @Test(dataProvider = "Lists")
+    public void testLists(List<String> instance) {
+         assertSame(getSyncCollectionMutex(instance.subList(0, 1)), getSyncCollectionMutex(instance));
+    }
+
+    @Test(dataProvider = "Sets")
+    public void testSets(Set<String> instance) {
+        // nothing to test, no subset methods
+
+    }
+
+    @Test(dataProvider = "SortedSets")
+    public void testSortedSets(SortedSet<String> instance) {
+         assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
+
+    }
+
+    @Test(dataProvider = "NavigableSets")
+    public void testNavigableSets(NavigableSet<String> instance) {
+         assertSame(getSyncCollectionMutex(instance.descendingSet()), getSyncCollectionMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.headSet("Echo", true)), getSyncCollectionMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.tailSet("Charlie", true)), getSyncCollectionMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.subSet("Charlie", true, "Echo", true)), getSyncCollectionMutex(instance));
+    }
+
+    @Test(dataProvider = "Maps")
+    public void testMaps(Map<String, String> instance) {
+         assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
+    }
+
+    @Test(dataProvider = "SortedMaps")
+    public void testSortedMaps(SortedMap<String, String> instance) {
+         assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.subMap("Charlie", "Echo")), getSyncMapMutex(instance));
+    }
+
+    @Test(dataProvider = "NavigableMaps")
+    public void testNavigableMaps(NavigableMap<String, String> instance) {
+         assertSame(getSyncMapMutex(instance.descendingMap()), getSyncMapMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.descendingKeySet()), getSyncMapMutex(instance));
+         assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.headMap("Echo", true)), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.tailMap("Charlie", true)), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
+         assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
+    }
+
+    @DataProvider(name = "Collections", parallel = true)
+    public static Iterator<Object[]> collectionProvider() {
+        return makeCollections().iterator();
+    }
+
+    @DataProvider(name = "Lists", parallel = true)
+    public static Iterator<Object[]> listProvider() {
+        return makeLists().iterator();
+    }
+
+    @DataProvider(name = "Sets", parallel = true)
+    public static Iterator<Object[]> setProvider() {
+        return makeSets().iterator();
+    }
+
+    @DataProvider(name = "SortedSets", parallel = true)
+    public static Iterator<Object[]> sortedsetProvider() {
+        return makeSortedSets().iterator();
+    }
+
+    @DataProvider(name = "NavigableSets", parallel = true)
+    public static Iterator<Object[]> navigablesetProvider() {
+        return makeNavigableSets().iterator();
+    }
+
+    @DataProvider(name = "Maps", parallel = true)
+    public static Iterator<Object[]> mapProvider() {
+        return makeMaps().iterator();
+    }
+
+    @DataProvider(name = "SortedMaps", parallel = true)
+    public static Iterator<Object[]> sortedmapProvider() {
+        return makeSortedMaps().iterator();
+    }
+
+    @DataProvider(name = "NavigableMaps", parallel = true)
+    public static Iterator<Object[]> navigablemapProvider() {
+        return makeNavigableMaps().iterator();
+    }
+
+    private static final Collection<String> BASE_COLLECTION = Collections.unmodifiableCollection(
+            Arrays.asList("Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf")
+    );
+    private static final Map<String, String> BASE_MAP;
+
+    static {
+        Map<String, String> map = new HashMap<>();
+        for(String each : BASE_COLLECTION) {
+            map.put(each, "*" + each + "*");
+        }
+        BASE_MAP = Collections.unmodifiableMap(map);
+    }
+
+    public static Collection<Object[]> makeCollections() {
+        Collection<Object[]> instances = new ArrayList<>();
+        instances.add(new Object[] {Collections.synchronizedCollection(new ArrayList<>(BASE_COLLECTION))});
+        instances.addAll(makeLists());
+
+        return instances;
+    }
+
+    public static Collection<Object[]> makeLists() {
+        Collection<Object[]> instances = new ArrayList<>();
+        instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION))});
+        instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION)).subList(1, 2)});
+
+        return instances;
+    }
+
+     public static Collection<Object[]> makeSets() {
+        Collection<Object[]> instances = new ArrayList<>();
+
+        instances.add(new Object[] {Collections.synchronizedSet(new TreeSet<>(BASE_COLLECTION))});
+        instances.addAll(makeSortedSets());
+        return instances;
+     }
+
+    public static Collection<Object[]> makeSortedSets() {
+        Collection<Object[]> instances = new ArrayList<>();
+        instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION))});
+        instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
+        instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
+        instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
+        instances.addAll(makeNavigableSets());
+
+        return instances;
+     }
+
+    public static Collection<Object[]> makeNavigableSets() {
+        Collection<Object[]> instances = new ArrayList<>();
+
+        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION))});
+        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).descendingSet().descendingSet()});
+        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
+        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot", true)});
+        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
+        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo", true)});
+        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
+        instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", true, "Foxtrot", true)});
+
+        return instances;
+    }
+
+    public static Collection<Object[]> makeMaps() {
+        Collection<Object[]> instances = new ArrayList<>();
+
+        instances.add(new Object[] {Collections.synchronizedMap(new HashMap<>(BASE_MAP))});
+        instances.addAll(makeSortedMaps());
+
+        return instances;
+    }
+
+    public static Collection<Object[]> makeSortedMaps() {
+        Collection<Object[]> instances = new ArrayList<>();
+
+        instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP))});
+        instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
+        instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
+        instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
+        instances.addAll(makeNavigableMaps());
+
+        return instances;
+    }
+
+    public static Collection<Object[]> makeNavigableMaps() {
+        Collection<Object[]> instances = new ArrayList<>();
+
+        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP))});
+        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP).descendingMap().descendingMap())});
+        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
+        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot", true)});
+        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
+        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo", true)});
+        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
+        instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", true, "Foxtrot", true)});
+
+        return instances;
+    }
+
+    private static Object getSyncCollectionMutex(Collection<?> from) {
+        try {
+            Class<?> synchronizedCollectionClazz = Class.forName("java.util.Collections$SynchronizedCollection");
+            Field f = synchronizedCollectionClazz.getDeclaredField("mutex");
+            f.setAccessible(true);
+            return f.get(from);
+        } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
+            throw new RuntimeException("Unable to get mutex field.", e);
+        }
+    }
+
+    private static Object getSyncMapMutex(Map<?,?> from) {
+        try {
+            Class<?> synchronizedMapClazz = Class.forName("java.util.Collections$SynchronizedMap");
+            Field f = synchronizedMapClazz.getDeclaredField("mutex");
+            f.setAccessible(true);
+            return f.get(from);
+        } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
+            throw new RuntimeException("Unable to get mutex field.", e);
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/Collections/T6433170.java b/ojluni/src/test/java/util/Collections/T6433170.java
new file mode 100644
index 0000000..65de4cc
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/T6433170.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 6433170
+ * @summary CheckedCollection.addAll should be all-or-nothing
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Vector;
+
+import static java.util.Collections.checkedCollection;
+import static java.util.Collections.checkedList;
+import static java.util.Collections.checkedSet;
+
+@SuppressWarnings("unchecked")
+public class T6433170 {
+    private void checkEmpty(Collection x) {
+        check(x.isEmpty());
+        check(x.size() == 0);
+        check(x.toArray().length == 0);
+    }
+
+    void test(String[] args) throws Throwable {
+        test(checkedList(
+                 checkedList(new ArrayList(), String.class),
+                 Object.class));
+        test(checkedSet(
+                 checkedSet(new HashSet(), String.class),
+                 Object.class));
+        test(checkedCollection(
+                 checkedCollection(new Vector(), String.class),
+                 Object.class));
+    }
+
+    void test(final Collection checked) {
+        checkEmpty(checked);
+        final List mixedList = Arrays.asList("1", 2, "3");
+        THROWS(ClassCastException.class,
+               new F(){void f(){ checked.addAll(mixedList); }});
+        checkEmpty(checked);
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    volatile int passed = 0, failed = 0;
+    void pass() {passed++;}
+    void fail() {failed++; Thread.dumpStack();}
+    void fail(String msg) {System.err.println(msg); fail();}
+    void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    void check(boolean cond) {if (cond) pass(); else fail();}
+    void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        new T6433170().instanceMain(args);}
+    void instanceMain(String[] args) throws Throwable {
+        try {test(args);} catch (Throwable t) {unexpected(t);}
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+    abstract class F {abstract void f() throws Throwable;}
+    void THROWS(Class<? extends Throwable> k, F... fs) {
+        for (F f : fs)
+            try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+            catch (Throwable t) {
+                if (k.isAssignableFrom(t.getClass())) pass();
+                else unexpected(t);}}
+}
diff --git a/ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java b/ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java
new file mode 100644
index 0000000..d7945d1
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/UnmodifiableMapEntrySet.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2013, 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
+ * @run testng UnmodifiableMapEntrySet
+ * @summary Unit tests for wrapping classes should delegate to default methods
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Spliterator;
+import java.util.TreeMap;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+
+import static org.testng.Assert.assertEquals;
+
+@Test(groups = "unit")
+public class UnmodifiableMapEntrySet {
+    static Object[][] collections;
+
+    static <M extends Map<Integer, Integer>> M fillMap(int size, M m) {
+        for (int i = 0; i < size; i++) {
+            m.put(i, i);
+        }
+        return m;
+    }
+
+    @DataProvider(name="maps")
+    static Object[][] mapCases() {
+        if (collections != null) {
+            return collections;
+        }
+
+        List<Object[]> cases = new ArrayList<>();
+        for (int size : new int[] {1, 2, 16}) {
+            cases.add(new Object[] {
+                    String.format("new HashMap(%d)", size),
+                    (Supplier<Map<Integer, Integer>>)
+                    () -> Collections.unmodifiableMap(fillMap(size, new HashMap<>())) });
+            cases.add(new Object[] {
+                    String.format("new TreeMap(%d)", size),
+                    (Supplier<Map<Integer, Integer>>)
+                    () -> Collections.unmodifiableSortedMap(fillMap(size, new TreeMap<>())) });
+        }
+
+        return cases.toArray(new Object[0][]);
+    }
+
+    static class EntryConsumer implements Consumer<Map.Entry<Integer, Integer>> {
+        int updates;
+        @Override
+        public void accept(Map.Entry<Integer, Integer> me) {
+            try {
+                me.setValue(Integer.MAX_VALUE);
+                updates++;
+            } catch (UnsupportedOperationException e) {
+            }
+        }
+
+        void assertNoUpdates() {
+            assertEquals(updates, 0, "Updates to entries");
+        }
+    }
+
+    void testWithEntryConsumer(Consumer<EntryConsumer> c) {
+        EntryConsumer ec = new EntryConsumer();
+        c.accept(ec);
+        ec.assertNoUpdates();
+    }
+
+    @Test(dataProvider = "maps")
+    public void testForEach(String d, Supplier<Map<Integer, Integer>> ms) {
+        testWithEntryConsumer(
+                ec -> ms.get().entrySet().forEach(ec));
+    }
+
+    @Test(dataProvider = "maps")
+    public void testIteratorForEachRemaining(String d, Supplier<Map<Integer, Integer>> ms) {
+        testWithEntryConsumer(
+                ec -> ms.get().entrySet().iterator().forEachRemaining(ec));
+    }
+
+    @Test(dataProvider = "maps")
+    public void testIteratorNext(String d, Supplier<Map<Integer, Integer>> ms) {
+        testWithEntryConsumer(ec -> {
+            for (Map.Entry<Integer, Integer> me : ms.get().entrySet()) {
+                ec.accept(me);
+            }
+        });
+    }
+
+    @Test(dataProvider = "maps")
+    public void testSpliteratorForEachRemaining(String d, Supplier<Map<Integer, Integer>> ms) {
+        testSpliterator(
+                ms.get().entrySet()::spliterator,
+                // Higher order function returning a consumer that
+                // traverses all spliterator elements using an EntryConsumer
+                s -> ec -> s.forEachRemaining(ec));
+    }
+
+    @Test(dataProvider = "maps")
+    public void testSpliteratorTryAdvance(String d, Supplier<Map<Integer, Integer>> ms) {
+        testSpliterator(
+                ms.get().entrySet()::spliterator,
+                // Higher order function returning a consumer that
+                // traverses all spliterator elements using an EntryConsumer
+                s -> ec -> { while (s.tryAdvance(ec)); });
+    }
+
+    void testSpliterator(Supplier<Spliterator<Map.Entry<Integer, Integer>>> ss,
+                         // Higher order function that given a spliterator returns a
+                         // consumer for that spliterator which traverses elements
+                         // using an EntryConsumer
+                         Function<Spliterator<Map.Entry<Integer, Integer>>, Consumer<EntryConsumer>> sc) {
+        testWithEntryConsumer(sc.apply(ss.get()));
+
+        Spliterator<Map.Entry<Integer, Integer>> s = ss.get();
+        Spliterator<Map.Entry<Integer, Integer>> split = s.trySplit();
+        if (split != null) {
+            testWithEntryConsumer(sc.apply(split));
+            testWithEntryConsumer(sc.apply(s));
+        }
+    }
+
+    @Test(dataProvider = "maps")
+    public void testStreamForEach(String d, Supplier<Map<Integer, Integer>> ms) {
+        testWithEntryConsumer(ec -> ms.get().entrySet().stream().forEach(ec));
+    }
+
+    @Test(dataProvider = "maps")
+    public void testParallelStreamForEach(String d, Supplier<Map<Integer, Integer>> ms) {
+        testWithEntryConsumer(ec -> ms.get().entrySet().parallelStream().forEach(ec));
+    }
+}
+
diff --git a/ojluni/src/test/java/util/Collections/ViewSynch.java b/ojluni/src/test/java/util/Collections/ViewSynch.java
new file mode 100644
index 0000000..9ad07b9
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/ViewSynch.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 1999, 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 4268780
+ * @summary Collection-views of submap-views of synchronized-views of
+ *          SortedMap objects do not synchronize on the correct object.
+ *          (Got that?)
+ */
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+public class ViewSynch {
+    static final Integer ZERO = new Integer(0);
+    static final Int INT_ZERO = new Int(0);
+    static final Int INT_ONE = new Int(1);
+    static SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
+    static Map m2 = m.tailMap(ZERO);
+    static Collection c = m2.values();
+
+    public static void main(String[] args) {
+        for (int i=0; i<10000; i++)
+            m.put(new Integer(i), INT_ZERO);
+
+        new Thread() {
+            public void run() {
+                for (int i=0; i<100; i++) {
+                    Thread.yield();
+                    m.remove(ZERO);
+                    m.put(ZERO, INT_ZERO);
+                }
+            }
+        }.start();
+
+        c.contains(INT_ONE);
+    }
+}
+
+/**
+ * Like Integer, except yields while doing equals comparison, to allow
+ * for interleaving.
+ */
+class Int {
+    Integer x;
+    Int(int i) {x = new Integer(i);}
+
+    public boolean equals(Object o) {
+        Thread.yield();
+        Int i = (Int)o;
+        return x.equals(i.x);
+    }
+
+    public int hashCode() {return x.hashCode();}
+}
diff --git a/ojluni/src/test/java/util/Collections/WrappedNull.java b/ojluni/src/test/java/util/Collections/WrappedNull.java
new file mode 100644
index 0000000..163a6a7
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/WrappedNull.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1999, 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 4189641
+ * @summary Wrapping a null collection/array should blow up sooner
+ *          rather than later
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+public class WrappedNull {
+    public static void main(String[] args) throws Exception {
+        boolean testSucceeded = false;
+        try {
+            List l = Arrays.asList(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("Arrays.asList");
+
+        testSucceeded = false;
+        try {
+            Collection c = Collections.unmodifiableCollection(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("unmodifiableCollection");
+
+        testSucceeded = false;
+        try {
+            Set c = Collections.unmodifiableSet(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("unmodifiableSet");
+
+        testSucceeded = false;
+        try {
+            List c = Collections.unmodifiableList(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("unmodifiableList");
+
+        testSucceeded = false;
+        try {
+            Map c = Collections.unmodifiableMap(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("unmodifiableMap");
+
+        testSucceeded = false;
+        try {
+            SortedSet c = Collections.unmodifiableSortedSet(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("unmodifiableSortedSet");
+
+        testSucceeded = false;
+        try {
+            SortedMap c = Collections.unmodifiableSortedMap(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("unmodifiableSortedMap");
+
+        testSucceeded = false;
+        try {
+            Collection c = Collections.synchronizedCollection(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("synchronizedCollection");
+
+        testSucceeded = false;
+        try {
+            Set c = Collections.synchronizedSet(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("synchronizedSet");
+
+        testSucceeded = false;
+        try {
+            List c = Collections.synchronizedList(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("synchronizedList");
+
+        testSucceeded = false;
+        try {
+            Map c = Collections.synchronizedMap(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("synchronizedMap");
+
+        testSucceeded = false;
+        try {
+            SortedSet c = Collections.synchronizedSortedSet(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("synchronizedSortedSet");
+
+        testSucceeded = false;
+        try {
+            SortedMap c = Collections.synchronizedSortedMap(null);
+        }
+        catch (NullPointerException e) {
+            testSucceeded = true;
+        }
+        if (!testSucceeded)
+            throw new Exception("synchronizedSortedMap");
+
+        // Make sure that non-null arguments don't throw exc.
+        List l = Arrays.asList(new Object[0]);
+        Collection c = Collections.unmodifiableCollection(
+                Collections.EMPTY_SET);
+        Set s = Collections.unmodifiableSet(Collections.EMPTY_SET);
+        l = Collections.unmodifiableList(Collections.EMPTY_LIST);
+        Map m = Collections.unmodifiableMap(Collections.EMPTY_MAP);
+        SortedSet ss = Collections.unmodifiableSortedSet(new TreeSet());
+        SortedMap sm = Collections.unmodifiableSortedMap(new TreeMap());
+
+        c = Collections.synchronizedCollection(Collections.EMPTY_SET);
+        s = Collections.synchronizedSet(Collections.EMPTY_SET);
+        l = Collections.synchronizedList(Collections.EMPTY_LIST);
+        m = Collections.synchronizedMap(Collections.EMPTY_MAP);
+        ss = Collections.synchronizedSortedSet(new TreeSet());
+        sm = Collections.synchronizedSortedMap(new TreeMap());
+    }
+}
diff --git a/ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java b/ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java
new file mode 100644
index 0000000..9b00d38
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/WrappedUnmodifiableCollections.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2021, 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 6323374
+ * @run testng WrappedUnmodifiableCollections
+ */
+
+import java.util.*;
+import java.util.function.Function;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+
+@Test
+public class WrappedUnmodifiableCollections {
+
+    private static <T,E extends T> void testWrapping(T collection, Function<T,E> wrapper) {
+        var collection1 = wrapper.apply(collection);
+        var collection2 = wrapper.apply(collection1);
+        assertNotSame(collection, collection2);
+        assertSame(collection1, collection2);
+    }
+
+    public void testUnmodifiableListsDontWrap() {
+        List<List<?>> lists = List.of(List.of(), List.of(1,2,3), List.of(1),
+                List.of(1,2,3,4,5,6),
+                List.of(1,2,3).subList(0,1),
+                new LinkedList<>(List.of(1,2,3)),
+                new ArrayList<>(List.of(1,2,3)));
+
+        for(List<?> list : lists) {
+            testWrapping(list, Collections::unmodifiableList);
+        }
+    }
+
+    public void testUnmodifiableCollectionsDontWrap() {
+        Collection<?> list = List.of();
+        testWrapping(list, Collections::unmodifiableCollection);
+    }
+
+    public void testUnmodifiableSetsDontWrap() {
+
+        List<Set<?>> sets = List.of(new TreeSet<>(),
+                                    Set.of(1, 2),
+                                    Set.of(1,2,3,4,5,6));
+
+        for (Set<?> set : sets) {
+            testWrapping(set, Collections::unmodifiableSet);
+        }
+
+        TreeSet<?> treeSet = new TreeSet<>();
+
+        //Collections.UnmodifiableSortedSet
+        testWrapping((SortedSet<?>) treeSet, Collections::unmodifiableSortedSet);
+
+        //Collections.UnmodifiableNavigableSet
+        testWrapping((NavigableSet<?>) treeSet, Collections::unmodifiableNavigableSet);
+
+    }
+
+    public void testUnmodifiableMapsDontWrap() {
+        TreeMap<?,?> treeMap = new TreeMap<>();
+
+        List<Map<?,?>> maps = List.of(treeMap,
+                Map.of(1,1),
+                Map.of(1, 1, 2, 2, 3, 3, 4, 4));
+
+        for (Map<?,?> map : maps) {
+            testWrapping(map, Collections::unmodifiableMap);
+        }
+
+        //Collections.UnModifiableSortedMap
+        testWrapping((SortedMap<?,?>) treeMap, Collections::unmodifiableSortedMap);
+
+        //Collections.UnModifiableNavigableMap
+        testWrapping((NavigableMap<?,?>) treeMap, Collections::unmodifiableNavigableMap);
+
+    }
+
+}
diff --git a/ojluni/src/test/java/util/Collections/Wrappers.java b/ojluni/src/test/java/util/Collections/Wrappers.java
new file mode 100644
index 0000000..3882a4e
--- /dev/null
+++ b/ojluni/src/test/java/util/Collections/Wrappers.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2013, 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
+ * @run testng Wrappers
+ * @summary Ensure Collections wrapping classes provide non-default implementations
+ */
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+
+import static org.testng.Assert.assertFalse;
+
+@Test(groups = "unit")
+public class Wrappers {
+    static Object[][] collections;
+
+    @DataProvider(name="collections")
+    public static Object[][] collectionCases() {
+        if (collections != null) {
+            return collections;
+        }
+
+        List<Object[]> cases = new ArrayList<>();
+        LinkedList<Integer> seedList = new LinkedList<>();
+        ArrayList<Integer> seedRandomAccess = new ArrayList<>();
+        TreeSet<Integer> seedSet = new TreeSet<>();
+        TreeMap<Integer, Integer> seedMap = new TreeMap<>();
+
+        for (int i = 1; i <= 10; i++) {
+            seedList.add(i);
+            seedRandomAccess.add(i);
+            seedSet.add(i);
+            seedMap.put(i, i);
+        }
+
+        cases.add(new Object[] { Collections.unmodifiableCollection(seedList) });
+        cases.add(new Object[] { Collections.unmodifiableList(seedList) });
+        cases.add(new Object[] { Collections.unmodifiableList(seedRandomAccess) });
+        cases.add(new Object[] { Collections.unmodifiableSet(seedSet) });
+        cases.add(new Object[] { Collections.unmodifiableSortedSet(seedSet) });
+        cases.add(new Object[] { Collections.unmodifiableNavigableSet(seedSet) });
+
+        // As sets from map also need to be unmodifiable, thus a wrapping
+        // layer exist and should not have default methods
+        cases.add(new Object[] { Collections.unmodifiableMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.unmodifiableMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.unmodifiableMap(seedMap).values() });
+        cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.unmodifiableSortedMap(seedMap).values() });
+        cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.unmodifiableNavigableMap(seedMap).values() });
+
+        // Synchronized
+        cases.add(new Object[] { Collections.synchronizedCollection(seedList) });
+        cases.add(new Object[] { Collections.synchronizedList(seedList) });
+        cases.add(new Object[] { Collections.synchronizedList(seedRandomAccess) });
+        cases.add(new Object[] { Collections.synchronizedSet(seedSet) });
+        cases.add(new Object[] { Collections.synchronizedSortedSet(seedSet) });
+        cases.add(new Object[] { Collections.synchronizedNavigableSet(seedSet) });
+
+        // As sets from map also need to be synchronized on the map, thus a
+        // wrapping layer exist and should not have default methods
+        cases.add(new Object[] { Collections.synchronizedMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.synchronizedMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.synchronizedMap(seedMap).values() });
+        cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.synchronizedSortedMap(seedMap).values() });
+        cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).entrySet() });
+        cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).keySet() });
+        cases.add(new Object[] { Collections.synchronizedNavigableMap(seedMap).values() });
+
+        // Checked
+        cases.add(new Object[] { Collections.checkedCollection(seedList, Integer.class) });
+        cases.add(new Object[] { Collections.checkedList(seedList, Integer.class) });
+        cases.add(new Object[] { Collections.checkedList(seedRandomAccess, Integer.class) });
+        cases.add(new Object[] { Collections.checkedSet(seedSet, Integer.class) });
+        cases.add(new Object[] { Collections.checkedSortedSet(seedSet, Integer.class) });
+        cases.add(new Object[] { Collections.checkedNavigableSet(seedSet, Integer.class) });
+        cases.add(new Object[] { Collections.checkedQueue(seedList, Integer.class) });
+
+        // asLifoQueue is another wrapper
+        cases.add(new Object[] { Collections.asLifoQueue(seedList) });
+
+        collections = cases.toArray(new Object[0][]);
+        return collections;
+    }
+
+    static Method[] defaultMethods;
+
+    static {
+        List<Method> list = new ArrayList<>();
+        Method[] methods = Collection.class.getMethods();
+        for (Method m: methods) {
+            if (m.isDefault()) {
+                list.add(m);
+            }
+        }
+        defaultMethods = list.toArray(new Method[0]);
+    }
+
+    @Test(dataProvider = "collections")
+    public static void testAllDefaultMethodsOverridden(Collection c) throws NoSuchMethodException {
+        Class cls = c.getClass();
+        for (Method m: defaultMethods) {
+            Method m2 = cls.getMethod(m.getName(), m.getParameterTypes());
+            // default had been override
+            assertFalse(m2.isDefault(), cls.getCanonicalName());
+        }
+    }
+}
+