|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  */ | 
|  |  | 
|  | package java.util; | 
|  |  | 
|  | import java.io.Serializable; | 
|  | import java.util.function.BiConsumer; | 
|  | import java.util.function.BiFunction; | 
|  | import java.util.function.Consumer; | 
|  |  | 
|  | /** | 
|  |  * A Red-Black tree based {@link NavigableMap} implementation. | 
|  |  * The map is sorted according to the {@linkplain Comparable natural | 
|  |  * ordering} of its keys, or by a {@link Comparator} provided at map | 
|  |  * creation time, depending on which constructor is used. | 
|  |  * | 
|  |  * <p>This implementation provides guaranteed log(n) time cost for the | 
|  |  * {@code containsKey}, {@code get}, {@code put} and {@code remove} | 
|  |  * operations.  Algorithms are adaptations of those in Cormen, Leiserson, and | 
|  |  * Rivest's <em>Introduction to Algorithms</em>. | 
|  |  * | 
|  |  * <p>Note that the ordering maintained by a tree map, like any sorted map, and | 
|  |  * whether or not an explicit comparator is provided, must be <em>consistent | 
|  |  * with {@code equals}</em> if this sorted map is to correctly implement the | 
|  |  * {@code Map} interface.  (See {@code Comparable} or {@code Comparator} for a | 
|  |  * precise definition of <em>consistent with equals</em>.)  This is so because | 
|  |  * the {@code Map} interface is defined in terms of the {@code equals} | 
|  |  * operation, but a sorted map performs all key comparisons using its {@code | 
|  |  * compareTo} (or {@code compare}) method, so two keys that are deemed equal by | 
|  |  * this method are, from the standpoint of the sorted map, equal.  The behavior | 
|  |  * of a sorted map <em>is</em> well-defined even if its ordering is | 
|  |  * inconsistent with {@code equals}; it just fails to obey the general contract | 
|  |  * of the {@code Map} interface. | 
|  |  * | 
|  |  * <p><strong>Note that this implementation is not synchronized.</strong> | 
|  |  * If multiple threads access a map concurrently, and at least one of the | 
|  |  * threads modifies the map structurally, it <em>must</em> be synchronized | 
|  |  * externally.  (A structural modification is any operation that adds or | 
|  |  * deletes one or more mappings; merely changing the value associated | 
|  |  * with an existing key is not a structural modification.)  This is | 
|  |  * typically accomplished by synchronizing on some object that naturally | 
|  |  * encapsulates the map. | 
|  |  * If no such object exists, the map should be "wrapped" using the | 
|  |  * {@link Collections#synchronizedSortedMap Collections.synchronizedSortedMap} | 
|  |  * method.  This is best done at creation time, to prevent accidental | 
|  |  * unsynchronized access to the map: <pre> | 
|  |  *   SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));</pre> | 
|  |  * | 
|  |  * <p>The iterators returned by the {@code iterator} method of the collections | 
|  |  * returned by all of this class's "collection view methods" are | 
|  |  * <em>fail-fast</em>: if the map is structurally modified at any time after | 
|  |  * the iterator is created, in any way except through the iterator's own | 
|  |  * {@code remove} method, the iterator will throw a {@link | 
|  |  * ConcurrentModificationException}.  Thus, in the face of concurrent | 
|  |  * modification, the iterator fails quickly and cleanly, rather than risking | 
|  |  * arbitrary, non-deterministic behavior at an undetermined time in the future. | 
|  |  * | 
|  |  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed | 
|  |  * as it is, generally speaking, impossible to make any hard guarantees in the | 
|  |  * presence of unsynchronized concurrent modification.  Fail-fast iterators | 
|  |  * throw {@code ConcurrentModificationException} on a best-effort basis. | 
|  |  * Therefore, it would be wrong to write a program that depended on this | 
|  |  * exception for its correctness:   <em>the fail-fast behavior of iterators | 
|  |  * should be used only to detect bugs.</em> | 
|  |  * | 
|  |  * <p>All {@code Map.Entry} pairs returned by methods in this class | 
|  |  * and its views represent snapshots of mappings at the time they were | 
|  |  * produced. They do <strong>not</strong> support the {@code Entry.setValue} | 
|  |  * method. (Note however that it is possible to change mappings in the | 
|  |  * associated map using {@code put}.) | 
|  |  * | 
|  |  * <p>This class is a member of the | 
|  |  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework"> | 
|  |  * Java Collections Framework</a>. | 
|  |  * | 
|  |  * @param <K> the type of keys maintained by this map | 
|  |  * @param <V> the type of mapped values | 
|  |  * | 
|  |  * @author  Josh Bloch and Doug Lea | 
|  |  * @see Map | 
|  |  * @see HashMap | 
|  |  * @see Hashtable | 
|  |  * @see Comparable | 
|  |  * @see Comparator | 
|  |  * @see Collection | 
|  |  * @since 1.2 | 
|  |  */ | 
|  |  | 
|  | public class TreeMap<K,V> | 
|  |     extends AbstractMap<K,V> | 
|  |     implements NavigableMap<K,V>, Cloneable, java.io.Serializable | 
|  | { | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private final Comparator<? super K> comparator; | 
|  |  | 
|  |     private transient Entry<K,V> root; | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     private transient int size = 0; | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     private transient int modCount = 0; | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public TreeMap() { | 
|  |         comparator = null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public TreeMap(Comparator<? super K> comparator) { | 
|  |         this.comparator = comparator; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public TreeMap(Map<? extends K, ? extends V> m) { | 
|  |         comparator = null; | 
|  |         putAll(m); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public TreeMap(SortedMap<K, ? extends V> m) { | 
|  |         comparator = m.comparator(); | 
|  |         try { | 
|  |             buildFromSorted(m.size(), m.entrySet().iterator(), null, null); | 
|  |         } catch (java.io.IOException | ClassNotFoundException cannotHappen) { | 
|  |         } | 
|  |     } | 
|  |  | 
|  |  | 
|  |     // Query Operations | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public int size() { | 
|  |         return size; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public boolean containsKey(Object key) { | 
|  |         return getEntry(key) != null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public boolean containsValue(Object value) { | 
|  |         for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) | 
|  |             if (valEquals(value, e.value)) | 
|  |                 return true; | 
|  |         return false; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public V get(Object key) { | 
|  |         Entry<K,V> p = getEntry(key); | 
|  |         return (p==null ? null : p.value); | 
|  |     } | 
|  |  | 
|  |     public Comparator<? super K> comparator() { | 
|  |         return comparator; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public K firstKey() { | 
|  |         return key(getFirstEntry()); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public K lastKey() { | 
|  |         return key(getLastEntry()); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public void putAll(Map<? extends K, ? extends V> map) { | 
|  |         int mapSize = map.size(); | 
|  |         if (size==0 && mapSize!=0 && map instanceof SortedMap) { | 
|  |             Comparator<?> c = ((SortedMap<?,?>)map).comparator(); | 
|  |             if (c == comparator || (c != null && c.equals(comparator))) { | 
|  |                 ++modCount; | 
|  |                 try { | 
|  |                     buildFromSorted(mapSize, map.entrySet().iterator(), | 
|  |                                     null, null); | 
|  |                 } catch (java.io.IOException | ClassNotFoundException cannotHappen) { | 
|  |                 } | 
|  |                 return; | 
|  |             } | 
|  |         } | 
|  |         super.putAll(map); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     final Entry<K,V> getEntry(Object key) { | 
|  |          | 
|  |         if (comparator != null) | 
|  |             return getEntryUsingComparator(key); | 
|  |         if (key == null) | 
|  |             throw new NullPointerException(); | 
|  |         @SuppressWarnings("unchecked") | 
|  |             Comparable<? super K> k = (Comparable<? super K>) key; | 
|  |         Entry<K,V> p = root; | 
|  |         while (p != null) { | 
|  |             int cmp = k.compareTo(p.key); | 
|  |             if (cmp < 0) | 
|  |                 p = p.left; | 
|  |             else if (cmp > 0) | 
|  |                 p = p.right; | 
|  |             else | 
|  |                 return p; | 
|  |         } | 
|  |         return null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     final Entry<K,V> getEntryUsingComparator(Object key) { | 
|  |         @SuppressWarnings("unchecked") | 
|  |             K k = (K) key; | 
|  |         Comparator<? super K> cpr = comparator; | 
|  |         if (cpr != null) { | 
|  |             Entry<K,V> p = root; | 
|  |             while (p != null) { | 
|  |                 int cmp = cpr.compare(k, p.key); | 
|  |                 if (cmp < 0) | 
|  |                     p = p.left; | 
|  |                 else if (cmp > 0) | 
|  |                     p = p.right; | 
|  |                 else | 
|  |                     return p; | 
|  |             } | 
|  |         } | 
|  |         return null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     final Entry<K,V> getCeilingEntry(K key) { | 
|  |         Entry<K,V> p = root; | 
|  |         while (p != null) { | 
|  |             int cmp = compare(key, p.key); | 
|  |             if (cmp < 0) { | 
|  |                 if (p.left != null) | 
|  |                     p = p.left; | 
|  |                 else | 
|  |                     return p; | 
|  |             } else if (cmp > 0) { | 
|  |                 if (p.right != null) { | 
|  |                     p = p.right; | 
|  |                 } else { | 
|  |                     Entry<K,V> parent = p.parent; | 
|  |                     Entry<K,V> ch = p; | 
|  |                     while (parent != null && ch == parent.right) { | 
|  |                         ch = parent; | 
|  |                         parent = parent.parent; | 
|  |                     } | 
|  |                     return parent; | 
|  |                 } | 
|  |             } else | 
|  |                 return p; | 
|  |         } | 
|  |         return null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     final Entry<K,V> getFloorEntry(K key) { | 
|  |         Entry<K,V> p = root; | 
|  |         while (p != null) { | 
|  |             int cmp = compare(key, p.key); | 
|  |             if (cmp > 0) { | 
|  |                 if (p.right != null) | 
|  |                     p = p.right; | 
|  |                 else | 
|  |                     return p; | 
|  |             } else if (cmp < 0) { | 
|  |                 if (p.left != null) { | 
|  |                     p = p.left; | 
|  |                 } else { | 
|  |                     Entry<K,V> parent = p.parent; | 
|  |                     Entry<K,V> ch = p; | 
|  |                     while (parent != null && ch == parent.left) { | 
|  |                         ch = parent; | 
|  |                         parent = parent.parent; | 
|  |                     } | 
|  |                     return parent; | 
|  |                 } | 
|  |             } else | 
|  |                 return p; | 
|  |  | 
|  |         } | 
|  |         return null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     final Entry<K,V> getHigherEntry(K key) { | 
|  |         Entry<K,V> p = root; | 
|  |         while (p != null) { | 
|  |             int cmp = compare(key, p.key); | 
|  |             if (cmp < 0) { | 
|  |                 if (p.left != null) | 
|  |                     p = p.left; | 
|  |                 else | 
|  |                     return p; | 
|  |             } else { | 
|  |                 if (p.right != null) { | 
|  |                     p = p.right; | 
|  |                 } else { | 
|  |                     Entry<K,V> parent = p.parent; | 
|  |                     Entry<K,V> ch = p; | 
|  |                     while (parent != null && ch == parent.right) { | 
|  |                         ch = parent; | 
|  |                         parent = parent.parent; | 
|  |                     } | 
|  |                     return parent; | 
|  |                 } | 
|  |             } | 
|  |         } | 
|  |         return null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     final Entry<K,V> getLowerEntry(K key) { | 
|  |         Entry<K,V> p = root; | 
|  |         while (p != null) { | 
|  |             int cmp = compare(key, p.key); | 
|  |             if (cmp > 0) { | 
|  |                 if (p.right != null) | 
|  |                     p = p.right; | 
|  |                 else | 
|  |                     return p; | 
|  |             } else { | 
|  |                 if (p.left != null) { | 
|  |                     p = p.left; | 
|  |                 } else { | 
|  |                     Entry<K,V> parent = p.parent; | 
|  |                     Entry<K,V> ch = p; | 
|  |                     while (parent != null && ch == parent.left) { | 
|  |                         ch = parent; | 
|  |                         parent = parent.parent; | 
|  |                     } | 
|  |                     return parent; | 
|  |                 } | 
|  |             } | 
|  |         } | 
|  |         return null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public V put(K key, V value) { | 
|  |         Entry<K,V> t = root; | 
|  |         if (t == null) { | 
|  |             compare(key, key);  | 
|  |  | 
|  |             root = new Entry<>(key, value, null); | 
|  |             size = 1; | 
|  |             modCount++; | 
|  |             return null; | 
|  |         } | 
|  |         int cmp; | 
|  |         Entry<K,V> parent; | 
|  |          | 
|  |         Comparator<? super K> cpr = comparator; | 
|  |         if (cpr != null) { | 
|  |             do { | 
|  |                 parent = t; | 
|  |                 cmp = cpr.compare(key, t.key); | 
|  |                 if (cmp < 0) | 
|  |                     t = t.left; | 
|  |                 else if (cmp > 0) | 
|  |                     t = t.right; | 
|  |                 else | 
|  |                     return t.setValue(value); | 
|  |             } while (t != null); | 
|  |         } | 
|  |         else { | 
|  |             if (key == null) | 
|  |                 throw new NullPointerException(); | 
|  |             @SuppressWarnings("unchecked") | 
|  |                 Comparable<? super K> k = (Comparable<? super K>) key; | 
|  |             do { | 
|  |                 parent = t; | 
|  |                 cmp = k.compareTo(t.key); | 
|  |                 if (cmp < 0) | 
|  |                     t = t.left; | 
|  |                 else if (cmp > 0) | 
|  |                     t = t.right; | 
|  |                 else | 
|  |                     return t.setValue(value); | 
|  |             } while (t != null); | 
|  |         } | 
|  |         Entry<K,V> e = new Entry<>(key, value, parent); | 
|  |         if (cmp < 0) | 
|  |             parent.left = e; | 
|  |         else | 
|  |             parent.right = e; | 
|  |         fixAfterInsertion(e); | 
|  |         size++; | 
|  |         modCount++; | 
|  |         return null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public V remove(Object key) { | 
|  |         Entry<K,V> p = getEntry(key); | 
|  |         if (p == null) | 
|  |             return null; | 
|  |  | 
|  |         V oldValue = p.value; | 
|  |         deleteEntry(p); | 
|  |         return oldValue; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public void clear() { | 
|  |         modCount++; | 
|  |         size = 0; | 
|  |         root = null; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public Object clone() { | 
|  |         TreeMap<?,?> clone; | 
|  |         try { | 
|  |             clone = (TreeMap<?,?>) super.clone(); | 
|  |         } catch (CloneNotSupportedException e) { | 
|  |             throw new InternalError(e); | 
|  |         } | 
|  |  | 
|  |          | 
|  |         clone.root = null; | 
|  |         clone.size = 0; | 
|  |         clone.modCount = 0; | 
|  |         clone.entrySet = null; | 
|  |         clone.navigableKeySet = null; | 
|  |         clone.descendingMap = null; | 
|  |  | 
|  |          | 
|  |         try { | 
|  |             clone.buildFromSorted(size, entrySet().iterator(), null, null); | 
|  |         } catch (java.io.IOException | ClassNotFoundException cannotHappen) { | 
|  |         } | 
|  |  | 
|  |         return clone; | 
|  |     } | 
|  |  | 
|  |     // NavigableMap API methods | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public Map.Entry<K,V> firstEntry() { | 
|  |         return exportEntry(getFirstEntry()); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public Map.Entry<K,V> lastEntry() { | 
|  |         return exportEntry(getLastEntry()); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public Map.Entry<K,V> pollFirstEntry() { | 
|  |         Entry<K,V> p = getFirstEntry(); | 
|  |         Map.Entry<K,V> result = exportEntry(p); | 
|  |         if (p != null) | 
|  |             deleteEntry(p); | 
|  |         return result; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public Map.Entry<K,V> pollLastEntry() { | 
|  |         Entry<K,V> p = getLastEntry(); | 
|  |         Map.Entry<K,V> result = exportEntry(p); | 
|  |         if (p != null) | 
|  |             deleteEntry(p); | 
|  |         return result; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public Map.Entry<K,V> lowerEntry(K key) { | 
|  |         return exportEntry(getLowerEntry(key)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public K lowerKey(K key) { | 
|  |         return keyOrNull(getLowerEntry(key)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public Map.Entry<K,V> floorEntry(K key) { | 
|  |         return exportEntry(getFloorEntry(key)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public K floorKey(K key) { | 
|  |         return keyOrNull(getFloorEntry(key)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public Map.Entry<K,V> ceilingEntry(K key) { | 
|  |         return exportEntry(getCeilingEntry(key)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public K ceilingKey(K key) { | 
|  |         return keyOrNull(getCeilingEntry(key)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public Map.Entry<K,V> higherEntry(K key) { | 
|  |         return exportEntry(getHigherEntry(key)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public K higherKey(K key) { | 
|  |         return keyOrNull(getHigherEntry(key)); | 
|  |     } | 
|  |  | 
|  |     // Views | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private transient EntrySet entrySet; | 
|  |     private transient KeySet<K> navigableKeySet; | 
|  |     private transient NavigableMap<K,V> descendingMap; | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public Set<K> keySet() { | 
|  |         return navigableKeySet(); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public NavigableSet<K> navigableKeySet() { | 
|  |         KeySet<K> nks = navigableKeySet; | 
|  |         return (nks != null) ? nks : (navigableKeySet = new KeySet<>(this)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public NavigableSet<K> descendingKeySet() { | 
|  |         return descendingMap().navigableKeySet(); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public Collection<V> values() { | 
|  |         Collection<V> vs = values; | 
|  |         if (vs == null) { | 
|  |             vs = new Values(); | 
|  |             values = vs; | 
|  |         } | 
|  |         return vs; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public Set<Map.Entry<K,V>> entrySet() { | 
|  |         EntrySet es = entrySet; | 
|  |         return (es != null) ? es : (entrySet = new EntrySet()); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     public NavigableMap<K, V> descendingMap() { | 
|  |         NavigableMap<K, V> km = descendingMap; | 
|  |         return (km != null) ? km : | 
|  |             (descendingMap = new DescendingSubMap<>(this, | 
|  |                                                     true, null, true, | 
|  |                                                     true, null, true)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, | 
|  |                                     K toKey,   boolean toInclusive) { | 
|  |         return new AscendingSubMap<>(this, | 
|  |                                      false, fromKey, fromInclusive, | 
|  |                                      false, toKey,   toInclusive); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { | 
|  |         return new AscendingSubMap<>(this, | 
|  |                                      true,  null,  true, | 
|  |                                      false, toKey, inclusive); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { | 
|  |         return new AscendingSubMap<>(this, | 
|  |                                      false, fromKey, inclusive, | 
|  |                                      true,  null,    true); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public SortedMap<K,V> subMap(K fromKey, K toKey) { | 
|  |         return subMap(fromKey, true, toKey, false); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public SortedMap<K,V> headMap(K toKey) { | 
|  |         return headMap(toKey, false); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     public SortedMap<K,V> tailMap(K fromKey) { | 
|  |         return tailMap(fromKey, true); | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public boolean replace(K key, V oldValue, V newValue) { | 
|  |         Entry<K,V> p = getEntry(key); | 
|  |         if (p!=null && Objects.equals(oldValue, p.value)) { | 
|  |             p.value = newValue; | 
|  |             return true; | 
|  |         } | 
|  |         return false; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public V replace(K key, V value) { | 
|  |         Entry<K,V> p = getEntry(key); | 
|  |         if (p!=null) { | 
|  |             V oldValue = p.value; | 
|  |             p.value = value; | 
|  |             return oldValue; | 
|  |         } | 
|  |         return null; | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void forEach(BiConsumer<? super K, ? super V> action) { | 
|  |         Objects.requireNonNull(action); | 
|  |         int expectedModCount = modCount; | 
|  |         for (Entry<K, V> e = getFirstEntry(); e != null; e = successor(e)) { | 
|  |             action.accept(e.key, e.value); | 
|  |  | 
|  |             if (expectedModCount != modCount) { | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             } | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     @Override | 
|  |     public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { | 
|  |         Objects.requireNonNull(function); | 
|  |         int expectedModCount = modCount; | 
|  |  | 
|  |         for (Entry<K, V> e = getFirstEntry(); e != null; e = successor(e)) { | 
|  |             e.value = function.apply(e.key, e.value); | 
|  |  | 
|  |             if (expectedModCount != modCount) { | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             } | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     // View class support | 
|  |  | 
|  |     class Values extends AbstractCollection<V> { | 
|  |         public Iterator<V> iterator() { | 
|  |             return new ValueIterator(getFirstEntry()); | 
|  |         } | 
|  |  | 
|  |         public int size() { | 
|  |             return TreeMap.this.size(); | 
|  |         } | 
|  |  | 
|  |         public boolean contains(Object o) { | 
|  |             return TreeMap.this.containsValue(o); | 
|  |         } | 
|  |  | 
|  |         public boolean remove(Object o) { | 
|  |             for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) { | 
|  |                 if (valEquals(e.getValue(), o)) { | 
|  |                     deleteEntry(e); | 
|  |                     return true; | 
|  |                 } | 
|  |             } | 
|  |             return false; | 
|  |         } | 
|  |  | 
|  |         public void clear() { | 
|  |             TreeMap.this.clear(); | 
|  |         } | 
|  |  | 
|  |         public Spliterator<V> spliterator() { | 
|  |             return new ValueSpliterator<>(TreeMap.this, null, null, 0, -1, 0); | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     class EntrySet extends AbstractSet<Map.Entry<K,V>> { | 
|  |         public Iterator<Map.Entry<K,V>> iterator() { | 
|  |             return new EntryIterator(getFirstEntry()); | 
|  |         } | 
|  |  | 
|  |         public boolean contains(Object o) { | 
|  |             if (!(o instanceof Map.Entry)) | 
|  |                 return false; | 
|  |             Map.Entry<?,?> entry = (Map.Entry<?,?>) o; | 
|  |             Object value = entry.getValue(); | 
|  |             Entry<K,V> p = getEntry(entry.getKey()); | 
|  |             return p != null && valEquals(p.getValue(), value); | 
|  |         } | 
|  |  | 
|  |         public boolean remove(Object o) { | 
|  |             if (!(o instanceof Map.Entry)) | 
|  |                 return false; | 
|  |             Map.Entry<?,?> entry = (Map.Entry<?,?>) o; | 
|  |             Object value = entry.getValue(); | 
|  |             Entry<K,V> p = getEntry(entry.getKey()); | 
|  |             if (p != null && valEquals(p.getValue(), value)) { | 
|  |                 deleteEntry(p); | 
|  |                 return true; | 
|  |             } | 
|  |             return false; | 
|  |         } | 
|  |  | 
|  |         public int size() { | 
|  |             return TreeMap.this.size(); | 
|  |         } | 
|  |  | 
|  |         public void clear() { | 
|  |             TreeMap.this.clear(); | 
|  |         } | 
|  |  | 
|  |         public Spliterator<Map.Entry<K,V>> spliterator() { | 
|  |             return new EntrySpliterator<>(TreeMap.this, null, null, 0, -1, 0); | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     /* | 
|  |      * Unlike Values and EntrySet, the KeySet class is static, | 
|  |      * delegating to a NavigableMap to allow use by SubMaps, which | 
|  |      * outweighs the ugliness of needing type-tests for the following | 
|  |      * Iterator methods that are defined appropriately in main versus | 
|  |      * submap classes. | 
|  |      */ | 
|  |  | 
|  |     Iterator<K> keyIterator() { | 
|  |         return new KeyIterator(getFirstEntry()); | 
|  |     } | 
|  |  | 
|  |     Iterator<K> descendingKeyIterator() { | 
|  |         return new DescendingKeyIterator(getLastEntry()); | 
|  |     } | 
|  |  | 
|  |     static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> { | 
|  |         private final NavigableMap<E, ?> m; | 
|  |         KeySet(NavigableMap<E,?> map) { m = map; } | 
|  |  | 
|  |         public Iterator<E> iterator() { | 
|  |             if (m instanceof TreeMap) | 
|  |                 return ((TreeMap<E,?>)m).keyIterator(); | 
|  |             else | 
|  |                 return ((TreeMap.NavigableSubMap<E,?>)m).keyIterator(); | 
|  |         } | 
|  |  | 
|  |         public Iterator<E> descendingIterator() { | 
|  |             if (m instanceof TreeMap) | 
|  |                 return ((TreeMap<E,?>)m).descendingKeyIterator(); | 
|  |             else | 
|  |                 return ((TreeMap.NavigableSubMap<E,?>)m).descendingKeyIterator(); | 
|  |         } | 
|  |  | 
|  |         public int size() { return m.size(); } | 
|  |         public boolean isEmpty() { return m.isEmpty(); } | 
|  |         public boolean contains(Object o) { return m.containsKey(o); } | 
|  |         public void clear() { m.clear(); } | 
|  |         public E lower(E e) { return m.lowerKey(e); } | 
|  |         public E floor(E e) { return m.floorKey(e); } | 
|  |         public E ceiling(E e) { return m.ceilingKey(e); } | 
|  |         public E higher(E e) { return m.higherKey(e); } | 
|  |         public E first() { return m.firstKey(); } | 
|  |         public E last() { return m.lastKey(); } | 
|  |         public Comparator<? super E> comparator() { return m.comparator(); } | 
|  |         public E pollFirst() { | 
|  |             Map.Entry<E,?> e = m.pollFirstEntry(); | 
|  |             return (e == null) ? null : e.getKey(); | 
|  |         } | 
|  |         public E pollLast() { | 
|  |             Map.Entry<E,?> e = m.pollLastEntry(); | 
|  |             return (e == null) ? null : e.getKey(); | 
|  |         } | 
|  |         public boolean remove(Object o) { | 
|  |             int oldSize = size(); | 
|  |             m.remove(o); | 
|  |             return size() != oldSize; | 
|  |         } | 
|  |         public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, | 
|  |                                       E toElement,   boolean toInclusive) { | 
|  |             return new KeySet<>(m.subMap(fromElement, fromInclusive, | 
|  |                                           toElement,   toInclusive)); | 
|  |         } | 
|  |         public NavigableSet<E> headSet(E toElement, boolean inclusive) { | 
|  |             return new KeySet<>(m.headMap(toElement, inclusive)); | 
|  |         } | 
|  |         public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { | 
|  |             return new KeySet<>(m.tailMap(fromElement, inclusive)); | 
|  |         } | 
|  |         public SortedSet<E> subSet(E fromElement, E toElement) { | 
|  |             return subSet(fromElement, true, toElement, false); | 
|  |         } | 
|  |         public SortedSet<E> headSet(E toElement) { | 
|  |             return headSet(toElement, false); | 
|  |         } | 
|  |         public SortedSet<E> tailSet(E fromElement) { | 
|  |             return tailSet(fromElement, true); | 
|  |         } | 
|  |         public NavigableSet<E> descendingSet() { | 
|  |             return new KeySet<>(m.descendingMap()); | 
|  |         } | 
|  |  | 
|  |         public Spliterator<E> spliterator() { | 
|  |             return keySpliteratorFor(m); | 
|  |         } | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     abstract class PrivateEntryIterator<T> implements Iterator<T> { | 
|  |         Entry<K,V> next; | 
|  |         Entry<K,V> lastReturned; | 
|  |         int expectedModCount; | 
|  |  | 
|  |         PrivateEntryIterator(Entry<K,V> first) { | 
|  |             expectedModCount = modCount; | 
|  |             lastReturned = null; | 
|  |             next = first; | 
|  |         } | 
|  |  | 
|  |         public final boolean hasNext() { | 
|  |             return next != null; | 
|  |         } | 
|  |  | 
|  |         final Entry<K,V> nextEntry() { | 
|  |             Entry<K,V> e = next; | 
|  |             if (e == null) | 
|  |                 throw new NoSuchElementException(); | 
|  |             if (modCount != expectedModCount) | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             next = successor(e); | 
|  |             lastReturned = e; | 
|  |             return e; | 
|  |         } | 
|  |  | 
|  |         final Entry<K,V> prevEntry() { | 
|  |             Entry<K,V> e = next; | 
|  |             if (e == null) | 
|  |                 throw new NoSuchElementException(); | 
|  |             if (modCount != expectedModCount) | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             next = predecessor(e); | 
|  |             lastReturned = e; | 
|  |             return e; | 
|  |         } | 
|  |  | 
|  |         public void remove() { | 
|  |             if (lastReturned == null) | 
|  |                 throw new IllegalStateException(); | 
|  |             if (modCount != expectedModCount) | 
|  |                 throw new ConcurrentModificationException(); | 
|  |              | 
|  |             if (lastReturned.left != null && lastReturned.right != null) | 
|  |                 next = lastReturned; | 
|  |             deleteEntry(lastReturned); | 
|  |             expectedModCount = modCount; | 
|  |             lastReturned = null; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> { | 
|  |         EntryIterator(Entry<K,V> first) { | 
|  |             super(first); | 
|  |         } | 
|  |         public Map.Entry<K,V> next() { | 
|  |             return nextEntry(); | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     final class ValueIterator extends PrivateEntryIterator<V> { | 
|  |         ValueIterator(Entry<K,V> first) { | 
|  |             super(first); | 
|  |         } | 
|  |         public V next() { | 
|  |             return nextEntry().value; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     final class KeyIterator extends PrivateEntryIterator<K> { | 
|  |         KeyIterator(Entry<K,V> first) { | 
|  |             super(first); | 
|  |         } | 
|  |         public K next() { | 
|  |             return nextEntry().key; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     final class DescendingKeyIterator extends PrivateEntryIterator<K> { | 
|  |         DescendingKeyIterator(Entry<K,V> first) { | 
|  |             super(first); | 
|  |         } | 
|  |         public K next() { | 
|  |             return prevEntry().key; | 
|  |         } | 
|  |         public void remove() { | 
|  |             if (lastReturned == null) | 
|  |                 throw new IllegalStateException(); | 
|  |             if (modCount != expectedModCount) | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             deleteEntry(lastReturned); | 
|  |             lastReturned = null; | 
|  |             expectedModCount = modCount; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     // Little utilities | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     @SuppressWarnings("unchecked") | 
|  |     final int compare(Object k1, Object k2) { | 
|  |         return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2) | 
|  |             : comparator.compare((K)k1, (K)k2); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     static final boolean valEquals(Object o1, Object o2) { | 
|  |         return (o1==null ? o2==null : o1.equals(o2)); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) { | 
|  |         return (e == null) ? null : | 
|  |             new AbstractMap.SimpleImmutableEntry<>(e); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) { | 
|  |         return (e == null) ? null : e.key; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     static <K> K key(Entry<K,?> e) { | 
|  |         if (e==null) | 
|  |             throw new NoSuchElementException(); | 
|  |         return e.key; | 
|  |     } | 
|  |  | 
|  |  | 
|  |     // SubMaps | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private static final Object UNBOUNDED = new Object(); | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V> | 
|  |         implements NavigableMap<K,V>, java.io.Serializable { | 
|  |         private static final long serialVersionUID = -2102997345730753016L; | 
|  |          | 
|  |  | 
|  |          */ | 
|  |         final TreeMap<K,V> m; | 
|  |  | 
|  |          | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |          */ | 
|  |         final K lo, hi; | 
|  |         final boolean fromStart, toEnd; | 
|  |         final boolean loInclusive, hiInclusive; | 
|  |  | 
|  |         NavigableSubMap(TreeMap<K,V> m, | 
|  |                         boolean fromStart, K lo, boolean loInclusive, | 
|  |                         boolean toEnd,     K hi, boolean hiInclusive) { | 
|  |             if (!fromStart && !toEnd) { | 
|  |                 if (m.compare(lo, hi) > 0) | 
|  |                     throw new IllegalArgumentException("fromKey > toKey"); | 
|  |             } else { | 
|  |                 if (!fromStart)  | 
|  |                     m.compare(lo, lo); | 
|  |                 if (!toEnd) | 
|  |                     m.compare(hi, hi); | 
|  |             } | 
|  |  | 
|  |             this.m = m; | 
|  |             this.fromStart = fromStart; | 
|  |             this.lo = lo; | 
|  |             this.loInclusive = loInclusive; | 
|  |             this.toEnd = toEnd; | 
|  |             this.hi = hi; | 
|  |             this.hiInclusive = hiInclusive; | 
|  |         } | 
|  |  | 
|  |         // internal utilities | 
|  |  | 
|  |         final boolean tooLow(Object key) { | 
|  |             if (!fromStart) { | 
|  |                 int c = m.compare(key, lo); | 
|  |                 if (c < 0 || (c == 0 && !loInclusive)) | 
|  |                     return true; | 
|  |             } | 
|  |             return false; | 
|  |         } | 
|  |  | 
|  |         final boolean tooHigh(Object key) { | 
|  |             if (!toEnd) { | 
|  |                 int c = m.compare(key, hi); | 
|  |                 if (c > 0 || (c == 0 && !hiInclusive)) | 
|  |                     return true; | 
|  |             } | 
|  |             return false; | 
|  |         } | 
|  |  | 
|  |         final boolean inRange(Object key) { | 
|  |             return !tooLow(key) && !tooHigh(key); | 
|  |         } | 
|  |  | 
|  |         final boolean inClosedRange(Object key) { | 
|  |             return (fromStart || m.compare(key, lo) >= 0) | 
|  |                 && (toEnd || m.compare(hi, key) >= 0); | 
|  |         } | 
|  |  | 
|  |         final boolean inRange(Object key, boolean inclusive) { | 
|  |             return inclusive ? inRange(key) : inClosedRange(key); | 
|  |         } | 
|  |  | 
|  |         /* | 
|  |          * Absolute versions of relation operations. | 
|  |          * Subclasses map to these using like-named "sub" | 
|  |          * versions that invert senses for descending maps | 
|  |          */ | 
|  |  | 
|  |         final TreeMap.Entry<K,V> absLowest() { | 
|  |             TreeMap.Entry<K,V> e = | 
|  |                 (fromStart ?  m.getFirstEntry() : | 
|  |                  (loInclusive ? m.getCeilingEntry(lo) : | 
|  |                                 m.getHigherEntry(lo))); | 
|  |             return (e == null || tooHigh(e.key)) ? null : e; | 
|  |         } | 
|  |  | 
|  |         final TreeMap.Entry<K,V> absHighest() { | 
|  |             TreeMap.Entry<K,V> e = | 
|  |                 (toEnd ?  m.getLastEntry() : | 
|  |                  (hiInclusive ?  m.getFloorEntry(hi) : | 
|  |                                  m.getLowerEntry(hi))); | 
|  |             return (e == null || tooLow(e.key)) ? null : e; | 
|  |         } | 
|  |  | 
|  |         final TreeMap.Entry<K,V> absCeiling(K key) { | 
|  |             if (tooLow(key)) | 
|  |                 return absLowest(); | 
|  |             TreeMap.Entry<K,V> e = m.getCeilingEntry(key); | 
|  |             return (e == null || tooHigh(e.key)) ? null : e; | 
|  |         } | 
|  |  | 
|  |         final TreeMap.Entry<K,V> absHigher(K key) { | 
|  |             if (tooLow(key)) | 
|  |                 return absLowest(); | 
|  |             TreeMap.Entry<K,V> e = m.getHigherEntry(key); | 
|  |             return (e == null || tooHigh(e.key)) ? null : e; | 
|  |         } | 
|  |  | 
|  |         final TreeMap.Entry<K,V> absFloor(K key) { | 
|  |             if (tooHigh(key)) | 
|  |                 return absHighest(); | 
|  |             TreeMap.Entry<K,V> e = m.getFloorEntry(key); | 
|  |             return (e == null || tooLow(e.key)) ? null : e; | 
|  |         } | 
|  |  | 
|  |         final TreeMap.Entry<K,V> absLower(K key) { | 
|  |             if (tooHigh(key)) | 
|  |                 return absHighest(); | 
|  |             TreeMap.Entry<K,V> e = m.getLowerEntry(key); | 
|  |             return (e == null || tooLow(e.key)) ? null : e; | 
|  |         } | 
|  |  | 
|  |          | 
|  |         final TreeMap.Entry<K,V> absHighFence() { | 
|  |             return (toEnd ? null : (hiInclusive ? | 
|  |                                     m.getHigherEntry(hi) : | 
|  |                                     m.getCeilingEntry(hi))); | 
|  |         } | 
|  |  | 
|  |          | 
|  |         final TreeMap.Entry<K,V> absLowFence() { | 
|  |             return (fromStart ? null : (loInclusive ? | 
|  |                                         m.getLowerEntry(lo) : | 
|  |                                         m.getFloorEntry(lo))); | 
|  |         } | 
|  |  | 
|  |         // Abstract methods defined in ascending vs descending classes | 
|  |         // These relay to the appropriate absolute versions | 
|  |  | 
|  |         abstract TreeMap.Entry<K,V> subLowest(); | 
|  |         abstract TreeMap.Entry<K,V> subHighest(); | 
|  |         abstract TreeMap.Entry<K,V> subCeiling(K key); | 
|  |         abstract TreeMap.Entry<K,V> subHigher(K key); | 
|  |         abstract TreeMap.Entry<K,V> subFloor(K key); | 
|  |         abstract TreeMap.Entry<K,V> subLower(K key); | 
|  |  | 
|  |          | 
|  |         abstract Iterator<K> keyIterator(); | 
|  |  | 
|  |         abstract Spliterator<K> keySpliterator(); | 
|  |  | 
|  |          | 
|  |         abstract Iterator<K> descendingKeyIterator(); | 
|  |  | 
|  |         // public methods | 
|  |  | 
|  |         public boolean isEmpty() { | 
|  |             return (fromStart && toEnd) ? m.isEmpty() : entrySet().isEmpty(); | 
|  |         } | 
|  |  | 
|  |         public int size() { | 
|  |             return (fromStart && toEnd) ? m.size() : entrySet().size(); | 
|  |         } | 
|  |  | 
|  |         public final boolean containsKey(Object key) { | 
|  |             return inRange(key) && m.containsKey(key); | 
|  |         } | 
|  |  | 
|  |         public final V put(K key, V value) { | 
|  |             if (!inRange(key)) | 
|  |                 throw new IllegalArgumentException("key out of range"); | 
|  |             return m.put(key, value); | 
|  |         } | 
|  |  | 
|  |         public final V get(Object key) { | 
|  |             return !inRange(key) ? null :  m.get(key); | 
|  |         } | 
|  |  | 
|  |         public final V remove(Object key) { | 
|  |             return !inRange(key) ? null : m.remove(key); | 
|  |         } | 
|  |  | 
|  |         public final Map.Entry<K,V> ceilingEntry(K key) { | 
|  |             return exportEntry(subCeiling(key)); | 
|  |         } | 
|  |  | 
|  |         public final K ceilingKey(K key) { | 
|  |             return keyOrNull(subCeiling(key)); | 
|  |         } | 
|  |  | 
|  |         public final Map.Entry<K,V> higherEntry(K key) { | 
|  |             return exportEntry(subHigher(key)); | 
|  |         } | 
|  |  | 
|  |         public final K higherKey(K key) { | 
|  |             return keyOrNull(subHigher(key)); | 
|  |         } | 
|  |  | 
|  |         public final Map.Entry<K,V> floorEntry(K key) { | 
|  |             return exportEntry(subFloor(key)); | 
|  |         } | 
|  |  | 
|  |         public final K floorKey(K key) { | 
|  |             return keyOrNull(subFloor(key)); | 
|  |         } | 
|  |  | 
|  |         public final Map.Entry<K,V> lowerEntry(K key) { | 
|  |             return exportEntry(subLower(key)); | 
|  |         } | 
|  |  | 
|  |         public final K lowerKey(K key) { | 
|  |             return keyOrNull(subLower(key)); | 
|  |         } | 
|  |  | 
|  |         public final K firstKey() { | 
|  |             return key(subLowest()); | 
|  |         } | 
|  |  | 
|  |         public final K lastKey() { | 
|  |             return key(subHighest()); | 
|  |         } | 
|  |  | 
|  |         public final Map.Entry<K,V> firstEntry() { | 
|  |             return exportEntry(subLowest()); | 
|  |         } | 
|  |  | 
|  |         public final Map.Entry<K,V> lastEntry() { | 
|  |             return exportEntry(subHighest()); | 
|  |         } | 
|  |  | 
|  |         public final Map.Entry<K,V> pollFirstEntry() { | 
|  |             TreeMap.Entry<K,V> e = subLowest(); | 
|  |             Map.Entry<K,V> result = exportEntry(e); | 
|  |             if (e != null) | 
|  |                 m.deleteEntry(e); | 
|  |             return result; | 
|  |         } | 
|  |  | 
|  |         public final Map.Entry<K,V> pollLastEntry() { | 
|  |             TreeMap.Entry<K,V> e = subHighest(); | 
|  |             Map.Entry<K,V> result = exportEntry(e); | 
|  |             if (e != null) | 
|  |                 m.deleteEntry(e); | 
|  |             return result; | 
|  |         } | 
|  |  | 
|  |          | 
|  |         transient NavigableMap<K,V> descendingMapView; | 
|  |         transient EntrySetView entrySetView; | 
|  |         transient KeySet<K> navigableKeySetView; | 
|  |  | 
|  |         public final NavigableSet<K> navigableKeySet() { | 
|  |             KeySet<K> nksv = navigableKeySetView; | 
|  |             return (nksv != null) ? nksv : | 
|  |                 (navigableKeySetView = new TreeMap.KeySet<>(this)); | 
|  |         } | 
|  |  | 
|  |         public final Set<K> keySet() { | 
|  |             return navigableKeySet(); | 
|  |         } | 
|  |  | 
|  |         public NavigableSet<K> descendingKeySet() { | 
|  |             return descendingMap().navigableKeySet(); | 
|  |         } | 
|  |  | 
|  |         public final SortedMap<K,V> subMap(K fromKey, K toKey) { | 
|  |             return subMap(fromKey, true, toKey, false); | 
|  |         } | 
|  |  | 
|  |         public final SortedMap<K,V> headMap(K toKey) { | 
|  |             return headMap(toKey, false); | 
|  |         } | 
|  |  | 
|  |         public final SortedMap<K,V> tailMap(K fromKey) { | 
|  |             return tailMap(fromKey, true); | 
|  |         } | 
|  |  | 
|  |         // View classes | 
|  |  | 
|  |         abstract class EntrySetView extends AbstractSet<Map.Entry<K,V>> { | 
|  |             private transient int size = -1, sizeModCount; | 
|  |  | 
|  |             public int size() { | 
|  |                 if (fromStart && toEnd) | 
|  |                     return m.size(); | 
|  |                 if (size == -1 || sizeModCount != m.modCount) { | 
|  |                     sizeModCount = m.modCount; | 
|  |                     size = 0; | 
|  |                     Iterator<?> i = iterator(); | 
|  |                     while (i.hasNext()) { | 
|  |                         size++; | 
|  |                         i.next(); | 
|  |                     } | 
|  |                 } | 
|  |                 return size; | 
|  |             } | 
|  |  | 
|  |             public boolean isEmpty() { | 
|  |                 TreeMap.Entry<K,V> n = absLowest(); | 
|  |                 return n == null || tooHigh(n.key); | 
|  |             } | 
|  |  | 
|  |             public boolean contains(Object o) { | 
|  |                 if (!(o instanceof Map.Entry)) | 
|  |                     return false; | 
|  |                 Map.Entry<?,?> entry = (Map.Entry<?,?>) o; | 
|  |                 Object key = entry.getKey(); | 
|  |                 if (!inRange(key)) | 
|  |                     return false; | 
|  |                 TreeMap.Entry<?,?> node = m.getEntry(key); | 
|  |                 return node != null && | 
|  |                     valEquals(node.getValue(), entry.getValue()); | 
|  |             } | 
|  |  | 
|  |             public boolean remove(Object o) { | 
|  |                 if (!(o instanceof Map.Entry)) | 
|  |                     return false; | 
|  |                 Map.Entry<?,?> entry = (Map.Entry<?,?>) o; | 
|  |                 Object key = entry.getKey(); | 
|  |                 if (!inRange(key)) | 
|  |                     return false; | 
|  |                 TreeMap.Entry<K,V> node = m.getEntry(key); | 
|  |                 if (node!=null && valEquals(node.getValue(), | 
|  |                                             entry.getValue())) { | 
|  |                     m.deleteEntry(node); | 
|  |                     return true; | 
|  |                 } | 
|  |                 return false; | 
|  |             } | 
|  |         } | 
|  |  | 
|  |          | 
|  |  | 
|  |          */ | 
|  |         abstract class SubMapIterator<T> implements Iterator<T> { | 
|  |             TreeMap.Entry<K,V> lastReturned; | 
|  |             TreeMap.Entry<K,V> next; | 
|  |             final Object fenceKey; | 
|  |             int expectedModCount; | 
|  |  | 
|  |             SubMapIterator(TreeMap.Entry<K,V> first, | 
|  |                            TreeMap.Entry<K,V> fence) { | 
|  |                 expectedModCount = m.modCount; | 
|  |                 lastReturned = null; | 
|  |                 next = first; | 
|  |                 fenceKey = fence == null ? UNBOUNDED : fence.key; | 
|  |             } | 
|  |  | 
|  |             public final boolean hasNext() { | 
|  |                 return next != null && next.key != fenceKey; | 
|  |             } | 
|  |  | 
|  |             final TreeMap.Entry<K,V> nextEntry() { | 
|  |                 TreeMap.Entry<K,V> e = next; | 
|  |                 if (e == null || e.key == fenceKey) | 
|  |                     throw new NoSuchElementException(); | 
|  |                 if (m.modCount != expectedModCount) | 
|  |                     throw new ConcurrentModificationException(); | 
|  |                 next = successor(e); | 
|  |                 lastReturned = e; | 
|  |                 return e; | 
|  |             } | 
|  |  | 
|  |             final TreeMap.Entry<K,V> prevEntry() { | 
|  |                 TreeMap.Entry<K,V> e = next; | 
|  |                 if (e == null || e.key == fenceKey) | 
|  |                     throw new NoSuchElementException(); | 
|  |                 if (m.modCount != expectedModCount) | 
|  |                     throw new ConcurrentModificationException(); | 
|  |                 next = predecessor(e); | 
|  |                 lastReturned = e; | 
|  |                 return e; | 
|  |             } | 
|  |  | 
|  |             final void removeAscending() { | 
|  |                 if (lastReturned == null) | 
|  |                     throw new IllegalStateException(); | 
|  |                 if (m.modCount != expectedModCount) | 
|  |                     throw new ConcurrentModificationException(); | 
|  |                  | 
|  |                 if (lastReturned.left != null && lastReturned.right != null) | 
|  |                     next = lastReturned; | 
|  |                 m.deleteEntry(lastReturned); | 
|  |                 lastReturned = null; | 
|  |                 expectedModCount = m.modCount; | 
|  |             } | 
|  |  | 
|  |             final void removeDescending() { | 
|  |                 if (lastReturned == null) | 
|  |                     throw new IllegalStateException(); | 
|  |                 if (m.modCount != expectedModCount) | 
|  |                     throw new ConcurrentModificationException(); | 
|  |                 m.deleteEntry(lastReturned); | 
|  |                 lastReturned = null; | 
|  |                 expectedModCount = m.modCount; | 
|  |             } | 
|  |  | 
|  |         } | 
|  |  | 
|  |         final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> { | 
|  |             SubMapEntryIterator(TreeMap.Entry<K,V> first, | 
|  |                                 TreeMap.Entry<K,V> fence) { | 
|  |                 super(first, fence); | 
|  |             } | 
|  |             public Map.Entry<K,V> next() { | 
|  |                 return nextEntry(); | 
|  |             } | 
|  |             public void remove() { | 
|  |                 removeAscending(); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> { | 
|  |             DescendingSubMapEntryIterator(TreeMap.Entry<K,V> last, | 
|  |                                           TreeMap.Entry<K,V> fence) { | 
|  |                 super(last, fence); | 
|  |             } | 
|  |  | 
|  |             public Map.Entry<K,V> next() { | 
|  |                 return prevEntry(); | 
|  |             } | 
|  |             public void remove() { | 
|  |                 removeDescending(); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |          | 
|  |         final class SubMapKeyIterator extends SubMapIterator<K> | 
|  |             implements Spliterator<K> { | 
|  |             SubMapKeyIterator(TreeMap.Entry<K,V> first, | 
|  |                               TreeMap.Entry<K,V> fence) { | 
|  |                 super(first, fence); | 
|  |             } | 
|  |             public K next() { | 
|  |                 return nextEntry().key; | 
|  |             } | 
|  |             public void remove() { | 
|  |                 removeAscending(); | 
|  |             } | 
|  |             public Spliterator<K> trySplit() { | 
|  |                 return null; | 
|  |             } | 
|  |             public void forEachRemaining(Consumer<? super K> action) { | 
|  |                 while (hasNext()) | 
|  |                     action.accept(next()); | 
|  |             } | 
|  |             public boolean tryAdvance(Consumer<? super K> action) { | 
|  |                 if (hasNext()) { | 
|  |                     action.accept(next()); | 
|  |                     return true; | 
|  |                 } | 
|  |                 return false; | 
|  |             } | 
|  |             public long estimateSize() { | 
|  |                 return Long.MAX_VALUE; | 
|  |             } | 
|  |             public int characteristics() { | 
|  |                 return Spliterator.DISTINCT | Spliterator.ORDERED | | 
|  |                     Spliterator.SORTED; | 
|  |             } | 
|  |             public final Comparator<? super K>  getComparator() { | 
|  |                 return NavigableSubMap.this.comparator(); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         final class DescendingSubMapKeyIterator extends SubMapIterator<K> | 
|  |             implements Spliterator<K> { | 
|  |             DescendingSubMapKeyIterator(TreeMap.Entry<K,V> last, | 
|  |                                         TreeMap.Entry<K,V> fence) { | 
|  |                 super(last, fence); | 
|  |             } | 
|  |             public K next() { | 
|  |                 return prevEntry().key; | 
|  |             } | 
|  |             public void remove() { | 
|  |                 removeDescending(); | 
|  |             } | 
|  |             public Spliterator<K> trySplit() { | 
|  |                 return null; | 
|  |             } | 
|  |             public void forEachRemaining(Consumer<? super K> action) { | 
|  |                 while (hasNext()) | 
|  |                     action.accept(next()); | 
|  |             } | 
|  |             public boolean tryAdvance(Consumer<? super K> action) { | 
|  |                 if (hasNext()) { | 
|  |                     action.accept(next()); | 
|  |                     return true; | 
|  |                 } | 
|  |                 return false; | 
|  |             } | 
|  |             public long estimateSize() { | 
|  |                 return Long.MAX_VALUE; | 
|  |             } | 
|  |             public int characteristics() { | 
|  |                 return Spliterator.DISTINCT | Spliterator.ORDERED; | 
|  |             } | 
|  |         } | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     static final class AscendingSubMap<K,V> extends NavigableSubMap<K,V> { | 
|  |         private static final long serialVersionUID = 912986545866124060L; | 
|  |  | 
|  |         AscendingSubMap(TreeMap<K,V> m, | 
|  |                         boolean fromStart, K lo, boolean loInclusive, | 
|  |                         boolean toEnd,     K hi, boolean hiInclusive) { | 
|  |             super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); | 
|  |         } | 
|  |  | 
|  |         public Comparator<? super K> comparator() { | 
|  |             return m.comparator(); | 
|  |         } | 
|  |  | 
|  |         public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, | 
|  |                                         K toKey,   boolean toInclusive) { | 
|  |             if (!inRange(fromKey, fromInclusive)) | 
|  |                 throw new IllegalArgumentException("fromKey out of range"); | 
|  |             if (!inRange(toKey, toInclusive)) | 
|  |                 throw new IllegalArgumentException("toKey out of range"); | 
|  |             return new AscendingSubMap<>(m, | 
|  |                                          false, fromKey, fromInclusive, | 
|  |                                          false, toKey,   toInclusive); | 
|  |         } | 
|  |  | 
|  |         public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { | 
|  |             if (!inRange(toKey, inclusive)) | 
|  |                 throw new IllegalArgumentException("toKey out of range"); | 
|  |             return new AscendingSubMap<>(m, | 
|  |                                          fromStart, lo,    loInclusive, | 
|  |                                          false,     toKey, inclusive); | 
|  |         } | 
|  |  | 
|  |         public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { | 
|  |             if (!inRange(fromKey, inclusive)) | 
|  |                 throw new IllegalArgumentException("fromKey out of range"); | 
|  |             return new AscendingSubMap<>(m, | 
|  |                                          false, fromKey, inclusive, | 
|  |                                          toEnd, hi,      hiInclusive); | 
|  |         } | 
|  |  | 
|  |         public NavigableMap<K,V> descendingMap() { | 
|  |             NavigableMap<K,V> mv = descendingMapView; | 
|  |             return (mv != null) ? mv : | 
|  |                 (descendingMapView = | 
|  |                  new DescendingSubMap<>(m, | 
|  |                                         fromStart, lo, loInclusive, | 
|  |                                         toEnd,     hi, hiInclusive)); | 
|  |         } | 
|  |  | 
|  |         Iterator<K> keyIterator() { | 
|  |             return new SubMapKeyIterator(absLowest(), absHighFence()); | 
|  |         } | 
|  |  | 
|  |         Spliterator<K> keySpliterator() { | 
|  |             return new SubMapKeyIterator(absLowest(), absHighFence()); | 
|  |         } | 
|  |  | 
|  |         Iterator<K> descendingKeyIterator() { | 
|  |             return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); | 
|  |         } | 
|  |  | 
|  |         final class AscendingEntrySetView extends EntrySetView { | 
|  |             public Iterator<Map.Entry<K,V>> iterator() { | 
|  |                 return new SubMapEntryIterator(absLowest(), absHighFence()); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         public Set<Map.Entry<K,V>> entrySet() { | 
|  |             EntrySetView es = entrySetView; | 
|  |             return (es != null) ? es : (entrySetView = new AscendingEntrySetView()); | 
|  |         } | 
|  |  | 
|  |         TreeMap.Entry<K,V> subLowest()       { return absLowest(); } | 
|  |         TreeMap.Entry<K,V> subHighest()      { return absHighest(); } | 
|  |         TreeMap.Entry<K,V> subCeiling(K key) { return absCeiling(key); } | 
|  |         TreeMap.Entry<K,V> subHigher(K key)  { return absHigher(key); } | 
|  |         TreeMap.Entry<K,V> subFloor(K key)   { return absFloor(key); } | 
|  |         TreeMap.Entry<K,V> subLower(K key)   { return absLower(key); } | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     static final class DescendingSubMap<K,V>  extends NavigableSubMap<K,V> { | 
|  |         private static final long serialVersionUID = 912986545866120460L; | 
|  |         DescendingSubMap(TreeMap<K,V> m, | 
|  |                         boolean fromStart, K lo, boolean loInclusive, | 
|  |                         boolean toEnd,     K hi, boolean hiInclusive) { | 
|  |             super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); | 
|  |         } | 
|  |  | 
|  |         private final Comparator<? super K> reverseComparator = | 
|  |             Collections.reverseOrder(m.comparator); | 
|  |  | 
|  |         public Comparator<? super K> comparator() { | 
|  |             return reverseComparator; | 
|  |         } | 
|  |  | 
|  |         public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, | 
|  |                                         K toKey,   boolean toInclusive) { | 
|  |             if (!inRange(fromKey, fromInclusive)) | 
|  |                 throw new IllegalArgumentException("fromKey out of range"); | 
|  |             if (!inRange(toKey, toInclusive)) | 
|  |                 throw new IllegalArgumentException("toKey out of range"); | 
|  |             return new DescendingSubMap<>(m, | 
|  |                                           false, toKey,   toInclusive, | 
|  |                                           false, fromKey, fromInclusive); | 
|  |         } | 
|  |  | 
|  |         public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { | 
|  |             if (!inRange(toKey, inclusive)) | 
|  |                 throw new IllegalArgumentException("toKey out of range"); | 
|  |             return new DescendingSubMap<>(m, | 
|  |                                           false, toKey, inclusive, | 
|  |                                           toEnd, hi,    hiInclusive); | 
|  |         } | 
|  |  | 
|  |         public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { | 
|  |             if (!inRange(fromKey, inclusive)) | 
|  |                 throw new IllegalArgumentException("fromKey out of range"); | 
|  |             return new DescendingSubMap<>(m, | 
|  |                                           fromStart, lo, loInclusive, | 
|  |                                           false, fromKey, inclusive); | 
|  |         } | 
|  |  | 
|  |         public NavigableMap<K,V> descendingMap() { | 
|  |             NavigableMap<K,V> mv = descendingMapView; | 
|  |             return (mv != null) ? mv : | 
|  |                 (descendingMapView = | 
|  |                  new AscendingSubMap<>(m, | 
|  |                                        fromStart, lo, loInclusive, | 
|  |                                        toEnd,     hi, hiInclusive)); | 
|  |         } | 
|  |  | 
|  |         Iterator<K> keyIterator() { | 
|  |             return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); | 
|  |         } | 
|  |  | 
|  |         Spliterator<K> keySpliterator() { | 
|  |             return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); | 
|  |         } | 
|  |  | 
|  |         Iterator<K> descendingKeyIterator() { | 
|  |             return new SubMapKeyIterator(absLowest(), absHighFence()); | 
|  |         } | 
|  |  | 
|  |         final class DescendingEntrySetView extends EntrySetView { | 
|  |             public Iterator<Map.Entry<K,V>> iterator() { | 
|  |                 return new DescendingSubMapEntryIterator(absHighest(), absLowFence()); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         public Set<Map.Entry<K,V>> entrySet() { | 
|  |             EntrySetView es = entrySetView; | 
|  |             return (es != null) ? es : (entrySetView = new DescendingEntrySetView()); | 
|  |         } | 
|  |  | 
|  |         TreeMap.Entry<K,V> subLowest()       { return absHighest(); } | 
|  |         TreeMap.Entry<K,V> subHighest()      { return absLowest(); } | 
|  |         TreeMap.Entry<K,V> subCeiling(K key) { return absFloor(key); } | 
|  |         TreeMap.Entry<K,V> subHigher(K key)  { return absLower(key); } | 
|  |         TreeMap.Entry<K,V> subFloor(K key)   { return absCeiling(key); } | 
|  |         TreeMap.Entry<K,V> subLower(K key)   { return absHigher(key); } | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private class SubMap extends AbstractMap<K,V> | 
|  |         implements SortedMap<K,V>, java.io.Serializable { | 
|  |         private static final long serialVersionUID = -6520786458950516097L; | 
|  |         private boolean fromStart = false, toEnd = false; | 
|  |         private K fromKey, toKey; | 
|  |         private Object readResolve() { | 
|  |             return new AscendingSubMap<>(TreeMap.this, | 
|  |                                          fromStart, fromKey, true, | 
|  |                                          toEnd, toKey, false); | 
|  |         } | 
|  |         public Set<Map.Entry<K,V>> entrySet() { throw new InternalError(); } | 
|  |         public K lastKey() { throw new InternalError(); } | 
|  |         public K firstKey() { throw new InternalError(); } | 
|  |         public SortedMap<K,V> subMap(K fromKey, K toKey) { throw new InternalError(); } | 
|  |         public SortedMap<K,V> headMap(K toKey) { throw new InternalError(); } | 
|  |         public SortedMap<K,V> tailMap(K fromKey) { throw new InternalError(); } | 
|  |         public Comparator<? super K> comparator() { throw new InternalError(); } | 
|  |     } | 
|  |  | 
|  |  | 
|  |     // Red-black mechanics | 
|  |  | 
|  |     private static final boolean RED   = false; | 
|  |     private static final boolean BLACK = true; | 
|  |  | 
|  |     /** | 
|  |      * Node in the Tree.  Doubles as a means to pass key-value pairs back to | 
|  |      * user (see Map.Entry). | 
|  |      */ | 
|  |  | 
|  |     static final class Entry<K,V> implements Map.Entry<K,V> { | 
|  |         K key; | 
|  |         V value; | 
|  |         Entry<K,V> left; | 
|  |         Entry<K,V> right; | 
|  |         Entry<K,V> parent; | 
|  |         boolean color = BLACK; | 
|  |  | 
|  |          | 
|  |  | 
|  |  | 
|  |          */ | 
|  |         Entry(K key, V value, Entry<K,V> parent) { | 
|  |             this.key = key; | 
|  |             this.value = value; | 
|  |             this.parent = parent; | 
|  |         } | 
|  |  | 
|  |          | 
|  |  | 
|  |  | 
|  |  | 
|  |          */ | 
|  |         public K getKey() { | 
|  |             return key; | 
|  |         } | 
|  |  | 
|  |          | 
|  |  | 
|  |  | 
|  |  | 
|  |          */ | 
|  |         public V getValue() { | 
|  |             return value; | 
|  |         } | 
|  |  | 
|  |          | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |          */ | 
|  |         public V setValue(V value) { | 
|  |             V oldValue = this.value; | 
|  |             this.value = value; | 
|  |             return oldValue; | 
|  |         } | 
|  |  | 
|  |         public boolean equals(Object o) { | 
|  |             if (!(o instanceof Map.Entry)) | 
|  |                 return false; | 
|  |             Map.Entry<?,?> e = (Map.Entry<?,?>)o; | 
|  |  | 
|  |             return valEquals(key,e.getKey()) && valEquals(value,e.getValue()); | 
|  |         } | 
|  |  | 
|  |         public int hashCode() { | 
|  |             int keyHash = (key==null ? 0 : key.hashCode()); | 
|  |             int valueHash = (value==null ? 0 : value.hashCode()); | 
|  |             return keyHash ^ valueHash; | 
|  |         } | 
|  |  | 
|  |         public String toString() { | 
|  |             return key + "=" + value; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     final Entry<K,V> getFirstEntry() { | 
|  |         Entry<K,V> p = root; | 
|  |         if (p != null) | 
|  |             while (p.left != null) | 
|  |                 p = p.left; | 
|  |         return p; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     final Entry<K,V> getLastEntry() { | 
|  |         Entry<K,V> p = root; | 
|  |         if (p != null) | 
|  |             while (p.right != null) | 
|  |                 p = p.right; | 
|  |         return p; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) { | 
|  |         if (t == null) | 
|  |             return null; | 
|  |         else if (t.right != null) { | 
|  |             Entry<K,V> p = t.right; | 
|  |             while (p.left != null) | 
|  |                 p = p.left; | 
|  |             return p; | 
|  |         } else { | 
|  |             Entry<K,V> p = t.parent; | 
|  |             Entry<K,V> ch = t; | 
|  |             while (p != null && ch == p.right) { | 
|  |                 ch = p; | 
|  |                 p = p.parent; | 
|  |             } | 
|  |             return p; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     static <K,V> Entry<K,V> predecessor(Entry<K,V> t) { | 
|  |         if (t == null) | 
|  |             return null; | 
|  |         else if (t.left != null) { | 
|  |             Entry<K,V> p = t.left; | 
|  |             while (p.right != null) | 
|  |                 p = p.right; | 
|  |             return p; | 
|  |         } else { | 
|  |             Entry<K,V> p = t.parent; | 
|  |             Entry<K,V> ch = t; | 
|  |             while (p != null && ch == p.left) { | 
|  |                 ch = p; | 
|  |                 p = p.parent; | 
|  |             } | 
|  |             return p; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     /** | 
|  |      * Balancing operations. | 
|  |      * | 
|  |      * Implementations of rebalancings during insertion and deletion are | 
|  |      * slightly different than the CLR version.  Rather than using dummy | 
|  |      * nilnodes, we use a set of accessors that deal properly with null.  They | 
|  |      * are used to avoid messiness surrounding nullness checks in the main | 
|  |      * algorithms. | 
|  |      */ | 
|  |  | 
|  |     private static <K,V> boolean colorOf(Entry<K,V> p) { | 
|  |         return (p == null ? BLACK : p.color); | 
|  |     } | 
|  |  | 
|  |     private static <K,V> Entry<K,V> parentOf(Entry<K,V> p) { | 
|  |         return (p == null ? null: p.parent); | 
|  |     } | 
|  |  | 
|  |     private static <K,V> void setColor(Entry<K,V> p, boolean c) { | 
|  |         if (p != null) | 
|  |             p.color = c; | 
|  |     } | 
|  |  | 
|  |     private static <K,V> Entry<K,V> leftOf(Entry<K,V> p) { | 
|  |         return (p == null) ? null: p.left; | 
|  |     } | 
|  |  | 
|  |     private static <K,V> Entry<K,V> rightOf(Entry<K,V> p) { | 
|  |         return (p == null) ? null: p.right; | 
|  |     } | 
|  |  | 
|  |      | 
|  |     private void rotateLeft(Entry<K,V> p) { | 
|  |         if (p != null) { | 
|  |             Entry<K,V> r = p.right; | 
|  |             p.right = r.left; | 
|  |             if (r.left != null) | 
|  |                 r.left.parent = p; | 
|  |             r.parent = p.parent; | 
|  |             if (p.parent == null) | 
|  |                 root = r; | 
|  |             else if (p.parent.left == p) | 
|  |                 p.parent.left = r; | 
|  |             else | 
|  |                 p.parent.right = r; | 
|  |             r.left = p; | 
|  |             p.parent = r; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |      | 
|  |     private void rotateRight(Entry<K,V> p) { | 
|  |         if (p != null) { | 
|  |             Entry<K,V> l = p.left; | 
|  |             p.left = l.right; | 
|  |             if (l.right != null) l.right.parent = p; | 
|  |             l.parent = p.parent; | 
|  |             if (p.parent == null) | 
|  |                 root = l; | 
|  |             else if (p.parent.right == p) | 
|  |                 p.parent.right = l; | 
|  |             else p.parent.left = l; | 
|  |             l.right = p; | 
|  |             p.parent = l; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |      | 
|  |     private void fixAfterInsertion(Entry<K,V> x) { | 
|  |         x.color = RED; | 
|  |  | 
|  |         while (x != null && x != root && x.parent.color == RED) { | 
|  |             if (parentOf(x) == leftOf(parentOf(parentOf(x)))) { | 
|  |                 Entry<K,V> y = rightOf(parentOf(parentOf(x))); | 
|  |                 if (colorOf(y) == RED) { | 
|  |                     setColor(parentOf(x), BLACK); | 
|  |                     setColor(y, BLACK); | 
|  |                     setColor(parentOf(parentOf(x)), RED); | 
|  |                     x = parentOf(parentOf(x)); | 
|  |                 } else { | 
|  |                     if (x == rightOf(parentOf(x))) { | 
|  |                         x = parentOf(x); | 
|  |                         rotateLeft(x); | 
|  |                     } | 
|  |                     setColor(parentOf(x), BLACK); | 
|  |                     setColor(parentOf(parentOf(x)), RED); | 
|  |                     rotateRight(parentOf(parentOf(x))); | 
|  |                 } | 
|  |             } else { | 
|  |                 Entry<K,V> y = leftOf(parentOf(parentOf(x))); | 
|  |                 if (colorOf(y) == RED) { | 
|  |                     setColor(parentOf(x), BLACK); | 
|  |                     setColor(y, BLACK); | 
|  |                     setColor(parentOf(parentOf(x)), RED); | 
|  |                     x = parentOf(parentOf(x)); | 
|  |                 } else { | 
|  |                     if (x == leftOf(parentOf(x))) { | 
|  |                         x = parentOf(x); | 
|  |                         rotateRight(x); | 
|  |                     } | 
|  |                     setColor(parentOf(x), BLACK); | 
|  |                     setColor(parentOf(parentOf(x)), RED); | 
|  |                     rotateLeft(parentOf(parentOf(x))); | 
|  |                 } | 
|  |             } | 
|  |         } | 
|  |         root.color = BLACK; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |      */ | 
|  |     private void deleteEntry(Entry<K,V> p) { | 
|  |         modCount++; | 
|  |         size--; | 
|  |  | 
|  |         // If strictly internal, copy successor's element to p and then make p | 
|  |          | 
|  |         if (p.left != null && p.right != null) { | 
|  |             Entry<K,V> s = successor(p); | 
|  |             p.key = s.key; | 
|  |             p.value = s.value; | 
|  |             p = s; | 
|  |         } // p has 2 children | 
|  |  | 
|  |          | 
|  |         Entry<K,V> replacement = (p.left != null ? p.left : p.right); | 
|  |  | 
|  |         if (replacement != null) { | 
|  |              | 
|  |             replacement.parent = p.parent; | 
|  |             if (p.parent == null) | 
|  |                 root = replacement; | 
|  |             else if (p == p.parent.left) | 
|  |                 p.parent.left  = replacement; | 
|  |             else | 
|  |                 p.parent.right = replacement; | 
|  |  | 
|  |              | 
|  |             p.left = p.right = p.parent = null; | 
|  |  | 
|  |              | 
|  |             if (p.color == BLACK) | 
|  |                 fixAfterDeletion(replacement); | 
|  |         } else if (p.parent == null) {  | 
|  |             root = null; | 
|  |         } else {  | 
|  |             if (p.color == BLACK) | 
|  |                 fixAfterDeletion(p); | 
|  |  | 
|  |             if (p.parent != null) { | 
|  |                 if (p == p.parent.left) | 
|  |                     p.parent.left = null; | 
|  |                 else if (p == p.parent.right) | 
|  |                     p.parent.right = null; | 
|  |                 p.parent = null; | 
|  |             } | 
|  |         } | 
|  |     } | 
|  |  | 
|  |      | 
|  |     private void fixAfterDeletion(Entry<K,V> x) { | 
|  |         while (x != root && colorOf(x) == BLACK) { | 
|  |             if (x == leftOf(parentOf(x))) { | 
|  |                 Entry<K,V> sib = rightOf(parentOf(x)); | 
|  |  | 
|  |                 if (colorOf(sib) == RED) { | 
|  |                     setColor(sib, BLACK); | 
|  |                     setColor(parentOf(x), RED); | 
|  |                     rotateLeft(parentOf(x)); | 
|  |                     sib = rightOf(parentOf(x)); | 
|  |                 } | 
|  |  | 
|  |                 if (colorOf(leftOf(sib))  == BLACK && | 
|  |                     colorOf(rightOf(sib)) == BLACK) { | 
|  |                     setColor(sib, RED); | 
|  |                     x = parentOf(x); | 
|  |                 } else { | 
|  |                     if (colorOf(rightOf(sib)) == BLACK) { | 
|  |                         setColor(leftOf(sib), BLACK); | 
|  |                         setColor(sib, RED); | 
|  |                         rotateRight(sib); | 
|  |                         sib = rightOf(parentOf(x)); | 
|  |                     } | 
|  |                     setColor(sib, colorOf(parentOf(x))); | 
|  |                     setColor(parentOf(x), BLACK); | 
|  |                     setColor(rightOf(sib), BLACK); | 
|  |                     rotateLeft(parentOf(x)); | 
|  |                     x = root; | 
|  |                 } | 
|  |             } else {  | 
|  |                 Entry<K,V> sib = leftOf(parentOf(x)); | 
|  |  | 
|  |                 if (colorOf(sib) == RED) { | 
|  |                     setColor(sib, BLACK); | 
|  |                     setColor(parentOf(x), RED); | 
|  |                     rotateRight(parentOf(x)); | 
|  |                     sib = leftOf(parentOf(x)); | 
|  |                 } | 
|  |  | 
|  |                 if (colorOf(rightOf(sib)) == BLACK && | 
|  |                     colorOf(leftOf(sib)) == BLACK) { | 
|  |                     setColor(sib, RED); | 
|  |                     x = parentOf(x); | 
|  |                 } else { | 
|  |                     if (colorOf(leftOf(sib)) == BLACK) { | 
|  |                         setColor(rightOf(sib), BLACK); | 
|  |                         setColor(sib, RED); | 
|  |                         rotateLeft(sib); | 
|  |                         sib = leftOf(parentOf(x)); | 
|  |                     } | 
|  |                     setColor(sib, colorOf(parentOf(x))); | 
|  |                     setColor(parentOf(x), BLACK); | 
|  |                     setColor(leftOf(sib), BLACK); | 
|  |                     rotateRight(parentOf(x)); | 
|  |                     x = root; | 
|  |                 } | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         setColor(x, BLACK); | 
|  |     } | 
|  |  | 
|  |     private static final long serialVersionUID = 919286545866124006L; | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private void writeObject(java.io.ObjectOutputStream s) | 
|  |         throws java.io.IOException { | 
|  |          | 
|  |         s.defaultWriteObject(); | 
|  |  | 
|  |          | 
|  |         s.writeInt(size); | 
|  |  | 
|  |          | 
|  |         for (Map.Entry<K, V> e : entrySet()) { | 
|  |             s.writeObject(e.getKey()); | 
|  |             s.writeObject(e.getValue()); | 
|  |         } | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private void readObject(final java.io.ObjectInputStream s) | 
|  |         throws java.io.IOException, ClassNotFoundException { | 
|  |          | 
|  |         s.defaultReadObject(); | 
|  |  | 
|  |          | 
|  |         int size = s.readInt(); | 
|  |  | 
|  |         buildFromSorted(size, null, s, null); | 
|  |     } | 
|  |  | 
|  |      | 
|  |     void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal) | 
|  |         throws java.io.IOException, ClassNotFoundException { | 
|  |         buildFromSorted(size, null, s, defaultVal); | 
|  |     } | 
|  |  | 
|  |      | 
|  |     void addAllForTreeSet(SortedSet<? extends K> set, V defaultVal) { | 
|  |         try { | 
|  |             buildFromSorted(set.size(), set.iterator(), null, defaultVal); | 
|  |         } catch (java.io.IOException | ClassNotFoundException cannotHappen) { | 
|  |         } | 
|  |     } | 
|  |  | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private void buildFromSorted(int size, Iterator<?> it, | 
|  |                                  java.io.ObjectInputStream str, | 
|  |                                  V defaultVal) | 
|  |         throws  java.io.IOException, ClassNotFoundException { | 
|  |         this.size = size; | 
|  |         root = buildFromSorted(0, 0, size-1, computeRedLevel(size), | 
|  |                                it, str, defaultVal); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     @SuppressWarnings("unchecked") | 
|  |     private final Entry<K,V> buildFromSorted(int level, int lo, int hi, | 
|  |                                              int redLevel, | 
|  |                                              Iterator<?> it, | 
|  |                                              java.io.ObjectInputStream str, | 
|  |                                              V defaultVal) | 
|  |         throws  java.io.IOException, ClassNotFoundException { | 
|  |         /* | 
|  |          * Strategy: The root is the middlemost element. To get to it, we | 
|  |          * have to first recursively construct the entire left subtree, | 
|  |          * so as to grab all of its elements. We can then proceed with right | 
|  |          * subtree. | 
|  |          * | 
|  |          * The lo and hi arguments are the minimum and maximum | 
|  |          * indices to pull out of the iterator or stream for current subtree. | 
|  |          * They are not actually indexed, we just proceed sequentially, | 
|  |          * ensuring that items are extracted in corresponding order. | 
|  |          */ | 
|  |  | 
|  |         if (hi < lo) return null; | 
|  |  | 
|  |         int mid = (lo + hi) >>> 1; | 
|  |  | 
|  |         Entry<K,V> left  = null; | 
|  |         if (lo < mid) | 
|  |             left = buildFromSorted(level+1, lo, mid - 1, redLevel, | 
|  |                                    it, str, defaultVal); | 
|  |  | 
|  |          | 
|  |         K key; | 
|  |         V value; | 
|  |         if (it != null) { | 
|  |             if (defaultVal==null) { | 
|  |                 Map.Entry<?,?> entry = (Map.Entry<?,?>)it.next(); | 
|  |                 key = (K)entry.getKey(); | 
|  |                 value = (V)entry.getValue(); | 
|  |             } else { | 
|  |                 key = (K)it.next(); | 
|  |                 value = defaultVal; | 
|  |             } | 
|  |         } else {  | 
|  |             key = (K) str.readObject(); | 
|  |             value = (defaultVal != null ? defaultVal : (V) str.readObject()); | 
|  |         } | 
|  |  | 
|  |         Entry<K,V> middle =  new Entry<>(key, value, null); | 
|  |  | 
|  |          | 
|  |         if (level == redLevel) | 
|  |             middle.color = RED; | 
|  |  | 
|  |         if (left != null) { | 
|  |             middle.left = left; | 
|  |             left.parent = middle; | 
|  |         } | 
|  |  | 
|  |         if (mid < hi) { | 
|  |             Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel, | 
|  |                                                it, str, defaultVal); | 
|  |             middle.right = right; | 
|  |             right.parent = middle; | 
|  |         } | 
|  |  | 
|  |         return middle; | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     private static int computeRedLevel(int size) { | 
|  |         return 31 - Integer.numberOfLeadingZeros(size + 1); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     static <K> Spliterator<K> keySpliteratorFor(NavigableMap<K,?> m) { | 
|  |         if (m instanceof TreeMap) { | 
|  |             @SuppressWarnings("unchecked") TreeMap<K,Object> t = | 
|  |                 (TreeMap<K,Object>) m; | 
|  |             return t.keySpliterator(); | 
|  |         } | 
|  |         if (m instanceof DescendingSubMap) { | 
|  |             @SuppressWarnings("unchecked") DescendingSubMap<K,?> dm = | 
|  |                 (DescendingSubMap<K,?>) m; | 
|  |             TreeMap<K,?> tm = dm.m; | 
|  |             if (dm == tm.descendingMap) { | 
|  |                 @SuppressWarnings("unchecked") TreeMap<K,Object> t = | 
|  |                     (TreeMap<K,Object>) tm; | 
|  |                 return t.descendingKeySpliterator(); | 
|  |             } | 
|  |         } | 
|  |         @SuppressWarnings("unchecked") NavigableSubMap<K,?> sm = | 
|  |             (NavigableSubMap<K,?>) m; | 
|  |         return sm.keySpliterator(); | 
|  |     } | 
|  |  | 
|  |     final Spliterator<K> keySpliterator() { | 
|  |         return new KeySpliterator<>(this, null, null, 0, -1, 0); | 
|  |     } | 
|  |  | 
|  |     final Spliterator<K> descendingKeySpliterator() { | 
|  |         return new DescendingKeySpliterator<>(this, null, null, 0, -2, 0); | 
|  |     } | 
|  |  | 
|  |      | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |      */ | 
|  |     static class TreeMapSpliterator<K,V> { | 
|  |         final TreeMap<K,V> tree; | 
|  |         TreeMap.Entry<K,V> current;  | 
|  |         TreeMap.Entry<K,V> fence;    | 
|  |         int side;                    | 
|  |         int est;                     | 
|  |         int expectedModCount;        | 
|  |  | 
|  |         TreeMapSpliterator(TreeMap<K,V> tree, | 
|  |                            TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence, | 
|  |                            int side, int est, int expectedModCount) { | 
|  |             this.tree = tree; | 
|  |             this.current = origin; | 
|  |             this.fence = fence; | 
|  |             this.side = side; | 
|  |             this.est = est; | 
|  |             this.expectedModCount = expectedModCount; | 
|  |         } | 
|  |  | 
|  |         final int getEstimate() {  | 
|  |             int s; TreeMap<K,V> t; | 
|  |             if ((s = est) < 0) { | 
|  |                 if ((t = tree) != null) { | 
|  |                     current = (s == -1) ? t.getFirstEntry() : t.getLastEntry(); | 
|  |                     s = est = t.size; | 
|  |                     expectedModCount = t.modCount; | 
|  |                 } | 
|  |                 else | 
|  |                     s = est = 0; | 
|  |             } | 
|  |             return s; | 
|  |         } | 
|  |  | 
|  |         public final long estimateSize() { | 
|  |             return (long)getEstimate(); | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     static final class KeySpliterator<K,V> | 
|  |         extends TreeMapSpliterator<K,V> | 
|  |         implements Spliterator<K> { | 
|  |         KeySpliterator(TreeMap<K,V> tree, | 
|  |                        TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence, | 
|  |                        int side, int est, int expectedModCount) { | 
|  |             super(tree, origin, fence, side, est, expectedModCount); | 
|  |         } | 
|  |  | 
|  |         public KeySpliterator<K,V> trySplit() { | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             int d = side; | 
|  |             TreeMap.Entry<K,V> e = current, f = fence, | 
|  |                 s = ((e == null || e == f) ? null :       | 
|  |                      (d == 0)              ? tree.root :  | 
|  |                      (d >  0)              ? e.right :    | 
|  |                      (d <  0 && f != null) ? f.left :     | 
|  |                      null); | 
|  |             if (s != null && s != e && s != f && | 
|  |                 tree.compare(e.key, s.key) < 0) {         | 
|  |                 side = 1; | 
|  |                 return new KeySpliterator<> | 
|  |                     (tree, e, current = s, -1, est >>>= 1, expectedModCount); | 
|  |             } | 
|  |             return null; | 
|  |         } | 
|  |  | 
|  |         public void forEachRemaining(Consumer<? super K> action) { | 
|  |             if (action == null) | 
|  |                 throw new NullPointerException(); | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             TreeMap.Entry<K,V> f = fence, e, p, pl; | 
|  |             if ((e = current) != null && e != f) { | 
|  |                 current = f;  | 
|  |                 do { | 
|  |                     action.accept(e.key); | 
|  |                     if ((p = e.right) != null) { | 
|  |                         while ((pl = p.left) != null) | 
|  |                             p = pl; | 
|  |                     } | 
|  |                     else { | 
|  |                         while ((p = e.parent) != null && e == p.right) | 
|  |                             e = p; | 
|  |                     } | 
|  |                 } while ((e = p) != null && e != f); | 
|  |                 if (tree.modCount != expectedModCount) | 
|  |                     throw new ConcurrentModificationException(); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         public boolean tryAdvance(Consumer<? super K> action) { | 
|  |             TreeMap.Entry<K,V> e; | 
|  |             if (action == null) | 
|  |                 throw new NullPointerException(); | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             if ((e = current) == null || e == fence) | 
|  |                 return false; | 
|  |             current = successor(e); | 
|  |             action.accept(e.key); | 
|  |             if (tree.modCount != expectedModCount) | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             return true; | 
|  |         } | 
|  |  | 
|  |         public int characteristics() { | 
|  |             return (side == 0 ? Spliterator.SIZED : 0) | | 
|  |                 Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED; | 
|  |         } | 
|  |  | 
|  |         public final Comparator<? super K>  getComparator() { | 
|  |             return tree.comparator; | 
|  |         } | 
|  |  | 
|  |     } | 
|  |  | 
|  |     static final class DescendingKeySpliterator<K,V> | 
|  |         extends TreeMapSpliterator<K,V> | 
|  |         implements Spliterator<K> { | 
|  |         DescendingKeySpliterator(TreeMap<K,V> tree, | 
|  |                                  TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence, | 
|  |                                  int side, int est, int expectedModCount) { | 
|  |             super(tree, origin, fence, side, est, expectedModCount); | 
|  |         } | 
|  |  | 
|  |         public DescendingKeySpliterator<K,V> trySplit() { | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             int d = side; | 
|  |             TreeMap.Entry<K,V> e = current, f = fence, | 
|  |                     s = ((e == null || e == f) ? null :       | 
|  |                          (d == 0)              ? tree.root :  | 
|  |                          (d <  0)              ? e.left :     | 
|  |                          (d >  0 && f != null) ? f.right :    | 
|  |                          null); | 
|  |             if (s != null && s != e && s != f && | 
|  |                 tree.compare(e.key, s.key) > 0) {        | 
|  |                 side = 1; | 
|  |                 return new DescendingKeySpliterator<> | 
|  |                         (tree, e, current = s, -1, est >>>= 1, expectedModCount); | 
|  |             } | 
|  |             return null; | 
|  |         } | 
|  |  | 
|  |         public void forEachRemaining(Consumer<? super K> action) { | 
|  |             if (action == null) | 
|  |                 throw new NullPointerException(); | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             TreeMap.Entry<K,V> f = fence, e, p, pr; | 
|  |             if ((e = current) != null && e != f) { | 
|  |                 current = f;  | 
|  |                 do { | 
|  |                     action.accept(e.key); | 
|  |                     if ((p = e.left) != null) { | 
|  |                         while ((pr = p.right) != null) | 
|  |                             p = pr; | 
|  |                     } | 
|  |                     else { | 
|  |                         while ((p = e.parent) != null && e == p.left) | 
|  |                             e = p; | 
|  |                     } | 
|  |                 } while ((e = p) != null && e != f); | 
|  |                 if (tree.modCount != expectedModCount) | 
|  |                     throw new ConcurrentModificationException(); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         public boolean tryAdvance(Consumer<? super K> action) { | 
|  |             TreeMap.Entry<K,V> e; | 
|  |             if (action == null) | 
|  |                 throw new NullPointerException(); | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             if ((e = current) == null || e == fence) | 
|  |                 return false; | 
|  |             current = predecessor(e); | 
|  |             action.accept(e.key); | 
|  |             if (tree.modCount != expectedModCount) | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             return true; | 
|  |         } | 
|  |  | 
|  |         public int characteristics() { | 
|  |             return (side == 0 ? Spliterator.SIZED : 0) | | 
|  |                 Spliterator.DISTINCT | Spliterator.ORDERED; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     static final class ValueSpliterator<K,V> | 
|  |             extends TreeMapSpliterator<K,V> | 
|  |             implements Spliterator<V> { | 
|  |         ValueSpliterator(TreeMap<K,V> tree, | 
|  |                          TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence, | 
|  |                          int side, int est, int expectedModCount) { | 
|  |             super(tree, origin, fence, side, est, expectedModCount); | 
|  |         } | 
|  |  | 
|  |         public ValueSpliterator<K,V> trySplit() { | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             int d = side; | 
|  |             TreeMap.Entry<K,V> e = current, f = fence, | 
|  |                     s = ((e == null || e == f) ? null :       | 
|  |                          (d == 0)              ? tree.root :  | 
|  |                          (d >  0)              ? e.right :    | 
|  |                          (d <  0 && f != null) ? f.left :     | 
|  |                          null); | 
|  |             if (s != null && s != e && s != f && | 
|  |                 tree.compare(e.key, s.key) < 0) {         | 
|  |                 side = 1; | 
|  |                 return new ValueSpliterator<> | 
|  |                         (tree, e, current = s, -1, est >>>= 1, expectedModCount); | 
|  |             } | 
|  |             return null; | 
|  |         } | 
|  |  | 
|  |         public void forEachRemaining(Consumer<? super V> action) { | 
|  |             if (action == null) | 
|  |                 throw new NullPointerException(); | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             TreeMap.Entry<K,V> f = fence, e, p, pl; | 
|  |             if ((e = current) != null && e != f) { | 
|  |                 current = f;  | 
|  |                 do { | 
|  |                     action.accept(e.value); | 
|  |                     if ((p = e.right) != null) { | 
|  |                         while ((pl = p.left) != null) | 
|  |                             p = pl; | 
|  |                     } | 
|  |                     else { | 
|  |                         while ((p = e.parent) != null && e == p.right) | 
|  |                             e = p; | 
|  |                     } | 
|  |                 } while ((e = p) != null && e != f); | 
|  |                 if (tree.modCount != expectedModCount) | 
|  |                     throw new ConcurrentModificationException(); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         public boolean tryAdvance(Consumer<? super V> action) { | 
|  |             TreeMap.Entry<K,V> e; | 
|  |             if (action == null) | 
|  |                 throw new NullPointerException(); | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             if ((e = current) == null || e == fence) | 
|  |                 return false; | 
|  |             current = successor(e); | 
|  |             action.accept(e.value); | 
|  |             if (tree.modCount != expectedModCount) | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             return true; | 
|  |         } | 
|  |  | 
|  |         public int characteristics() { | 
|  |             return (side == 0 ? Spliterator.SIZED : 0) | Spliterator.ORDERED; | 
|  |         } | 
|  |     } | 
|  |  | 
|  |     static final class EntrySpliterator<K,V> | 
|  |         extends TreeMapSpliterator<K,V> | 
|  |         implements Spliterator<Map.Entry<K,V>> { | 
|  |         EntrySpliterator(TreeMap<K,V> tree, | 
|  |                          TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence, | 
|  |                          int side, int est, int expectedModCount) { | 
|  |             super(tree, origin, fence, side, est, expectedModCount); | 
|  |         } | 
|  |  | 
|  |         public EntrySpliterator<K,V> trySplit() { | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             int d = side; | 
|  |             TreeMap.Entry<K,V> e = current, f = fence, | 
|  |                     s = ((e == null || e == f) ? null :       | 
|  |                          (d == 0)              ? tree.root :  | 
|  |                          (d >  0)              ? e.right :    | 
|  |                          (d <  0 && f != null) ? f.left :     | 
|  |                          null); | 
|  |             if (s != null && s != e && s != f && | 
|  |                 tree.compare(e.key, s.key) < 0) {         | 
|  |                 side = 1; | 
|  |                 return new EntrySpliterator<> | 
|  |                         (tree, e, current = s, -1, est >>>= 1, expectedModCount); | 
|  |             } | 
|  |             return null; | 
|  |         } | 
|  |  | 
|  |         public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) { | 
|  |             if (action == null) | 
|  |                 throw new NullPointerException(); | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             TreeMap.Entry<K,V> f = fence, e, p, pl; | 
|  |             if ((e = current) != null && e != f) { | 
|  |                 current = f;  | 
|  |                 do { | 
|  |                     action.accept(e); | 
|  |                     if ((p = e.right) != null) { | 
|  |                         while ((pl = p.left) != null) | 
|  |                             p = pl; | 
|  |                     } | 
|  |                     else { | 
|  |                         while ((p = e.parent) != null && e == p.right) | 
|  |                             e = p; | 
|  |                     } | 
|  |                 } while ((e = p) != null && e != f); | 
|  |                 if (tree.modCount != expectedModCount) | 
|  |                     throw new ConcurrentModificationException(); | 
|  |             } | 
|  |         } | 
|  |  | 
|  |         public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) { | 
|  |             TreeMap.Entry<K,V> e; | 
|  |             if (action == null) | 
|  |                 throw new NullPointerException(); | 
|  |             if (est < 0) | 
|  |                 getEstimate();  | 
|  |             if ((e = current) == null || e == fence) | 
|  |                 return false; | 
|  |             current = successor(e); | 
|  |             action.accept(e); | 
|  |             if (tree.modCount != expectedModCount) | 
|  |                 throw new ConcurrentModificationException(); | 
|  |             return true; | 
|  |         } | 
|  |  | 
|  |         public int characteristics() { | 
|  |             return (side == 0 ? Spliterator.SIZED : 0) | | 
|  |                     Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED; | 
|  |         } | 
|  |  | 
|  |         @Override | 
|  |         public Comparator<Map.Entry<K, V>> getComparator() { | 
|  |              | 
|  |             if (tree.comparator != null) { | 
|  |                 return Map.Entry.comparingByKey(tree.comparator); | 
|  |             } | 
|  |             else { | 
|  |                 return (Comparator<Map.Entry<K, V>> & Serializable) (e1, e2) -> { | 
|  |                     @SuppressWarnings("unchecked") | 
|  |                     Comparable<? super K> k1 = (Comparable<? super K>) e1.getKey(); | 
|  |                     return k1.compareTo(e2.getKey()); | 
|  |                 }; | 
|  |             } | 
|  |         } | 
|  |     } | 
|  | } |