Hack around AutoBean regression wrt j.u.Iterator

j.u.Iterator#remove was changed to a default method in Java 8, and
default methods aren't exposed to generators, so AutoBean no longer
sees j.u.Iterator#remove and thus no longer generates the remove()
method in the j.u.Iterator shim delegating to the wrapped j.u.Iterator.
This also applies to j.u.ListIterator transitively.

The AutoBean generator now special-cases j.u.Iterator and j.u.ListIterator
to hard-code the remove() method into the shims.

Change-Id: I8710f20ce777e6f922fb8161375a25b4e9848755
diff --git a/user/src/com/google/web/bindery/autobean/gwt/rebind/AutoBeanFactoryGenerator.java b/user/src/com/google/web/bindery/autobean/gwt/rebind/AutoBeanFactoryGenerator.java
index 3505af2..f5d1b79 100644
--- a/user/src/com/google/web/bindery/autobean/gwt/rebind/AutoBeanFactoryGenerator.java
+++ b/user/src/com/google/web/bindery/autobean/gwt/rebind/AutoBeanFactoryGenerator.java
@@ -54,7 +54,9 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
 
 /**
@@ -561,6 +563,18 @@
       sw.println("}");
     }
 
+    // HACK: Iterator#remove was changed to a default method in Java 8,
+    // and those are hidden to generators
+    if (type.getPeerType().getQualifiedSourceName().equals(Iterator.class.getCanonicalName()) ||
+        type.getPeerType().getQualifiedSourceName().equals(ListIterator.class.getCanonicalName())) {
+      sw.println("@Override public void remove() {");
+      sw.indent();
+      sw.println("%s.this.getWrapped().remove();", type.getSimpleSourceName());
+      sw.println("%s.this.call(\"remove\", null);", type.getSimpleSourceName());
+      sw.outdent();
+      sw.println("}");
+    }
+
     // Delegate equals(), hashCode(), and toString() to wrapped object
     sw.println("@Override public boolean equals(Object o) {");
     sw.indentln("return this == o || getWrapped().equals(o);");
diff --git a/user/test/com/google/web/bindery/autobean/gwt/client/AutoBeanTest.java b/user/test/com/google/web/bindery/autobean/gwt/client/AutoBeanTest.java
index 76150f1..d55b039 100644
--- a/user/test/com/google/web/bindery/autobean/gwt/client/AutoBeanTest.java
+++ b/user/test/com/google/web/bindery/autobean/gwt/client/AutoBeanTest.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 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
@@ -26,6 +26,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
@@ -375,6 +376,33 @@
     assertEquals(42, intf.getInt());
   }
 
+  public void testListShim() {
+    HasList hl = factory.hasList().as();
+    hl.setList(new ArrayList<Intf>());
+    hl.getList().add(factory.intf().as());
+    hl.getList().add(factory.intf().as());
+
+    Iterator<Intf> iter = hl.getList().iterator();
+    assertEquals(hl.getList().get(0), iter.next());
+    assertTrue(iter.hasNext());
+    assertEquals(hl.getList().get(1), iter.next());
+    // Iterator#remove became a 'default' method in Java 8; test non-regression
+    iter.remove();
+    assertFalse(iter.hasNext());
+    assertEquals(1, hl.getList().size());
+
+    // Same with ListIterator
+    hl.getList().add(factory.intf().as());
+    iter = hl.getList().listIterator();
+    assertEquals(hl.getList().get(0), iter.next());
+    assertTrue(iter.hasNext());
+    assertEquals(hl.getList().get(1), iter.next());
+    // ListIterator#remove became a 'default' method in Java 8; test non-regression
+    iter.remove();
+    assertFalse(iter.hasNext());
+    assertEquals(1, hl.getList().size());
+  }
+
   public void testNested() {
     AutoBean<OtherIntf> auto = factory.otherIntf();
     OtherIntf other = auto.as();