Fixing TreeMap serialization issues.

When I was testing this on the JDK I had my own TreeMap on
the classpath, which caused my tests to pass even when they
shouldn't have.

The new serialization data was generated by the JDK's
collections, both v5 and v6. The tests pass on both Dalvik
and the JDK.
diff --git a/libcore/luni/src/main/java/java/util/Collections.java b/libcore/luni/src/main/java/java/util/Collections.java
index 7e96e10..af49cc0 100644
--- a/libcore/luni/src/main/java/java/util/Collections.java
+++ b/libcore/luni/src/main/java/java/util/Collections.java
@@ -209,31 +209,26 @@
         }
     }
 
-    private static final class ReverseComparatorWithComparator<T> implements
-            Comparator<T>, Serializable {
+    private static final class ReverseComparator2<T>
+            implements Comparator<T>, Serializable {
         private static final long serialVersionUID = 4374092139857L;
+        private final Comparator<T> cmp;
 
-        private final Comparator<T> comparator;
-
-        ReverseComparatorWithComparator(Comparator<T> comparator) {
-            super();
-            this.comparator = comparator;
+        ReverseComparator2(Comparator<T> comparator) {
+            this.cmp = comparator;
         }
 
         public int compare(T o1, T o2) {
-            return comparator.compare(o2, o1);
+            return cmp.compare(o2, o1);
         }
 
-        @Override
-        public boolean equals(Object o) {
-            return o instanceof ReverseComparatorWithComparator
-                    && ((ReverseComparatorWithComparator) o).comparator
-                            .equals(comparator);
+        @Override public boolean equals(Object o) {
+            return o instanceof ReverseComparator2
+                    && ((ReverseComparator2) o).cmp.equals(cmp);
         }
 
-        @Override
-        public int hashCode() {
-            return ~comparator.hashCode();
+        @Override public int hashCode() {
+            return ~cmp.hashCode();
         }
     }
 
@@ -1835,10 +1830,10 @@
         if (c == null) {
             return reverseOrder();
         }
-        if (c instanceof ReverseComparatorWithComparator) {
-            return ((ReverseComparatorWithComparator<T>) c).comparator;
+        if (c instanceof ReverseComparator2) {
+            return ((ReverseComparator2<T>) c).cmp;
         }
-        return new ReverseComparatorWithComparator<T>(c);
+        return new ReverseComparator2<T>(c);
     }
 
     /**
diff --git a/libcore/luni/src/main/java/java/util/TreeMap.java b/libcore/luni/src/main/java/java/util/TreeMap.java
index 98680d0..7075cec 100644
--- a/libcore/luni/src/main/java/java/util/TreeMap.java
+++ b/libcore/luni/src/main/java/java/util/TreeMap.java
@@ -1596,6 +1596,7 @@
     }
 
     static abstract class NavigableSubMap<K, V> extends AbstractMap<K, V> implements Serializable {
+        private static final long serialVersionUID = -2102997345730753016L;
         TreeMap<K, V> m;
         Object lo;
         Object hi;
@@ -1608,8 +1609,8 @@
             this.m = delegate;
             this.lo = from;
             this.hi = to;
-            this.fromStart = fromBound != NO_BOUND;
-            this.toEnd = toBound != NO_BOUND;
+            this.fromStart = fromBound == NO_BOUND;
+            this.toEnd = toBound == NO_BOUND;
             this.loInclusive = fromBound == INCLUSIVE;
             this.hiInclusive = toBound == INCLUSIVE;
         }
@@ -1619,9 +1620,9 @@
         }
 
         @SuppressWarnings("unchecked") // we have to trust that the bounds are Ks
-        private Object readResolve() throws ObjectStreamException {
-            Bound fromBound = fromStart ? (loInclusive ? INCLUSIVE : EXCLUSIVE) : NO_BOUND;
-            Bound toBound = toEnd ? (hiInclusive ? INCLUSIVE : EXCLUSIVE) : NO_BOUND;
+        protected Object readResolve() throws ObjectStreamException {
+            Bound fromBound = fromStart ? NO_BOUND : (loInclusive ? INCLUSIVE : EXCLUSIVE);
+            Bound toBound = toEnd ? NO_BOUND : (hiInclusive ? INCLUSIVE : EXCLUSIVE);
             boolean ascending = !(this instanceof DescendingSubMap);
             return m.new BoundedMap(ascending, (K) lo, fromBound, (K) hi, toBound);
         }
@@ -1642,11 +1643,10 @@
         }
     }
 
-    static class SubMap<K, V> extends AbstractMap<K, V> implements Serializable {
+    class SubMap extends AbstractMap<K, V> implements Serializable {
         private static final long serialVersionUID = -6520786458950516097L;
-        TreeMap<K, V> m;
-        Object lo;
-        Object hi;
+        Object fromKey;
+        Object toKey;
         boolean fromStart;
         boolean toEnd;
 
@@ -1655,10 +1655,10 @@
         }
 
         @SuppressWarnings("unchecked") // we have to trust that the bounds are Ks
-        private Object readResolve() throws ObjectStreamException {
-            Bound fromBound = fromStart ? INCLUSIVE : NO_BOUND;
-            Bound toBound = toEnd ? EXCLUSIVE : NO_BOUND;
-            return m.new BoundedMap(true, (K) lo, fromBound, (K) hi, toBound);
+        protected Object readResolve() throws ObjectStreamException {
+            Bound fromBound = fromStart ? NO_BOUND : INCLUSIVE;
+            Bound toBound = toEnd ? NO_BOUND : EXCLUSIVE;
+            return new BoundedMap(true, (K) fromKey, fromBound, (K) toKey, toBound);
         }
     }
 }
diff --git a/libcore/luni/src/test/java/java/util/TreeMapTest.java b/libcore/luni/src/test/java/java/util/TreeMapTest.java
index 2ce0bb5..87992da 100644
--- a/libcore/luni/src/test/java/java/util/TreeMapTest.java
+++ b/libcore/luni/src/test/java/java/util/TreeMapTest.java
@@ -155,9 +155,9 @@
     }
 
     public void testEmptyMapSerialization() {
-        String s = "aced0005737200166578616d706c65732e6a657373652e547265654d61700cc1f"
-                + "63e2d256ae60300014c000a636f6d70617261746f727400164c6a6176612f75746"
-                + "96c2f436f6d70617261746f723b78707077040000000078";
+        String s = "aced0005737200116a6176612e7574696c2e547265654d61700cc1f63e2d256a"
+                + "e60300014c000a636f6d70617261746f727400164c6a6176612f7574696c2f436"
+                + "f6d70617261746f723b78707077040000000078";
         TreeMap<String, String> map = new TreeMap<String, String>();
         new SerializableTester<TreeMap<String, String>>(map, s).test();
     }
@@ -270,5 +270,53 @@
             }
         }.test();
     }
-}
 
+    public void testJava5SerializationWithComparator() {
+        String s = "aced0005737200116a6176612e7574696c2e547265654d61700cc1f63e2d256a"
+                + "e60300014c000a636f6d70617261746f727400164c6a6176612f7574696c2f436"
+                + "f6d70617261746f723b78707372002a6a6176612e6c616e672e537472696e6724"
+                + "43617365496e73656e736974697665436f6d70617261746f7277035c7d5c50e5c"
+                + "e02000078707704000000027400016171007e00057400016271007e000678";
+        TreeMap<String,String> map = new TreeMap<String, String>(
+                String.CASE_INSENSITIVE_ORDER);
+        map.put("a", "a");
+        map.put("b", "b");
+        new SerializableTester<TreeMap<String, String>>(map, s) {
+            @Override protected void verify(TreeMap<String, String> deserialized) {
+                assertEquals(0, deserialized.comparator().compare("X", "x"));
+            }
+        }.test();
+    }
+
+    /**
+     * On JDK5, this fails with a NullPointerException after deserialization!
+     */
+    public void testJava5SubmapSerialization() {
+        String s = "aced0005737200186a6176612e7574696c2e547265654d6170245375624d6170"
+                + "a5818343a213c27f0200055a000966726f6d53746172745a0005746f456e644c0"
+                + "00766726f6d4b65797400124c6a6176612f6c616e672f4f626a6563743b4c0006"
+                + "7468697324307400134c6a6176612f7574696c2f547265654d61703b4c0005746"
+                + "f4b657971007e00017870000074000161737200116a6176612e7574696c2e5472"
+                + "65654d61700cc1f63e2d256ae60300014c000a636f6d70617261746f727400164"
+                + "c6a6176612f7574696c2f436f6d70617261746f723b78707372002a6a6176612e"
+                + "6c616e672e537472696e672443617365496e73656e736974697665436f6d70617"
+                + "261746f7277035c7d5c50e5ce020000787077040000000471007e000471007e00" 
+                + "047400016271007e000a7400016371007e000b7400016471007e000c7871007e0"
+                + "00b";
+        TreeMap<String,String> map = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+        map.put("a", "a");
+        map.put("b", "b");
+        map.put("c", "c");
+        map.put("d", "d");
+        SortedMap<String, String> submap = map.subMap("a", "c");
+        new SerializableTester<SortedMap<String, String>>(submap, s) {
+            @Override protected void verify(SortedMap<String, String> deserialized) {
+                try {
+                    deserialized.put("e", "e");
+                    fail();
+                } catch (IllegalArgumentException e) {
+                }
+            }
+        }.test();
+    }
+}