Update unmodifiableList to throw on Java8 methods.

Change-Id: Ibdb3c9f297bff47e3a54aa0d254167840a1b9a30
Review-Link: https://gwt-review.googlesource.com/#/c/20260/
diff --git a/user/super/com/google/gwt/emul/java/util/Collections.java b/user/super/com/google/gwt/emul/java/util/Collections.java
index c41e884..498b321 100644
--- a/user/super/com/google/gwt/emul/java/util/Collections.java
+++ b/user/super/com/google/gwt/emul/java/util/Collections.java
@@ -21,6 +21,8 @@
 import static javaemul.internal.InternalPreconditions.checkNotNull;
 
 import java.io.Serializable;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
 
 /**
  * Utility methods that operate on collections.
@@ -351,6 +353,11 @@
     }
 
     @Override
+    public boolean removeIf(Predicate<? super T> p) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
     public int size() {
       return coll.size();
     }
@@ -431,6 +438,16 @@
     }
 
     @Override
+    public void replaceAll(UnaryOperator<T> operator) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sort(Comparator<? super T> c) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
     public T remove(int index) {
       throw new UnsupportedOperationException();
     }
diff --git a/user/test/com/google/gwt/emultest/EmulJava8Suite.java b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
index abab98a..6a1c5d4 100644
--- a/user/test/com/google/gwt/emultest/EmulJava8Suite.java
+++ b/user/test/com/google/gwt/emultest/EmulJava8Suite.java
@@ -22,6 +22,7 @@
 import com.google.gwt.emultest.java8.math.BigIntegerConvertTest;
 import com.google.gwt.emultest.java8.util.ArrayListTest;
 import com.google.gwt.emultest.java8.util.ArraysTest;
+import com.google.gwt.emultest.java8.util.CollectionsTest;
 import com.google.gwt.emultest.java8.util.ComparatorTest;
 import com.google.gwt.emultest.java8.util.DoubleSummaryStatisticsTest;
 import com.google.gwt.emultest.java8.util.HashMapTest;
@@ -68,6 +69,7 @@
   //-- java.util
   ArraysTest.class,
   ArrayListTest.class,
+  CollectionsTest.class,
   LinkedListTest.class,
   ListTest.class,
   VectorTest.class,
diff --git a/user/test/com/google/gwt/emultest/java8/util/CollectionsTest.java b/user/test/com/google/gwt/emultest/java8/util/CollectionsTest.java
new file mode 100644
index 0000000..ea7e9c4
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java8/util/CollectionsTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2017 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.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.function.Consumer;
+
+/** Tests for Collections that require Java8 syntax. */
+public class CollectionsTest extends EmulTestBase {
+
+  public void testUnmodifiableList() {
+    List<String> list = Collections.unmodifiableList(Arrays.asList("1", "2", "3"));
+    doTestModificationsToList(list);
+    doTestModificationsToListViaIterator(list);
+  }
+
+  public void testUnmodifiableList_emptyList() {
+    List<String> list = Collections.unmodifiableList(new ArrayList<>());
+    doTestModificationsToList(list);
+  }
+
+  private void doTestModificationsToList(List<String> list) {
+    assertUnmodifiableContract(list, l -> l.add("4"));
+    assertUnmodifiableContract(list, l -> l.add(0, "5"));
+    assertUnmodifiableContract(list, l -> l.addAll(Arrays.asList("6")));
+    assertUnmodifiableContract(list, l -> l.addAll(0, Arrays.asList("7")));
+    assertUnmodifiableContract(list, l -> l.addAll(Arrays.asList()));
+    assertUnmodifiableContract(list, l -> l.clear());
+    assertUnmodifiableContract(list, l -> l.replaceAll((s) -> s + "asdf"));
+    assertUnmodifiableContract(list, l -> l.remove("1"));
+    assertUnmodifiableContract(list, l -> l.remove(0));
+    assertUnmodifiableContract(list, l -> l.removeAll(Arrays.asList("1")));
+    assertUnmodifiableContract(list, l -> l.removeIf((s) -> true));
+    assertUnmodifiableContract(list, l -> l.retainAll(Arrays.asList("4")));
+    assertUnmodifiableContract(list, l -> l.set(0, "24"));
+    assertUnmodifiableContract(
+        list, l -> l.sort((s1, s2) -> Integer.valueOf(s2) - Integer.valueOf(s1)));
+    assertUnmodifiableContract(list, l -> l.subList(0, 0).remove(0));
+  }
+ 
+  private void doTestModificationsToListViaIterator(List<String> list) {
+    assertUnmodifiableContractThroughIterator(list, i -> i.add("4"));
+    assertUnmodifiableContractThroughIterator(list, i -> i.remove());
+    assertUnmodifiableContractThroughIterator(list, i -> i.set("4"));
+  }
+
+  private static void assertUnmodifiableContractThroughIterator(
+      List<String> list, Consumer<ListIterator<String>> consumer) {
+    assertUnmodifiableContract(
+        list,
+        l -> {
+          ListIterator<String> listIterator = l.listIterator();
+          listIterator.next();
+          consumer.accept(listIterator);
+        });
+
+    assertUnmodifiableContract(
+        list,
+        l -> {
+          ListIterator<String> listIterator = l.listIterator(1);
+          listIterator.next();
+          consumer.accept(listIterator);
+        });
+  }
+
+  private static void assertUnmodifiableContract(
+      List<String> list, Consumer<List<String>> consumer) {
+    List<?> originalContent = new ArrayList<>(list);
+    try {
+      consumer.accept(list);
+      fail();
+    } catch (UnsupportedOperationException e) {
+    }
+    assertEquals(originalContent, list);
+  }
+}