Workaround bogus TreeMap Comparators.

Try our best not to compare elements against themselves.

**** THIS CHANGE WILL BE REVERTED IN A FUTURE ANDROID RELEASE ****

bug: 26336181
Change-Id: I67e846159c1be9e9a5595ece5a32a00ff8eacccd
diff --git a/luni/src/test/java/libcore/java/util/TreeMapTest.java b/luni/src/test/java/libcore/java/util/TreeMapTest.java
index 1518e25..6864379 100644
--- a/luni/src/test/java/libcore/java/util/TreeMapTest.java
+++ b/luni/src/test/java/libcore/java/util/TreeMapTest.java
@@ -17,6 +17,7 @@
 package libcore.java.util;
 
 import java.util.AbstractMap.SimpleEntry;
+import java.util.Comparator;
 import java.util.ConcurrentModificationException;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -434,4 +435,31 @@
             }
         }.test();
     }
+
+    // http://b//26336181
+    //
+    // Note that this is only worth working around because these bogus comparators worked
+    // somewhat-fine on M and below provided that :
+    //
+    // (1) put was called with distinct elements (i.e, with no two elements equal() to each other)
+    // (2) get or get-like methods are never called
+    //
+    // These comparators are clearly bogus but are somewhat common.
+    public void testTreeMapWithBogusComparator() {
+        TreeMap<String, String> treeMap = new TreeMap<String, String>(
+                new Comparator<String>() {
+                    @Override
+                    public int compare(String o1, String o2) {
+                        if (o1.equals(o2)) {
+                            throw new IllegalArgumentException("Expected unequal elements");
+                        }
+
+                        return o1.compareTo(o2);
+                    }
+                }
+        );
+
+        treeMap.put("candy", "floss");
+        treeMap.put("cheddar", "cheese");
+    }
 }
diff --git a/ojluni/src/main/java/java/util/TreeMap.java b/ojluni/src/main/java/java/util/TreeMap.java
index e57c5a9..f25e5af 100755
--- a/ojluni/src/main/java/java/util/TreeMap.java
+++ b/ojluni/src/main/java/java/util/TreeMap.java
@@ -529,7 +529,31 @@
     public V put(K key, V value) {
         TreeMapEntry<K,V> t = root;
         if (t == null) {
-            compare(key, key); // type (and possibly null) check
+            // We could just call compare(key, key) for its side effect of checking the type and
+            // nullness of the input key. However, several applications seem to have written comparators
+            // that only expect to be called on elements that aren't equal to each other (after
+            // making assumptions about the domain of the map). Clearly, such comparators are bogus
+            // because get() would never work, but TreeSets are frequently used for sorting a set
+            // of distinct elements.
+            //
+            // As a temporary work around, we perform the null & instanceof checks by hand so that
+            // we can guarantee that elements are never compared against themselves.
+            //
+            // compare(key, key);
+            //
+            // **** THIS CHANGE WILL BE REVERTED IN A FUTURE ANDROID RELEASE ****
+            if (comparator != null) {
+                if (key == null) {
+                    comparator.compare(key, key);
+                }
+            } else {
+                if (key == null) {
+                    throw new NullPointerException("key == null");
+                } else if (!(key instanceof Comparable)) {
+                    throw new ClassCastException(
+                            "Cannot cast" + key.getClass().getName() + " to Comparable.");
+                }
+            }
 
             root = new TreeMapEntry<>(key, value, null);
             size = 1;