diff --git a/user/super/com/google/gwt/emul/java/util/Comparator.java b/user/super/com/google/gwt/emul/java/util/Comparator.java
index 563608b..e0a9813 100644
--- a/user/super/com/google/gwt/emul/java/util/Comparator.java
+++ b/user/super/com/google/gwt/emul/java/util/Comparator.java
@@ -15,6 +15,14 @@
  */
 package java.util;
 
+import static javaemul.internal.InternalPreconditions.checkCriticalNotNull;
+
+import java.io.Serializable;
+import java.util.function.Function;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
 /**
  * An interface used a basis for implementing custom ordering. <a
  * href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html">[Sun
@@ -22,6 +30,7 @@
  *
  * @param <T> the type to be compared.
  */
+@FunctionalInterface
 public interface Comparator<T> {
 
   int compare(T a, T b);
@@ -29,4 +38,84 @@
   @Override
   boolean equals(Object other);
 
+  default Comparator<T> reversed() {
+    return (a, b) -> compare(b, a);
+  }
+
+  default Comparator<T> thenComparing(Comparator<? super T> other) {
+    checkCriticalNotNull(other);
+    return (Comparator<T> & Serializable) (a, b) -> {
+      int c = compare(a, b);
+      return (c != 0) ? c : other.compare(a, b);
+    };
+  }
+
+  default <U> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor,
+      Comparator<? super U> keyComparator) {
+    return thenComparing(comparing(keyExtractor, keyComparator));
+  }
+
+  default <U extends Comparable<? super U>> Comparator<T> thenComparing(
+      Function<? super T, ? extends U> keyExtractor) {
+    return thenComparing(comparing(keyExtractor));
+  }
+
+  default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
+    return thenComparing(comparingInt(keyExtractor));
+  }
+
+  default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
+    return thenComparing(comparingLong(keyExtractor));
+  }
+
+  default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
+    return thenComparing(comparingDouble(keyExtractor));
+  }
+
+  static <T, U> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor,
+      Comparator<? super U> keyComparator) {
+    checkCriticalNotNull(keyExtractor);
+    checkCriticalNotNull(keyComparator);
+    return (Comparator<T> & Serializable) (a, b) ->
+        keyComparator.compare(keyExtractor.apply(a), keyExtractor.apply(b));
+  }
+
+  static <T, U extends Comparable<? super U>> Comparator<T> comparing(
+      Function<? super T, ? extends U> keyExtractor) {
+    return comparing(keyExtractor, naturalOrder());
+  }
+
+  static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) {
+    checkCriticalNotNull(keyExtractor);
+    return (Comparator<T> & Serializable) (a, b) ->
+        Double.compare(keyExtractor.applyAsDouble(a), keyExtractor.applyAsDouble(b));
+  }
+
+  static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) {
+    checkCriticalNotNull(keyExtractor);
+    return (Comparator<T> & Serializable) (a, b) ->
+        Integer.compare(keyExtractor.applyAsInt(a), keyExtractor.applyAsInt(b));
+  }
+
+  static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) {
+    checkCriticalNotNull(keyExtractor);
+    return (Comparator<T> & Serializable) (a, b) ->
+        Long.compare(keyExtractor.applyAsLong(a), keyExtractor.applyAsLong(b));
+  }
+
+  static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
+    return Comparators.natural();
+  }
+
+  static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
+    return new Comparators.NullComparator<>(true, comparator);
+  }
+
+  static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
+    return new Comparators.NullComparator<>(false, comparator);
+  }
+
+  static <T extends Comparable<? super T>> Comparator<T> reverseOrder() {
+    return Comparators.reverseOrder();
+  }
 }
diff --git a/user/super/com/google/gwt/emul/java/util/Comparators.java b/user/super/com/google/gwt/emul/java/util/Comparators.java
index e575a80..b01804c 100644
--- a/user/super/com/google/gwt/emul/java/util/Comparators.java
+++ b/user/super/com/google/gwt/emul/java/util/Comparators.java
@@ -17,31 +17,57 @@
 
 import static javaemul.internal.InternalPreconditions.checkNotNull;
 
+import java.io.Serializable;
+
 class Comparators {
   /*
-   * This is a utility class that provides a default Comparator. This class
+   * This is a utility class that provides default Comparators. This class
    * exists so Arrays and Collections can share the natural comparator without
    * having to know internals of each other.
    *
    * This class is package protected since it is not in the JRE.
    */
 
-  /**
-   * Compares two Objects according to their <i>natural ordering</i>.
-   *
-   * @see java.lang.Comparable
-   */
-  private static final Comparator<Object> NATURAL = new Comparator<Object>() {
-    @Override
-    public int compare(Object o1, Object o2) {
-      checkNotNull(o1);
-      checkNotNull(o2);
-      return ((Comparable<Object>) o1).compareTo(o2);
+  private static final Comparator<Comparable<Object>> NATURAL = (a, b) -> checkNotNull(a).compareTo(checkNotNull(b));
+
+  private static final Comparator<Comparable<Object>> REVERSE_ORDER = (a, b) -> checkNotNull(b).compareTo(checkNotNull(a));
+
+  static final class NullComparator<T> implements Comparator<T>, Serializable {
+    private final boolean nullFirst;
+    private final Comparator<T> delegate;
+
+    @SuppressWarnings("unchecked")
+    NullComparator(boolean nullFirst, Comparator<? super T> delegate) {
+      this.nullFirst = nullFirst;
+      this.delegate = (Comparator<T>) delegate;
     }
-  };
+
+    @Override
+    public int compare(T a, T b) {
+      if (a == null) {
+        return b == null ? 0 : (nullFirst ? -1 : 1);
+      }
+      if (b == null) {
+        return nullFirst ? 1 : -1;
+      }
+      return delegate == null ? 0 : delegate.compare(a, b);
+    }
+
+    @Override
+    public Comparator<T> reversed() {
+      return new NullComparator<>(!nullFirst, delegate == null ? null : delegate.reversed());
+    }
+
+    @Override
+    public Comparator<T> thenComparing(Comparator<? super T> other) {
+      return new NullComparator<>(nullFirst, delegate == null ?
+          other : delegate.thenComparing(other));
+    }
+  }
 
   /**
-   * Returns the natural Comparator.
+   * Returns the natural Comparator which compares two Objects
+   * according to their <i>natural ordering</i>.
    * <p>
    * Example:
    *
@@ -49,7 +75,13 @@
    *
    * @return the natural Comparator
    */
+  @SuppressWarnings("unchecked")
   public static <T> Comparator<T> natural() {
     return (Comparator<T>) NATURAL;
   }
+
+  @SuppressWarnings("unchecked")
+  public static <T> Comparator<T> reverseOrder() {
+    return (Comparator<T>) REVERSE_ORDER;
+  }
 }
diff --git a/user/test/com/google/gwt/emultest/EmulJava8Suite.java b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
index 09394ae..7b311b3 100644
--- a/user/test/com/google/gwt/emultest/EmulJava8Suite.java
+++ b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.emultest;
 
+import com.google.gwt.emultest.java8.util.ComparatorTest;
 import com.google.gwt.emultest.java8.util.DoubleSummaryStatisticsTest;
 import com.google.gwt.emultest.java8.util.IntSummaryStatisticsTest;
 import com.google.gwt.emultest.java8.util.LongSummaryStatisticsTest;
@@ -37,6 +38,7 @@
     GWTTestSuite suite = new GWTTestSuite("Tests for com.google.gwt.emul.java8");
 
     //-- java.util
+    suite.addTestSuite(ComparatorTest.class);
     suite.addTestSuite(OptionalTest.class);
     suite.addTestSuite(OptionalIntTest.class);
     suite.addTestSuite(OptionalLongTest.class);
diff --git a/user/test/com/google/gwt/emultest/java8/util/ComparatorTest.java b/user/test/com/google/gwt/emultest/java8/util/ComparatorTest.java
new file mode 100644
index 0000000..9460571
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/util/ComparatorTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.emultest.java8.util;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+/**
+ * Java 8 methods to test in java.util.Comparator.
+ */
+public class ComparatorTest extends EmulTestBase {
+
+  public void testThenComparing() {
+    Supplier<String[]> strings = () -> new String[] {"1,b", "1,a", "2,a"};
+    // expected sort results for 1st and 2nd char, each (f)orward or (r)everse
+    String[] f1f2 = {"1,a", "1,b", "2,a"};
+    String[] f1r2 = {"1,b", "1,a", "2,a"};
+    String[] f2f1 = {"1,a", "2,a" ,"1,b"};
+
+    // keyextractor
+    assertSortedEquals(f1f2, strings,
+        Comparator.<String, String>comparing(s -> s.split(",")[0])
+            .thenComparing(s -> s.split(",")[1])
+    );
+    // keyextractor, keycomparator
+    assertSortedEquals(f1r2, strings,
+        Comparator.<String, String>comparing(s -> s.split(",")[0])
+            .thenComparing(
+                s -> s.split(",")[1],
+                Comparator.<String>reverseOrder()
+            )
+    );
+
+    // int key extractor
+    assertSortedEquals(f2f1, strings,
+        Comparator.<String, String>comparing(s -> s.split(",")[1])
+            .thenComparingInt(
+                s -> Integer.parseInt(s.split(",")[0])
+            )
+    );
+    // long key extractor
+    assertSortedEquals(f2f1, strings,
+        Comparator.<String, String>comparing(s -> s.split(",")[1])
+            .thenComparingLong(
+                s -> Long.parseLong(s.split(",")[0])
+            )
+    );
+    // double key extractor
+    assertSortedEquals(f2f1, strings,
+        Comparator.<String, String>comparing(s -> s.split(",")[1])
+            .thenComparingDouble(
+                s -> Double.parseDouble(s.split(",")[0])
+            )
+    );
+  }
+
+  public void testComparing() {
+    Supplier<String[]> strings = () -> new String[] {"1b3", "2a1", "3c2"};
+    // pre-sorted lists to test against, named for which char (1-indexed) they are sorted on
+    String[] first = {"1b3", "2a1", "3c2"};
+    String[] second = {"2a1", "1b3", "3c2"};
+    String[] secondReversed = {"3c2", "1b3", "2a1"};
+    String[] third = {"2a1", "3c2", "1b3"};
+
+    // keyextractor
+    assertSortedEquals(first, strings, Comparator.comparing(Function.identity()));
+    assertSortedEquals(second, strings, Comparator.comparing(a -> a.substring(1)));
+    assertSortedEquals(third, strings, Comparator.comparing(a -> a.substring(2)));
+
+    // keyextractor, keycomparator
+    assertSortedEquals(secondReversed, strings, Comparator.comparing(a -> a.substring(1), Comparator.<String>reverseOrder()));
+
+    // double key extractor
+    assertSortedEquals(third, strings, Comparator.comparingDouble(a -> Double.parseDouble(a.substring(2))));
+    // int key extractor
+    assertSortedEquals(third, strings, Comparator.comparingInt(a -> Integer.parseInt(a.substring(2))));
+    // long key extractor
+    assertSortedEquals(third, strings, Comparator.comparingLong(a -> Long.parseLong(a.substring(2))));
+  }
+
+  public void testNullsFirst() {
+    Supplier<String[]> strings = () -> new String[]{"a", null, "c", null, "b"};
+    assertSortedEquals(
+        new String[] {null, null, "a", "b", "c"},
+        strings,
+        Comparator.nullsFirst(Comparator.naturalOrder())
+    );
+    assertSortedEquals(
+        new String[] {null, null, "c", "b", "a"},
+        strings,
+        Comparator.nullsFirst(Comparator.reverseOrder())
+    );
+  }
+
+  public void testNullsLast() {
+    Supplier<String[]> strings = () -> new String[]{"a", null, "c", null, "b"};
+    assertSortedEquals(
+        new String[] {"a", "b", "c", null, null},
+        strings,
+        Comparator.nullsLast(Comparator.naturalOrder())
+    );
+    assertSortedEquals(
+        new String[] {"c", "b", "a", null, null},
+        strings,
+        Comparator.nullsLast(Comparator.reverseOrder())
+    );
+  }
+
+  private static void assertSortedEquals(String[] expected, Supplier<String[]> presort, Comparator<String> comparator) {
+    String[] presortedArray = presort.get();
+    Arrays.sort(presortedArray, comparator);
+    assertEquals(expected, presortedArray);
+  }
+}
