1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.collection.TreeMap;
13 
14 import hunt.collection.AbstractCollection;
15 import hunt.collection.AbstractMap;
16 import hunt.collection.AbstractSet;
17 import hunt.collection.Collection;
18 import hunt.collection.Iterator;
19 import hunt.collection.Map;
20 import hunt.collection.NavigableMap;
21 import hunt.collection.NavigableSet;
22 import hunt.collection.Set;
23 import hunt.collection.SortedMap;
24 import hunt.collection.SortedSet;
25 
26 import hunt.Exceptions;
27 import hunt.Functions;
28 import hunt.Object;
29 import hunt.util.Comparator;
30 import hunt.util.Spliterator;
31 
32 import std.algorithm;
33 import std.conv;
34 import std.exception;
35 import std.math;
36 import std.range;
37 import std.traits;
38 
39 
40 version (HUNT_DEBUG) import hunt.logging.ConsoleLogger;
41 
42 // Red-black mechanics
43 
44 private enum bool RED   = false;
45 private enum bool BLACK = true;
46 
47 
48 /**
49  * A Red-Black tree based {@link NavigableMap} implementation.
50  * The map is sorted according to the {@linkplain Comparable natural
51  * ordering} of its keys, or by a {@link Comparator} provided at map
52  * creation time, depending on which constructor is used.
53  *
54  * <p>This implementation provides guaranteed log(n) time cost for the
55  * {@code containsKey}, {@code get}, {@code put} and {@code remove}
56  * operations.  Algorithms are adaptations of those in Cormen, Leiserson, and
57  * Rivest's <em>Introduction to Algorithms</em>.
58  *
59  * <p>Note that the ordering maintained by a tree map, like any sorted map, and
60  * whether or not an explicit comparator is provided, must be <em>consistent
61  * with {@code equals}</em> if this sorted map is to correctly implement the
62  * {@code Map} interface.  (See {@code Comparable} or {@code Comparator} for a
63  * precise definition of <em>consistent with equals</em>.)  This is so because
64  * the {@code Map} interface is defined in terms of the {@code equals}
65  * operation, but a sorted map performs all key comparisons using its {@code
66  * compareTo} (or {@code compare}) method, so two keys that are deemed equal by
67  * this method are, from the standpoint of the sorted map, equal.  The behavior
68  * of a sorted map <em>is</em> well-defined even if its ordering is
69  * inconsistent with {@code equals}; it just fails to obey the general contract
70  * of the {@code Map} interface.
71  *
72  * <p><strong>Note that this implementation is not synchronized.</strong>
73  * If multiple threads access a map concurrently, and at least one of the
74  * threads modifies the map structurally, it <em>must</em> be synchronized
75  * externally.  (A structural modification is any operation that adds or
76  * deletes one or more mappings; merely changing the value associated
77  * with an existing key is not a structural modification.)  This is
78  * typically accomplished by synchronizing on some object that naturally
79  * encapsulates the map.
80  * If no such object exists, the map should be "wrapped" using the
81  * {@link Collections#synchronizedSortedMap Collections.synchronizedSortedMap}
82  * method.  This is best done at creation time, to prevent accidental
83  * unsynchronized access to the map: <pre>
84  *   SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));</pre>
85  *
86  * <p>The iterators returned by the {@code iterator} method of the collections
87  * returned by all of this class's "collection view methods" are
88  * <em>fail-fast</em>: if the map is structurally modified at any time after
89  * the iterator is created, in any way except through the iterator's own
90  * {@code remove} method, the iterator will throw a {@link
91  * ConcurrentModificationException}.  Thus, in the face of concurrent
92  * modification, the iterator fails quickly and cleanly, rather than risking
93  * arbitrary, non-deterministic behavior at an undetermined time in the future.
94  *
95  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
96  * as it is, generally speaking, impossible to make any hard guarantees in the
97  * presence of unsynchronized concurrent modification.  Fail-fast iterators
98  * throw {@code ConcurrentModificationException} on a best-effort basis.
99  * Therefore, it would be wrong to write a program that depended on this
100  * exception for its correctness:   <em>the fail-fast behavior of iterators
101  * should be used only to detect bugs.</em>
102  *
103  * <p>All {@code MapEntry} pairs returned by methods in this class
104  * and its views represent snapshots of mappings at the time they were
105  * produced. They do <strong>not</strong> support the {@code Entry.setValue}
106  * method. (Note however that it is possible to change mappings in the
107  * associated map using {@code put}.)
108  *
109  * <p>This class is a member of the
110  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
111  * Java Collections Framework</a>.
112  *
113  * @param !K the type of keys maintained by this map
114  * @param !V the type of mapped values
115  *
116  * @author  Josh Bloch and Doug Lea
117  * @see Map
118  * @see HashMap
119  * @see Hashtable
120  * @see Comparable
121  * @see Comparator
122  * @see Collection
123  * @since 1.2
124  */
125 
126 class TreeMap(K,V) : AbstractMap!(K,V), NavigableMap!(K,V) { //, Cloneable, java.io.Serializable
127 
128     /**
129      * The comparator used to maintain order in this tree map, or
130      * null if it uses the natural ordering of its keys.
131      *
132      * @serial
133      */
134     private Comparator!K _comparator;
135 
136     private TreeMapEntry!(K,V) root;
137 
138     /**
139      * The number of entries in the tree
140      */
141     // private int _size = 0;
142 
143     /**
144      * The number of structural modifications to the tree.
145      */
146     private int modCount = 0;
147 
148     /**
149      * Constructs a new, empty tree map, using the natural ordering of its
150      * keys.  All keys inserted into the map must implement the {@link
151      * Comparable} interface.  Furthermore, all such keys must be
152      * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
153      * a {@code ClassCastException} for any keys {@code k1} and
154      * {@code k2} in the map.  If the user attempts to put a key into the
155      * map that violates this constraint (for example, the user attempts to
156      * put a string key into a map whose keys are integers), the
157      * {@code put(Object key, Object value)} call will throw a
158      * {@code ClassCastException}.
159      */
160     this() {
161         _comparator = null;
162     }
163 
164     /**
165      * Constructs a new, empty tree map, ordered according to the given
166      * comparator.  All keys inserted into the map must be <em>mutually
167      * comparable</em> by the given comparator: {@code comparator.compare(k1,
168      * k2)} must not throw a {@code ClassCastException} for any keys
169      * {@code k1} and {@code k2} in the map.  If the user attempts to put
170      * a key into the map that violates this constraint, the {@code put(Object
171      * key, Object value)} call will throw a
172      * {@code ClassCastException}.
173      *
174      * @param comparator the comparator that will be used to order this map.
175      *        If {@code null}, the {@linkplain Comparable natural
176      *        ordering} of the keys will be used.
177      */
178     this(Comparator!K comparator) {
179         this._comparator = comparator;
180     }
181 
182     /**
183      * Constructs a new tree map containing the same mappings as the given
184      * map, ordered according to the <em>natural ordering</em> of its keys.
185      * All keys inserted into the new map must implement the {@link
186      * Comparable} interface.  Furthermore, all such keys must be
187      * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
188      * a {@code ClassCastException} for any keys {@code k1} and
189      * {@code k2} in the map.  This method runs in n*log(n) time.
190      *
191      * @param  m the map whose mappings are to be placed in this map
192      * @throws ClassCastException if the keys in m are not {@link Comparable},
193      *         or are not mutually comparable
194      * @throws NullPointerException if the specified map is null
195      */
196     this(Map!(K, V) m) {
197         _comparator = null;
198         putAll(m);
199     }
200 
201     /**
202      * Constructs a new tree map containing the same mappings and
203      * using the same ordering as the specified sorted map.  This
204      * method runs in linear time.
205      *
206      * @param  m the sorted map whose mappings are to be placed in this map,
207      *         and whose comparator is to be used to sort this map
208      * @throws NullPointerException if the specified map is null
209      */
210     // this(SortedMap!(K, V) m) {
211     //     _comparator = m.comparator();
212     //     try {
213     //         buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
214     //     } catch (IOException cannotHappen) {
215     //     } catch (ClassNotFoundException cannotHappen) {
216     //     }
217     // }
218 
219 
220     // Query Operations
221 
222     /**
223      * Returns the number of key-value mappings in this map.
224      *
225      * @return the number of key-value mappings in this map
226      */
227     // override int size() {
228     //     return _size;
229     // }
230 
231     /**
232      * Returns {@code true} if this map contains a mapping for the specified
233      * key.
234      *
235      * @param key key whose presence in this map is to be tested
236      * @return {@code true} if this map contains a mapping for the
237      *         specified key
238      * @throws ClassCastException if the specified key cannot be compared
239      *         with the keys currently in the map
240      * @throws NullPointerException if the specified key is null
241      *         and this map uses natural ordering, or its comparator
242      *         does not permit null keys
243      */
244     override bool containsKey(K key) {
245         return getEntry(key) !is null;
246     }
247 
248     /**
249      * Returns {@code true} if this map maps one or more keys to the
250      * specified value.  More formally, returns {@code true} if and only if
251      * this map contains at least one mapping to a value {@code v} such
252      * that {@code (value is null ? v is null : value.equals(v))}.  This
253      * operation will probably require time linear in the map size for
254      * most implementations.
255      *
256      * @param value value whose presence in this map is to be tested
257      * @return {@code true} if a mapping to {@code value} exists;
258      *         {@code false} otherwise
259      * @since 1.2
260      */
261     override bool containsValue(V value) {
262         for (TreeMapEntry!(K,V) e = getFirstEntry(); e !is null; e = successor(e))
263             if (valEquals(value, e.value))
264                 return true;
265         return false;
266     }
267 
268     /**
269      * Returns the value to which the specified key is mapped,
270      * or {@code null} if this map contains no mapping for the key.
271      *
272      * <p>More formally, if this map contains a mapping from a key
273      * {@code k} to a value {@code v} such that {@code key} compares
274      * equal to {@code k} according to the map's ordering, then this
275      * method returns {@code v}; otherwise it returns {@code null}.
276      * (There can be at most one such mapping.)
277      *
278      * <p>A return value of {@code null} does not <em>necessarily</em>
279      * indicate that the map contains no mapping for the key; it's also
280      * possible that the map explicitly maps the key to {@code null}.
281      * The {@link #containsKey containsKey} operation may be used to
282      * distinguish these two cases.
283      *
284      * @throws ClassCastException if the specified key cannot be compared
285      *         with the keys currently in the map
286      * @throws NullPointerException if the specified key is null
287      *         and this map uses natural ordering, or its comparator
288      *         does not permit null keys
289      */
290     override V get(K key) {
291         TreeMapEntry!(K,V) p = getEntry(key);
292         return (p is null ? null : p.value);
293     }
294 
295     Comparator!K comparator() {
296         return _comparator;
297     }
298 
299     /**
300      * @throws NoSuchElementException {@inheritDoc}
301      */
302     K firstKey() {
303         return key(getFirstEntry());
304     }
305 
306     /**
307      * @throws NoSuchElementException {@inheritDoc}
308      */
309     K lastKey() {
310         return key(getLastEntry());
311     }
312 
313     /**
314      * Copies all of the mappings from the specified map to this map.
315      * These mappings replace any mappings that this map had for any
316      * of the keys currently in the specified map.
317      *
318      * @param  map mappings to be stored in this map
319      * @throws ClassCastException if the class of a key or value in
320      *         the specified map prevents it from being stored in this map
321      * @throws NullPointerException if the specified map is null or
322      *         the specified map contains a null key and this map does not
323      *         permit null keys
324      */
325     override void putAll(Map!(K, V) map) {
326         int mapSize = map.size();
327         SortedMap!(K, V) sortedMap = cast(SortedMap!(K, V)) map;
328         if (_size==0 && mapSize !is 0 && sortedMap !is null) {
329             Comparator!K c = sortedMap.comparator();
330             if (c == _comparator) {
331                 ++modCount;
332                 implementationMissing(false);
333                 // try {
334                 //     buildFromSorted(mapSize, map, //.entrySet().iterator(),
335                 //                     null, null);
336                 // } catch (IOException cannotHappen) {
337                 // } 
338                 // catch (ClassNotFoundException cannotHappen) {
339                 // }
340                 return;
341             }
342         }
343         super.putAll(map);
344     }
345 
346     /**
347      * Returns this map's entry for the given key, or {@code null} if the map
348      * does not contain an entry for the key.
349      *
350      * @return this map's entry for the given key, or {@code null} if the map
351      *         does not contain an entry for the key
352      * @throws ClassCastException if the specified key cannot be compared
353      *         with the keys currently in the map
354      * @throws NullPointerException if the specified key is null
355      *         and this map uses natural ordering, or its comparator
356      *         does not permit null keys
357      */
358     final TreeMapEntry!(K,V) getEntry(K key) {
359         // Offload comparator-based version for sake of performance
360         if (_comparator !is null)
361             return getEntryUsingComparator(key);
362         static if(is(T == class))
363         {
364             if (key is null)
365                 throw new NullPointerException();
366         }
367         K k = key;
368         TreeMapEntry!(K,V) p = root;
369         while (p !is null) {
370             // static if(isNumeric!(K))
371             //     int cp = std.math.cmp(cast(float)k, cast(float)p.key);
372             // else
373             //     int cp = std.algorithm.cmp(k, p.key);
374             int cp = compare(k, p.key);
375 
376             if (cp < 0)
377                 p = p.left;
378             else if (cp > 0)
379                 p = p.right;
380             else
381                 return p;
382         }
383         return null;
384     }
385 
386     /**
387      * Version of getEntry using comparator. Split off from getEntry
388      * for performance. (This is not worth doing for most methods,
389      * that are less dependent on comparator performance, but is
390      * worthwhile here.)
391      */
392     final TreeMapEntry!(K,V) getEntryUsingComparator(K key) {
393         K k = key;
394         Comparator!K cpr = _comparator;
395         if (cpr !is null) {
396             TreeMapEntry!(K,V) p = root;
397             while (p !is null) {
398                 int cmp = cpr.compare(k, p.key);
399                 if (cmp < 0)
400                     p = p.left;
401                 else if (cmp > 0)
402                     p = p.right;
403                 else
404                     return p;
405             }
406         }
407         return null;
408     }
409 
410     /**
411      * Gets the entry corresponding to the specified key; if no such entry
412      * exists, returns the entry for the least key greater than the specified
413      * key; if no such entry exists (i.e., the greatest key in the Tree is less
414      * than the specified key), returns {@code null}.
415      */
416     final TreeMapEntry!(K,V) getCeilingEntry(K key) {
417         TreeMapEntry!(K,V) p = root;
418         while (p !is null) {
419             int cmp = compare(key, p.key);
420             if (cmp < 0) {
421                 if (p.left !is null)
422                     p = p.left;
423                 else
424                     return p;
425             } else if (cmp > 0) {
426                 if (p.right !is null) {
427                     p = p.right;
428                 } else {
429                     TreeMapEntry!(K,V) parent = p.parent;
430                     TreeMapEntry!(K,V) ch = p;
431                     while (parent !is null && ch == parent.right) {
432                         ch = parent;
433                         parent = parent.parent;
434                     }
435                     return parent;
436                 }
437             } else
438                 return p;
439         }
440         return null;
441     }
442 
443     /**
444      * Gets the entry corresponding to the specified key; if no such entry
445      * exists, returns the entry for the greatest key less than the specified
446      * key; if no such entry exists, returns {@code null}.
447      */
448     final TreeMapEntry!(K,V) getFloorEntry(K key) {
449         TreeMapEntry!(K,V) p = root;
450         while (p !is null) {
451             int cmp = compare(key, p.key);
452             if (cmp > 0) {
453                 if (p.right !is null)
454                     p = p.right;
455                 else
456                     return p;
457             } else if (cmp < 0) {
458                 if (p.left !is null) {
459                     p = p.left;
460                 } else {
461                     TreeMapEntry!(K,V) parent = p.parent;
462                     TreeMapEntry!(K,V) ch = p;
463                     while (parent !is null && ch == parent.left) {
464                         ch = parent;
465                         parent = parent.parent;
466                     }
467                     return parent;
468                 }
469             } else
470                 return p;
471 
472         }
473         return null;
474     }
475 
476     /**
477      * Gets the entry for the least key greater than the specified
478      * key; if no such entry exists, returns the entry for the least
479      * key greater than the specified key; if no such entry exists
480      * returns {@code null}.
481      */
482     final TreeMapEntry!(K,V) getHigherEntry(K key) {
483         TreeMapEntry!(K,V) p = root;
484         while (p !is null) {
485             int cmp = compare(key, p.key);
486             if (cmp < 0) {
487                 if (p.left !is null)
488                     p = p.left;
489                 else
490                     return p;
491             } else {
492                 if (p.right !is null) {
493                     p = p.right;
494                 } else {
495                     TreeMapEntry!(K,V) parent = p.parent;
496                     TreeMapEntry!(K,V) ch = p;
497                     while (parent !is null && ch == parent.right) {
498                         ch = parent;
499                         parent = parent.parent;
500                     }
501                     return parent;
502                 }
503             }
504         }
505         return null;
506     }
507 
508     /**
509      * Returns the entry for the greatest key less than the specified key; if
510      * no such entry exists (i.e., the least key in the Tree is greater than
511      * the specified key), returns {@code null}.
512      */
513     final TreeMapEntry!(K,V) getLowerEntry(K key) {
514         TreeMapEntry!(K,V) p = root;
515         while (p !is null) {
516             int cmp = compare(key, p.key);
517             if (cmp > 0) {
518                 if (p.right !is null)
519                     p = p.right;
520                 else
521                     return p;
522             } else {
523                 if (p.left !is null) {
524                     p = p.left;
525                 } else {
526                     TreeMapEntry!(K,V) parent = p.parent;
527                     TreeMapEntry!(K,V) ch = p;
528                     while (parent !is null && ch == parent.left) {
529                         ch = parent;
530                         parent = parent.parent;
531                     }
532                     return parent;
533                 }
534             }
535         }
536         return null;
537     }
538 
539     /**
540      * Associates the specified value with the specified key in this map.
541      * If the map previously contained a mapping for the key, the old
542      * value is replaced.
543      *
544      * @param key key with which the specified value is to be associated
545      * @param value value to be associated with the specified key
546      *
547      * @return the previous value associated with {@code key}, or
548      *         {@code null} if there was no mapping for {@code key}.
549      *         (A {@code null} return can also indicate that the map
550      *         previously associated {@code null} with {@code key}.)
551      * @throws ClassCastException if the specified key cannot be compared
552      *         with the keys currently in the map
553      * @throws NullPointerException if the specified key is null
554      *         and this map uses natural ordering, or its comparator
555      *         does not permit null keys
556      */
557     override V put(K key, V value) {
558         TreeMapEntry!(K,V) t = root;
559         if (t is null) {
560             // compare(key, key); // type (and possibly null) check
561 
562             root = new TreeMapEntry!(K,V)(key, value, null);
563             _size = 1;
564             modCount++;
565             return null;
566         }
567         int _cmp;
568         TreeMapEntry!(K,V) parent;
569         // split comparator and comparable paths
570         Comparator!K cpr = _comparator;
571         if (cpr !is null) {
572             do {
573                 parent = t;
574                 _cmp = cpr.compare(key, t.key);
575                 if (_cmp < 0)
576                     t = t.left;
577                 else if (_cmp > 0)
578                     t = t.right;
579                 else
580                     return t.setValue(value);
581             } while (t !is null);
582         }
583         else {
584             // if (key is null)
585             //     throw new NullPointerException();
586             // Comparable!K k = cast(Comparable!K) key;
587             K k = key;
588             do {
589                 parent = t;
590                 // _cmp = k.compareTo(t.key);
591                 
592                 // static if(isNumeric!(K))
593                 //     _cmp = std.math.cmp(cast(float)k, cast(float)t.key);
594                 // else
595                 //     _cmp = std.algorithm.cmp(k, t.key);
596                 _cmp = compare(k, t.key);
597 
598                 if (_cmp < 0)
599                     t = t.left;
600                 else if (_cmp > 0)
601                     t = t.right;
602                 else
603                     return t.setValue(value);
604             } while (t !is null);
605         }
606         TreeMapEntry!(K,V) e = new TreeMapEntry!(K,V)(key, value, parent);
607         if (_cmp < 0)
608             parent.left = e;
609         else
610             parent.right = e;
611         fixAfterInsertion(e);
612         _size++;
613         modCount++;
614         return null;
615     }
616 
617     /**
618      * Removes the mapping for this key from this TreeMap if present.
619      *
620      * @param  key key for which mapping should be removed
621      * @return the previous value associated with {@code key}, or
622      *         {@code null} if there was no mapping for {@code key}.
623      *         (A {@code null} return can also indicate that the map
624      *         previously associated {@code null} with {@code key}.)
625      * @throws ClassCastException if the specified key cannot be compared
626      *         with the keys currently in the map
627      * @throws NullPointerException if the specified key is null
628      *         and this map uses natural ordering, or its comparator
629      *         does not permit null keys
630      */
631     override V remove(K key) {
632         TreeMapEntry!(K,V) p = getEntry(key);
633         if (p is null)
634             return null;
635 
636         V oldValue = p.value;
637         deleteEntry(p);
638         return oldValue;
639     }
640 
641     /**
642      * Removes all of the mappings from this map.
643      * The map will be empty after this call returns.
644      */
645     override void clear() {
646         modCount++;
647         _size = 0;
648         root = null;
649     }
650 
651     /**
652      * Returns a shallow copy of this {@code TreeMap} instance. (The keys and
653      * values themselves are not cloned.)
654      *
655      * @return a shallow copy of this map
656      */
657     // Object clone() {
658     //     TreeMap<?,?> clone;
659     //     try {
660     //         clone = (TreeMap<?,?>) super.clone();
661     //     } catch (CloneNotSupportedException e) {
662     //         throw new InternalError(e);
663     //     }
664 
665     //     // Put clone into "virgin" state (except for comparator)
666     //     clone.root = null;
667     //     clone.size = 0;
668     //     clone.modCount = 0;
669     //     clone.entrySet = null;
670     //     clone._navigableKeySet = null;
671     //     clone._descendingMap = null;
672 
673     //     // Initialize clone with our mappings
674     //     try {
675     //         clone.buildFromSorted(size, entrySet().iterator(), null, null);
676     //     } catch (java.io.IOException cannotHappen) {
677     //     } catch (ClassNotFoundException cannotHappen) {
678     //     }
679 
680     //     return clone;
681     // }
682 
683     // NavigableMap API methods
684 
685     /**
686      * @since 1.6
687      */
688     MapEntry!(K,V) firstEntry() {
689         return exportEntry!(K,V)(getFirstEntry());
690     }
691 
692     /**
693      * @since 1.6
694      */
695     MapEntry!(K,V) lastEntry() {
696         return exportEntry!(K,V)(getLastEntry());
697     }
698 
699     /**
700      * @since 1.6
701      */
702     MapEntry!(K,V) pollFirstEntry() {
703         TreeMapEntry!(K,V) p = getFirstEntry();
704         MapEntry!(K,V) result = exportEntry!(K,V)(p);
705         if (p !is null)
706             deleteEntry(p);
707         return result;
708     }
709 
710     /**
711      * @since 1.6
712      */
713     MapEntry!(K,V) pollLastEntry() {
714         TreeMapEntry!(K,V) p = getLastEntry();
715         MapEntry!(K,V) result = exportEntry!(K,V)(p);
716         if (p !is null)
717             deleteEntry(p);
718         return result;
719     }
720 
721     /**
722      * @throws ClassCastException {@inheritDoc}
723      * @throws NullPointerException if the specified key is null
724      *         and this map uses natural ordering, or its comparator
725      *         does not permit null keys
726      * @since 1.6
727      */
728     MapEntry!(K,V) lowerEntry(K key) {
729         return exportEntry!(K,V)(getLowerEntry(key));
730     }
731 
732     /**
733      * @throws ClassCastException {@inheritDoc}
734      * @throws NullPointerException if the specified key is null
735      *         and this map uses natural ordering, or its comparator
736      *         does not permit null keys
737      * @since 1.6
738      */
739     K lowerKey(K key) {
740         return keyOrNull(getLowerEntry(key));
741     }
742 
743     /**
744      * @throws ClassCastException {@inheritDoc}
745      * @throws NullPointerException if the specified key is null
746      *         and this map uses natural ordering, or its comparator
747      *         does not permit null keys
748      * @since 1.6
749      */
750     MapEntry!(K,V) floorEntry(K key) {
751         return exportEntry!(K,V)(getFloorEntry(key));
752     }
753 
754     /**
755      * @throws ClassCastException {@inheritDoc}
756      * @throws NullPointerException if the specified key is null
757      *         and this map uses natural ordering, or its comparator
758      *         does not permit null keys
759      * @since 1.6
760      */
761     K floorKey(K key) {
762         return keyOrNull(getFloorEntry(key));
763     }
764 
765     /**
766      * @throws ClassCastException {@inheritDoc}
767      * @throws NullPointerException if the specified key is null
768      *         and this map uses natural ordering, or its comparator
769      *         does not permit null keys
770      * @since 1.6
771      */
772     MapEntry!(K,V) ceilingEntry(K key) {
773         return exportEntry!(K,V)(getCeilingEntry(key));
774     }
775 
776     /**
777      * @throws ClassCastException {@inheritDoc}
778      * @throws NullPointerException if the specified key is null
779      *         and this map uses natural ordering, or its comparator
780      *         does not permit null keys
781      * @since 1.6
782      */
783     K ceilingKey(K key) {
784         return keyOrNull(getCeilingEntry(key));
785     }
786 
787     /**
788      * @throws ClassCastException {@inheritDoc}
789      * @throws NullPointerException if the specified key is null
790      *         and this map uses natural ordering, or its comparator
791      *         does not permit null keys
792      * @since 1.6
793      */
794     MapEntry!(K,V) higherEntry(K key) {
795         return exportEntry!(K,V)(getHigherEntry(key));
796     }
797 
798     /**
799      * @throws ClassCastException {@inheritDoc}
800      * @throws NullPointerException if the specified key is null
801      *         and this map uses natural ordering, or its comparator
802      *         does not permit null keys
803      * @since 1.6
804      */
805     K higherKey(K key) {
806         return keyOrNull(getHigherEntry(key));
807     }
808 
809     // Views
810 
811     /**
812      * Fields initialized to contain an instance of the entry set view
813      * the first time this view is requested.  Views are stateless, so
814      * there's no reason to create more than one.
815      */
816     // private EntrySet _entrySet;
817     // private KeySet!(K,V) _navigableKeySet;
818     private NavigableMap!(K,V) _descendingMap;
819 
820     /**
821      * Returns a {@link Set} view of the keys contained in this map.
822      *
823      * <p>The set's iterator returns the keys in ascending order.
824      * The set's spliterator is
825      * <em><a href="Spliterator.html#binding">late-binding</a></em>,
826      * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED}
827      * and {@link Spliterator#ORDERED} with an encounter order that is ascending
828      * key order.  The spliterator's comparator (see
829      * {@link java.util.Spliterator#getComparator()}) is {@code null} if
830      * the tree map's comparator (see {@link #comparator()}) is {@code null}.
831      * Otherwise, the spliterator's comparator is the same as or imposes the
832      * same total ordering as the tree map's comparator.
833      *
834      * <p>The set is backed by the map, so changes to the map are
835      * reflected in the set, and vice-versa.  If the map is modified
836      * while an iteration over the set is in progress (except through
837      * the iterator's own {@code remove} operation), the results of
838      * the iteration are undefined.  The set supports element removal,
839      * which removes the corresponding mapping from the map, via the
840      * {@code Iterator.remove}, {@code Set.remove},
841      * {@code removeAll}, {@code retainAll}, and {@code clear}
842      * operations.  It does not support the {@code add} or {@code addAll}
843      * operations.
844      */
845     // Set!K keySet() {
846     //     return navigableKeySet();
847     // }
848 
849     /**
850      * @since 1.6
851      */
852     // NavigableSet!K navigableKeySet() {
853     //     KeySet!(K, V) nks = _navigableKeySet;
854     //     return (nks !is null) ? nks : (_navigableKeySet = new KeySet!(K, V)(this));
855     // }
856 
857     /**
858      * @since 1.6
859      */
860     // NavigableSet!K descendingKeySet() {
861     //     return descendingMap().navigableKeySet();
862     // }
863 
864     /**
865      * Returns a {@link Collection} view of the values contained in this map.
866      *
867      * <p>The collection's iterator returns the values in ascending order
868      * of the corresponding keys. The collection's spliterator is
869      * <em><a href="Spliterator.html#binding">late-binding</a></em>,
870      * <em>fail-fast</em>, and additionally reports {@link Spliterator#ORDERED}
871      * with an encounter order that is ascending order of the corresponding
872      * keys.
873      *
874      * <p>The collection is backed by the map, so changes to the map are
875      * reflected in the collection, and vice-versa.  If the map is
876      * modified while an iteration over the collection is in progress
877      * (except through the iterator's own {@code remove} operation),
878      * the results of the iteration are undefined.  The collection
879      * supports element removal, which removes the corresponding
880      * mapping from the map, via the {@code Iterator.remove},
881      * {@code Collection.remove}, {@code removeAll},
882      * {@code retainAll} and {@code clear} operations.  It does not
883      * support the {@code add} or {@code addAll} operations.
884      */
885     // Collection!V values() {
886     //     Collection!V vs = values;
887     //     if (vs is null) {
888     //         vs = new Values();
889     //         values = vs;
890     //     }
891     //     return vs;
892     // }
893 
894     /**
895      * Returns a {@link Set} view of the mappings contained in this map.
896      *
897      * <p>The set's iterator returns the entries in ascending key order. The
898      * sets's spliterator is
899      * <em><a href="Spliterator.html#binding">late-binding</a></em>,
900      * <em>fail-fast</em>, and additionally reports {@link Spliterator#SORTED} and
901      * {@link Spliterator#ORDERED} with an encounter order that is ascending key
902      * order.
903      *
904      * <p>The set is backed by the map, so changes to the map are
905      * reflected in the set, and vice-versa.  If the map is modified
906      * while an iteration over the set is in progress (except through
907      * the iterator's own {@code remove} operation, or through the
908      * {@code setValue} operation on a map entry returned by the
909      * iterator) the results of the iteration are undefined.  The set
910      * supports element removal, which removes the corresponding
911      * mapping from the map, via the {@code Iterator.remove},
912      * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
913      * {@code clear} operations.  It does not support the
914      * {@code add} or {@code addAll} operations.
915      */
916     // Set!(MapEntry!(K,V)) entrySet() {
917     //     EntrySet es = _entrySet;
918     //     return (es !is null) ? es : (_entrySet = new EntrySet());
919     // }
920 
921     /**
922      * @since 1.6
923      */
924     // NavigableMap!(K, V) descendingMap() {
925     //     NavigableMap!(K, V) km = _descendingMap;
926     //     return (km !is null) ? km :
927     //         (_descendingMap = new DescendingSubMap!(K, V)(this,
928     //                                                 true, K.init, true,
929     //                                                 true, K.init, true));
930     // }
931 
932     /**
933      * @throws ClassCastException       {@inheritDoc}
934      * @throws NullPointerException if {@code fromKey} or {@code toKey} is
935      *         null and this map uses natural ordering, or its comparator
936      *         does not permit null keys
937      * @throws IllegalArgumentException {@inheritDoc}
938      * @since 1.6
939      */
940     NavigableMap!(K,V) subMap(K fromKey, bool fromInclusive,
941                                     K toKey,   bool toInclusive) {
942         return new AscendingSubMap!(K, V)(this,
943                                      false, fromKey, fromInclusive,
944                                      false, toKey,   toInclusive);
945     }
946 
947     /**
948      * @throws ClassCastException       {@inheritDoc}
949      * @throws NullPointerException if {@code toKey} is null
950      *         and this map uses natural ordering, or its comparator
951      *         does not permit null keys
952      * @throws IllegalArgumentException {@inheritDoc}
953      * @since 1.6
954      */
955     NavigableMap!(K,V) headMap(K toKey, bool inclusive) {
956         return new AscendingSubMap!(K, V)(this,
957                                      true,  K.init,  true,
958                                      false, toKey, inclusive);
959     }
960 
961     /**
962      * @throws ClassCastException       {@inheritDoc}
963      * @throws NullPointerException if {@code fromKey} is null
964      *         and this map uses natural ordering, or its comparator
965      *         does not permit null keys
966      * @throws IllegalArgumentException {@inheritDoc}
967      * @since 1.6
968      */
969     NavigableMap!(K,V) tailMap(K fromKey, bool inclusive) {
970         return new AscendingSubMap!(K, V)(this,
971                                      false, fromKey, inclusive,
972                                      true,  K.init,    true);
973     }
974 
975     /**
976      * @throws ClassCastException       {@inheritDoc}
977      * @throws NullPointerException if {@code fromKey} or {@code toKey} is
978      *         null and this map uses natural ordering, or its comparator
979      *         does not permit null keys
980      * @throws IllegalArgumentException {@inheritDoc}
981      */
982     SortedMap!(K,V) subMap(K fromKey, K toKey) {
983         return subMap(fromKey, true, toKey, false);
984     }
985 
986     /**
987      * @throws ClassCastException       {@inheritDoc}
988      * @throws NullPointerException if {@code toKey} is null
989      *         and this map uses natural ordering, or its comparator
990      *         does not permit null keys
991      * @throws IllegalArgumentException {@inheritDoc}
992      */
993     SortedMap!(K,V) headMap(K toKey) {
994         return headMap(toKey, false);
995     }
996 
997     /**
998      * @throws ClassCastException       {@inheritDoc}
999      * @throws NullPointerException if {@code fromKey} is null
1000      *         and this map uses natural ordering, or its comparator
1001      *         does not permit null keys
1002      * @throws IllegalArgumentException {@inheritDoc}
1003      */
1004     SortedMap!(K,V) tailMap(K fromKey) {
1005         return tailMap(fromKey, true);
1006     }
1007 
1008     override
1009     bool replace(K key, V oldValue, V newValue) {
1010         TreeMapEntry!(K,V) p = getEntry(key);
1011         if (p !is null && oldValue == p.value) {
1012             p.value = newValue;
1013             return true;
1014         }
1015         return false;
1016     }
1017 
1018     override
1019     V replace(K key, V value) {
1020         TreeMapEntry!(K,V) p = getEntry(key);
1021         if (p !is null) {
1022             V oldValue = p.value;
1023             p.value = value;
1024             return oldValue;
1025         }
1026         return null;
1027     }
1028 
1029     // override
1030     // void replaceAll(BiFunction<K, V, ? : V> function) {
1031     //     Objects.requireNonNull(function);
1032     //     int expectedModCount = modCount;
1033 
1034     //     for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) {
1035     //         e.value = function.apply(e.key, e.value);
1036 
1037     //         if (expectedModCount  !is  modCount) {
1038     //             throw new ConcurrentModificationException();
1039     //         }
1040     //     }
1041     // }
1042 
1043 
1044     // View class support
1045 
1046     override int opApply(scope int delegate(ref K, ref V) dg) {
1047         if(dg is null)
1048             throw new NullPointerException();
1049 
1050         int result = 0;
1051         int expectedModCount = modCount;
1052         for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) {
1053             result = dg(e.key, e.value);
1054             if(result != 0) return result;
1055         }
1056 
1057         if (expectedModCount  !is  modCount) 
1058             throw new ConcurrentModificationException();
1059 
1060         return result;
1061     }
1062 
1063     
1064     override int opApply(scope int delegate(MapEntry!(K, V) entry) dg) {
1065         if(dg is null)
1066             throw new NullPointerException();
1067 
1068         int result = 0;
1069         int expectedModCount = modCount;
1070         for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) {
1071             result = dg(e);
1072             if(result != 0) return result;
1073         }
1074 
1075         if (expectedModCount  !is  modCount) 
1076             throw new ConcurrentModificationException();
1077 
1078         return result;
1079     }
1080     
1081     override InputRange!K byKey()
1082     {
1083         return new KeyInputRange();
1084         // throw new NotImplementedException();
1085     }
1086 
1087     override InputRange!V byValue()
1088     {
1089         return new ValueInputRange();
1090         // throw new NotImplementedException();
1091     }
1092 
1093 
1094     // class Values : AbstractCollection!V {
1095     //     Iterator!V iterator() {
1096     //         return new ValueIterator(getFirstEntry());
1097     //     }
1098 
1099     //     override int size() {
1100     //         return this.outer.size();
1101     //     }
1102 
1103     //     override bool contains(V o) {
1104     //         return this.outer.containsValue(o);
1105     //     }
1106 
1107     //     bool remove(V o) {
1108     //         for (TreeMapEntry!(K,V) e = getFirstEntry(); e !is null; e = successor(e)) {
1109     //             if (valEquals(e.getValue(), o)) {
1110     //                 deleteEntry(e);
1111     //                 return true;
1112     //             }
1113     //         }
1114     //         return false;
1115     //     }
1116 
1117     //     override void clear() {
1118     //         this.outer.clear();
1119     //     }
1120 
1121     //     // Spliterator!V spliterator() {
1122     //     //     return new ValueSpliterator!(K,V)(TreeMap.this, null, null, 0, -1, 0);
1123     //     // }
1124     // }
1125 
1126     // class EntrySet : AbstractSet!(MapEntry!(K,V)) {
1127 
1128     //     Iterator!(MapEntry!(K,V)) iterator() {
1129     //         return new EntryIterator(getFirstEntry());
1130     //     }
1131 
1132     //     override bool contains(MapEntry!(K,V) entry) {
1133     //         // if (!(o instanceof MapEntry))
1134     //         //     return false;
1135     //         // MapEntry<?,?> entry = (MapEntry<?,?>) o;
1136     //         V value = entry.getValue();
1137     //         TreeMapEntry!(K,V) p = getEntry(entry.getKey());
1138     //         return p !is null && valEquals(p.getValue(), value);
1139     //     }
1140 
1141     //     bool remove(MapEntry!(K,V) entry) {
1142     //         // if (!(o instanceof MapEntry))
1143     //         //     return false;
1144     //         // MapEntry<?,?> entry = (MapEntry<?,?>) o;
1145     //         V value = entry.getValue();
1146     //         TreeMapEntry!(K,V) p = getEntry(entry.getKey());
1147     //         if (p !is null && valEquals(p.getValue(), value)) {
1148     //             deleteEntry(p);
1149     //             return true;
1150     //         }
1151     //         return false;
1152     //     }
1153 
1154     //     override int size() {
1155     //         return this.outer.size();
1156     //     }
1157 
1158     //     override void clear() {
1159     //         this.outer.clear();
1160     //     }
1161 
1162     //     // Spliterator!(MapEntry!(K,V)) spliterator() {
1163     //     //     return new EntrySpliterator!(K,V)(this.outer, null, null, 0, -1, 0);
1164     //     // }
1165     // }
1166 
1167     /*
1168      * Unlike Values and EntrySet, the KeySet class is static,
1169      * delegating to a NavigableMap to allow use by SubMaps, which
1170      * outweighs the ugliness of needing type-tests for the following
1171      * Iterator methods that are defined appropriately in main versus
1172      * submap classes.
1173      */
1174 
1175     // Iterator!K keyIterator() {
1176     //     return new KeyIterator(getFirstEntry());
1177     // }
1178 
1179     // Iterator!K descendingKeyIterator() {
1180     //     return new DescendingKeyIterator(getLastEntry());
1181     // }
1182 
1183     // static final class KeySet(E, V) : AbstractSet!E , NavigableSet!E {
1184     //     private NavigableMap!(E, V) m;
1185 
1186     //     this(NavigableMap!(E, V) map) { m = map; }
1187 
1188     //     Iterator!E iterator() {
1189     //         TreeMap!(E, V) mm = cast(TreeMap!(E, V))m;
1190     //         if (mm !is null)
1191     //             return mm.keyIterator();
1192     //         else
1193     //             return (cast(TreeMap.NavigableSubMap!(E, V))m).keyIterator();
1194     //     }
1195 
1196     //     Iterator!E descendingIterator() {
1197     //         TreeMap!(E, V) mm = cast(TreeMap!(E, V))m;
1198     //         if (mm !is null)
1199     //             return mm.descendingKeyIterator();
1200     //         else
1201     //             return (cast(TreeMap.NavigableSubMap!(E, V))m).descendingKeyIterator();
1202     //     }
1203 
1204     //     override int size() { return m.size(); }
1205     //     override bool isEmpty() { return m.isEmpty(); }
1206     //     override bool contains(K o) { return m.containsKey(o); }
1207     //     override void clear() { m.clear(); }
1208     //     E lower(E e) { return m.lowerKey(e); }
1209     //     E floor(E e) { return m.floorKey(e); }
1210     //     E ceiling(E e) { return m.ceilingKey(e); }
1211     //     E higher(E e) { return m.higherKey(e); }
1212     //     E first() { return m.firstKey(); }
1213     //     E last() { return m.lastKey(); }
1214     //     // Comparator!E comparator() { return m.comparator(); }
1215     //     E pollFirst() {
1216     //         MapEntry!(E, V) e = m.pollFirstEntry();
1217     //         return (e is null) ? E.init : e.getKey();
1218     //     }
1219     //     E pollLast() {
1220     //         MapEntry!(E, V) e = m.pollLastEntry();
1221     //         return (e is null) ? E.init : e.getKey();
1222     //     }
1223     //     bool remove(E o) {
1224     //         int oldSize = size();
1225     //         m.remove(o);
1226     //         return size()  !is  oldSize;
1227     //     }
1228     //     NavigableSet!E subSet(E fromElement, bool fromInclusive,
1229     //                                   E toElement,   bool toInclusive) {
1230     //         return new KeySet!(E, V)(m.subMap(fromElement, fromInclusive,
1231     //                                       toElement,   toInclusive));
1232     //     }
1233     //     NavigableSet!E headSet(E toElement, bool inclusive) {
1234     //         return new KeySet!(E, V)(m.headMap(toElement, inclusive));
1235     //     }
1236     //     NavigableSet!E tailSet(E fromElement, bool inclusive) {
1237     //         return new KeySet!(E, V)(m.tailMap(fromElement, inclusive));
1238     //     }
1239     //     SortedSet!E subSet(E fromElement, E toElement) {
1240     //         return subSet(fromElement, true, toElement, false);
1241     //     }
1242     //     SortedSet!E headSet(E toElement) {
1243     //         return headSet(toElement, false);
1244     //     }
1245     //     SortedSet!E tailSet(E fromElement) {
1246     //         return tailSet(fromElement, true);
1247     //     }
1248     //     NavigableSet!E descendingSet() {
1249     //         return new KeySet!(E, V)(m.descendingMap());
1250     //     }
1251 
1252     //     // Spliterator!E spliterator() {
1253     //     //     return keySpliteratorFor(m);
1254     //     // }
1255     // }
1256 
1257     /**
1258      * Base class for TreeMap Iterators
1259      */
1260 
1261     mixin template TreeMapIterator() {
1262         TreeMapEntry!(K,V) next;
1263         TreeMapEntry!(K,V) lastReturned;
1264         int expectedModCount;
1265 
1266         this() {
1267             expectedModCount = modCount;
1268             lastReturned = null;
1269             next = getFirstEntry();
1270         }
1271 
1272         final bool empty() {
1273             return next is null;
1274         }
1275 
1276         final void popFront() {
1277             TreeMapEntry!(K,V) e = next;
1278             if (e is null)
1279                 throw new NoSuchElementException();
1280             if (modCount  !is  expectedModCount)
1281                 throw new ConcurrentModificationException();
1282             next = successor(e);
1283             lastReturned = e;
1284             // return e;
1285         }
1286 
1287         // final TreeMapEntry!(K,V) prevEntry() {
1288         //     TreeMapEntry!(K,V) e = next;
1289         //     if (e is null)
1290         //         throw new NoSuchElementException();
1291         //     if (modCount  !is  expectedModCount)
1292         //         throw new ConcurrentModificationException();
1293         //     next = predecessor(e);
1294         //     lastReturned = e;
1295         //     return e;
1296         // }
1297     }
1298 
1299     final class KeyInputRange :  InputRange!K {
1300         mixin TreeMapIterator;
1301 
1302         final K front() @property { return next.key; }
1303 
1304         // https://forum.dlang.org/thread/amzthhonuozlobghqqgk@forum.dlang.org?page=1
1305         // https://issues.dlang.org/show_bug.cgi?id=18036
1306         final K moveFront() @property { throw new NotSupportedException(); }
1307         
1308         int opApply(scope int delegate(K) dg) {
1309             if(dg is null)
1310                 throw new NullPointerException();
1311 
1312             int result = 0;
1313             int expectedModCount = modCount;
1314             for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) {
1315                 result = dg(e.key);
1316                 if(result != 0) return result;
1317             }
1318 
1319             if (expectedModCount !is modCount) 
1320                 throw new ConcurrentModificationException();
1321 
1322             return result;
1323         }
1324 
1325         int opApply(scope int delegate(size_t, K) dg) {
1326             if(dg is null)
1327                 throw new NullPointerException();
1328 
1329             int result = 0;
1330             int mc = modCount;
1331             size_t index = 0;
1332              for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) {
1333                 result = dg(index++, e.key);
1334                 if(result != 0) return result;
1335             }
1336 
1337             if(modCount != mc)
1338                 throw new ConcurrentModificationException();
1339 
1340             return result;
1341         }
1342     }
1343     
1344     final class ValueInputRange :  InputRange!V {
1345         mixin TreeMapIterator;
1346 
1347         final V front() @property { return next.value; }
1348 
1349         final V moveFront() @property { throw new NotSupportedException(); }
1350         
1351         int opApply(scope int delegate(V) dg) {
1352             if(dg is null)
1353                 throw new NullPointerException();
1354 
1355             int result = 0;
1356             int mc = modCount;
1357              for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) {
1358                 result = dg(e.value);
1359                 if(result != 0) return result;
1360             }
1361 
1362             if(modCount != mc)
1363                 throw new ConcurrentModificationException();
1364 
1365             return result;
1366         }
1367 
1368         int opApply(scope int delegate(size_t, V) dg) {
1369             if(dg is null)
1370                 throw new NullPointerException();
1371 
1372             int result = 0;
1373             int mc = modCount;
1374             size_t index = 0;
1375             for (TreeMapEntry!(K, V) e = getFirstEntry(); e !is null; e = successor(e)) {
1376                 result = dg(index++, e.value);
1377                 if(result != 0) return result;
1378             }
1379 
1380             if(modCount != mc)
1381                 throw new ConcurrentModificationException();
1382 
1383             return result;
1384         }
1385     }
1386 
1387     // abstract class PrivateEntryIterator(T) : Iterator!T {
1388     //     TreeMapEntry!(K,V) next;
1389     //     TreeMapEntry!(K,V) lastReturned;
1390     //     int expectedModCount;
1391 
1392     //     this(TreeMapEntry!(K,V) first) {
1393     //         expectedModCount = modCount;
1394     //         lastReturned = null;
1395     //         next = first;
1396     //     }
1397 
1398     //     final bool hasNext() {
1399     //         return next !is null;
1400     //     }
1401 
1402     //     final TreeMapEntry!(K,V) nextEntry() {
1403     //         TreeMapEntry!(K,V) e = next;
1404     //         if (e is null)
1405     //             throw new NoSuchElementException();
1406     //         if (modCount  !is  expectedModCount)
1407     //             throw new ConcurrentModificationException();
1408     //         next = successor(e);
1409     //         lastReturned = e;
1410     //         return e;
1411     //     }
1412 
1413     //     final TreeMapEntry!(K,V) prevEntry() {
1414     //         TreeMapEntry!(K,V) e = next;
1415     //         if (e is null)
1416     //             throw new NoSuchElementException();
1417     //         if (modCount  !is  expectedModCount)
1418     //             throw new ConcurrentModificationException();
1419     //         next = predecessor(e);
1420     //         lastReturned = e;
1421     //         return e;
1422     //     }
1423 
1424     //     void remove() {
1425     //         if (lastReturned is null)
1426     //             throw new IllegalStateException();
1427     //         if (modCount  !is  expectedModCount)
1428     //             throw new ConcurrentModificationException();
1429     //         // deleted entries are replaced by their successors
1430     //         if (lastReturned.left !is null && lastReturned.right !is null)
1431     //             next = lastReturned;
1432     //         deleteEntry(lastReturned);
1433     //         expectedModCount = modCount;
1434     //         lastReturned = null;
1435     //     }
1436     // }
1437 
1438     // final class EntryIterator : PrivateEntryIterator!(MapEntry!(K,V)) {
1439     //     this(TreeMapEntry!(K,V) first) {
1440     //         super(first);
1441     //     }
1442     //     MapEntry!(K,V) next() {
1443     //         return nextEntry();
1444     //     }
1445     // }
1446 
1447     // final class ValueIterator : PrivateEntryIterator!V {
1448     //     this(TreeMapEntry!(K,V) first) {
1449     //         super(first);
1450     //     }
1451     //     V next() {
1452     //         return nextEntry().value;
1453     //     }
1454     // }
1455 
1456     // final class KeyIterator : PrivateEntryIterator!K {
1457     //     this(TreeMapEntry!(K,V) first) {
1458     //         super(first);
1459     //     }
1460     //     K next() {
1461     //         return nextEntry().key;
1462     //     }
1463     // }
1464 
1465     // final class DescendingKeyIterator : PrivateEntryIterator!K {
1466     //     this(TreeMapEntry!(K,V) first) {
1467     //         super(first);
1468     //     }
1469     //     K next() {
1470     //         return prevEntry().key;
1471     //     }
1472 
1473     //     override void remove() {
1474     //         if (lastReturned is null)
1475     //             throw new IllegalStateException();
1476     //         if (modCount  !is  expectedModCount)
1477     //             throw new ConcurrentModificationException();
1478     //         deleteEntry(lastReturned);
1479     //         lastReturned = null;
1480     //         expectedModCount = modCount;
1481     //     }
1482     // }
1483 
1484     /**
1485      * Compares two keys using the correct comparison method for this TreeMap.
1486      */
1487     // final private int compare(K k1, K k2) {
1488     //     if(k1 == k2) return 0;
1489     //     else if(k1 > k2) return 1;
1490     //     else return -1;
1491     // }
1492 
1493 
1494     // SubMaps
1495 
1496     /**
1497      * Dummy value serving as unmatchable fence key for unbounded
1498      * SubMapIterators
1499      */
1500     private __gshared Object UNBOUNDED;
1501 
1502     shared static this()
1503     {
1504         UNBOUNDED = new Object();
1505     }
1506 
1507     /**
1508      * This class exists solely for the sake of serialization
1509      * compatibility with previous releases of TreeMap that did not
1510      * support NavigableMap.  It translates an old-version SubMap into
1511      * a new-version AscendingSubMap. This class is never otherwise
1512      * used.
1513      *
1514      * @serial include
1515      */
1516     private class SubMap : AbstractMap!(K,V), SortedMap!(K,V) {
1517 
1518         private bool fromStart = false, toEnd = false;
1519         private K fromKey, toKey;
1520         // private Object readResolve() {
1521         //     return new AscendingSubMap<>(TreeMap.this,
1522         //                                  fromStart, fromKey, true,
1523         //                                  toEnd, toKey, false);
1524         // }
1525         Set!(MapEntry!(K,V)) entrySet() { throw new InternalError(); }
1526         K lastKey() { throw new InternalError(); }
1527         K firstKey() { throw new InternalError(); }
1528         SortedMap!(K,V) subMap(K fromKey, K toKey) { throw new InternalError(); }
1529         SortedMap!(K,V) headMap(K toKey) { throw new InternalError(); }
1530         SortedMap!(K,V) tailMap(K fromKey) { throw new InternalError(); }
1531         Comparator!K comparator() { throw new InternalError(); }
1532 
1533         
1534         override bool opEquals(IObject o) {
1535             return opEquals(cast(Object) o);
1536         }
1537         
1538         override bool opEquals(Object o) {
1539             return super.opEquals(o);
1540         }
1541 
1542         override size_t toHash() @trusted nothrow {
1543             return super.toHash();
1544         }
1545 
1546         override string toString() {
1547             return super.toString();
1548         }
1549 
1550         override K[] keySet() {
1551             return super.keySet();
1552         }
1553 
1554         override V[] values() {
1555             return super.values;
1556         }
1557     }
1558 
1559 
1560     /**
1561      * Returns the first Entry in the TreeMap (according to the TreeMap's
1562      * key-sort function).  Returns null if the TreeMap is empty.
1563      */
1564     final TreeMapEntry!(K,V) getFirstEntry() {
1565         TreeMapEntry!(K,V) p = root;
1566         if (p !is null)
1567             while (p.left !is null)
1568                 p = p.left;
1569         return p;
1570     }
1571 
1572     /**
1573      * Returns the last Entry in the TreeMap (according to the TreeMap's
1574      * key-sort function).  Returns null if the TreeMap is empty.
1575      */
1576     final TreeMapEntry!(K,V) getLastEntry() {
1577         TreeMapEntry!(K,V) p = root;
1578         if (p !is null)
1579             while (p.right !is null)
1580                 p = p.right;
1581         return p;
1582     }
1583 
1584     
1585 
1586     /**
1587      * Balancing operations.
1588      *
1589      * Implementations of rebalancings during insertion and deletion are
1590      * slightly different than the CLR version.  Rather than using dummy
1591      * nilnodes, we use a set of accessors that deal properly with null.  They
1592      * are used to avoid messiness surrounding nullness checks in the main
1593      * algorithms.
1594      */
1595 
1596     private static bool colorOf(K,V)(TreeMapEntry!(K,V) p) {
1597         return (p is null ? BLACK : p.color);
1598     }
1599 
1600     private static TreeMapEntry!(K,V) parentOf(K,V)(TreeMapEntry!(K,V) p) {
1601         return (p is null ? null: p.parent);
1602     }
1603 
1604     private static void setColor(K,V)(TreeMapEntry!(K,V) p, bool c) {
1605         if (p !is null)
1606             p.color = c;
1607     }
1608 
1609     private static TreeMapEntry!(K,V) leftOf(K,V)(TreeMapEntry!(K,V) p) {
1610         return (p is null) ? null: p.left;
1611     }
1612 
1613     private static TreeMapEntry!(K,V) rightOf(K,V)(TreeMapEntry!(K,V) p) {
1614         return (p is null) ? null: p.right;
1615     }
1616 
1617     /** From CLR */
1618     private void rotateLeft(TreeMapEntry!(K,V) p) {
1619         if (p !is null) {
1620             TreeMapEntry!(K,V) r = p.right;
1621             p.right = r.left;
1622             if (r.left !is null)
1623                 r.left.parent = p;
1624             r.parent = p.parent;
1625             if (p.parent is null)
1626                 root = r;
1627             else if (p.parent.left == p)
1628                 p.parent.left = r;
1629             else
1630                 p.parent.right = r;
1631             r.left = p;
1632             p.parent = r;
1633         }
1634     }
1635 
1636     /** From CLR */
1637     private void rotateRight(TreeMapEntry!(K,V) p) {
1638         if (p !is null) {
1639             TreeMapEntry!(K,V) l = p.left;
1640             p.left = l.right;
1641             if (l.right !is null) l.right.parent = p;
1642             l.parent = p.parent;
1643             if (p.parent is null)
1644                 root = l;
1645             else if (p.parent.right == p)
1646                 p.parent.right = l;
1647             else p.parent.left = l;
1648             l.right = p;
1649             p.parent = l;
1650         }
1651     }
1652 
1653     /** From CLR */
1654     private void fixAfterInsertion(TreeMapEntry!(K,V) x) {
1655         x.color = RED;
1656 
1657         while (x !is null && x  !is  root && x.parent.color == RED) {
1658             if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
1659                 TreeMapEntry!(K,V) y = rightOf(parentOf(parentOf(x)));
1660                 if (colorOf(y) == RED) {
1661                     setColor(parentOf(x), BLACK);
1662                     setColor(y, BLACK);
1663                     setColor(parentOf(parentOf(x)), RED);
1664                     x = parentOf(parentOf(x));
1665                 } else {
1666                     if (x == rightOf(parentOf(x))) {
1667                         x = parentOf(x);
1668                         rotateLeft(x);
1669                     }
1670                     setColor(parentOf(x), BLACK);
1671                     setColor(parentOf(parentOf(x)), RED);
1672                     rotateRight(parentOf(parentOf(x)));
1673                 }
1674             } else {
1675                 TreeMapEntry!(K,V) y = leftOf(parentOf(parentOf(x)));
1676                 if (colorOf(y) == RED) {
1677                     setColor(parentOf(x), BLACK);
1678                     setColor(y, BLACK);
1679                     setColor(parentOf(parentOf(x)), RED);
1680                     x = parentOf(parentOf(x));
1681                 } else {
1682                     if (x == leftOf(parentOf(x))) {
1683                         x = parentOf(x);
1684                         rotateRight(x);
1685                     }
1686                     setColor(parentOf(x), BLACK);
1687                     setColor(parentOf(parentOf(x)), RED);
1688                     rotateLeft(parentOf(parentOf(x)));
1689                 }
1690             }
1691         }
1692         root.color = BLACK;
1693     }
1694 
1695     /**
1696      * Delete node p, and then rebalance the tree.
1697      */
1698     private void deleteEntry(TreeMapEntry!(K,V) p) {
1699         modCount++;
1700         _size--;
1701 
1702         // If strictly internal, copy successor's element to p and then make p
1703         // point to successor.
1704         if (p.left !is null && p.right !is null) {
1705             TreeMapEntry!(K,V) s = successor(p);
1706             p.key = s.key;
1707             p.value = s.value;
1708             p = s;
1709         } // p has 2 children
1710 
1711         // Start fixup at replacement node, if it exists.
1712         TreeMapEntry!(K,V) replacement = (p.left !is null ? p.left : p.right);
1713 
1714         if (replacement !is null) {
1715             // Link replacement to parent
1716             replacement.parent = p.parent;
1717             if (p.parent is null)
1718                 root = replacement;
1719             else if (p == p.parent.left)
1720                 p.parent.left  = replacement;
1721             else
1722                 p.parent.right = replacement;
1723 
1724             // Null out links so they are OK to use by fixAfterDeletion.
1725             p.left = p.right = p.parent = null;
1726 
1727             // Fix replacement
1728             if (p.color == BLACK)
1729                 fixAfterDeletion(replacement);
1730         } else if (p.parent is null) { // return if we are the only node.
1731             root = null;
1732         } else { //  No children. Use self as phantom replacement and unlink.
1733             if (p.color == BLACK)
1734                 fixAfterDeletion(p);
1735 
1736             if (p.parent !is null) {
1737                 if (p == p.parent.left)
1738                     p.parent.left = null;
1739                 else if (p == p.parent.right)
1740                     p.parent.right = null;
1741                 p.parent = null;
1742             }
1743         }
1744     }
1745 
1746     /** From CLR */
1747     private void fixAfterDeletion(TreeMapEntry!(K,V) x) {
1748         while (x  !is  root && colorOf(x) == BLACK) {
1749             if (x == leftOf(parentOf(x))) {
1750                 TreeMapEntry!(K,V) sib = rightOf(parentOf(x));
1751 
1752                 if (colorOf(sib) == RED) {
1753                     setColor(sib, BLACK);
1754                     setColor(parentOf(x), RED);
1755                     rotateLeft(parentOf(x));
1756                     sib = rightOf(parentOf(x));
1757                 }
1758 
1759                 if (colorOf(leftOf(sib))  == BLACK &&
1760                     colorOf(rightOf(sib)) == BLACK) {
1761                     setColor(sib, RED);
1762                     x = parentOf(x);
1763                 } else {
1764                     if (colorOf(rightOf(sib)) == BLACK) {
1765                         setColor(leftOf(sib), BLACK);
1766                         setColor(sib, RED);
1767                         rotateRight(sib);
1768                         sib = rightOf(parentOf(x));
1769                     }
1770                     setColor(sib, colorOf(parentOf(x)));
1771                     setColor(parentOf(x), BLACK);
1772                     setColor(rightOf(sib), BLACK);
1773                     rotateLeft(parentOf(x));
1774                     x = root;
1775                 }
1776             } else { // symmetric
1777                 TreeMapEntry!(K,V) sib = leftOf(parentOf(x));
1778 
1779                 if (colorOf(sib) == RED) {
1780                     setColor(sib, BLACK);
1781                     setColor(parentOf(x), RED);
1782                     rotateRight(parentOf(x));
1783                     sib = leftOf(parentOf(x));
1784                 }
1785 
1786                 if (colorOf(rightOf(sib)) == BLACK &&
1787                     colorOf(leftOf(sib)) == BLACK) {
1788                     setColor(sib, RED);
1789                     x = parentOf(x);
1790                 } else {
1791                     if (colorOf(leftOf(sib)) == BLACK) {
1792                         setColor(rightOf(sib), BLACK);
1793                         setColor(sib, RED);
1794                         rotateLeft(sib);
1795                         sib = leftOf(parentOf(x));
1796                     }
1797                     setColor(sib, colorOf(parentOf(x)));
1798                     setColor(parentOf(x), BLACK);
1799                     setColor(leftOf(sib), BLACK);
1800                     rotateRight(parentOf(x));
1801                     x = root;
1802                 }
1803             }
1804         }
1805 
1806         setColor(x, BLACK);
1807     }
1808 
1809     // private static final long serialVersionUID = 919286545866124006L;
1810 
1811     /**
1812      * Save the state of the {@code TreeMap} instance to a stream (i.e.,
1813      * serialize it).
1814      *
1815      * @serialData The <em>size</em> of the TreeMap (the number of key-value
1816      *             mappings) is emitted (int), followed by the key (Object)
1817      *             and value (Object) for each key-value mapping represented
1818      *             by the TreeMap. The key-value mappings are emitted in
1819      *             key-order (as determined by the TreeMap's Comparator,
1820      *             or by the keys' natural ordering if the TreeMap has no
1821      *             Comparator).
1822      */
1823     // private void writeObject(java.io.ObjectOutputStream s)
1824     //     throws java.io.IOException {
1825     //     // Write out the Comparator and any hidden stuff
1826     //     s.defaultWriteObject();
1827 
1828     //     // Write out size (number of Mappings)
1829     //     s.writeInt(size);
1830 
1831     //     // Write out keys and values (alternating)
1832     //     for (Iterator!(MapEntry!(K,V)) i = entrySet().iterator(); i.hasNext(); ) {
1833     //         MapEntry!(K,V) e = i.next();
1834     //         s.writeObject(e.getKey());
1835     //         s.writeObject(e.getValue());
1836     //     }
1837     // }
1838 
1839     /**
1840      * Reconstitute the {@code TreeMap} instance from a stream (i.e.,
1841      * deserialize it).
1842      */
1843     // private void readObject(final java.io.ObjectInputStream s)
1844     //     throws java.io.IOException, ClassNotFoundException {
1845     //     // Read in the Comparator and any hidden stuff
1846     //     s.defaultReadObject();
1847 
1848     //     // Read in size
1849     //     int size = s.readInt();
1850 
1851     //     buildFromSorted(size, null, s, null);
1852     // }
1853 
1854     /** Intended to be called only from TreeSet.readObject */
1855     // void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal) {
1856     //     buildFromSorted(size, null, s, defaultVal);
1857     // }
1858 
1859     /** Intended to be called only from TreeSet.addAll */
1860     // void addAllForTreeSet(SortedSet!K set, V defaultVal) {
1861     //     try {
1862     //         buildFromSorted(set.size(), set.iterator(), null, defaultVal);
1863     //     } catch (IOException cannotHappen) {
1864     //     } catch (ClassNotFoundException cannotHappen) {
1865     //     }
1866     // }
1867 
1868 
1869     /**
1870      * Linear time tree building algorithm from sorted data.  Can accept keys
1871      * and/or values from iterator or stream. This leads to too many
1872      * parameters, but seems better than alternatives.  The four formats
1873      * that this method accepts are:
1874      *
1875      *    1) An iterator of Map.Entries.  (it !is null, defaultVal is null).
1876      *    2) An iterator of keys.         (it !is null, defaultVal !is null).
1877      *    3) A stream of alternating serialized keys and values.
1878      *                                   (it is null, defaultVal is null).
1879      *    4) A stream of serialized keys. (it is null, defaultVal !is null).
1880      *
1881      * It is assumed that the comparator of the TreeMap is already set prior
1882      * to calling this method.
1883      *
1884      * @param size the number of keys (or key-value pairs) to be read from
1885      *        the iterator or stream
1886      * @param it If non-null, new entries are created from entries
1887      *        or keys read from this iterator.
1888      * @param str If non-null, new entries are created from keys and
1889      *        possibly values read from this stream in serialized form.
1890      *        Exactly one of it and str should be non-null.
1891      * @param defaultVal if non-null, this default value is used for
1892      *        each value in the map.  If null, each value is read from
1893      *        iterator or stream, as described above.
1894      * @throws java.io.IOException propagated from stream reads. This cannot
1895      *         occur if str is null.
1896      * @throws ClassNotFoundException propagated from readObject.
1897      *         This cannot occur if str is null.
1898      */
1899     // private void buildFromSorted(int size, Iterator<?> it,
1900     //                             //  java.io.ObjectInputStream str,
1901     //                              V defaultVal) {
1902     //     this._size = size;
1903     //     root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
1904     //                            it, defaultVal);
1905     // }
1906 
1907     /**
1908      * Recursive "helper method" that does the real work of the
1909      * previous method.  Identically named parameters have
1910      * identical definitions.  Additional parameters are documented below.
1911      * It is assumed that the comparator and size fields of the TreeMap are
1912      * already set prior to calling this method.  (It ignores both fields.)
1913      *
1914      * @param level the current level of tree. Initial call should be 0.
1915      * @param lo the first element index of this subtree. Initial should be 0.
1916      * @param hi the last element index of this subtree.  Initial should be
1917      *        size-1.
1918      * @param redLevel the level at which nodes should be red.
1919      *        Must be equal to computeRedLevel for tree of this size.
1920      */
1921     // private final TreeMapEntry!(K,V) buildFromSorted(int level, int lo, int hi,
1922     //                                          int redLevel,
1923     //                                          Iterator<?> it,
1924     //                                         //  java.io.ObjectInputStream str,
1925     //                                          V defaultVal) {
1926     //     /*
1927     //      * Strategy: The root is the middlemost element. To get to it, we
1928     //      * have to first recursively construct the entire left subtree,
1929     //      * so as to grab all of its elements. We can then proceed with right
1930     //      * subtree.
1931     //      *
1932     //      * The lo and hi arguments are the minimum and maximum
1933     //      * indices to pull out of the iterator or stream for current subtree.
1934     //      * They are not actually indexed, we just proceed sequentially,
1935     //      * ensuring that items are extracted in corresponding order.
1936     //      */
1937 
1938     //     if (hi < lo) return null;
1939 
1940     //     int mid = (lo + hi) >>> 1;
1941 
1942     //     TreeMapEntry!(K,V) left  = null;
1943     //     if (lo < mid)
1944     //         left = buildFromSorted(level+1, lo, mid - 1, redLevel,
1945     //                                it, str, defaultVal);
1946 
1947     //     // extract key and/or value from iterator or stream
1948     //     K key;
1949     //     V value;
1950     //     if (it !is null) {
1951     //         if (defaultVal is null) {
1952     //             MapEntry<?,?> entry = (MapEntry<?,?>)it.next();
1953     //             key = (K)entry.getKey();
1954     //             value = (V)entry.getValue();
1955     //         } else {
1956     //             key = (K)it.next();
1957     //             value = defaultVal;
1958     //         }
1959     //     } else { // use stream
1960     //         key = (K) str.readObject();
1961     //         value = (defaultVal !is null ? defaultVal : (V) str.readObject());
1962     //     }
1963 
1964     //     TreeMapEntry!(K,V) middle =  new Entry<>(key, value, null);
1965 
1966     //     // color nodes in non-full bottommost level red
1967     //     if (level == redLevel)
1968     //         middle.color = RED;
1969 
1970     //     if (left !is null) {
1971     //         middle.left = left;
1972     //         left.parent = middle;
1973     //     }
1974 
1975     //     if (mid < hi) {
1976     //         TreeMapEntry!(K,V) right = buildFromSorted(level+1, mid+1, hi, redLevel,
1977     //                                            it, str, defaultVal);
1978     //         middle.right = right;
1979     //         right.parent = middle;
1980     //     }
1981 
1982     //     return middle;
1983     // }
1984 
1985     /**
1986      * Find the level down to which to assign all nodes BLACK.  This is the
1987      * last `full' level of the complete binary tree produced by
1988      * buildTree. The remaining nodes are colored RED. (This makes a `nice'
1989      * set of color assignments wrt future insertions.) This level number is
1990      * computed by finding the number of splits needed to reach the zeroeth
1991      * node.  (The answer is ~lg(N), but in any case must be computed by same
1992      * quick O(lg(N)) loop.)
1993      */
1994     private static int computeRedLevel(int sz) {
1995         int level = 0;
1996         for (int m = sz - 1; m >= 0; m = m / 2 - 1)
1997             level++;
1998         return level;
1999     }
2000 
2001     /**
2002      * Currently, we support Spliterator-based versions only for the
2003      * full map, in either plain of descending form, otherwise relying
2004      * on defaults because size estimation for submaps would dominate
2005      * costs. The type tests needed to check these for key views are
2006      * not very nice but avoid disrupting existing class
2007      * structures. Callers must use plain default spliterators if this
2008      * returns null.
2009      */
2010     // static !K Spliterator!K keySpliteratorFor(NavigableMap<K,?> m) {
2011     //     if (m instanceof TreeMap) {
2012     //     TreeMap<K,Object> t =
2013     //             (TreeMap<K,Object>) m;
2014     //         return t.keySpliterator();
2015     //     }
2016     //     if (m instanceof DescendingSubMap) {
2017     //     DescendingSubMap<K,?> dm =
2018     //             (DescendingSubMap<K,?>) m;
2019     //         TreeMap<K,?> tm = dm.m;
2020     //         if (dm == tm.descendingMap) {
2021     //         TreeMap<K,Object> t =
2022     //                 (TreeMap<K,Object>) tm;
2023     //             return t.descendingKeySpliterator();
2024     //         }
2025     //     }
2026     // NavigableSubMap<K,?> sm =
2027     //         (NavigableSubMap<K,?>) m;
2028     //     return sm.keySpliterator();
2029     // }
2030 
2031     // final Spliterator!K keySpliterator() {
2032     //     return new KeySpliterator!(K,V)(this, null, null, 0, -1, 0);
2033     // }
2034 
2035     // final Spliterator!K descendingKeySpliterator() {
2036     //     return new DescendingKeySpliterator!(K,V)(this, null, null, 0, -2, 0);
2037     // }
2038 
2039     /**
2040      * Base class for spliterators.  Iteration starts at a given
2041      * origin and continues up to but not including a given fence (or
2042      * null for end).  At top-level, for ascending cases, the first
2043      * split uses the root as left-fence/right-origin. From there,
2044      * right-hand splits replace the current fence with its left
2045      * child, also serving as origin for the split-off spliterator.
2046      * Left-hands are symmetric. Descending versions place the origin
2047      * at the end and invert ascending split rules.  This base class
2048      * is non-commital about directionality, or whether the top-level
2049      * spliterator covers the whole tree. This means that the actual
2050      * split mechanics are located in subclasses. Some of the subclass
2051      * trySplit methods are identical (except for return types), but
2052      * not nicely factorable.
2053      *
2054      * Currently, subclass versions exist only for the full map
2055      * (including descending keys via its descendingMap).  Others are
2056      * possible but currently not worthwhile because submaps require
2057      * O(n) computations to determine size, which substantially limits
2058      * potential speed-ups of using custom Spliterators versus default
2059      * mechanics.
2060      *
2061      * To boostrap initialization, external constructors use
2062      * negative size estimates: -1 for ascend, -2 for descend.
2063      */
2064     // static class TreeMapSpliterator!(K,V) {
2065     //     final TreeMap!(K,V) tree;
2066     //     TreeMapEntry!(K,V) current; // traverser; initially first node in range
2067     //     TreeMapEntry!(K,V) fence;   // one past last, or null
2068     //     int side;                   // 0: top, -1: is a left split, +1: right
2069     //     int est;                    // size estimate (exact only for top-level)
2070     //     int expectedModCount;       // for CME checks
2071 
2072     //     TreeMapSpliterator(TreeMap!(K,V) tree,
2073     //                        TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence,
2074     //                        int side, int est, int expectedModCount) {
2075     //         this.tree = tree;
2076     //         this.current = origin;
2077     //         this.fence = fence;
2078     //         this.side = side;
2079     //         this.est = est;
2080     //         this.expectedModCount = expectedModCount;
2081     //     }
2082 
2083     //     final int getEstimate() { // force initialization
2084     //         int s; TreeMap!(K,V) t;
2085     //         if ((s = est) < 0) {
2086     //             if ((t = tree) !is null) {
2087     //                 current = (s == -1) ? t.getFirstEntry() : t.getLastEntry();
2088     //                 s = est = t.size;
2089     //                 expectedModCount = t.modCount;
2090     //             }
2091     //             else
2092     //                 s = est = 0;
2093     //         }
2094     //         return s;
2095     //     }
2096 
2097     //     final long estimateSize() {
2098     //         return (long)getEstimate();
2099     //     }
2100     // }
2101 
2102     // static final class KeySpliterator!(K,V)
2103     //     : TreeMapSpliterator!(K,V)
2104     //     , Spliterator!K {
2105     //     KeySpliterator(TreeMap!(K,V) tree,
2106     //                    TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence,
2107     //                    int side, int est, int expectedModCount) {
2108     //         super(tree, origin, fence, side, est, expectedModCount);
2109     //     }
2110 
2111     //     KeySpliterator!(K,V) trySplit() {
2112     //         if (est < 0)
2113     //             getEstimate(); // force initialization
2114     //         int d = side;
2115     //         TreeMapEntry!(K,V) e = current, f = fence,
2116     //             s = ((e is null || e == f) ? null :      // empty
2117     //                  (d == 0)              ? tree.root : // was top
2118     //                  (d >  0)              ? e.right :   // was right
2119     //                  (d <  0 && f !is null) ? f.left :    // was left
2120     //                  null);
2121     //         if (s !is null && s  !is  e && s  !is  f &&
2122     //             tree.compare(e.key, s.key) < 0) {        // e not already past s
2123     //             side = 1;
2124     //             return new KeySpliterator<>
2125     //                 (tree, e, current = s, -1, est >>>= 1, expectedModCount);
2126     //         }
2127     //         return null;
2128     //     }
2129 
2130     //     void forEachRemaining(Consumer!K action) {
2131     //         if (action is null)
2132     //             throw new NullPointerException();
2133     //         if (est < 0)
2134     //             getEstimate(); // force initialization
2135     //         TreeMapEntry!(K,V) f = fence, e, p, pl;
2136     //         if ((e = current) !is null && e  !is  f) {
2137     //             current = f; // exhaust
2138     //             do {
2139     //                 action.accept(e.key);
2140     //                 if ((p = e.right) !is null) {
2141     //                     while ((pl = p.left) !is null)
2142     //                         p = pl;
2143     //                 }
2144     //                 else {
2145     //                     while ((p = e.parent) !is null && e == p.right)
2146     //                         e = p;
2147     //                 }
2148     //             } while ((e = p) !is null && e  !is  f);
2149     //             if (tree.modCount  !is  expectedModCount)
2150     //                 throw new ConcurrentModificationException();
2151     //         }
2152     //     }
2153 
2154     //     bool tryAdvance(Consumer!K action) {
2155     //         TreeMapEntry!(K,V) e;
2156     //         if (action is null)
2157     //             throw new NullPointerException();
2158     //         if (est < 0)
2159     //             getEstimate(); // force initialization
2160     //         if ((e = current) is null || e == fence)
2161     //             return false;
2162     //         current = successor(e);
2163     //         action.accept(e.key);
2164     //         if (tree.modCount  !is  expectedModCount)
2165     //             throw new ConcurrentModificationException();
2166     //         return true;
2167     //     }
2168 
2169     //     int characteristics() {
2170     //         return (side == 0 ? Spliterator.SIZED : 0) |
2171     //             Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
2172     //     }
2173 
2174     //     final Comparator!K  getComparator() {
2175     //         return tree.comparator;
2176     //     }
2177 
2178     // }
2179 
2180     // static final class DescendingKeySpliterator!(K,V)
2181     //     : TreeMapSpliterator!(K,V)
2182     //     , Spliterator!K {
2183     //     DescendingKeySpliterator(TreeMap!(K,V) tree,
2184     //                              TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence,
2185     //                              int side, int est, int expectedModCount) {
2186     //         super(tree, origin, fence, side, est, expectedModCount);
2187     //     }
2188 
2189     //     DescendingKeySpliterator!(K,V) trySplit() {
2190     //         if (est < 0)
2191     //             getEstimate(); // force initialization
2192     //         int d = side;
2193     //         TreeMapEntry!(K,V) e = current, f = fence,
2194     //                 s = ((e is null || e == f) ? null :      // empty
2195     //                      (d == 0)              ? tree.root : // was top
2196     //                      (d <  0)              ? e.left :    // was left
2197     //                      (d >  0 && f !is null) ? f.right :   // was right
2198     //                      null);
2199     //         if (s !is null && s  !is  e && s  !is  f &&
2200     //             tree.compare(e.key, s.key) > 0) {       // e not already past s
2201     //             side = 1;
2202     //             return new DescendingKeySpliterator<>
2203     //                     (tree, e, current = s, -1, est >>>= 1, expectedModCount);
2204     //         }
2205     //         return null;
2206     //     }
2207 
2208     //     void forEachRemaining(Consumer!K action) {
2209     //         if (action is null)
2210     //             throw new NullPointerException();
2211     //         if (est < 0)
2212     //             getEstimate(); // force initialization
2213     //         TreeMapEntry!(K,V) f = fence, e, p, pr;
2214     //         if ((e = current) !is null && e  !is  f) {
2215     //             current = f; // exhaust
2216     //             do {
2217     //                 action.accept(e.key);
2218     //                 if ((p = e.left) !is null) {
2219     //                     while ((pr = p.right) !is null)
2220     //                         p = pr;
2221     //                 }
2222     //                 else {
2223     //                     while ((p = e.parent) !is null && e == p.left)
2224     //                         e = p;
2225     //                 }
2226     //             } while ((e = p) !is null && e  !is  f);
2227     //             if (tree.modCount  !is  expectedModCount)
2228     //                 throw new ConcurrentModificationException();
2229     //         }
2230     //     }
2231 
2232     //     bool tryAdvance(Consumer!K action) {
2233     //         TreeMapEntry!(K,V) e;
2234     //         if (action is null)
2235     //             throw new NullPointerException();
2236     //         if (est < 0)
2237     //             getEstimate(); // force initialization
2238     //         if ((e = current) is null || e == fence)
2239     //             return false;
2240     //         current = predecessor(e);
2241     //         action.accept(e.key);
2242     //         if (tree.modCount  !is  expectedModCount)
2243     //             throw new ConcurrentModificationException();
2244     //         return true;
2245     //     }
2246 
2247     //     int characteristics() {
2248     //         return (side == 0 ? Spliterator.SIZED : 0) |
2249     //             Spliterator.DISTINCT | Spliterator.ORDERED;
2250     //     }
2251     // }
2252 
2253     // static final class ValueSpliterator!(K,V)
2254     //         : TreeMapSpliterator!(K,V)
2255     //         , Spliterator!V {
2256     //     ValueSpliterator(TreeMap!(K,V) tree,
2257     //                      TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence,
2258     //                      int side, int est, int expectedModCount) {
2259     //         super(tree, origin, fence, side, est, expectedModCount);
2260     //     }
2261 
2262     //     ValueSpliterator!(K,V) trySplit() {
2263     //         if (est < 0)
2264     //             getEstimate(); // force initialization
2265     //         int d = side;
2266     //         TreeMapEntry!(K,V) e = current, f = fence,
2267     //                 s = ((e is null || e == f) ? null :      // empty
2268     //                      (d == 0)              ? tree.root : // was top
2269     //                      (d >  0)              ? e.right :   // was right
2270     //                      (d <  0 && f !is null) ? f.left :    // was left
2271     //                      null);
2272     //         if (s !is null && s  !is  e && s  !is  f &&
2273     //             tree.compare(e.key, s.key) < 0) {        // e not already past s
2274     //             side = 1;
2275     //             return new ValueSpliterator<>
2276     //                     (tree, e, current = s, -1, est >>>= 1, expectedModCount);
2277     //         }
2278     //         return null;
2279     //     }
2280 
2281     //     void forEachRemaining(Consumer<V> action) {
2282     //         if (action is null)
2283     //             throw new NullPointerException();
2284     //         if (est < 0)
2285     //             getEstimate(); // force initialization
2286     //         TreeMapEntry!(K,V) f = fence, e, p, pl;
2287     //         if ((e = current) !is null && e  !is  f) {
2288     //             current = f; // exhaust
2289     //             do {
2290     //                 action.accept(e.value);
2291     //                 if ((p = e.right) !is null) {
2292     //                     while ((pl = p.left) !is null)
2293     //                         p = pl;
2294     //                 }
2295     //                 else {
2296     //                     while ((p = e.parent) !is null && e == p.right)
2297     //                         e = p;
2298     //                 }
2299     //             } while ((e = p) !is null && e  !is  f);
2300     //             if (tree.modCount  !is  expectedModCount)
2301     //                 throw new ConcurrentModificationException();
2302     //         }
2303     //     }
2304 
2305     //     bool tryAdvance(Consumer<V> action) {
2306     //         TreeMapEntry!(K,V) e;
2307     //         if (action is null)
2308     //             throw new NullPointerException();
2309     //         if (est < 0)
2310     //             getEstimate(); // force initialization
2311     //         if ((e = current) is null || e == fence)
2312     //             return false;
2313     //         current = successor(e);
2314     //         action.accept(e.value);
2315     //         if (tree.modCount  !is  expectedModCount)
2316     //             throw new ConcurrentModificationException();
2317     //         return true;
2318     //     }
2319 
2320     //     int characteristics() {
2321     //         return (side == 0 ? Spliterator.SIZED : 0) | Spliterator.ORDERED;
2322     //     }
2323     // }
2324 
2325     // static final class EntrySpliterator!(K,V)
2326     //     : TreeMapSpliterator!(K,V)
2327     //     , Spliterator!(MapEntry!(K,V)) {
2328     //     EntrySpliterator(TreeMap!(K,V) tree,
2329     //                      TreeMapEntry!(K,V) origin, TreeMapEntry!(K,V) fence,
2330     //                      int side, int est, int expectedModCount) {
2331     //         super(tree, origin, fence, side, est, expectedModCount);
2332     //     }
2333 
2334     //     EntrySpliterator!(K,V) trySplit() {
2335     //         if (est < 0)
2336     //             getEstimate(); // force initialization
2337     //         int d = side;
2338     //         TreeMapEntry!(K,V) e = current, f = fence,
2339     //                 s = ((e is null || e == f) ? null :      // empty
2340     //                      (d == 0)              ? tree.root : // was top
2341     //                      (d >  0)              ? e.right :   // was right
2342     //                      (d <  0 && f !is null) ? f.left :    // was left
2343     //                      null);
2344     //         if (s !is null && s  !is  e && s  !is  f &&
2345     //             tree.compare(e.key, s.key) < 0) {        // e not already past s
2346     //             side = 1;
2347     //             return new EntrySpliterator<>
2348     //                     (tree, e, current = s, -1, est >>>= 1, expectedModCount);
2349     //         }
2350     //         return null;
2351     //     }
2352 
2353     //     void forEachRemaining(Consumer<MapEntry!(K, V)> action) {
2354     //         if (action is null)
2355     //             throw new NullPointerException();
2356     //         if (est < 0)
2357     //             getEstimate(); // force initialization
2358     //         TreeMapEntry!(K,V) f = fence, e, p, pl;
2359     //         if ((e = current) !is null && e  !is  f) {
2360     //             current = f; // exhaust
2361     //             do {
2362     //                 action.accept(e);
2363     //                 if ((p = e.right) !is null) {
2364     //                     while ((pl = p.left) !is null)
2365     //                         p = pl;
2366     //                 }
2367     //                 else {
2368     //                     while ((p = e.parent) !is null && e == p.right)
2369     //                         e = p;
2370     //                 }
2371     //             } while ((e = p) !is null && e  !is  f);
2372     //             if (tree.modCount  !is  expectedModCount)
2373     //                 throw new ConcurrentModificationException();
2374     //         }
2375     //     }
2376 
2377     //     bool tryAdvance(Consumer<MapEntry!(K,V)> action) {
2378     //         TreeMapEntry!(K,V) e;
2379     //         if (action is null)
2380     //             throw new NullPointerException();
2381     //         if (est < 0)
2382     //             getEstimate(); // force initialization
2383     //         if ((e = current) is null || e == fence)
2384     //             return false;
2385     //         current = successor(e);
2386     //         action.accept(e);
2387     //         if (tree.modCount  !is  expectedModCount)
2388     //             throw new ConcurrentModificationException();
2389     //         return true;
2390     //     }
2391 
2392     //     int characteristics() {
2393     //         return (side == 0 ? Spliterator.SIZED : 0) |
2394     //                 Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
2395     //     }
2396 
2397     //     override
2398     //     Comparator<MapEntry!(K, V)> getComparator() {
2399     //         // Adapt or create a key-based comparator
2400     //         if (tree.comparator !is null) {
2401     //             return MapEntry.comparingByKey(tree.comparator);
2402     //         }
2403     //         else {
2404     //             return (Comparator<MapEntry!(K, V)> & Serializable) (e1, e2) -> {
2405     //             
2406     //                 Comparable!K k1 = (Comparable!K) e1.getKey();
2407     //                 return k1.compareTo(e2.getKey());
2408     //             };
2409     //         }
2410     //     }
2411     // }
2412 
2413         override bool opEquals(IObject o) {
2414             return opEquals(cast(Object) o);
2415         }
2416         
2417         override bool opEquals(Object o) {
2418             return super.opEquals(o);
2419         }
2420 
2421         override size_t toHash() @trusted nothrow {
2422             return super.toHash();
2423         }
2424 
2425         override string toString() {
2426             return super.toString();
2427         }    
2428 }
2429 
2430 
2431 /**
2432 * Node in the Tree.  Doubles as a means to pass key-value pairs back to
2433 * user (see MapEntry).
2434 */
2435 
2436 static final class TreeMapEntry(K,V) : MapEntry!(K,V) {
2437     K key;
2438     V value;
2439     TreeMapEntry!(K,V) left;
2440     TreeMapEntry!(K,V) right;
2441     TreeMapEntry!(K,V) parent;
2442     bool color = BLACK;
2443 
2444     /**
2445         * Make a new cell with given key, value, and parent, and with
2446         * {@code null} child links, and BLACK color.
2447         */
2448     this(K key, V value, TreeMapEntry!(K,V) parent) {
2449         this.key = key;
2450         this.value = value;
2451         this.parent = parent;
2452     }
2453 
2454     /**
2455         * Returns the key.
2456         *
2457         * @return the key
2458         */
2459     K getKey() {
2460         return key;
2461     }
2462 
2463     /**
2464         * Returns the value associated with the key.
2465         *
2466         * @return the value associated with the key
2467         */
2468     V getValue() {
2469         return value;
2470     }
2471 
2472     /**
2473         * Replaces the value currently associated with the key with the given
2474         * value.
2475         *
2476         * @return the value associated with the key before this method was
2477         *         called
2478         */
2479     V setValue(V value) {
2480         V oldValue = this.value;
2481         this.value = value;
2482         return oldValue;
2483     }
2484 
2485     bool opEquals(IObject o) {
2486         return opEquals(cast(Object) o);
2487     }
2488 
2489     override bool opEquals(Object o) {
2490         MapEntry!(K, V) e = cast(MapEntry!(K, V))o;
2491         if (e is null)
2492             return false;
2493 
2494         return key == e.getKey() && value == e.getValue();
2495     }
2496 
2497     override size_t toHash() @trusted nothrow {
2498         // int keyHash = (key is null ? 0 : key.hashCode());
2499         // int valueHash = (value is null ? 0 : value.hashCode());
2500         // return keyHash ^ valueHash;
2501         static if(is(K == class)) {
2502             size_t kHash = 0;
2503             if(key !is null) kHash = key.toHash();
2504         }
2505         else {
2506             size_t kHash = hashOf(key);
2507         }
2508         
2509         static if(is(V == class)) {
2510             size_t vHash = 0;
2511             if(value !is null) vHash = value.toHash();
2512         }
2513         else {
2514             size_t vHash = hashOf(value);
2515         }
2516 
2517         return kHash ^ vHash;
2518     }
2519 
2520     override string toString() {
2521         return key.to!string() ~ "=" ~ value.to!string();
2522     }
2523 }
2524 
2525 
2526 /**
2527  * @serial include
2528  */
2529 abstract static class NavigableSubMap(K,V) : AbstractMap!(K,V) , NavigableMap!(K,V) {
2530     /**
2531      * The backing map.
2532      */
2533     protected TreeMap!(K,V) m;
2534 
2535     /**
2536      * Endpoints are represented as triples (fromStart, lo,
2537      * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is
2538      * true, then the low (absolute) bound is the start of the
2539      * backing map, and the other values are ignored. Otherwise,
2540      * if loInclusive is true, lo is the inclusive bound, else lo
2541      * is the exclusive bound. Similarly for the upper bound.
2542      */
2543     K lo, hi;
2544     bool fromStart, toEnd;
2545     bool loInclusive, hiInclusive;
2546 
2547     int sizeModCount = 0;
2548 
2549     this(TreeMap!(K,V) m,
2550                     bool fromStart, K lo, bool loInclusive,
2551                     bool toEnd,     K hi, bool hiInclusive) {
2552         if (!fromStart && !toEnd) {
2553             if (compare(lo, hi) > 0)
2554                 throw new IllegalArgumentException("fromKey > toKey");
2555         } else {
2556             // if (!fromStart) // type check
2557             //     compare(lo, lo);
2558             // if (!toEnd)
2559             //     compare(hi, hi);
2560         }
2561 
2562         this.m = m;
2563         this.fromStart = fromStart;
2564         this.lo = lo;
2565         this.loInclusive = loInclusive;
2566         this.toEnd = toEnd;
2567         this.hi = hi;
2568         this.hiInclusive = hiInclusive;
2569 
2570         this._size = -1;
2571         // if(fromStart && toEnd)
2572         //     this._size = m.size();
2573         // else
2574         //     updateSize();
2575     }
2576 
2577     // internal utilities
2578 
2579     final bool tooLow(K key) {
2580         if (!fromStart) {
2581             int c = compare(key, lo);
2582             if (c < 0 || (c == 0 && !loInclusive))
2583                 return true;
2584         }
2585         return false;
2586     }
2587 
2588     final bool tooHigh(K key) {
2589         if (!toEnd) {
2590             int c = compare(key, hi);
2591             if (c > 0 || (c == 0 && !hiInclusive))
2592                 return true;
2593         }
2594         return false;
2595     }
2596 
2597     final bool inRange(K key) {
2598         return !tooLow(key) && !tooHigh(key);
2599     }
2600 
2601     final bool inClosedRange(K key) {
2602         return (fromStart || compare(key, lo) >= 0)
2603             && (toEnd || compare(hi, key) >= 0);
2604     }
2605 
2606     final bool inRange(K key, bool inclusive) {
2607         return inclusive ? inRange(key) : inClosedRange(key);
2608     }
2609 
2610     /*
2611      * Absolute versions of relation operations.
2612      * Subclasses map to these using like-named "sub"
2613      * versions that invert senses for descending maps
2614      */
2615 
2616     final TreeMapEntry!(K,V) absLowest() {
2617         TreeMapEntry!(K,V) e =
2618             (fromStart ?  m.getFirstEntry() :
2619              (loInclusive ? m.getCeilingEntry(lo) :
2620                             m.getHigherEntry(lo)));
2621         return (e is null || tooHigh(e.key)) ? null : e;
2622     }
2623 
2624     final TreeMapEntry!(K,V) absHighest() {
2625         TreeMapEntry!(K,V) e =
2626             (toEnd ?  m.getLastEntry() :
2627              (hiInclusive ?  m.getFloorEntry(hi) :
2628                              m.getLowerEntry(hi)));
2629         return (e is null || tooLow(e.key)) ? null : e;
2630     }
2631 
2632     final TreeMapEntry!(K,V) absCeiling(K key) {
2633         if (tooLow(key))
2634             return absLowest();
2635         TreeMapEntry!(K,V) e = m.getCeilingEntry(key);
2636         return (e is null || tooHigh(e.key)) ? null : e;
2637     }
2638 
2639     final TreeMapEntry!(K,V) absHigher(K key) {
2640         if (tooLow(key))
2641             return absLowest();
2642         TreeMapEntry!(K,V) e = m.getHigherEntry(key);
2643         return (e is null || tooHigh(e.key)) ? null : e;
2644     }
2645 
2646     final TreeMapEntry!(K,V) absFloor(K key) {
2647         if (tooHigh(key))
2648             return absHighest();
2649         TreeMapEntry!(K,V) e = m.getFloorEntry(key);
2650         return (e is null || tooLow(e.key)) ? null : e;
2651     }
2652 
2653     final TreeMapEntry!(K,V) absLower(K key) {
2654         if (tooHigh(key))
2655             return absHighest();
2656         TreeMapEntry!(K,V) e = m.getLowerEntry(key);
2657         return (e is null || tooLow(e.key)) ? null : e;
2658     }
2659 
2660     /** Returns the absolute high fence for ascending traversal */
2661     final TreeMapEntry!(K,V) absHighFence() {
2662         return (toEnd ? null : (hiInclusive ?
2663                                 m.getHigherEntry(hi) :
2664                                 m.getCeilingEntry(hi)));
2665     }
2666 
2667     /** Return the absolute low fence for descending traversal  */
2668     final TreeMapEntry!(K,V) absLowFence() {
2669         return (fromStart ? null : (loInclusive ?
2670                                     m.getLowerEntry(lo) :
2671                                     m.getFloorEntry(lo)));
2672     }
2673 
2674     // Abstract methods defined in ascending vs descending classes
2675     // These relay to the appropriate absolute versions
2676 
2677     abstract TreeMapEntry!(K,V) subLowest();
2678     abstract TreeMapEntry!(K,V) subHighest();
2679     abstract TreeMapEntry!(K,V) subCeiling(K key);
2680     abstract TreeMapEntry!(K,V) subHigher(K key);
2681     abstract TreeMapEntry!(K,V) subFloor(K key);
2682     abstract TreeMapEntry!(K,V) subLower(K key);
2683 
2684     /** Returns ascending iterator from the perspective of this submap */
2685     // abstract Iterator!K keyIterator();
2686 
2687     // abstract Spliterator!K keySpliterator();
2688 
2689     /** Returns descending iterator from the perspective of this submap */
2690     // abstract Iterator!K descendingKeyIterator();
2691 
2692 
2693     // methods
2694     override bool opEquals(IObject o) {
2695         return opEquals(cast(Object) o);
2696     }
2697     
2698     override bool opEquals(Object o) {
2699         return super.opEquals(o);
2700     }
2701 
2702     override size_t toHash() @trusted nothrow {
2703         return super.toHash();
2704     }
2705 
2706     override string toString() {
2707         return super.toString();
2708     }    
2709 
2710     override bool isEmpty() {
2711         if(fromStart && toEnd)
2712             return m.isEmpty();
2713         else {
2714             TreeMapEntry!(K,V) n = absLowest();
2715             return n is null || tooHigh(n.key);
2716         }
2717     }
2718 
2719     override int size() { 
2720         if(fromStart && toEnd)
2721             return m.size();
2722         if(_size == -1 || sizeModCount != m.modCount)
2723             updateSize();
2724         return _size;
2725     }
2726 
2727     private void updateSize() {
2728         int s = 0;
2729         foreach(item; this) {
2730             s++;
2731         }
2732         _size = s;
2733     }
2734 
2735     final override bool containsKey(K key) {
2736         return inRange(key) && m.containsKey(key);
2737     }
2738 
2739     final override V put(K key, V value) {
2740         if (!inRange(key))
2741             throw new IllegalArgumentException("key out of range");
2742         // _size++;
2743         return m.put(key, value);
2744     }
2745 
2746     final override V get(K key) {
2747         return !inRange(key) ? null :  m.get(key);
2748     }
2749 
2750     final override V remove(K key) {
2751         // _size--;
2752         return !inRange(key) ? null : m.remove(key);
2753     }
2754 
2755     final MapEntry!(K,V) ceilingEntry(K key) {
2756         return exportEntry!(K,V)(subCeiling(key));
2757     }
2758 
2759     final K ceilingKey(K key) {
2760         return keyOrNull(subCeiling(key));
2761     }
2762 
2763     final MapEntry!(K,V) higherEntry(K key) {
2764         return exportEntry!(K,V)(subHigher(key));
2765     }
2766 
2767     final K higherKey(K key) {
2768         return keyOrNull(subHigher(key));
2769     }
2770 
2771     final MapEntry!(K,V) floorEntry(K key) {
2772         return exportEntry!(K,V)(subFloor(key));
2773     }
2774 
2775     final K floorKey(K key) {
2776         return keyOrNull(subFloor(key));
2777     }
2778 
2779     final MapEntry!(K,V) lowerEntry(K key) {
2780         return exportEntry!(K,V)(subLower(key));
2781     }
2782 
2783     final K lowerKey(K key) {
2784         return keyOrNull(subLower(key));
2785     }
2786 
2787     final K firstKey() {
2788         return key(subLowest());
2789     }
2790 
2791     final K lastKey() {
2792         return key(subHighest());
2793     }
2794 
2795     final MapEntry!(K,V) firstEntry() {
2796         return exportEntry!(K,V)(subLowest());
2797     }
2798 
2799     final MapEntry!(K,V) lastEntry() {
2800         return exportEntry!(K,V)(subHighest());
2801     }
2802 
2803     final MapEntry!(K,V) pollFirstEntry() {
2804         TreeMapEntry!(K,V) e = subLowest();
2805         MapEntry!(K,V) result = exportEntry!(K,V)(e);
2806         if (e !is null)
2807             m.deleteEntry(e);
2808         return result;
2809     }
2810 
2811     final MapEntry!(K,V) pollLastEntry() {
2812         TreeMapEntry!(K,V) e = subHighest();
2813         MapEntry!(K,V) result = exportEntry!(K,V)(e);
2814         if (e !is null)
2815             m.deleteEntry(e);
2816         return result;
2817     }
2818 
2819     // Views
2820     // NavigableMap!(K,V) descendingMapView;
2821     // EntrySetView entrySetView;
2822     // KeySet!(K, V) navigableKeySetView;
2823 
2824     // final NavigableSet!K navigableKeySet() {
2825     //     KeySet!(K, V) nksv = navigableKeySetView;
2826     //     return (nksv !is null) ? nksv :
2827     //         (navigableKeySetView = new TreeMap.KeySet!(K, V)(this));
2828     // }
2829 
2830     // final Set!K keySet() {
2831     //     return navigableKeySet();
2832     // }
2833 
2834     // NavigableSet!K descendingKeySet() {
2835     //     return descendingMap().navigableKeySet();
2836     // }
2837 
2838     alias subMap = NavigableMap!(K,V).subMap;
2839     alias headMap = NavigableMap!(K,V).headMap;
2840     alias tailMap = NavigableMap!(K,V).tailMap;
2841 
2842     final SortedMap!(K,V) subMap(K fromKey, K toKey) {
2843         return subMap(fromKey, true, toKey, false);
2844     }
2845 
2846     final SortedMap!(K,V) headMap(K toKey) {
2847         return headMap(toKey, false);
2848     }
2849 
2850     final SortedMap!(K,V) tailMap(K fromKey) {
2851         return tailMap(fromKey, true);
2852     }
2853 
2854     // View classes
2855 
2856     // abstract class EntrySetView : AbstractSet!(MapEntry!(K,V)) {
2857     //     private int _size = -1, sizeModCount;
2858 
2859     //     override int size() {
2860     //         if (fromStart && toEnd)
2861     //             return m.size();
2862     //         // if (_size == -1 || sizeModCount  !is  m.modCount) {
2863     //         //     sizeModCount = m.modCount;
2864     //         //     _size = 0;
2865     //         //     Iterator!K i = iterator();
2866     //         //     while (i.hasNext()) {
2867     //         //         _size++;
2868     //         //         i.next();
2869     //         //     }
2870     //         // }
2871     //         implementationMissing();
2872     //         return _size;
2873     //     }
2874 
2875     //     override bool isEmpty() {
2876     //         TreeMapEntry!(K,V) n = absLowest();
2877     //         return n is null || tooHigh(n.key);
2878     //     }
2879 
2880     //     override bool contains(MapEntry!(K,V) entry) {
2881     //         // MapEntry!(K,V) entry = cast(MapEntry!(K,V)) o;
2882     //         // if (!(o instanceof MapEntry))
2883     //         //     return false;
2884     //         K key = entry.getKey();
2885     //         if (!inRange(key))
2886     //             return false;
2887     //         TreeMapEntry!(K,V) node = m.getEntry(key);
2888     //         return node !is null &&
2889     //             valEquals(node.getValue(), entry.getValue());
2890     //     }
2891 
2892     //     bool remove(MapEntry!(K,V) entry) {
2893     //         // if (!(o instanceof MapEntry))
2894     //         //     return false;
2895     //         // MapEntry<?,?> entry = (MapEntry<?,?>) o;
2896     //         K key = entry.getKey();
2897     //         if (!inRange(key))
2898     //             return false;
2899     //         TreeMapEntry!(K,V) node = m.getEntry(key);
2900     //         if (node !is null && valEquals(node.getValue(),
2901     //                                     entry.getValue())) {
2902     //             m.deleteEntry(node);
2903     //             return true;
2904     //         }
2905     //         return false;
2906     //     }
2907     // }
2908 
2909 
2910     /**
2911      * Iterators for SubMaps
2912      */
2913 
2914     // see also: SubMapIterator
2915     mixin template SubMapInputRange() {
2916         TreeMapEntry!(K,V) lastReturned;
2917         TreeMapEntry!(K,V) next;
2918         K fenceKey;
2919         int expectedModCount;
2920 
2921         this(TreeMapEntry!(K,V) first,
2922                        TreeMapEntry!(K,V) fence) {
2923             expectedModCount = m.modCount;
2924             lastReturned = null;
2925             next = first;
2926             fenceKey = fence is null ? K.init : fence.key;
2927         }
2928 
2929         final bool empty() {
2930             return next is null || next.key == fenceKey;
2931         }
2932 
2933         final void popFront() {
2934             TreeMapEntry!(K,V) e = next;
2935             if (e is null || e.key == fenceKey) {
2936                 throw new NoSuchElementException();
2937             }
2938             
2939             next = successor(e);
2940             lastReturned = e;
2941             // return e;
2942         }
2943     }
2944 
2945     final class KeyInputRange :  InputRange!K {
2946         mixin SubMapInputRange;
2947 
2948         final K front() @property { return next.key; }
2949 
2950         final K moveFront() @property { throw new NotSupportedException(); }
2951         
2952         int opApply(scope int delegate(K) dg) {
2953             if(dg is null)
2954                 throw new NullPointerException();
2955 
2956             int result = 0;
2957             while(!empty()) {
2958                 result = dg(next.key);
2959                 // popFront();
2960                 if(result != 0) return result;
2961                 next = successor(next);
2962             }
2963 
2964             if (m.modCount  !=  expectedModCount)
2965                 throw new ConcurrentModificationException();
2966             return result;
2967         }
2968 
2969         int opApply(scope int delegate(size_t, K) dg) {
2970             if(dg is null)
2971                 throw new NullPointerException();
2972 
2973             int result = 0;
2974             size_t index = 0;
2975             while(!empty()) {
2976                 result = dg(index++, next.key);
2977                 if(result != 0) return result;
2978                 next = successor(next);
2979             }
2980 
2981             if (m.modCount  !=  expectedModCount)
2982                 throw new ConcurrentModificationException();
2983 
2984             return result;
2985         }
2986     }
2987 
2988     final class ValueInputRange :  InputRange!V {
2989         mixin SubMapInputRange;
2990 
2991         final V front() @property { return next.value; }
2992 
2993         final V moveFront() @property { throw new NotSupportedException(); }
2994         
2995         int opApply(scope int delegate(V) dg) {
2996             if(dg is null)
2997                 throw new NullPointerException();
2998 
2999             int result = 0;
3000             while(!empty()) {
3001                 result = dg(next.value);
3002                 if(result != 0) return result;
3003                 next = successor(next);
3004             }
3005 
3006             if (m.modCount  !=  expectedModCount)
3007                 throw new ConcurrentModificationException();
3008             return result;
3009         }
3010 
3011         int opApply(scope int delegate(size_t, V) dg) {
3012             if(dg is null)
3013                 throw new NullPointerException();
3014 
3015             int result = 0;
3016             size_t index = 0;
3017             while(!empty()) {
3018                 result = dg(index++, next.value);
3019                 if(result != 0) return result;
3020                 next = successor(next);
3021             }
3022 
3023             if (m.modCount  !=  expectedModCount)
3024                 throw new ConcurrentModificationException();
3025 
3026             return result;
3027         }
3028     }
3029 
3030 
3031     abstract class SubMapIterator(T) : Iterator!T {
3032         TreeMapEntry!(K,V) lastReturned;
3033         TreeMapEntry!(K,V) next;
3034         K fenceKey;
3035         int expectedModCount;
3036 
3037         this(TreeMapEntry!(K,V) first,
3038                        TreeMapEntry!(K,V) fence) {
3039             expectedModCount = m.modCount;
3040             lastReturned = null;
3041             next = first;
3042             fenceKey = fence is null ? K.init : fence.key;
3043         }
3044 
3045         final bool hasNext() {
3046             return next !is null && next.key  !is  fenceKey;
3047         }
3048 
3049         final TreeMapEntry!(K,V) nextEntry() {
3050             TreeMapEntry!(K,V) e = next;
3051             if (e is null || e.key == fenceKey)
3052                 throw new NoSuchElementException();
3053             if (m.modCount  !is  expectedModCount)
3054                 throw new ConcurrentModificationException();
3055             next = successor(e);
3056             lastReturned = e;
3057             return e;
3058         }
3059 
3060         final TreeMapEntry!(K,V) prevEntry() {
3061             TreeMapEntry!(K,V) e = next;
3062             if (e is null || e.key == fenceKey)
3063                 throw new NoSuchElementException();
3064             if (m.modCount  !is  expectedModCount)
3065                 throw new ConcurrentModificationException();
3066             next = predecessor(e);
3067             lastReturned = e;
3068             return e;
3069         }
3070 
3071         final void removeAscending() {
3072             if (lastReturned is null)
3073                 throw new IllegalStateException();
3074             if (m.modCount  !is  expectedModCount)
3075                 throw new ConcurrentModificationException();
3076             // deleted entries are replaced by their successors
3077             if (lastReturned.left !is null && lastReturned.right !is null)
3078                 next = lastReturned;
3079             m.deleteEntry(lastReturned);
3080             lastReturned = null;
3081             expectedModCount = m.modCount;
3082         }
3083 
3084         final void removeDescending() {
3085             if (lastReturned is null)
3086                 throw new IllegalStateException();
3087             if (m.modCount  !is  expectedModCount)
3088                 throw new ConcurrentModificationException();
3089             m.deleteEntry(lastReturned);
3090             lastReturned = null;
3091             expectedModCount = m.modCount;
3092         }
3093 
3094     }
3095 
3096     final class SubMapEntryIterator : SubMapIterator!(MapEntry!(K,V)) {
3097         this(TreeMapEntry!(K,V) first,
3098                             TreeMapEntry!(K,V) fence) {
3099             super(first, fence);
3100         }
3101         MapEntry!(K,V) next() {
3102             return nextEntry();
3103         }
3104         void remove() {
3105             removeAscending();
3106         }
3107     }
3108 
3109     final class DescendingSubMapEntryIterator : SubMapIterator!(MapEntry!(K,V)) {
3110         this(TreeMapEntry!(K,V) last, TreeMapEntry!(K,V) fence) {
3111             super(last, fence);
3112         }
3113 
3114         MapEntry!(K,V) next() {
3115             return prevEntry();
3116         }
3117         void remove() {
3118             removeDescending();
3119         }
3120     }
3121 
3122     // Implement minimal Spliterator as KeySpliterator backup
3123     final class SubMapKeyIterator : SubMapIterator!K { // , Spliterator!K
3124         this(TreeMapEntry!(K,V) first,
3125                           TreeMapEntry!(K,V) fence) {
3126             super(first, fence);
3127         }
3128         K next() {
3129             return nextEntry().key;
3130         }
3131         void remove() {
3132             removeAscending();
3133         }
3134         Spliterator!K trySplit() {
3135             return null;
3136         }
3137         void forEachRemaining(Consumer!K action) {
3138             while (hasNext())
3139                 action(next());
3140         }
3141         bool tryAdvance(Consumer!K action) {
3142             if (hasNext()) {
3143                 action(next());
3144                 return true;
3145             }
3146             return false;
3147         }
3148         long estimateSize() {
3149             return long.max;
3150         }
3151         int characteristics() {
3152             return SpliteratorCharacteristic.DISTINCT | SpliteratorCharacteristic.ORDERED |
3153                 SpliteratorCharacteristic.SORTED;
3154         }
3155         final Comparator!K  getComparator() {
3156             return this.outer.comparator();
3157         }
3158     }
3159 
3160     final class DescendingSubMapKeyIterator : SubMapIterator!K { // , Spliterator!K
3161         this(TreeMapEntry!(K,V) last,
3162                                     TreeMapEntry!(K,V) fence) {
3163             super(last, fence);
3164         }
3165         K next() {
3166             return prevEntry().key;
3167         }
3168         void remove() {
3169             removeDescending();
3170         }
3171         Spliterator!K trySplit() {
3172             return null;
3173         }
3174         void forEachRemaining(Consumer!K action) {
3175             while (hasNext())
3176                 action(next());
3177         }
3178         bool tryAdvance(Consumer!K action) {
3179             if (hasNext()) {
3180                 action(next());
3181                 return true;
3182             }
3183             return false;
3184         }
3185         long estimateSize() {
3186             return long.max;
3187         }
3188         // int characteristics() {
3189         //     return Spliterator.DISTINCT | Spliterator.ORDERED;
3190         // }
3191     }
3192 
3193     
3194 }
3195 
3196 /**
3197  * @serial include
3198  */
3199 final class AscendingSubMap(K,V) : NavigableSubMap!(K,V) {
3200     // private static final long serialVersionUID = 912986545866124060L;
3201 
3202     this(TreeMap!(K,V) m,
3203                     bool fromStart, K lo, bool loInclusive,
3204                     bool toEnd,     K hi, bool hiInclusive) {
3205         super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
3206     }
3207 
3208     Comparator!K comparator() {
3209         return m.comparator();
3210     }
3211 
3212     NavigableMap!(K,V) subMap(K fromKey, bool fromInclusive,
3213                                     K toKey,   bool toInclusive) {
3214         if (!inRange(fromKey, fromInclusive))
3215             throw new IllegalArgumentException("fromKey out of range");
3216         if (!inRange(toKey, toInclusive))
3217             throw new IllegalArgumentException("toKey out of range");
3218         return new AscendingSubMap!(K,V)(m,
3219                                      false, fromKey, fromInclusive,
3220                                      false, toKey,   toInclusive);
3221     }
3222 
3223     NavigableMap!(K,V) headMap(K toKey, bool inclusive) {
3224         if (!inRange(toKey, inclusive))
3225             throw new IllegalArgumentException("toKey out of range");
3226         return new AscendingSubMap!(K,V)(m,
3227                                      fromStart, lo,    loInclusive,
3228                                      false,     toKey, inclusive);
3229     }
3230 
3231     NavigableMap!(K,V) tailMap(K fromKey, bool inclusive) {
3232         if (!inRange(fromKey, inclusive))
3233             throw new IllegalArgumentException("fromKey out of range");
3234         return new AscendingSubMap!(K,V)(m,
3235                                      false, fromKey, inclusive,
3236                                      toEnd, hi,      hiInclusive);
3237     }
3238 
3239     // NavigableMap!(K,V) descendingMap() {
3240     //     NavigableMap!(K,V) mv = descendingMapView;
3241     //     return (mv !is null) ? mv :
3242     //         (descendingMapView =
3243     //          new DescendingSubMap!(K,V)(m,
3244     //                                 fromStart, lo, loInclusive,
3245     //                                 toEnd,     hi, hiInclusive));
3246     // }
3247 
3248     override InputRange!K byKey()    {
3249         return new KeyInputRange(absLowest(), absHighFence());
3250     }
3251 
3252     override InputRange!V byValue()    {
3253         return new ValueInputRange(absLowest(), absHighFence());
3254     }
3255     // override Iterator!K keyIterator() {
3256     //     return new SubMapKeyIterator(absLowest(), absHighFence());
3257     // }
3258 
3259     // Spliterator!K keySpliterator() {
3260     //     return new SubMapKeyIterator(absLowest(), absHighFence());
3261     // }
3262 
3263     // override Iterator!K descendingKeyIterator() {
3264     //     return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
3265     // }
3266 
3267 
3268     override int opApply(scope int delegate(ref K, ref V) dg)  {
3269         if(dg is null)
3270             throw new NullPointerException();
3271 
3272         int result = 0;
3273         Iterator!(MapEntry!(K,V)) iterator = new SubMapEntryIterator(absLowest(), absHighFence());
3274         while(iterator.hasNext()) {
3275             TreeMapEntry!(K,V) e = cast(TreeMapEntry!(K,V)) iterator.next();
3276             result = dg(e.key, e.value);
3277             if(result != 0) return result;
3278         }
3279 
3280         return result;
3281     }
3282     
3283     override int opApply(scope int delegate(MapEntry!(K, V) entry) dg) {
3284         if(dg is null)
3285             throw new NullPointerException();
3286 
3287         int result = 0;
3288         Iterator!(MapEntry!(K,V)) iterator = new SubMapEntryIterator(absLowest(), absHighFence());
3289         while(iterator.hasNext()) {
3290             result = dg(iterator.next());
3291             if(result != 0) return result;
3292         }
3293 
3294         return result;
3295     }
3296 
3297     // final class AscendingEntrySetView : EntrySetView {
3298     //     Iterator!(MapEntry!(K,V)) iterator() {
3299     //         return new SubMapEntryIterator(absLowest(), absHighFence());
3300     //     }
3301     // }
3302 
3303     // Set!(MapEntry!(K,V)) entrySet() {
3304     //     EntrySetView es = entrySetView;
3305     //     return (es !is null) ? es : (entrySetView = new AscendingEntrySetView());
3306     // }
3307 
3308     override TreeMapEntry!(K,V) subLowest()       { return absLowest(); }
3309     override TreeMapEntry!(K,V) subHighest()      { return absHighest(); }
3310     override TreeMapEntry!(K,V) subCeiling(K key) { return absCeiling(key); }
3311     override TreeMapEntry!(K,V) subHigher(K key)  { return absHigher(key); }
3312     override TreeMapEntry!(K,V) subFloor(K key)   { return absFloor(key); }
3313     override TreeMapEntry!(K,V) subLower(K key)   { return absLower(key); }
3314 }
3315 
3316 /**
3317  * @serial include
3318  */
3319 final class DescendingSubMap(K,V)  : NavigableSubMap!(K,V) {
3320     // private static final long serialVersionUID = 912986545866120460L;
3321     this(TreeMap!(K,V) m,
3322                     bool fromStart, K lo, bool loInclusive,
3323                     bool toEnd,     K hi, bool hiInclusive) {
3324         super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
3325 
3326         // reverseComparator = Collections.reverseOrder(m._comparator);
3327     }
3328 
3329     private Comparator!K reverseComparator;
3330 
3331     Comparator!K comparator() {
3332         implementationMissing();
3333         return reverseComparator;
3334     }
3335 
3336     NavigableMap!(K,V) subMap(K fromKey, bool fromInclusive,
3337                                     K toKey,   bool toInclusive) {
3338         if (!inRange(fromKey, fromInclusive))
3339             throw new IllegalArgumentException("fromKey out of range");
3340         if (!inRange(toKey, toInclusive))
3341             throw new IllegalArgumentException("toKey out of range");
3342         return new DescendingSubMap!(K,V)(m,
3343                                       false, toKey,   toInclusive,
3344                                       false, fromKey, fromInclusive);
3345     }
3346 
3347     NavigableMap!(K,V) headMap(K toKey, bool inclusive) {
3348         if (!inRange(toKey, inclusive))
3349             throw new IllegalArgumentException("toKey out of range");
3350         return new DescendingSubMap!(K,V)(m,
3351                                       false, toKey, inclusive,
3352                                       toEnd, hi,    hiInclusive);
3353     }
3354 
3355     NavigableMap!(K,V) tailMap(K fromKey, bool inclusive) {
3356         if (!inRange(fromKey, inclusive))
3357             throw new IllegalArgumentException("fromKey out of range");
3358         return new DescendingSubMap!(K,V)(m,
3359                                       fromStart, lo, loInclusive,
3360                                       false, fromKey, inclusive);
3361     }
3362 
3363     // NavigableMap!(K,V) descendingMap() {
3364     //     NavigableMap!(K,V) mv = descendingMapView;
3365     //     return (mv !is null) ? mv :
3366     //         (descendingMapView =
3367     //          new AscendingSubMap!(K,V)(m,
3368     //                                fromStart, lo, loInclusive,
3369     //                                toEnd,     hi, hiInclusive));
3370     // }
3371 
3372     // override Iterator!K keyIterator() {
3373     //     return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
3374     // }
3375 
3376     // override Spliterator!K keySpliterator() {
3377     //     return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
3378     // }
3379 
3380     // override Iterator!K descendingKeyIterator() {
3381     //     return new SubMapKeyIterator(absLowest(), absHighFence());
3382     // }
3383 
3384     // final class DescendingEntrySetView : EntrySetView {
3385     //     Iterator!(MapEntry!(K,V)) iterator() {
3386     //         return new DescendingSubMapEntryIterator(absHighest(), absLowFence());
3387     //     }
3388     // }
3389 
3390     // Set!(MapEntry!(K,V)) entrySet() {
3391     //     EntrySetView es = entrySetView;
3392     //     return (es !is null) ? es : (entrySetView = new DescendingEntrySetView());
3393     // }
3394 
3395     override TreeMapEntry!(K,V) subLowest()       { return absHighest(); }
3396     override TreeMapEntry!(K,V) subHighest()      { return absLowest(); }
3397     override TreeMapEntry!(K,V) subCeiling(K key) { return absFloor(key); }
3398     override TreeMapEntry!(K,V) subHigher(K key)  { return absLower(key); }
3399     override TreeMapEntry!(K,V) subFloor(K key)   { return absCeiling(key); }
3400     override TreeMapEntry!(K,V) subLower(K key)   { return absHigher(key); }
3401 }
3402 
3403 
3404 // Little utilities
3405 
3406 /**
3407 * Returns the successor of the specified Entry, or null if no such.
3408 */
3409 private TreeMapEntry!(K,V) successor(K,V)(TreeMapEntry!(K,V) t) {
3410     if (t is null)
3411         return null;
3412     else if (t.right !is null) {
3413         TreeMapEntry!(K,V) p = t.right;
3414         while (p.left !is null)
3415             p = p.left;
3416         return p;
3417     } else {
3418         TreeMapEntry!(K,V) p = t.parent;
3419         TreeMapEntry!(K,V) ch = t;
3420         while (p !is null && ch == p.right) {
3421             ch = p;
3422             p = p.parent;
3423         }
3424         return p;
3425     }
3426 }
3427 
3428 /**
3429 * Returns the predecessor of the specified Entry, or null if no such.
3430 */
3431 private TreeMapEntry!(K,V) predecessor(K,V)(TreeMapEntry!(K,V) t) {
3432     if (t is null)
3433         return null;
3434     else if (t.left !is null) {
3435         TreeMapEntry!(K,V) p = t.left;
3436         while (p.right !is null)
3437             p = p.right;
3438         return p;
3439     } else {
3440         TreeMapEntry!(K,V) p = t.parent;
3441         TreeMapEntry!(K,V) ch = t;
3442         while (p !is null && ch == p.left) {
3443             ch = p;
3444             p = p.parent;
3445         }
3446         return p;
3447     }
3448 }
3449 
3450 
3451 /**
3452 * Test two values for equality.  Differs from o1.equals(o2) only in
3453 * that it copes with {@code null} o1 properly.
3454 */
3455 private bool valEquals(V)(V o1, V o2) {
3456     // return (o1 is null ? o2 is null : o1.equals(o2));
3457     return o1 == o2;
3458 }
3459 
3460 /**
3461 * Return SimpleImmutableEntry for entry, or null if null
3462 */
3463 private MapEntry!(K,V) exportEntry(K,V)(TreeMapEntry!(K,V) e) {
3464     return (e is null) ? null :
3465         new SimpleImmutableEntry!(K,V)(e);
3466 }
3467 
3468 /**
3469 * Return key for entry, or null if null
3470 */
3471 private K keyOrNull(K,V)(TreeMapEntry!(K,V) e) {        
3472     return (e is null) ? K.init : e.key;
3473 }
3474 
3475 /**
3476 * Returns the key corresponding to the specified Entry.
3477 * @throws NoSuchElementException if the Entry is null
3478 */
3479 private K key(K, V)(TreeMapEntry!(K,V) e) {
3480     if (e is null)
3481         throw new NoSuchElementException();
3482     return e.key;
3483 }