Fix up PriorityQueue.iterator() to support remove().

Change-Id: Iedc73edafaaf0c81ef4bdbfe3b1d144a487e4a81
Review-Link: https://gwt-review.googlesource.com/#/c/18900/
diff --git a/user/super/com/google/gwt/emul/java/util/PriorityQueue.java b/user/super/com/google/gwt/emul/java/util/PriorityQueue.java
index 59de7e9..90480b8 100644
--- a/user/super/com/google/gwt/emul/java/util/PriorityQueue.java
+++ b/user/super/com/google/gwt/emul/java/util/PriorityQueue.java
@@ -124,8 +124,31 @@
 
   @Override
   public Iterator<E> iterator() {
-    // TODO(jat): PriorityQueue is supposed to have a modifiable iterator.
-    return Collections.unmodifiableList(heap).iterator();
+    return new Iterator<E>() {
+      private E current = null;
+      // Make a copy of the elements so that remove() doesn't screw up the order.
+      Iterator<E> elementsToTraverse = new ArrayList<>(heap).iterator();
+      @Override
+      public boolean hasNext() {
+        return elementsToTraverse.hasNext();
+      }
+
+      @Override
+      public E next() {
+        current = elementsToTraverse.next();
+        return current;
+      }
+
+      @Override
+      public void remove() {
+        if (current == null) {
+          throw new IllegalStateException("remove() called before iteration or removed already.");
+        }
+        // Remove the current element. Keep on iterating.
+        PriorityQueue.this.remove(current);
+        current = null;
+      }
+    };
   }
 
   @Override
diff --git a/user/test/com/google/gwt/emultest/java/util/PriorityQueueTest.java b/user/test/com/google/gwt/emultest/java/util/PriorityQueueTest.java
index 6b07adf..4f10055 100644
--- a/user/test/com/google/gwt/emultest/java/util/PriorityQueueTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/PriorityQueueTest.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2008 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
@@ -21,6 +21,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.NoSuchElementException;
 import java.util.PriorityQueue;
 import java.util.TreeSet;
@@ -186,7 +187,7 @@
     assertTrue(queue.contains(3));
     assertFalse(queue.contains(4));
   }
-  
+
   public void testPeekElement() {
     PriorityQueue<Integer> queue = new PriorityQueue<>();
     try {
@@ -245,5 +246,40 @@
     PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
     addArray(pq, values);
     return pq;
-  } 
+  }
+
+  public void testIteratorRemove() {
+    PriorityQueue<Integer> queue = new PriorityQueue<>();
+    queue.add(1);
+    queue.add(2);
+    queue.add(3);
+    queue.add(5);
+    queue.add(6);
+
+    int sum = 0;
+    Iterator<Integer> it = queue.iterator();
+    while (it.hasNext()) {
+      int i = it.next();
+      if (i == 2) {
+        it.remove();
+      }
+      sum += i;
+    }
+    assertEquals(17, sum);
+    assertEquals(4, queue.size());
+
+    try {
+      queue.iterator().remove();
+      fail();
+    } catch (IllegalStateException e) { }
+
+    try {
+      Iterator<Integer> itt = queue.iterator();
+      while (itt.hasNext()) {
+        it.remove();
+        it.remove();
+        fail();
+      }
+    } catch (IllegalStateException e) { };
+  }
 }