Fix TreeMap.Node.equals() to allow nodes to be equal to other types of Map.Entry.
While there, eliminate an unnecessary unchecked cast.

Review at http://gwt-code-reviews.appspot.com/1523804

Review by: rchandia@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10527 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/super/com/google/gwt/emul/java/util/TreeMap.java b/user/super/com/google/gwt/emul/java/util/TreeMap.java
index 0761e75..71195cd 100644
--- a/user/super/com/google/gwt/emul/java/util/TreeMap.java
+++ b/user/super/com/google/gwt/emul/java/util/TreeMap.java
@@ -199,16 +199,14 @@
       this.isRed = isRed;
     }
 
-    @SuppressWarnings("unchecked")
-    // generic cast
     @Override
     public boolean equals(Object o) {
-      if (!(o instanceof Node)) {
+      if (!(o instanceof Map.Entry)) {
         return false;
       }
-      Node<K, V> other = (Node<K, V>) o; // suppress unchecked
-      return Utility.equalsWithNullCheck(key, other.key)
-          && Utility.equalsWithNullCheck(value, other.value);
+      Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
+      return Utility.equalsWithNullCheck(key, other.getKey())
+          && Utility.equalsWithNullCheck(value, other.getValue());
     }
 
     public K getKey() {
diff --git a/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java b/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
index 4b5eb2e..94a3b44 100644
--- a/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/TreeMapTest.java
@@ -46,6 +46,50 @@
  * work.
  */
 public abstract class TreeMapTest<K extends Comparable<K>, V> extends TestMap {
+  private static final class SimpleEntry<K, V> implements Entry<K, V> {
+    private static boolean equal(Object a, Object b) {
+      return (a == null) ? (b == null) : a.equals(b);
+    }
+
+    private final K key;
+    private final V value;
+
+    private SimpleEntry(K key, V value) {
+      this.key = key;
+      this.value = value;
+    }
+
+    @Override
+    public boolean equals(Object object) {
+      if (object instanceof Entry) {
+        Entry<?, ?> other = (Entry<?, ?>) object;
+        return equal(key, other.getKey()) && equal(value, other.getValue());
+      }
+      return false;
+    }
+
+    @Override
+    public K getKey() {
+      return key;
+    }
+
+    @Override
+    public V getValue() {
+      return value;
+    }
+
+    @Override
+    public int hashCode() {
+      return ((key == null) ? 0 : key.hashCode())
+          ^ ((value == null) ? 0 : value.hashCode());
+    }
+
+    @Override
+    public final V setValue(V value) {
+      throw new UnsupportedOperationException();
+    }
+  }
+
   /**
    * Verify a Collection is explicitly and implicitly empty.
    * 
@@ -515,6 +559,10 @@
 
     assertEquals(entry.getKey(), getKeys()[0]);
     assertEquals(entry.getValue(), getValues()[0]);
+    // Don't use assertEquals; we want to be clear about which object's equals()
+    // method to test.
+    assertTrue(
+        entry.equals(new SimpleEntry<K, V>(getKeys()[0], getValues()[0])));
   }
 
   /**