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