8009736: Comparator API cleanup
authorhenryjen
Tue, 11 Jun 2013 13:41:38 -0700
changeset 18571 8e3cb3c46ae8
parent 18570 9078dc28a187
child 18572 53b8b8c30086
8009736: Comparator API cleanup Reviewed-by: psandoz, briangoetz, mduigou, plevart
jdk/src/share/classes/java/util/Collections.java
jdk/src/share/classes/java/util/Comparator.java
jdk/src/share/classes/java/util/Comparators.java
jdk/src/share/classes/java/util/Map.java
jdk/src/share/classes/java/util/TreeMap.java
jdk/src/share/classes/java/util/function/BinaryOperator.java
jdk/src/share/classes/java/util/stream/Collectors.java
jdk/src/share/classes/java/util/stream/ReferencePipeline.java
jdk/src/share/classes/java/util/stream/SortedOps.java
jdk/test/java/nio/file/Files/StreamTest.java
jdk/test/java/util/Collection/ListDefaults.java
jdk/test/java/util/Comparator/BasicTest.java
jdk/test/java/util/Comparator/TypeTest.java
jdk/test/java/util/Comparators/BasicTest.java
jdk/test/java/util/Map/EntryComparators.java
jdk/test/java/util/function/BinaryOperator/BasicTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java
jdk/test/sun/misc/JavaLangAccess/NewUnsafeString.java
--- a/jdk/src/share/classes/java/util/Collections.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/Collections.java	Tue Jun 11 13:41:38 2013 -0700
@@ -4304,6 +4304,11 @@
         }
 
         private Object readResolve() { return Collections.reverseOrder(); }
+
+        @Override
+        public Comparator<Comparable<Object>> reversed() {
+            return Comparator.naturalOrder();
+        }
     }
 
     /**
@@ -4367,6 +4372,11 @@
         public int hashCode() {
             return cmp.hashCode() ^ Integer.MIN_VALUE;
         }
+
+        @Override
+        public Comparator<T> reversed() {
+            return cmp;
+        }
     }
 
     /**
--- a/jdk/src/share/classes/java/util/Comparator.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/Comparator.java	Tue Jun 11 13:41:38 2013 -0700
@@ -25,10 +25,12 @@
 
 package java.util;
 
+import java.io.Serializable;
 import java.util.function.Function;
 import java.util.function.ToIntFunction;
 import java.util.function.ToLongFunction;
 import java.util.function.ToDoubleFunction;
+import java.util.Comparators;
 
 /**
  * A comparison function, which imposes a <i>total ordering</i> on some
@@ -175,88 +177,357 @@
      * Returns a comparator that imposes the reverse ordering of this
      * comparator.
      *
-     * @return A comparator that imposes the reverse ordering of this
+     * @return a comparator that imposes the reverse ordering of this
      *         comparator.
      * @since 1.8
      */
-    default Comparator<T> reverseOrder() {
+    default Comparator<T> reversed() {
         return Collections.reverseOrder(this);
     }
 
     /**
-     * Constructs a lexicographic order comparator with another comparator.
-     * For example, a {@code Comparator<Person> byLastName} can be composed
-     * with another {@code Comparator<Person> byFirstName}, then {@code
-     * byLastName.thenComparing(byFirstName)} creates a {@code
-     * Comparator<Person>} which sorts by last name, and for equal last names
-     * sorts by first name.
+     * Returns a lexicographic-order comparator with another comparator.
+     * If this {@code Comparator} considers two elements equal, i.e.
+     * {@code compare(a, b) == 0}, {@code other} is used to determine the order.
+     *
+     * <p>The returned comparator is serializable if the specified comparator
+     * is also serializable.
      *
-     * @param other the other comparator used when equals on this.
+     * @apiNote
+     * For example, to sort a collection of {@code String} based on the length
+     * and then case-insensitive natural ordering, the comparator can be
+     * composed using following code,
+     *
+     * <pre>{@code
+     *     Comparator<String> cmp = Comparator.comparing(String::length)
+     *             .thenComparing(String.CASE_INSENSITIVE_ORDER);
+     * }</pre>
+     *
+     * @param  other the other comparator to be used when this comparator
+     *         compares two objects that are equal.
+     * @return a lexicographic-order comparator composed of this and then the
+     *         other comparator
      * @throws NullPointerException if the argument is null.
      * @since 1.8
      */
     default Comparator<T> thenComparing(Comparator<? super T> other) {
-        return Comparators.compose(this, other);
+        Objects.requireNonNull(other);
+        return (Comparator<T> & Serializable) (c1, c2) -> {
+            int res = compare(c1, c2);
+            return (res != 0) ? res : other.compare(c1, c2);
+        };
+    }
+
+    /**
+     * Returns a lexicographic-order comparator with a function that
+     * extracts a key to be compared with the given {@code Comparator}.
+     *
+     * @implSpec This default implementation behaves as if {@code
+     *           thenComparing(comparing(keyExtractor, cmp))}.
+     *
+     * @param  <U>  the type of the sort key
+     * @param  keyExtractor the function used to extract the sort key
+     * @param  keyComparator the {@code Comparator} used to compare the sort key
+     * @return a lexicographic-order comparator composed of this comparator
+     *         and then comparing on the key extracted by the keyExtractor function
+     * @throws NullPointerException if the argument is null.
+     * @see #comparing(Function, Comparator)
+     * @see #thenComparing(Comparator)
+     * @since 1.8
+     */
+    default <U extends Comparable<? super U>> Comparator<T> thenComparing(
+            Function<? super T, ? extends U> keyExtractor,
+            Comparator<? super U> keyComparator)
+    {
+        return thenComparing(comparing(keyExtractor, keyComparator));
     }
 
     /**
-     * Constructs a lexicographic order comparator with a function that
-     * extracts a {@code Comparable} key.  This default implementation calls
-     * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+     * Returns a lexicographic-order comparator with a function that
+     * extracts a {@code Comparable} sort key.
+     *
+     * @implSpec This default implementation behaves as if {@code
+     *           thenComparing(comparing(keyExtractor))}.
      *
-     * @param <U> the {@link Comparable} type for comparison
-     * @param keyExtractor the function used to extract the {@link Comparable} sort key
+     * @param  <U>  the type of the {@link Comparable} sort key
+     * @param  keyExtractor the function used to extract the {@link
+     *         Comparable} sort key
+     * @return a lexicographic-order comparator composed of this and then the
+     *         {@link Comparable} sort key.
      * @throws NullPointerException if the argument is null.
-     * @see Comparators#comparing(Function)
+     * @see #comparing(Function)
      * @see #thenComparing(Comparator)
      * @since 1.8
      */
-    default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor) {
-        return thenComparing(Comparators.comparing(keyExtractor));
+    default <U extends Comparable<? super U>> Comparator<T> thenComparing(
+            Function<? super T, ? extends U> keyExtractor)
+    {
+        return thenComparing(comparing(keyExtractor));
     }
 
     /**
-     * Constructs a lexicographic order comparator with a function that
-     * extracts a {@code int} value.  This default implementation calls {@code
-     * thenComparing(this, Comparators.comparing(keyExtractor))}.
+     * Returns a lexicographic-order comparator with a function that
+     * extracts a {@code int} sort key.
+     *
+     * @implSpec This default implementation behaves as if {@code
+     *           thenComparing(comparing(keyExtractor))}.
      *
-     * @param keyExtractor the function used to extract the integer value
+     * @param  keyExtractor the function used to extract the integer sort key
+     * @return a lexicographic-order comparator composed of this and then the
+     *         {@code int} sort key
      * @throws NullPointerException if the argument is null.
-     * @see Comparators#comparing(ToIntFunction)
+     * @see #comparing(ToIntFunction)
      * @see #thenComparing(Comparator)
      * @since 1.8
      */
     default Comparator<T> thenComparing(ToIntFunction<? super T> keyExtractor) {
-        return thenComparing(Comparators.comparing(keyExtractor));
+        return thenComparing(comparing(keyExtractor));
     }
 
     /**
-     * Constructs a lexicographic order comparator with a function that
-     * extracts a {@code long} value.  This default implementation calls
-     * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+     * Returns a lexicographic-order comparator with a function that
+     * extracts a {@code long} sort key.
+     *
+     * @implSpec This default implementation behaves as if {@code
+     *           thenComparing(comparing(keyExtractor))}.
      *
-     * @param keyExtractor the function used to extract the long value
+     * @param  keyExtractor the function used to extract the long sort key
+     * @return a lexicographic-order comparator composed of this and then the
+     *         {@code long} sort key
      * @throws NullPointerException if the argument is null.
-     * @see Comparators#comparing(ToLongFunction)
+     * @see #comparing(ToLongFunction)
      * @see #thenComparing(Comparator)
      * @since 1.8
      */
     default Comparator<T> thenComparing(ToLongFunction<? super T> keyExtractor) {
-        return thenComparing(Comparators.comparing(keyExtractor));
+        return thenComparing(comparing(keyExtractor));
     }
 
     /**
-     * Constructs a lexicographic order comparator with a function that
-     * extracts a {@code double} value.  This default implementation calls
-     * {@code thenComparing(this, Comparators.comparing(keyExtractor))}.
+     * Returns a lexicographic-order comparator with a function that
+     * extracts a {@code double} sort key.
+     *
+     * @implSpec This default implementation behaves as if {@code
+     *           thenComparing(comparing(keyExtractor))}.
      *
-     * @param keyExtractor the function used to extract the double value
+     * @param  keyExtractor the function used to extract the double sort key
+     * @return a lexicographic-order comparator composed of this and then the
+     *         {@code double} sort key
      * @throws NullPointerException if the argument is null.
-     * @see Comparators#comparing(ToDoubleFunction)
+     * @see #comparing(ToDoubleFunction)
      * @see #thenComparing(Comparator)
      * @since 1.8
      */
     default Comparator<T> thenComparing(ToDoubleFunction<? super T> keyExtractor) {
-        return thenComparing(Comparators.comparing(keyExtractor));
+        return thenComparing(comparing(keyExtractor));
+    }
+
+    /**
+     * Returns a comparator that imposes the reverse of the <em>natural
+     * ordering</em>.
+     *
+     * <p>The returned comparator is serializable and throws {@link
+     * NullPointerException} when comparing {@code null}.
+     *
+     * @param  <T> the {@link Comparable} type of element to be compared
+     * @return a comparator that imposes the reverse of the <i>natural
+     *         ordering</i> on {@code Comparable} objects.
+     * @see Comparable
+     * @since 1.8
+     */
+    public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
+        return Collections.reverseOrder();
+    }
+
+    /**
+     * Returns a comparator that compares {@link Comparable} objects in natural
+     * order.
+     *
+     * <p>The returned comparator is serializable and throws {@link
+     * NullPointerException} when comparing {@code null}.
+     *
+     * @param  <T> the {@link Comparable} type of element to be compared
+     * @return a comparator that imposes the <i>natural ordering</i> on {@code
+     *         Comparable} objects.
+     * @see Comparable
+     * @since 1.8
+     */
+    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
+        return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
+    }
+
+    /**
+     * Returns a null-friendly comparator that considers {@code null} to be
+     * less than non-null. When both are {@code null}, they are considered
+     * equal. If both are non-null, the specified {@code Comparator} is used
+     * to determine the order. If the specified comparator is {@code null},
+     * then the returned comparator considers all non-null values to be equal.
+     *
+     * <p>The returned comparator is serializable if the specified comparator
+     * is serializable.
+     *
+     * @param  <T> the type of the elements to be compared
+     * @param  comparator a {@code Comparator} for comparing non-null values
+     * @return a comparator that considers {@code null} to be less than
+     *         non-null, and compares non-null objects with the supplied
+     *         {@code Comparator}.
+     * @since 1.8
+     */
+    public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
+        return new Comparators.NullComparator(true, comparator);
+    }
+
+    /**
+     * Returns a null-friendly comparator that considers {@code null} to be
+     * greater than non-null. When both are {@code null}, they are considered
+     * equal. If both are non-null, the specified {@code Comparator} is used
+     * to determine the order. If the specified comparator is {@code null},
+     * then the returned comparator considers all non-null values to be equal.
+     *
+     * <p>The returned comparator is serializable if the specified comparator
+     * is serializable.
+     *
+     * @param  <T> the type of the elements to be compared
+     * @param  comparator a {@code Comparator} for comparing non-null values
+     * @return a comparator that considers {@code null} to be greater than
+     *         non-null, and compares non-null objects with the supplied
+     *         {@code Comparator}.
+     * @since 1.8
+     */
+    public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
+        return new Comparators.NullComparator(false, comparator);
+    }
+
+    /**
+     * Accepts a function that extracts a sort key from a type {@code T}, and
+     * returns a {@code Comparator<T>} that compares by that sort key using
+     * the specified {@link Comparator}.
+      *
+     * <p>The returned comparator is serializable if the specified function
+     * and comparator are both serializable.
+     *
+     * @apiNote
+     * For example, to obtain a {@code Comparator} that compares {@code
+     * Person} objects by their last name ignoring case differences,
+     *
+     * <pre>{@code
+     *     Comparator<Person> cmp = Comparator.comparing(
+     *             Person::getLastName,
+     *             String.CASE_INSENSITIVE_ORDER);
+     * }</pre>
+     *
+     * @param  <T> the type of element to be compared
+     * @param  <U> the type of the sort key
+     * @param  keyExtractor the function used to extract the sort key
+     * @param  keyComparator the {@code Comparator} used to compare the sort key
+     * @return a comparator that compares by an extracted key using the
+     *         specified {@code Comparator}
+     * @throws NullPointerException if either argument is null
+     * @since 1.8
+     */
+    public static <T, U> Comparator<T> comparing(
+            Function<? super T, ? extends U> keyExtractor,
+            Comparator<? super U> keyComparator)
+    {
+        Objects.requireNonNull(keyExtractor);
+        Objects.requireNonNull(keyComparator);
+        return (Comparator<T> & Serializable)
+            (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
+                                              keyExtractor.apply(c2));
+    }
+
+    /**
+     * Accepts a function that extracts a {@link java.lang.Comparable
+     * Comparable} sort key from a type {@code T}, and returns a {@code
+     * Comparator<T>} that compares by that sort key.
+     *
+     * <p>The returned comparator is serializable if the specified function
+     * is also serializable.
+     *
+     * @apiNote
+     * For example, to obtain a {@code Comparator} that compares {@code
+     * Person} objects by their last name,
+     *
+     * <pre>{@code
+     *     Comparator<Person> byLastName = Comparator.comparing(Person::getLastName);
+     * }</pre>
+     *
+     * @param  <T> the type of element to be compared
+     * @param  <U> the type of the {@code Comparable} sort key
+     * @param  keyExtractor the function used to extract the {@link
+     *         Comparable} sort key
+     * @return a comparator that compares by an extracted key
+     * @throws NullPointerException if the argument is null
+     * @since 1.8
+     */
+    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
+            Function<? super T, ? extends U> keyExtractor)
+    {
+        Objects.requireNonNull(keyExtractor);
+        return (Comparator<T> & Serializable)
+            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
+    }
+
+    /**
+     * Accepts a function that extracts an {@code int} sort key from a type
+     * {@code T}, and returns a {@code Comparator<T>} that compares by that
+     * sort key.
+     *
+     * <p>The returned comparator is serializable if the specified function
+     * is also serializable.
+     *
+     * @param  <T> the type of element to be compared
+     * @param  keyExtractor the function used to extract the integer sort key
+     * @return a comparator that compares by an extracted key
+     * @see #comparing(Function)
+     * @throws NullPointerException if the argument is null
+     * @since 1.8
+     */
+    public static <T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor) {
+        Objects.requireNonNull(keyExtractor);
+        return (Comparator<T> & Serializable)
+            (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
+    }
+
+    /**
+     * Accepts a function that extracts a {@code long} sort key from a type
+     * {@code T}, and returns a {@code Comparator<T>} that compares by that
+     * sort key.
+     *
+     * <p>The returned comparator is serializable if the specified function is
+     * also serializable.
+     *
+     * @param  <T> the type of element to be compared
+     * @param  keyExtractor the function used to extract the long sort key
+     * @return a comparator that compares by an extracted key
+     * @see #comparing(Function)
+     * @throws NullPointerException if the argument is null
+     * @since 1.8
+     */
+    public static <T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor) {
+        Objects.requireNonNull(keyExtractor);
+        return (Comparator<T> & Serializable)
+            (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
+    }
+
+    /**
+     * Accepts a function that extracts a {@code double} sort key from a type
+     * {@code T}, and returns a {@code Comparator<T>} that compares by that
+     * sort key.
+     *
+     * <p>The returned comparator is serializable if the specified function
+     * is also serializable.
+     *
+     * @param  <T> the type of element to be compared
+     * @param  keyExtractor the function used to extract the double sort key
+     * @return a comparator that compares by an extracted key
+     * @see #comparing(Function)
+     * @throws NullPointerException if the argument is null
+     * @since 1.8
+     */
+    public static<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor) {
+        Objects.requireNonNull(keyExtractor);
+        return (Comparator<T> & Serializable)
+            (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
     }
 }
--- a/jdk/src/share/classes/java/util/Comparators.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/Comparators.java	Tue Jun 11 13:41:38 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -32,16 +32,9 @@
 import java.util.function.ToLongFunction;
 
 /**
- * This class consists of {@code static} utility methods for comparators. Mostly
- * factory method that returns a {@link Comparator}.
- *
- * <p> Unless otherwise noted, passing a {@code null} argument to a method in
- * this class will cause a {@link NullPointerException} to be thrown.
- *
- * @see Comparator
- * @since 1.8
+ * Package private supporting class for {@link Comparator}.
  */
-public class Comparators {
+class Comparators {
     private Comparators() {
         throw new AssertionError("no instances");
     }
@@ -51,231 +44,55 @@
      *
      * @see Comparable
      */
-    private enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
+    enum NaturalOrderComparator implements Comparator<Comparable<Object>> {
         INSTANCE;
 
         @Override
         public int compare(Comparable<Object> c1, Comparable<Object> c2) {
             return c1.compareTo(c2);
         }
-    }
 
-    /**
-     * Returns a comparator that imposes the reverse of the <em>natural
-     * ordering</em>.
-     *
-     * <p>The returned comparator is serializable.
-     *
-     * @param <T> {@link Comparable} type
-     *
-     * @return A comparator that imposes the reverse of the <i>natural
-     *         ordering</i> on a collection of objects that implement
-     *         the {@link Comparable} interface.
-     * @see Comparable
-     */
-    public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
-        return Collections.reverseOrder();
-    }
-
-    /**
-     * Returns a comparator that imposes the reverse ordering of the specified
-     * {@link Comparator}.
-     *
-     * <p>The returned comparator is serializable (assuming the specified
-     * comparator is also serializable).
-     *
-     * @param <T> the element type to be compared
-     * @param cmp a comparator whose ordering is to be reversed by the returned
-     *            comparator
-     * @return A comparator that imposes the reverse ordering of the
-     *         specified comparator.
-     */
-    public static <T> Comparator<T> reverseOrder(Comparator<T> cmp) {
-        Objects.requireNonNull(cmp);
-        return Collections.reverseOrder(cmp);
-    }
-
-    /**
-     * Gets a comparator compares {@link Comparable} type in natural order.
-     *
-     * @param <T> {@link Comparable} type
-     */
-    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
-        return (Comparator<T>) NaturalOrderComparator.INSTANCE;
-    }
-
-    /**
-     * Gets a comparator compares {@link Map.Entry} in natural order on key.
-     *
-     * @param <K> {@link Comparable} key type
-     * @param <V> value type
-     */
-    public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> naturalOrderKeys() {
-        return (Comparator<Map.Entry<K, V>> & Serializable)
-            (c1, c2) -> c1.getKey().compareTo(c2.getKey());
-    }
-
-    /**
-     * Gets a comparator compares {@link Map.Entry} in natural order on value.
-     *
-     * @param <K> key type
-     * @param <V> {@link Comparable} value type
-     */
-    public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> naturalOrderValues() {
-        return (Comparator<Map.Entry<K, V>> & Serializable)
-            (c1, c2) -> c1.getValue().compareTo(c2.getValue());
-    }
-
-    /**
-     * Gets a comparator compares {@link Map.Entry} by key using the given
-     * {@link Comparator}.
-     *
-     * <p>The returned comparator is serializable assuming the specified
-     * comparators are also serializable.
-     *
-     * @param <K> key type
-     * @param <V> value type
-     * @param cmp the key {@link Comparator}
-     */
-    public static <K, V> Comparator<Map.Entry<K, V>> byKey(Comparator<? super K> cmp) {
-        Objects.requireNonNull(cmp);
-        return (Comparator<Map.Entry<K, V>> & Serializable)
-            (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
-    }
-
-    /**
-     * Gets a comparator compares {@link Map.Entry} by value using the given
-     * {@link Comparator}.
-     *
-     * @param <K> key type
-     * @param <V> value type
-     * @param cmp the value {@link Comparator}
-     */
-    public static <K, V> Comparator<Map.Entry<K, V>> byValue(Comparator<? super V> cmp) {
-        Objects.requireNonNull(cmp);
-        return (Comparator<Map.Entry<K, V>> & Serializable)
-            (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
+        @Override
+        public Comparator<Comparable<Object>> reversed() {
+            return Comparator.reverseOrder();
+        }
     }
 
     /**
-     * Accepts a function that extracts a {@link java.lang.Comparable
-     * Comparable} sort key from a type {@code T}, and returns a {@code
-     * Comparator<T>} that compares by that sort key.  For example, if a class
-     * {@code Person} has a {@code String}-valued getter {@code getLastName},
-     * then {@code comparing(Person::getLastName)} would return a {@code
-     * Comparator<Person>} that compares {@code Person} objects by their last
-     * name.
-     *
-     * @param <T> the original element type
-     * @param <U> the {@link Comparable} type for comparison
-     * @param keyExtractor the function used to extract the {@link Comparable} sort key
+     * Null-friendly comparators
      */
-    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor) {
-        Objects.requireNonNull(keyExtractor);
-        return (Comparator<T> & Serializable)
-            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
-    }
+    final static class NullComparator<T> implements Comparator<T>, Serializable {
+        private static final long serialVersionUID = -7569533591570686392L;
+        private final boolean nullFirst;
+        // if null, non-null Ts are considered equal
+        private final Comparator<T> real;
 
-    /**
-     * Accepts a function that extracts an {@code int} value from a type {@code
-     * T}, and returns a {@code Comparator<T>} that compares by that value.
-     *
-     * <p>The returned comparator is serializable assuming the specified
-     * function is also serializable.
-     *
-     * @see #comparing(Function)
-     * @param <T> the original element type
-     * @param keyExtractor the function used to extract the integer value
-     */
-    public static <T> Comparator<T> comparing(ToIntFunction<? super T> keyExtractor) {
-        Objects.requireNonNull(keyExtractor);
-        return (Comparator<T> & Serializable)
-            (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
-    }
-
-    /**
-     * Accepts a function that extracts a {@code long} value from a type {@code
-     * T}, and returns a {@code Comparator<T>} that compares by that value.
-     *
-     * <p>The returned comparator is serializable assuming the specified
-     * function is also serializable.
-     *
-     * @see #comparing(Function)
-     * @param <T> the original element type
-     * @param keyExtractor the function used to extract the long value
-     */
-    public static <T> Comparator<T> comparing(ToLongFunction<? super T> keyExtractor) {
-        Objects.requireNonNull(keyExtractor);
-        return (Comparator<T> & Serializable)
-            (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
-    }
+        @SuppressWarnings("unchecked")
+        NullComparator(boolean nullFirst, Comparator<? super T> real) {
+            this.nullFirst = nullFirst;
+            this.real = (Comparator<T>) real;
+        }
 
-    /**
-     * Accepts a function that extracts a {@code double} value from a type
-     * {@code T}, and returns a {@code Comparator<T>} that compares by that
-     * value.
-     *
-     * <p>The returned comparator is serializable assuming the specified
-     * function is also serializable.
-     *
-     * @see #comparing(Function)
-     * @param <T> the original element type
-     * @param keyExtractor the function used to extract the double value
-     */
-    public static<T> Comparator<T> comparing(ToDoubleFunction<? super T> keyExtractor) {
-        Objects.requireNonNull(keyExtractor);
-        return (Comparator<T> & Serializable)
-            (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
-    }
+        @Override
+        public int compare(T a, T b) {
+            if (a == null) {
+                return (b == null) ? 0 : (nullFirst ? -1 : 1);
+            } else if (b == null) {
+                return nullFirst ? 1: -1;
+            } else {
+                return (real == null) ? 0 : real.compare(a, b);
+            }
+        }
 
-    /**
-     * Constructs a lexicographic order from two {@link Comparator}s.  For
-     * example, if you have comparators {@code byLastName} and {@code
-     * byFirstName}, each of type {@code Comparator<Person>}, then {@code
-     * compose(byLastName, byFirstName)} creates a {@code Comparator<Person>}
-     * which sorts by last name, and for equal last names sorts by first name.
-     *
-     * <p>The returned comparator is serializable assuming the specified
-     * comparators are also serializable.
-     *
-     * @param <T> the element type to be compared
-     * @param first the first comparator
-     * @param second the secondary comparator used when equals on the first
-     */
-    public static<T> Comparator<T> compose(Comparator<? super T> first, Comparator<? super T> second) {
-        Objects.requireNonNull(first);
-        Objects.requireNonNull(second);
-        return (Comparator<T> & Serializable) (c1, c2) -> {
-            int res = first.compare(c1, c2);
-            return (res != 0) ? res : second.compare(c1, c2);
-        };
-    }
+        @Override
+        public Comparator<T> thenComparing(Comparator<? super T> other) {
+            Objects.requireNonNull(other);
+            return new NullComparator(nullFirst, real == null ? other : real.thenComparing(other));
+        }
 
-    /**
-     * Constructs a {@link BinaryOperator} which returns the lesser of two elements
-     * according to the specified {@code Comparator}
-     *
-     * @param comparator A {@code Comparator} for comparing the two values
-     * @param <T> the type of the elements to be compared
-     * @return a {@code BinaryOperator} which returns the lesser of its operands,
-     * according to the supplied {@code Comparator}
-     */
-    public static<T> BinaryOperator<T> lesserOf(Comparator<? super T> comparator) {
-        Objects.requireNonNull(comparator);
-        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
-    }
-
-    /**
-     * Constructs a {@link BinaryOperator} which returns the greater of two elements
-     * according to the specified {@code Comparator}
-     *
-     * @param comparator A {@code Comparator} for comparing the two values
-     * @param <T> the type of the elements to be compared
-     * @return a {@code BinaryOperator} which returns the greater of its operands,
-     * according to the supplied {@code Comparator}
-     */
-    public static<T> BinaryOperator<T> greaterOf(Comparator<? super T> comparator) {
-        Objects.requireNonNull(comparator);
-        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
+        @Override
+        public Comparator<T> reversed() {
+            return new NullComparator(!nullFirst, real == null ? null : real.reversed());
+        }
     }
 }
--- a/jdk/src/share/classes/java/util/Map.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/Map.java	Tue Jun 11 13:41:38 2013 -0700
@@ -28,6 +28,7 @@
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.Function;
+import java.io.Serializable;
 
 /**
  * An object that maps keys to values.  A map cannot contain duplicate keys;
@@ -446,6 +447,74 @@
          * @see #equals(Object)
          */
         int hashCode();
+
+        /**
+         * Returns a comparator that compares {@link Map.Entry} in natural order on key.
+         *
+         * <p>The returned comparator is serializable and throws {@link
+         * NullPointerException} when comparing an entry with a null key.
+         *
+         * @param  <K> the {@link Comparable} type of then map keys
+         * @param  <V> the type of the map values
+         * @return a comparator that compares {@link Map.Entry} in natural order on key.
+         * @see Comparable
+         */
+        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
+            return (Comparator<Map.Entry<K, V>> & Serializable)
+                (c1, c2) -> c1.getKey().compareTo(c2.getKey());
+        }
+
+        /**
+         * Returns a comparator that compares {@link Map.Entry} in natural order on value.
+         *
+         * <p>The returned comparator is serializable and throws {@link
+         * NullPointerException} when comparing an entry with null values.
+         *
+         * @param <K> the type of the map keys
+         * @param <V> the {@link Comparable} type of the map values
+         * @return a comparator that compares {@link Map.Entry} in natural order on value.
+         * @see Comparable
+         */
+        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
+            return (Comparator<Map.Entry<K, V>> & Serializable)
+                (c1, c2) -> c1.getValue().compareTo(c2.getValue());
+        }
+
+        /**
+         * Returns a comparator that compares {@link Map.Entry} by key using the given
+         * {@link Comparator}.
+         *
+         * <p>The returned comparator is serializable if the specified comparator
+         * is also serializable.
+         *
+         * @param  <K> the type of the map keys
+         * @param  <V> the type of the map values
+         * @param  cmp the key {@link Comparator}
+         * @return a comparator that compares {@link Map.Entry} by the key.
+         */
+        public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
+            Objects.requireNonNull(cmp);
+            return (Comparator<Map.Entry<K, V>> & Serializable)
+                (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
+        }
+
+        /**
+         * Returns a comparator that compares {@link Map.Entry} by value using the given
+         * {@link Comparator}.
+         *
+         * <p>The returned comparator is serializable if the specified comparator
+         * is also serializable.
+         *
+         * @param  <K> the type of the map keys
+         * @param  <V> the type of the map values
+         * @param  cmp the value {@link Comparator}
+         * @return a comparator that compares {@link Map.Entry} by the value.
+         */
+        public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
+            Objects.requireNonNull(cmp);
+            return (Comparator<Map.Entry<K, V>> & Serializable)
+                (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
+        }
     }
 
     // Comparison and hashing
--- a/jdk/src/share/classes/java/util/TreeMap.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/TreeMap.java	Tue Jun 11 13:41:38 2013 -0700
@@ -2938,13 +2938,13 @@
 
         public int characteristics() {
             return (side == 0 ? Spliterator.SIZED : 0) |
-                   Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
+                    Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
         }
 
         @Override
         public Comparator<? super Map.Entry<K, V>> getComparator() {
             return tree.comparator != null ?
-                   Comparators.byKey(tree.comparator) : null;
+                    Map.Entry.comparingByKey(tree.comparator) : null;
         }
     }
 }
--- a/jdk/src/share/classes/java/util/function/BinaryOperator.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/function/BinaryOperator.java	Tue Jun 11 13:41:38 2013 -0700
@@ -24,6 +24,9 @@
  */
 package java.util.function;
 
+import java.util.Objects;
+import java.util.Comparator;
+
 /**
  * An operation upon two operands yielding a result. This is a specialization of
  * {@code BiFunction} where the operands and the result are all of the same type.
@@ -35,4 +38,31 @@
  */
 @FunctionalInterface
 public interface BinaryOperator<T> extends BiFunction<T,T,T> {
+    /**
+     * Returns a {@link BinaryOperator} which returns the lesser of two elements
+     * according to the specified {@code Comparator}
+     *
+     * @param  comparator a {@code Comparator} for comparing the two values
+     * @return a {@code BinaryOperator} which returns the lesser of its operands,
+     *         according to the supplied {@code Comparator}
+     * @throws NullPointerException if the argument is null
+     */
+    public static<T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
+        Objects.requireNonNull(comparator);
+        return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
+    }
+
+    /**
+     * Returns a {@link BinaryOperator} which returns the greater of two elements
+     * according to the specified {@code Comparator}
+     *
+     * @param  comparator a {@code Comparator} for comparing the two values
+     * @return a {@code BinaryOperator} which returns the greater of its operands,
+     *         according to the supplied {@code Comparator}
+     * @throws NullPointerException if the argument is null
+     */
+    public static<T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
+        Objects.requireNonNull(comparator);
+        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
+    }
 }
--- a/jdk/src/share/classes/java/util/stream/Collectors.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/Collectors.java	Tue Jun 11 13:41:38 2013 -0700
@@ -30,7 +30,6 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Comparators;
 import java.util.DoubleSummaryStatistics;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -78,7 +77,7 @@
  *
  *     // Find highest-paid employee
  *     Employee highestPaid = employees.stream()
- *                                     .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
+ *                                     .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)));
  *
  *     // Group employees by department
  *     Map<Department, List<Employee>> byDept
@@ -89,7 +88,7 @@
  *     Map<Department, Employee> highestPaidByDept
  *         = employees.stream()
  *                    .collect(Collectors.groupingBy(Employee::getDepartment,
- *                                                   Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
+ *                                                   Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
  *
  *     // Partition students into passing and failing
  *     Map<Boolean, List<Student>> passingFailing =
@@ -404,7 +403,7 @@
      * @implSpec
      * This produces a result equivalent to:
      * <pre>{@code
-     *     reducing(Comparators.lesserOf(comparator))
+     *     reducing(BinaryOperator.minBy(comparator))
      * }</pre>
      *
      * @param <T> the type of the input elements
@@ -413,7 +412,7 @@
      */
     public static <T> Collector<T, T>
     minBy(Comparator<? super T> comparator) {
-        return reducing(Comparators.lesserOf(comparator));
+        return reducing(BinaryOperator.minBy(comparator));
     }
 
     /**
@@ -423,7 +422,7 @@
      * @implSpec
      * This produces a result equivalent to:
      * <pre>{@code
-     *     reducing(Comparators.greaterOf(comparator))
+     *     reducing(BinaryOperator.maxBy(comparator))
      * }</pre>
      *
      * @param <T> the type of the input elements
@@ -432,7 +431,7 @@
      */
     public static <T> Collector<T, T>
     maxBy(Comparator<? super T> comparator) {
-        return reducing(Comparators.greaterOf(comparator));
+        return reducing(BinaryOperator.maxBy(comparator));
     }
 
     /**
@@ -491,8 +490,8 @@
      * <p>For example, given a stream of {@code Person}, to calculate tallest
      * person in each city:
      * <pre>{@code
-     *     Comparator<Person> byHeight = Comparators.comparing(Person::getHeight);
-     *     BinaryOperator<Person> tallerOf = Comparators.greaterOf(byHeight);
+     *     Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
+     *     BinaryOperator<Person> tallerOf = BinaryOperator.greaterOf(byHeight);
      *     Map<City, Person> tallestByCity
      *         = people.stream().collect(groupingBy(Person::getCity, reducing(tallerOf)));
      * }</pre>
@@ -531,8 +530,8 @@
      * <p>For example, given a stream of {@code Person}, to calculate the longest
      * last name of residents in each city:
      * <pre>{@code
-     *     Comparator<String> byLength = Comparators.comparing(String::length);
-     *     BinaryOperator<String> longerOf = Comparators.greaterOf(byLength);
+     *     Comparator<String> byLength = Comparator.comparing(String::length);
+     *     BinaryOperator<String> longerOf = BinaryOperator.greaterOf(byLength);
      *     Map<City, String> longestLastNameByCity
      *         = people.stream().collect(groupingBy(Person::getCity,
      *                                              reducing(Person::getLastName, longerOf)));
--- a/jdk/src/share/classes/java/util/stream/ReferencePipeline.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/ReferencePipeline.java	Tue Jun 11 13:41:38 2013 -0700
@@ -25,7 +25,6 @@
 package java.util.stream;
 
 import java.util.Comparator;
-import java.util.Comparators;
 import java.util.Iterator;
 import java.util.Objects;
 import java.util.Optional;
@@ -512,12 +511,12 @@
 
     @Override
     public final Optional<P_OUT> max(Comparator<? super P_OUT> comparator) {
-        return reduce(Comparators.greaterOf(comparator));
+        return reduce(BinaryOperator.maxBy(comparator));
     }
 
     @Override
     public final Optional<P_OUT> min(Comparator<? super P_OUT> comparator) {
-        return reduce(Comparators.lesserOf(comparator));
+        return reduce(BinaryOperator.minBy(comparator));
 
     }
 
--- a/jdk/src/share/classes/java/util/stream/SortedOps.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/src/share/classes/java/util/stream/SortedOps.java	Tue Jun 11 13:41:38 2013 -0700
@@ -27,7 +27,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
-import java.util.Comparators;
 import java.util.Objects;
 import java.util.Spliterator;
 import java.util.concurrent.ForkJoinTask;
@@ -114,7 +113,7 @@
                   StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
             this.isNaturalSort = true;
             // Will throw CCE when we try to sort if T is not Comparable
-            this.comparator = (Comparator<? super T>) Comparators.naturalOrder();
+            this.comparator = (Comparator<? super T>) Comparator.naturalOrder();
         }
 
         /**
--- a/jdk/test/java/nio/file/Files/StreamTest.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/test/java/nio/file/Files/StreamTest.java	Tue Jun 11 13:41:38 2013 -0700
@@ -43,7 +43,7 @@
 import java.nio.file.Paths;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Arrays;
-import java.util.Comparators;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
@@ -139,7 +139,7 @@
 
     public void testBasic() {
         try (CloseableStream<Path> s = Files.list(testFolder)) {
-            Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
+            Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
             assertEquals(actual, level1);
         } catch (IOException ioe) {
             fail("Unexpected IOException");
@@ -155,7 +155,7 @@
 
     public void testWalk() {
         try (CloseableStream<Path> s = Files.walk(testFolder)) {
-            Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
+            Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
             assertEquals(actual, all);
         } catch (IOException ioe) {
             fail("Unexpected IOException");
@@ -165,7 +165,7 @@
     public void testWalkOneLevel() {
         try (CloseableStream<Path> s = Files.walk(testFolder, 1)) {
             Object[] actual = s.filter(path -> ! path.equals(testFolder))
-                               .sorted(Comparators.naturalOrder())
+                               .sorted(Comparator.naturalOrder())
                                .toArray();
             assertEquals(actual, level1);
         } catch (IOException ioe) {
@@ -177,7 +177,7 @@
         // If link is not supported, the directory structure won't have link.
         // We still want to test the behavior with FOLLOW_LINKS option.
         try (CloseableStream<Path> s = Files.walk(testFolder, FileVisitOption.FOLLOW_LINKS)) {
-            Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
+            Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
             assertEquals(actual, all_folowLinks);
         } catch (IOException ioe) {
             fail("Unexpected IOException");
@@ -637,13 +637,13 @@
     public void testClosedStream() throws IOException {
         try (CloseableStream<Path> s = Files.list(testFolder)) {
             s.close();
-            Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
+            Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
             assertTrue(actual.length <= level1.length);
         }
 
         try (CloseableStream<Path> s = Files.walk(testFolder)) {
             s.close();
-            Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
+            Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
             fail("Operate on closed stream should throw IllegalStateException");
         } catch (IllegalStateException ex) {
             // expected
@@ -652,7 +652,7 @@
         try (CloseableStream<Path> s = Files.find(testFolder, Integer.MAX_VALUE,
                     (p, attr) -> true)) {
             s.close();
-            Object[] actual = s.sorted(Comparators.naturalOrder()).toArray();
+            Object[] actual = s.sorted(Comparator.naturalOrder()).toArray();
             fail("Operate on closed stream should throw IllegalStateException");
         } catch (IllegalStateException ex) {
             // expected
--- a/jdk/test/java/util/Collection/ListDefaults.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/test/java/util/Collection/ListDefaults.java	Tue Jun 11 13:41:38 2013 -0700
@@ -25,7 +25,6 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Comparators;
 import java.util.List;
 import java.util.LinkedList;
 import java.util.Stack;
@@ -337,23 +336,23 @@
 
             CollectionSupplier.shuffle(list);
             list.sort(null);
-            CollectionAsserts.assertSorted(list, Comparators.<Integer>naturalOrder());
+            CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
             if (test.name.startsWith("reverse")) {
                 Collections.reverse(list);
             }
             CollectionAsserts.assertContents(list, original);
 
             CollectionSupplier.shuffle(list);
-            list.sort(Comparators.<Integer>naturalOrder());
-            CollectionAsserts.assertSorted(list, Comparators.<Integer>naturalOrder());
+            list.sort(Comparator.<Integer>naturalOrder());
+            CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
             if (test.name.startsWith("reverse")) {
                 Collections.reverse(list);
             }
             CollectionAsserts.assertContents(list, original);
 
             CollectionSupplier.shuffle(list);
-            list.sort(Comparators.<Integer>reverseOrder());
-            CollectionAsserts.assertSorted(list, Comparators.<Integer>reverseOrder());
+            list.sort(Comparator.<Integer>reverseOrder());
+            CollectionAsserts.assertSorted(list, Comparator.<Integer>reverseOrder());
             if (!test.name.startsWith("reverse")) {
                 Collections.reverse(list);
             }
@@ -390,8 +389,8 @@
                 final List<Integer> copy = new ArrayList<>(list);
                 final List<Integer> subList = list.subList(SUBLIST_FROM, SUBLIST_TO);
                 CollectionSupplier.shuffle(subList);
-                subList.sort(Comparators.<Integer>naturalOrder());
-                CollectionAsserts.assertSorted(subList, Comparators.<Integer>naturalOrder());
+                subList.sort(Comparator.<Integer>naturalOrder());
+                CollectionAsserts.assertSorted(subList, Comparator.<Integer>naturalOrder());
                 // verify that elements [0, from) remain unmodified
                 for (int i = 0; i < SUBLIST_FROM; i++) {
                     assertTrue(list.get(i) == copy.get(i),
@@ -412,8 +411,8 @@
                 public void call(final List<Integer> list) {
                     final List<Integer> copy = new ArrayList<>(list);
                     CollectionSupplier.shuffle(list);
-                    list.sort(Comparators.<Integer>naturalOrder());
-                    CollectionAsserts.assertSorted(list, Comparators.<Integer>naturalOrder());
+                    list.sort(Comparator.<Integer>naturalOrder());
+                    CollectionAsserts.assertSorted(list, Comparator.<Integer>naturalOrder());
                 }
             });
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Comparator/BasicTest.java	Tue Jun 11 13:41:38 2013 -0700
@@ -0,0 +1,369 @@
+/*
+ * 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
+ * @summary Comparator default method tests
+ * @run testng BasicTest
+ */
+
+import java.util.TreeMap;
+import java.util.Comparator;
+import org.testng.annotations.Test;
+
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+import java.util.function.ToDoubleFunction;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+@Test(groups = "unit")
+public class BasicTest {
+    private static class Thing {
+        public final int intField;
+        public final long longField;
+        public final double doubleField;
+        public final String stringField;
+
+        private Thing(int intField, long longField, double doubleField, String stringField) {
+            this.intField = intField;
+            this.longField = longField;
+            this.doubleField = doubleField;
+            this.stringField = stringField;
+        }
+
+        public int getIntField() {
+            return intField;
+        }
+
+        public long getLongField() {
+            return longField;
+        }
+
+        public double getDoubleField() {
+            return doubleField;
+        }
+
+        public String getStringField() {
+            return stringField;
+        }
+    }
+
+    private final int[] intValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+    private final long[] longValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+    private final double[] doubleValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
+    private final String[] stringValues = { "a", "a", "b", "b", "c", "c", "d", "d", "e", "e" };
+    private final int[] comparisons = { 0, -1, 0, -1, 0, -1, 0, -1, 0 };
+
+    private<T> void assertComparisons(T[] things, Comparator<T> comp, int[] comparisons) {
+        for (int i=0; i<comparisons.length; i++) {
+            assertEquals(comparisons.length + 1, things.length);
+            assertEquals(comparisons[i], comp.compare(things[i], things[i+1]));
+            assertEquals(-comparisons[i], comp.compare(things[i+1], things[i]));
+        }
+    }
+
+    public void testIntComparator() {
+        Thing[] things = new Thing[intValues.length];
+        for (int i=0; i<intValues.length; i++)
+            things[i] = new Thing(intValues[i], 0L, 0.0, null);
+        Comparator<Thing> comp = Comparator.comparing(new ToIntFunction<Thing>() {
+            @Override
+            public int applyAsInt(Thing thing) {
+                return thing.getIntField();
+            }
+        });
+
+        assertComparisons(things, comp, comparisons);
+    }
+
+    public void testLongComparator() {
+        Thing[] things = new Thing[longValues.length];
+        for (int i=0; i<longValues.length; i++)
+            things[i] = new Thing(0, longValues[i], 0.0, null);
+        Comparator<Thing> comp = Comparator.comparing(new ToLongFunction<Thing>() {
+            @Override
+            public long applyAsLong(Thing thing) {
+                return thing.getLongField();
+            }
+        });
+
+        assertComparisons(things, comp, comparisons);
+    }
+
+    public void testDoubleComparator() {
+        Thing[] things = new Thing[doubleValues.length];
+        for (int i=0; i<doubleValues.length; i++)
+            things[i] = new Thing(0, 0L, doubleValues[i], null);
+        Comparator<Thing> comp = Comparator.comparing(new ToDoubleFunction<Thing>() {
+            @Override
+            public double applyAsDouble(Thing thing) {
+                return thing.getDoubleField();
+            }
+        });
+
+        assertComparisons(things, comp, comparisons);
+    }
+
+    public void testComparing() {
+        Thing[] things = new Thing[doubleValues.length];
+        for (int i=0; i<doubleValues.length; i++)
+            things[i] = new Thing(0, 0L, 0.0, stringValues[i]);
+        Comparator<Thing> comp = Comparator.comparing(new Function<Thing, String>() {
+            @Override
+            public String apply(Thing thing) {
+                return thing.getStringField();
+            }
+        });
+
+        assertComparisons(things, comp, comparisons);
+    }
+
+    public void testNaturalOrderComparator() {
+        Comparator<String> comp = Comparator.naturalOrder();
+
+        assertComparisons(stringValues, comp, comparisons);
+    }
+
+    public void testReverseComparator() {
+        Comparator<String> cmpr = Comparator.reverseOrder();
+        Comparator<String> cmp = cmpr.reversed();
+
+        assertEquals(cmp.reversed(), cmpr);
+        assertEquals(0, cmp.compare("a", "a"));
+        assertEquals(0, cmpr.compare("a", "a"));
+        assertTrue(cmp.compare("a", "b") < 0);
+        assertTrue(cmpr.compare("a", "b") > 0);
+        assertTrue(cmp.compare("b", "a") > 0);
+        assertTrue(cmpr.compare("b", "a") < 0);
+    }
+
+    public void testReverseComparator2() {
+        Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();
+        Comparator<String> cmpr = cmp.reversed();
+
+        assertEquals(cmpr.reversed(), cmp);
+        assertEquals(0, cmp.compare("abc", "def"));
+        assertEquals(0, cmpr.compare("abc", "def"));
+        assertTrue(cmp.compare("abcd", "def") > 0);
+        assertTrue(cmpr.compare("abcd", "def") < 0);
+        assertTrue(cmp.compare("abc", "defg") < 0);
+        assertTrue(cmpr.compare("abc", "defg") > 0);
+    }
+
+    private <T> void assertComparison(Comparator<T> cmp, T less, T greater) {
+        assertTrue(cmp.compare(less, greater) < 0, "less");
+        assertTrue(cmp.compare(less, less) == 0, "equal");
+        assertTrue(cmp.compare(greater, greater) == 0, "equal");
+        assertTrue(cmp.compare(greater, less) > 0, "greater");
+    }
+
+    private static class People {
+        final String firstName;
+        final String lastName;
+        final int age;
+
+        People(String first, String last, int age) {
+            firstName = first;
+            lastName = last;
+            this.age = age;
+        }
+
+        String getFirstName() { return firstName; }
+        String getLastName() { return lastName; }
+        int getAge() { return age; }
+        long getAgeAsLong() { return (long) age; };
+        double getAgeAsDouble() { return (double) age; };
+    }
+
+    private final People people[] = {
+        new People("John", "Doe", 34),
+        new People("Mary", "Doe", 30),
+        new People("Maria", "Doe", 14),
+        new People("Jonah", "Doe", 10),
+        new People("John", "Cook", 54),
+        new People("Mary", "Cook", 50),
+        new People("Mary", null, 25),
+        new People("John", null, 27)
+    };
+
+    public void testComparatorDefaultMethods() {
+        Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
+        Comparator<People> cmp2 = Comparator.comparing((Function<People, String>) People::getLastName);
+        // reverseOrder
+        assertComparison(cmp.reversed(), people[1], people[0]);
+        // thenComparing(Comparator)
+        assertComparison(cmp.thenComparing(cmp2), people[0], people[1]);
+        assertComparison(cmp.thenComparing(cmp2), people[4], people[0]);
+        // thenComparing(Function)
+        assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);
+        assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);
+        // thenComparing(ToIntFunction)
+        assertComparison(cmp.thenComparing(People::getAge), people[0], people[1]);
+        assertComparison(cmp.thenComparing(People::getAge), people[1], people[5]);
+        // thenComparing(ToLongFunction)
+        assertComparison(cmp.thenComparing(People::getAgeAsLong), people[0], people[1]);
+        assertComparison(cmp.thenComparing(People::getAgeAsLong), people[1], people[5]);
+        // thenComparing(ToDoubleFunction)
+        assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[0], people[1]);
+        assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[1], people[5]);
+    }
+
+
+    public void testNullsFirst() {
+        Comparator<String> strcmp = Comparator.nullsFirst(Comparator.naturalOrder());
+        Comparator<People> cmp = Comparator.<People, String>comparing(People::getLastName, strcmp)
+                                           .thenComparing(People::getFirstName, strcmp);
+        // Mary.null vs Mary.Cook - solve by last name
+        assertComparison(cmp, people[6], people[5]);
+        // John.null vs Mary.null - solve by first name
+        assertComparison(cmp, people[7], people[6]);
+
+        // More than one thenComparing
+        strcmp = Comparator.nullsFirst(Comparator.comparing((ToIntFunction<String>) String::length)
+                                                 .thenComparing(String.CASE_INSENSITIVE_ORDER));
+        assertComparison(strcmp, null, "abc");
+        assertComparison(strcmp, "ab", "abc");
+        assertComparison(strcmp, "abc", "def");
+        assertEquals(0, strcmp.compare("abc", "ABC"));
+
+        // Ensure reverse still handle null properly
+        Comparator<String> strcmp2 = strcmp.reversed().thenComparing(Comparator.naturalOrder());
+        assertComparison(strcmp2, "abc", null);
+        assertComparison(strcmp2, "abc", "ab");
+        assertComparison(strcmp2, "def", "abc");
+        assertComparison(strcmp2, "ABC", "abc");
+
+        // Considering non-null values to be equal
+        Comparator<String> blind = Comparator.nullsFirst(null);
+        assertComparison(blind, null, "abc");
+        assertEquals(0, blind.compare("abc", "def"));
+        // reverse still consider non-null values to be equal
+        strcmp = blind.reversed();
+        assertComparison(strcmp, "abc", null);
+        assertEquals(0, strcmp.compare("abc", "def"));
+        // chain with another comparator to compare non-nulls
+        strcmp = blind.thenComparing(Comparator.naturalOrder());
+        assertComparison(strcmp, null, "abc");
+        assertComparison(strcmp, "abc", "def");
+    }
+
+    public void testNullsLast() {
+        Comparator<String> strcmp = Comparator.nullsLast(Comparator.naturalOrder());
+        Comparator<People> cmp = Comparator.<People, String>comparing(People::getLastName, strcmp)
+                                           .thenComparing(People::getFirstName, strcmp);
+        // Mary.null vs Mary.Cook - solve by last name
+        assertComparison(cmp, people[5], people[6]);
+        // John.null vs Mary.null - solve by first name
+        assertComparison(cmp, people[7], people[6]);
+
+        // More than one thenComparing
+        strcmp = Comparator.nullsLast(Comparator.comparing((ToIntFunction<String>) String::length)
+                                                .thenComparing(String.CASE_INSENSITIVE_ORDER));
+        assertComparison(strcmp, "abc", null);
+        assertComparison(strcmp, "ab", "abc");
+        assertComparison(strcmp, "abc", "def");
+
+        // Ensure reverse still handle null properly
+        Comparator<String> strcmp2 = strcmp.reversed().thenComparing(Comparator.naturalOrder());
+        assertComparison(strcmp2, null, "abc");
+        assertComparison(strcmp2, "abc", "ab");
+        assertComparison(strcmp2, "def", "abc");
+        assertComparison(strcmp2, "ABC", "abc");
+
+        // Considering non-null values to be equal
+        Comparator<String> blind = Comparator.nullsLast(null);
+        assertComparison(blind, "abc", null);
+        assertEquals(0, blind.compare("abc", "def"));
+        // reverse still consider non-null values to be equal
+        strcmp = blind.reversed();
+        assertComparison(strcmp, null, "abc");
+        assertEquals(0, strcmp.compare("abc", "def"));
+        // chain with another comparator to compare non-nulls
+        strcmp = blind.thenComparing(Comparator.naturalOrder());
+        assertComparison(strcmp, "abc", null);
+        assertComparison(strcmp, "abc", "def");
+    }
+
+    public void testComposeComparator() {
+        // Longer string in front
+        Comparator<String> first = (s1, s2) -> s2.length() - s1.length();
+        Comparator<String> second = Comparator.naturalOrder();
+        Comparator<String> composed = first.thenComparing(second);
+
+        assertTrue(composed.compare("abcdefg", "abcdef") < 0);
+        assertTrue(composed.compare("abcdef", "abcdefg") > 0);
+        assertTrue(composed.compare("abcdef", "abcdef") == 0);
+        assertTrue(composed.compare("abcdef", "ghijkl") < 0);
+        assertTrue(composed.compare("ghijkl", "abcdefg") > 0);
+    }
+
+    public void testNulls() {
+        try {
+            Comparator.<String>naturalOrder().compare("abc", (String) null);
+            fail("expected NPE with naturalOrder");
+        } catch (NullPointerException npe) {}
+        try {
+            Comparator.<String>naturalOrder().compare((String) null, "abc");
+            fail("expected NPE with naturalOrder");
+        } catch (NullPointerException npe) {}
+
+        try {
+            Comparator.<String>reverseOrder().compare("abc", (String) null);
+            fail("expected NPE with naturalOrder");
+        } catch (NullPointerException npe) {}
+        try {
+            Comparator.<String>reverseOrder().compare((String) null, "abc");
+            fail("expected NPE with naturalOrder");
+        } catch (NullPointerException npe) {}
+
+        try {
+            Comparator<People> cmp = Comparator.comparing((Function<People, String>) null, Comparator.<String>naturalOrder());
+            fail("comparing(null, cmp) should throw NPE");
+        } catch (NullPointerException npe) {}
+        try {
+            Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName, null);
+            fail("comparing(f, null) should throw NPE");
+        } catch (NullPointerException npe) {}
+
+        try {
+            Comparator<People> cmp = Comparator.comparing((Function<People, String>) null);
+            fail("comparing(null) should throw NPE");
+        } catch (NullPointerException npe) {}
+        try {
+            Comparator<People> cmp = Comparator.comparing((ToIntFunction<People>) null);
+            fail("comparing(null) should throw NPE");
+        } catch (NullPointerException npe) {}
+        try {
+            Comparator<People> cmp = Comparator.comparing((ToLongFunction<People>) null);
+            fail("comparing(null) should throw NPE");
+        } catch (NullPointerException npe) {}
+        try {
+            Comparator<People> cmp = Comparator.comparing((ToDoubleFunction<People>) null);
+            fail("comparing(null) should throw NPE");
+        } catch (NullPointerException npe) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Comparator/TypeTest.java	Tue Jun 11 13:41:38 2013 -0700
@@ -0,0 +1,96 @@
+/*
+ * 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
+ * @summary Comparator API narrowing type test
+ * @run testng TypeTest
+ */
+
+import java.util.function.Function;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.Comparator;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit")
+public class TypeTest {
+    static class Person {
+        String name;
+        static Comparator<Person> C = (p1, p2) -> p1.name.compareTo(p2.name);
+
+        Person(String name) {
+            this.name = name;
+        }
+
+        String getName() { return name; }
+    }
+
+    static class Employee extends Person {
+        int id;
+        static Comparator<Employee> C = (e1, e2) -> e1.id - e2.id;
+
+        Employee(int id, String name) {
+            super(name);
+            this.id = id;
+        }
+    }
+
+    static class Manager extends Employee {
+        long reports;
+        static Comparator<Manager> C = (e1, e2) -> (int) (e1.reports - e2.reports);
+
+        Manager(String name, int id, long reports) {
+            super(id, name);
+            this.reports = reports;
+        }
+    }
+
+    static <T> void assertOrder(T o1, T o2, Comparator<? super T> cmp) {
+        if (cmp.compare(o1, o2) > 0) {
+            System.out.println("Fail!!");
+        }
+        if (cmp.compare(o1, o2) == 0) {
+            System.out.println("Equal!!");
+        }
+    }
+
+    public static void main(String[] args) {
+        Manager m1 = new Manager("Manager", 2, 2000);
+        Manager m2 = new Manager("Manager", 4, 1300);
+
+        // Comparator<Employee> tmp = Person.C;
+
+        // Comparator<Manager> cmp = Employee.C.thenComparing(Person.C);
+        Comparator<Employee> cmp = Employee.C.thenComparing(Person.C);
+        assertOrder(m1, m2, Employee.C.thenComparing(Person.C));
+        assertOrder(m1, m2, cmp);
+        assertOrder(m1, new Employee(1, "Z"), Person.C);
+        assertOrder(new Employee(1, "Z"), m2, Employee.C);
+
+        assertOrder(m1, m2, Comparator.comparing(Employee::getName, String.CASE_INSENSITIVE_ORDER));
+
+        Map<String, Integer> map = new TreeMap<>();
+        map.entrySet().stream().sorted(Map.Entry.comparingByKey(String.CASE_INSENSITIVE_ORDER));
+    }
+}
--- a/jdk/test/java/util/Comparators/BasicTest.java	Thu Jun 27 19:22:51 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,412 +0,0 @@
-/*
- * 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 8001667 8010279
- * @run testng BasicTest
- */
-
-import java.util.Comparator;
-import java.util.Comparators;
-import java.util.AbstractMap;
-import java.util.Map;
-import org.testng.annotations.Test;
-
-import java.util.function.BinaryOperator;
-import java.util.function.Function;
-import java.util.function.ToIntFunction;
-import java.util.function.ToLongFunction;
-import java.util.function.ToDoubleFunction;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.fail;
-
-/**
- * Unit tests for helper methods in Comparators
- */
-@Test(groups = "unit")
-public class BasicTest {
-    private static class Thing {
-        public final int intField;
-        public final long longField;
-        public final double doubleField;
-        public final String stringField;
-
-        private Thing(int intField, long longField, double doubleField, String stringField) {
-            this.intField = intField;
-            this.longField = longField;
-            this.doubleField = doubleField;
-            this.stringField = stringField;
-        }
-
-        public int getIntField() {
-            return intField;
-        }
-
-        public long getLongField() {
-            return longField;
-        }
-
-        public double getDoubleField() {
-            return doubleField;
-        }
-
-        public String getStringField() {
-            return stringField;
-        }
-    }
-
-    private final int[] intValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
-    private final long[] longValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
-    private final double[] doubleValues = { -2, -2, -1, -1, 0, 0, 1, 1, 2, 2 };
-    private final String[] stringValues = { "a", "a", "b", "b", "c", "c", "d", "d", "e", "e" };
-    private final int[] comparisons = { 0, -1, 0, -1, 0, -1, 0, -1, 0 };
-
-    private<T> void assertComparisons(T[] things, Comparator<T> comp, int[] comparisons) {
-        for (int i=0; i<comparisons.length; i++) {
-            assertEquals(comparisons.length + 1, things.length);
-            assertEquals(comparisons[i], comp.compare(things[i], things[i+1]));
-            assertEquals(-comparisons[i], comp.compare(things[i+1], things[i]));
-        }
-    }
-
-    public void testIntComparator() {
-        Thing[] things = new Thing[intValues.length];
-        for (int i=0; i<intValues.length; i++)
-            things[i] = new Thing(intValues[i], 0L, 0.0, null);
-        Comparator<Thing> comp = Comparators.comparing(new ToIntFunction<BasicTest.Thing>() {
-            @Override
-            public int applyAsInt(Thing thing) {
-                return thing.getIntField();
-            }
-        });
-
-        assertComparisons(things, comp, comparisons);
-    }
-
-    public void testLongComparator() {
-        Thing[] things = new Thing[longValues.length];
-        for (int i=0; i<longValues.length; i++)
-            things[i] = new Thing(0, longValues[i], 0.0, null);
-        Comparator<Thing> comp = Comparators.comparing(new ToLongFunction<BasicTest.Thing>() {
-            @Override
-            public long applyAsLong(Thing thing) {
-                return thing.getLongField();
-            }
-        });
-
-        assertComparisons(things, comp, comparisons);
-    }
-
-    public void testDoubleComparator() {
-        Thing[] things = new Thing[doubleValues.length];
-        for (int i=0; i<doubleValues.length; i++)
-            things[i] = new Thing(0, 0L, doubleValues[i], null);
-        Comparator<Thing> comp = Comparators.comparing(new ToDoubleFunction<BasicTest.Thing>() {
-            @Override
-            public double applyAsDouble(Thing thing) {
-                return thing.getDoubleField();
-            }
-        });
-
-        assertComparisons(things, comp, comparisons);
-    }
-
-    public void testComparing() {
-        Thing[] things = new Thing[doubleValues.length];
-        for (int i=0; i<doubleValues.length; i++)
-            things[i] = new Thing(0, 0L, 0.0, stringValues[i]);
-        Comparator<Thing> comp = Comparators.comparing(new Function<Thing, String>() {
-            @Override
-            public String apply(Thing thing) {
-                return thing.getStringField();
-            }
-        });
-
-        assertComparisons(things, comp, comparisons);
-    }
-
-    public void testNaturalOrderComparator() {
-        Comparator<String> comp = Comparators.naturalOrder();
-
-        assertComparisons(stringValues, comp, comparisons);
-    }
-
-    public void testReverseComparator() {
-        Comparator<String> cmpr = Comparators.reverseOrder();
-        Comparator<String> cmp = cmpr.reverseOrder();
-
-        assertEquals(cmp.reverseOrder(), cmpr);
-        assertEquals(0, cmp.compare("a", "a"));
-        assertEquals(0, cmpr.compare("a", "a"));
-        assertTrue(cmp.compare("a", "b") < 0);
-        assertTrue(cmpr.compare("a", "b") > 0);
-        assertTrue(cmp.compare("b", "a") > 0);
-        assertTrue(cmpr.compare("b", "a") < 0);
-    }
-
-    public void testReverseComparator2() {
-        Comparator<String> cmp = (s1, s2) -> s1.length() - s2.length();
-        Comparator<String> cmpr = cmp.reverseOrder();
-
-        assertEquals(cmpr.reverseOrder(), cmp);
-        assertEquals(0, cmp.compare("abc", "def"));
-        assertEquals(0, cmpr.compare("abc", "def"));
-        assertTrue(cmp.compare("abcd", "def") > 0);
-        assertTrue(cmpr.compare("abcd", "def") < 0);
-        assertTrue(cmp.compare("abc", "defg") < 0);
-        assertTrue(cmpr.compare("abc", "defg") > 0);
-    }
-
-    @Test(expectedExceptions=NullPointerException.class)
-    public void testReverseComparatorNPE() {
-        Comparator<String> cmp = Comparators.reverseOrder(null);
-    }
-
-    public void testComposeComparator() {
-        // Longer string in front
-        Comparator<String> first = (s1, s2) -> s2.length() - s1.length();
-        Comparator<String> second = Comparators.naturalOrder();
-        Comparator<String> composed = Comparators.compose(first, second);
-
-        assertTrue(composed.compare("abcdefg", "abcdef") < 0);
-        assertTrue(composed.compare("abcdef", "abcdefg") > 0);
-        assertTrue(composed.compare("abcdef", "abcdef") == 0);
-        assertTrue(composed.compare("abcdef", "ghijkl") < 0);
-        assertTrue(composed.compare("ghijkl", "abcdefg") > 0);
-    }
-
-    private <K, V> void assertPairComparison(K k1, V v1, K k2, V v2,
-                                        Comparator<Map.Entry<K, V>> ck,
-                                        Comparator<Map.Entry<K, V>> cv) {
-        final Map.Entry<K, V> p11 = new AbstractMap.SimpleImmutableEntry<>(k1, v1);
-        final Map.Entry<K, V> p12 = new AbstractMap.SimpleImmutableEntry<>(k1, v2);
-        final Map.Entry<K, V> p21 = new AbstractMap.SimpleImmutableEntry<>(k2, v1);
-        final Map.Entry<K, V> p22 = new AbstractMap.SimpleImmutableEntry<>(k2, v2);
-
-        assertTrue(ck.compare(p11, p11) == 0);
-        assertTrue(ck.compare(p12, p11) == 0);
-        assertTrue(ck.compare(p11, p12) == 0);
-        assertTrue(ck.compare(p12, p22) < 0);
-        assertTrue(ck.compare(p12, p21) < 0);
-        assertTrue(ck.compare(p21, p11) > 0);
-        assertTrue(ck.compare(p21, p12) > 0);
-
-        assertTrue(cv.compare(p11, p11) == 0);
-        assertTrue(cv.compare(p12, p11) > 0);
-        assertTrue(cv.compare(p11, p12) < 0);
-        assertTrue(cv.compare(p12, p22) == 0);
-        assertTrue(cv.compare(p12, p21) > 0);
-        assertTrue(cv.compare(p21, p11) == 0);
-        assertTrue(cv.compare(p21, p12) < 0);
-
-        Comparator<Map.Entry<K, V>> cmp = Comparators.compose(ck, cv);
-        assertTrue(cmp.compare(p11, p11) == 0);
-        assertTrue(cmp.compare(p12, p11) > 0);
-        assertTrue(cmp.compare(p11, p12) < 0);
-        assertTrue(cmp.compare(p12, p22) < 0);
-        assertTrue(cmp.compare(p12, p21) < 0);
-        assertTrue(cmp.compare(p21, p11) > 0);
-        assertTrue(cmp.compare(p21, p12) > 0);
-
-        cmp = Comparators.compose(cv, ck);
-        assertTrue(cmp.compare(p11, p11) == 0);
-        assertTrue(cmp.compare(p12, p11) > 0);
-        assertTrue(cmp.compare(p11, p12) < 0);
-        assertTrue(cmp.compare(p12, p22) < 0);
-        assertTrue(cmp.compare(p12, p21) > 0);
-        assertTrue(cmp.compare(p21, p11) > 0);
-        assertTrue(cmp.compare(p21, p12) < 0);
-    }
-
-    public void testKVComparatorable() {
-        assertPairComparison(1, "ABC", 2, "XYZ",
-                         Comparators.<Integer, String>naturalOrderKeys(),
-                         Comparators.<Integer, String>naturalOrderValues());
-    }
-
-    private static class People {
-        final String firstName;
-        final String lastName;
-        final int age;
-
-        People(String first, String last, int age) {
-            firstName = first;
-            lastName = last;
-            this.age = age;
-        }
-
-        String getFirstName() { return firstName; }
-        String getLastName() { return lastName; }
-        int getAge() { return age; }
-        long getAgeAsLong() { return (long) age; };
-        double getAgeAsDouble() { return (double) age; };
-    }
-
-    private final People people[] = {
-        new People("John", "Doe", 34),
-        new People("Mary", "Doe", 30),
-        new People("Maria", "Doe", 14),
-        new People("Jonah", "Doe", 10),
-        new People("John", "Cook", 54),
-        new People("Mary", "Cook", 50),
-    };
-
-    public void testKVComparators() {
-        // Comparator<People> cmp = Comparators.naturalOrder(); // Should fail to compiler as People is not comparable
-        // We can use simple comparator, but those have been tested above.
-        // Thus choose to do compose for some level of interation.
-        Comparator<People> cmp1 = Comparators.comparing((Function<People, String>) People::getFirstName);
-        Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
-        Comparator<People> cmp = Comparators.compose(cmp1, cmp2);
-
-        assertPairComparison(people[0], people[0], people[1], people[1],
-                         Comparators.<People, People>byKey(cmp),
-                         Comparators.<People, People>byValue(cmp));
-
-    }
-
-    private <T> void assertComparison(Comparator<T> cmp, T less, T greater) {
-        assertTrue(cmp.compare(less, greater) < 0, "less");
-        assertTrue(cmp.compare(less, less) == 0, "equal");
-        assertTrue(cmp.compare(greater, less) > 0, "greater");
-    }
-
-    public void testComparatorDefaultMethods() {
-        Comparator<People> cmp = Comparators.comparing((Function<People, String>) People::getFirstName);
-        Comparator<People> cmp2 = Comparators.comparing((Function<People, String>) People::getLastName);
-        // reverseOrder
-        assertComparison(cmp.reverseOrder(), people[1], people[0]);
-        // thenComparing(Comparator)
-        assertComparison(cmp.thenComparing(cmp2), people[0], people[1]);
-        assertComparison(cmp.thenComparing(cmp2), people[4], people[0]);
-        // thenComparing(Function)
-        assertComparison(cmp.thenComparing(People::getLastName), people[0], people[1]);
-        assertComparison(cmp.thenComparing(People::getLastName), people[4], people[0]);
-        // thenComparing(ToIntFunction)
-        assertComparison(cmp.thenComparing(People::getAge), people[0], people[1]);
-        assertComparison(cmp.thenComparing(People::getAge), people[1], people[5]);
-        // thenComparing(ToLongFunction)
-        assertComparison(cmp.thenComparing(People::getAgeAsLong), people[0], people[1]);
-        assertComparison(cmp.thenComparing(People::getAgeAsLong), people[1], people[5]);
-        // thenComparing(ToDoubleFunction)
-        assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[0], people[1]);
-        assertComparison(cmp.thenComparing(People::getAgeAsDouble), people[1], people[5]);
-    }
-
-    public void testGreaterOf() {
-        // lesser
-        assertSame(Comparators.greaterOf(Comparators.comparing(
-                                    (Function<People, String>) People::getFirstName))
-                              .apply(people[0], people[1]),
-                   people[1]);
-        // euqal
-        assertSame(Comparators.greaterOf(Comparators.comparing(
-                                    (Function<People, String>) People::getLastName))
-                              .apply(people[0], people[1]),
-                   people[0]);
-        // greater
-        assertSame(Comparators.greaterOf(Comparators.comparing(
-                                    (ToIntFunction<People>) People::getAge))
-                              .apply(people[0], people[1]),
-                   people[0]);
-    }
-
-    public void testLesserOf() {
-        // lesser
-        assertSame(Comparators.lesserOf(Comparators.comparing(
-                                    (Function<People, String>) People::getFirstName))
-                              .apply(people[0], people[1]),
-                   people[0]);
-        // euqal
-        assertSame(Comparators.lesserOf(Comparators.comparing(
-                                    (Function<People, String>) People::getLastName))
-                              .apply(people[0], people[1]),
-                   people[0]);
-        // greater
-        assertSame(Comparators.lesserOf(Comparators.comparing(
-                                    (ToIntFunction<People>) People::getAge))
-                              .apply(people[0], people[1]),
-                   people[1]);
-    }
-
-    public void testNulls() {
-        try {
-            Comparators.<String>naturalOrder().compare("abc", (String) null);
-            fail("expected NPE with naturalOrder");
-        } catch (NullPointerException npe) {}
-        try {
-            Comparators.<String>naturalOrder().compare((String) null, "abc");
-            fail("expected NPE with naturalOrder");
-        } catch (NullPointerException npe) {}
-
-        try {
-            Comparators.<String>reverseOrder().compare("abc", (String) null);
-            fail("expected NPE with naturalOrder");
-        } catch (NullPointerException npe) {}
-        try {
-            Comparators.<String>reverseOrder().compare((String) null, "abc");
-            fail("expected NPE with naturalOrder");
-        } catch (NullPointerException npe) {}
-
-        try {
-            Comparator<Map.Entry<String, String>> cmp = Comparators.byKey(null);
-            fail("byKey(null) should throw NPE");
-        } catch (NullPointerException npe) {}
-
-        try {
-            Comparator<Map.Entry<String, String>> cmp = Comparators.byValue(null);
-            fail("byValue(null) should throw NPE");
-        } catch (NullPointerException npe) {}
-
-        try {
-            Comparator<People> cmp = Comparators.comparing((Function<People, String>) null);
-            fail("comparing(null) should throw NPE");
-        } catch (NullPointerException npe) {}
-        try {
-            Comparator<People> cmp = Comparators.comparing((ToIntFunction<People>) null);
-            fail("comparing(null) should throw NPE");
-        } catch (NullPointerException npe) {}
-        try {
-            Comparator<People> cmp = Comparators.comparing((ToLongFunction<People>) null);
-            fail("comparing(null) should throw NPE");
-        } catch (NullPointerException npe) {}
-        try {
-            Comparator<People> cmp = Comparators.comparing((ToDoubleFunction<People>) null);
-            fail("comparing(null) should throw NPE");
-        } catch (NullPointerException npe) {}
-
-        try {
-            BinaryOperator<String> op = Comparators.lesserOf(null);
-            fail("lesserOf(null) should throw NPE");
-        } catch (NullPointerException npe) {}
-
-        try {
-            BinaryOperator<String> op = Comparators.greaterOf(null);
-            fail("lesserOf(null) should throw NPE");
-        } catch (NullPointerException npe) {}
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Map/EntryComparators.java	Tue Jun 11 13:41:38 2013 -0700
@@ -0,0 +1,139 @@
+/*
+ * 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 8009736 8010279
+ * @run testng EntryComparators
+ */
+import java.util.function.Function;
+import java.util.Comparator;
+import java.util.AbstractMap;
+import java.util.Map;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * Unit tests for Map.Entry.comparing
+ */
+@Test(groups = "unit")
+public class EntryComparators {
+
+    private <K, V> void assertPairComparison(K k1, V v1, K k2, V v2,
+                                        Comparator<Map.Entry<K, V>> ck,
+                                        Comparator<Map.Entry<K, V>> cv) {
+        final Map.Entry<K, V> p11 = new AbstractMap.SimpleImmutableEntry<>(k1, v1);
+        final Map.Entry<K, V> p12 = new AbstractMap.SimpleImmutableEntry<>(k1, v2);
+        final Map.Entry<K, V> p21 = new AbstractMap.SimpleImmutableEntry<>(k2, v1);
+        final Map.Entry<K, V> p22 = new AbstractMap.SimpleImmutableEntry<>(k2, v2);
+
+        assertTrue(ck.compare(p11, p11) == 0);
+        assertTrue(ck.compare(p12, p11) == 0);
+        assertTrue(ck.compare(p11, p12) == 0);
+        assertTrue(ck.compare(p12, p22) < 0);
+        assertTrue(ck.compare(p12, p21) < 0);
+        assertTrue(ck.compare(p21, p11) > 0);
+        assertTrue(ck.compare(p21, p12) > 0);
+
+        assertTrue(cv.compare(p11, p11) == 0);
+        assertTrue(cv.compare(p12, p11) > 0);
+        assertTrue(cv.compare(p11, p12) < 0);
+        assertTrue(cv.compare(p12, p22) == 0);
+        assertTrue(cv.compare(p12, p21) > 0);
+        assertTrue(cv.compare(p21, p11) == 0);
+        assertTrue(cv.compare(p21, p12) < 0);
+
+        Comparator<Map.Entry<K, V>> cmp = ck.thenComparing(cv);
+        assertTrue(cmp.compare(p11, p11) == 0);
+        assertTrue(cmp.compare(p12, p11) > 0);
+        assertTrue(cmp.compare(p11, p12) < 0);
+        assertTrue(cmp.compare(p12, p22) < 0);
+        assertTrue(cmp.compare(p12, p21) < 0);
+        assertTrue(cmp.compare(p21, p11) > 0);
+        assertTrue(cmp.compare(p21, p12) > 0);
+
+        cmp = cv.thenComparing(ck);
+        assertTrue(cmp.compare(p11, p11) == 0);
+        assertTrue(cmp.compare(p12, p11) > 0);
+        assertTrue(cmp.compare(p11, p12) < 0);
+        assertTrue(cmp.compare(p12, p22) < 0);
+        assertTrue(cmp.compare(p12, p21) > 0);
+        assertTrue(cmp.compare(p21, p11) > 0);
+        assertTrue(cmp.compare(p21, p12) < 0);
+    }
+
+    public void testKVComparables() {
+        assertPairComparison(1, "ABC", 2, "XYZ",
+                         Map.Entry.<Integer, String>comparingByKey(),
+                         Map.Entry.<Integer, String>comparingByValue());
+    }
+
+    private static class People {
+        final String firstName;
+        final String lastName;
+        final int age;
+
+        People(String first, String last, int age) {
+            firstName = first;
+            lastName = last;
+            this.age = age;
+        }
+
+        String getFirstName() { return firstName; }
+        String getLastName() { return lastName; }
+        int getAge() { return age; }
+    }
+
+    private final People people[] = {
+        new People("John", "Doe", 34),
+        new People("Mary", "Doe", 30),
+    };
+
+    public void testKVComparators() {
+        // Comparator<People> cmp = Comparator.naturalOrder(); // Should fail to compiler as People is not comparable
+        // We can use simple comparator, but those have been tested above.
+        // Thus choose to do compose for some level of interation.
+        Comparator<People> cmp1 = Comparator.comparing((Function<People, String>) People::getFirstName);
+        Comparator<People> cmp2 = Comparator.comparing((Function<People, String>) People::getLastName);
+        Comparator<People> cmp = cmp1.thenComparing(cmp2);
+
+        assertPairComparison(people[0], people[0], people[1], people[1],
+                         Map.Entry.<People, People>comparingByKey(cmp),
+                         Map.Entry.<People, People>comparingByValue(cmp));
+
+    }
+
+    public void testNulls() {
+        try {
+            Comparator<Map.Entry<String, String>> cmp = Map.Entry.comparingByKey(null);
+            fail("comparingByKey(null) should throw NPE");
+        } catch (NullPointerException npe) {}
+
+        try {
+            Comparator<Map.Entry<String, String>> cmp = Map.Entry.comparingByValue(null);
+            fail("comparingByValue(null) should throw NPE");
+        } catch (NullPointerException npe) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/function/BinaryOperator/BasicTest.java	Tue Jun 11 13:41:38 2013 -0700
@@ -0,0 +1,104 @@
+/*
+ * 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 8009736 8010279
+ * @run testng BasicTest
+ */
+
+import java.util.Comparator;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import org.testng.annotations.Test;
+
+
+import static java.util.function.BinaryOperator.minBy;
+import static java.util.function.BinaryOperator.maxBy;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.fail;
+
+/**
+ * Unit tests for helper methods in Comparators
+ */
+@Test(groups = "unit")
+public class BasicTest {
+
+    private static class People {
+        final String firstName;
+        final String lastName;
+        final int age;
+
+        People(String first, String last, int age) {
+            firstName = first;
+            lastName = last;
+            this.age = age;
+        }
+
+        String getFirstName() { return firstName; }
+        String getLastName() { return lastName; }
+        int getAge() { return age; }
+    }
+
+    private final People people[] = {
+        new People("John", "Doe", 34),
+        new People("Mary", "Doe", 30),
+    };
+
+    public void testMaxBy() {
+        Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
+        // lesser
+        assertSame(maxBy(cmp).apply(people[0], people[1]), people[1]);
+        // euqal
+        cmp = Comparator.comparing((Function<People, String>) People::getLastName);
+        assertSame(maxBy(cmp).apply(people[0], people[1]), people[0]);
+        // greater
+        cmp = Comparator.comparing((ToIntFunction<People>) People::getAge);
+        assertSame(maxBy(cmp).apply(people[0], people[1]), people[0]);
+    }
+
+    public void testLesserOf() {
+        Comparator<People> cmp = Comparator.comparing((Function<People, String>) People::getFirstName);
+        // lesser
+        assertSame(minBy(cmp).apply(people[0], people[1]), people[0]);
+        // euqal
+        cmp = Comparator.comparing((Function<People, String>) People::getLastName);
+        assertSame(minBy(cmp).apply(people[0], people[1]), people[0]);
+        // greater
+        cmp = Comparator.comparing((ToIntFunction<People>) People::getAge);
+        assertSame(minBy(cmp).apply(people[0], people[1]), people[1]);
+    }
+
+    public void testNulls() {
+        try {
+            BinaryOperator<String> op = minBy(null);
+            fail("minBy(null) should throw NPE");
+        } catch (NullPointerException npe) {}
+
+        try {
+            BinaryOperator<String> op = maxBy(null);
+            fail("maxBy(null) should throw NPE");
+        } catch (NullPointerException npe) {}
+    }
+}
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java	Tue Jun 11 13:41:38 2013 -0700
@@ -22,7 +22,6 @@
  */
 package org.openjdk.tests.java.util.stream;
 
-import java.util.Comparators;
 import java.util.stream.LambdaTestHelpers;
 import java.util.stream.OpTestCase;
 import java.util.stream.StreamTestDataProvider;
@@ -109,9 +108,9 @@
                 = new UnaryOperator[] {
                 (UnaryOperator<Stream<Integer>>) s -> s,
                 (UnaryOperator<Stream<Integer>>) s -> s.map(id),
-                (UnaryOperator<Stream<Integer>>) s -> s.sorted(Comparators.naturalOrder()),
-                (UnaryOperator<Stream<Integer>>) s -> s.map(id).sorted(Comparators.naturalOrder()).map(id),
-                (UnaryOperator<Stream<Integer>>) s -> s.filter(LambdaTestHelpers.pEven).sorted(Comparators.naturalOrder()).map(id),
+                (UnaryOperator<Stream<Integer>>) s -> s.sorted(Comparator.naturalOrder()),
+                (UnaryOperator<Stream<Integer>>) s -> s.map(id).sorted(Comparator.naturalOrder()).map(id),
+                (UnaryOperator<Stream<Integer>>) s -> s.filter(LambdaTestHelpers.pEven).sorted(Comparator.naturalOrder()).map(id),
         };
 
         for (int c1Index = 0; c1Index < changers.length; c1Index++) {
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java	Tue Jun 11 13:41:38 2013 -0700
@@ -270,7 +270,7 @@
     public void testLimitSort() {
         List<Integer> l = countTo(100);
         Collections.reverse(l);
-        exerciseOps(l, s -> s.limit(10).sorted(Comparators.naturalOrder()));
+        exerciseOps(l, s -> s.limit(10).sorted(Comparator.naturalOrder()));
     }
 
     @Test(groups = { "serialization-hostile" })
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java	Tue Jun 11 13:41:38 2013 -0700
@@ -40,10 +40,10 @@
     public void testSorted() {
         assertCountSum(countTo(0).stream().sorted(), 0, 0);
         assertCountSum(countTo(10).stream().sorted(), 10, 55);
-        assertCountSum(countTo(10).stream().sorted(cInteger.reverseOrder()), 10, 55);
+        assertCountSum(countTo(10).stream().sorted(cInteger.reversed()), 10, 55);
 
         List<Integer> to10 = countTo(10);
-        assertSorted(to10.stream().sorted(cInteger.reverseOrder()).iterator(), cInteger.reverseOrder());
+        assertSorted(to10.stream().sorted(cInteger.reversed()).iterator(), cInteger.reversed());
 
         Collections.reverse(to10);
         assertSorted(to10.stream().sorted().iterator());
@@ -51,7 +51,7 @@
         Spliterator<Integer> s = to10.stream().sorted().spliterator();
         assertTrue(s.hasCharacteristics(Spliterator.SORTED));
 
-        s = to10.stream().sorted(cInteger.reverseOrder()).spliterator();
+        s = to10.stream().sorted(cInteger.reversed()).spliterator();
         assertFalse(s.hasCharacteristics(Spliterator.SORTED));
     }
 
@@ -87,8 +87,8 @@
         assertSorted(result.iterator());
         assertContentsUnordered(data, result);
 
-        result = exerciseOps(data, s -> s.sorted(cInteger.reverseOrder()));
-        assertSorted(result.iterator(), cInteger.reverseOrder());
+        result = exerciseOps(data, s -> s.sorted(cInteger.reversed()));
+        assertSorted(result.iterator(), cInteger.reversed());
         assertContentsUnordered(data, result);
     }
 
@@ -104,23 +104,23 @@
         assertContentsUnordered(data, result);
 
         result = withData(data)
-                .stream(s -> s.sorted(cInteger.reverseOrder()).sorted(cInteger.reverseOrder()),
+                .stream(s -> s.sorted(cInteger.reversed()).sorted(cInteger.reversed()),
                         new CollectorOps.TestParallelSizedOp<Integer>())
                 .exercise();
 
-        assertSorted(result, cInteger.reverseOrder());
+        assertSorted(result, cInteger.reversed());
         assertContentsUnordered(data, result);
 
         result = withData(data)
-                .stream(s -> s.sorted().sorted(cInteger.reverseOrder()),
+                .stream(s -> s.sorted().sorted(cInteger.reversed()),
                         new CollectorOps.TestParallelSizedOp<Integer>())
                 .exercise();
 
-        assertSorted(result, cInteger.reverseOrder());
+        assertSorted(result, cInteger.reversed());
         assertContentsUnordered(data, result);
 
         result = withData(data)
-                .stream(s -> s.sorted(cInteger.reverseOrder()).sorted(),
+                .stream(s -> s.sorted(cInteger.reversed()).sorted(),
                         new CollectorOps.TestParallelSizedOp<Integer>())
                 .exercise();
 
--- a/jdk/test/sun/misc/JavaLangAccess/NewUnsafeString.java	Thu Jun 27 19:22:51 2013 -0700
+++ b/jdk/test/sun/misc/JavaLangAccess/NewUnsafeString.java	Tue Jun 11 13:41:38 2013 -0700
@@ -22,7 +22,7 @@
  */
 
 import java.util.Objects;
-import java.util.Comparators;
+import java.util.Comparator;
 import sun.misc.JavaLangAccess;
 import sun.misc.SharedSecrets;
 
@@ -48,7 +48,7 @@
         if (!benchmark.equals(constructorCopy)) {
             throw new Error("Copy not equal");
         }
-        if (0 != Objects.compare(benchmark, constructorCopy, Comparators.naturalOrder())) {
+        if (0 != Objects.compare(benchmark, constructorCopy, Comparator.naturalOrder())) {
             throw new Error("Copy not equal");
         }
 
@@ -58,7 +58,7 @@
         if (!benchmark.equals(jlaCopy)) {
             throw new Error("Copy not equal");
         }
-        if (0 != Objects.compare(benchmark, jlaCopy, Comparators.naturalOrder())) {
+        if (0 != Objects.compare(benchmark, jlaCopy, Comparator.naturalOrder())) {
             throw new Error("Copy not equal");
         }
 
@@ -68,7 +68,7 @@
         if (!constructorCopy.equals(jlaCopy)) {
             throw new Error("Copy not equal");
         }
-        if (0 != Objects.compare(constructorCopy, jlaCopy, Comparators.naturalOrder())) {
+        if (0 != Objects.compare(constructorCopy, jlaCopy, Comparator.naturalOrder())) {
             throw new Error("Copy not equal");
         }