001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2015
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see http://www.gnu.org/licenses.
027 */
028package edu.wisc.ssec.mcidasv.util.trie;
029
030import java.io.Serializable;
031import java.util.AbstractCollection;
032import java.util.AbstractMap;
033import java.util.AbstractSet;
034import java.util.Collection;
035import java.util.Comparator;
036import java.util.ConcurrentModificationException;
037import java.util.Iterator;
038import java.util.Map;
039import java.util.NoSuchElementException;
040import java.util.Set;
041import java.util.SortedMap;
042
043/**
044 * A PATRICIA Trie. 
045 * <p>
046 * PATRICIA = Practical Algorithm to Retrieve Information Coded in Alphanumeric
047 * <p>
048 * A PATRICIA Trie is a compressed Trie. Instead of storing all data at the
049 * edges of the Trie (and having empty internal nodes), PATRICIA stores data
050 * in every node. This allows for very efficient traversal, insert, delete,
051 * predecessor, successor, prefix, range, and 'select' operations. All operations
052 * are performed at worst in O(K) time, where K is the number of bits in the
053 * largest item in the tree. In practice, operations actually take O(A(K))
054 * time, where A(K) is the average number of bits of all items in the tree.
055 * <p>
056 * Most importantly, PATRICIA requires very few comparisons to keys while
057 * doing any operation. While performing a lookup, each comparison
058 * (at most K of them, described above) will perform a single bit comparison
059 * against the given key, instead of comparing the entire key to another key.
060 * <p>
061 * The Trie can return operations in lexicographical order using the 'traverse',
062 * 'prefix', 'submap', or 'iterator' methods. The Trie can also scan for items
063 * that are 'bitwise' (using an XOR metric) by the 'select' method. Bitwise
064 * closeness is determined by the {@link KeyAnalyzer} returning true or 
065 * false for a bit being set or not in a given key.
066 * <p>
067 * This PATRICIA Trie supports both variable length & fixed length keys.
068 * Some methods, such as {@code getPrefixedBy(...)} are suited only to
069 * variable length keys, whereas {@code getPrefixedByBits(...)} is suited
070 * to fixed-size keys.
071 * <p>
072 * Additionally see <a 
073 * href="http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/PATRICIA/">PATRICIA</a>
074 * for more information.
075 * <p>
076 * Any methods here that take an {@code Object} may throw a
077 * {@code ClassCastException} if the method is expecting an instance of K
078 * (and it isn't K).
079 * 
080 * <pre>
081    PatriciaTrie&lt;String, String&gt; trie = new PatriciaTrie&lt;String, String&gt;
082    (new CharSequenceKeyAnalyzer());
083    
084    trie.put("Lime", "Lime");
085    trie.put("LimeWire", "LimeWire");
086    trie.put("LimeRadio", "LimeRadio");
087    trie.put("Lax", "Lax");
088    trie.put("Lake", "Lake");
089    trie.put("Lovely", "Lovely");
090
091    System.out.println(trie.select("Lo"));
092    System.out.println(trie.select("Lime"));
093
094    System.out.println(trie.getPrefixedBy("La").toString());            
095    
096    Output:
097        Lovely
098        Lime
099        {Lake=Lake, Lax=Lax}
100
101 * </pre>
102 * @author Roger Kapsi
103 * @author Sam Berlin
104
105 */
106public class PatriciaTrie<K, V> extends AbstractMap<K, V> implements Trie<K, V>, Serializable {
107    
108    private static final long serialVersionUID = 110232526181493307L;
109
110    /** The root element of the Trie. */
111    private final TrieEntry<K, V> root = new TrieEntry<K, V>(null, null, -1);
112    
113    /** The current size (total number of elements) of the Trie. */
114    private int size = 0;
115    
116    /** The number of times this has been modified (to fail-fast the iterators). */
117    private transient int modCount = 0;
118    
119    /** The keyAnalyzer used to analyze bit values of keys. */
120    private final KeyAnalyzer<? super K> keyAnalyzer;
121    
122    /** Constructs a new PatriciaTrie using the given keyAnalyzer. */
123    public PatriciaTrie(KeyAnalyzer<? super K> keyAnalyzer) {
124        this.keyAnalyzer = keyAnalyzer;
125    }
126    
127    /** Returns the KeyAnalyzer that constructed the trie. */
128    public KeyAnalyzer<? super K> getKeyAnalyzer() {
129        return keyAnalyzer;
130    }
131
132    /** Returns the KeyAnalyzer as a comparator. */
133    public Comparator<? super K> comparator() {
134        return keyAnalyzer;
135    }
136    
137    /** Clears the Trie (i.e. removes all elements). */
138    public void clear() {
139        root.key = null;
140        root.bitIndex = -1;
141        root.value = null;
142        
143        root.parent = null;
144        root.left = root;
145        root.right = null;
146        root.predecessor = root;
147        
148        size = 0;
149        incrementModCount();
150    }
151    
152    /** Returns true if the Trie is empty */
153    public boolean isEmpty() {
154        return size == 0;
155    }
156    
157    /** Returns the number items in the Trie */
158    public int size() {
159        return size;
160    }
161   
162    /** Increments both the size and mod counter. */
163    private void incrementSize() {
164        size++;
165        incrementModCount();
166    }
167    
168    /** Decrements the size and increments the mod counter. */
169    private void decrementSize() {
170        size--;
171        incrementModCount();
172    }
173    
174    /** Increments the mod counter. */
175    private void incrementModCount() {
176        modCount++;
177    }
178    
179    /**
180     * Adds a new <key, value> pair to the Trie and if a pair already
181     * exists it will be replaced. In the latter case it will return
182     * the old value.
183     */
184    public V put(K key, V value) {
185        if (key == null) {
186            throw new NullPointerException("Key cannot be null");
187        }
188        
189        int keyLength = length(key);
190        
191        // The only place to store a key with a length
192        // of zero bits is the root node
193        if (keyLength == 0) {
194            if (root.isEmpty()) {
195                incrementSize();
196            } else {
197                incrementModCount();
198            }
199            return root.setKeyValue(key, value);
200        }
201        
202        TrieEntry<K, V> found = getNearestEntryForKey(key, keyLength);
203        if (key.equals(found.key)) {
204            if (found.isEmpty()) { // <- must be the root
205                incrementSize();
206            } else {
207                incrementModCount();
208            }
209            return found.setKeyValue(key, value);
210        }
211        
212        int bitIndex = bitIndex(key, found.key);
213        if (isValidBitIndex(bitIndex)) { // in 99.999...9% the case
214            /* NEW KEY+VALUE TUPLE */
215            TrieEntry<K, V> t = new TrieEntry<K, V>(key, value, bitIndex);
216            addEntry(t, keyLength);
217            incrementSize();
218            return null;
219        } else if (isNullBitKey(bitIndex)) {
220            // A bits of the Key are zero. The only place to
221            // store such a Key is the root Node!
222            
223            /* NULL BIT KEY */
224            if (root.isEmpty()) {
225                incrementSize();
226            } else {
227                incrementModCount();
228            }
229            return root.setKeyValue(key, value);
230            
231        } else if (isEqualBitKey(bitIndex)) {
232            // This is a very special and rare case.
233            
234            /* REPLACE OLD KEY+VALUE */
235            if (found != root) {
236                incrementModCount();
237                return found.setKeyValue(key, value);
238            }
239        }
240        
241        throw new IndexOutOfBoundsException("Failed to put: " + key + " -> " + value + ", " + bitIndex);
242    }
243    
244    /** Adds the given entry into the Trie. */
245    private TrieEntry<K, V> addEntry(TrieEntry<K, V> toAdd, int keyLength) {
246        TrieEntry<K, V> current = root.left;
247        TrieEntry<K, V> path = root;
248        while(true) {
249            if(current.bitIndex >= toAdd.bitIndex || current.bitIndex <= path.bitIndex) {
250                toAdd.predecessor = toAdd;
251                
252                if (!isBitSet(toAdd.key, keyLength, toAdd.bitIndex)) {
253                    toAdd.left = toAdd;
254                    toAdd.right = current;
255                } else {
256                    toAdd.left = current;
257                    toAdd.right = toAdd;
258                }
259               
260                toAdd.parent = path;
261                if (current.bitIndex >= toAdd.bitIndex) {
262                    current.parent = toAdd;
263                }
264                
265                // if we inserted an uplink, set the predecessor on it
266                if(current.bitIndex <= path.bitIndex) {
267                    current.predecessor = toAdd;
268                }
269         
270                if (path == root || !isBitSet(toAdd.key, keyLength, path.bitIndex))
271                    path.left = toAdd;
272                else
273                    path.right = toAdd;
274                return toAdd;
275            }
276                
277            path = current;
278            if(!isBitSet(toAdd.key, keyLength, current.bitIndex))
279                current = current.left;
280            else
281                current = current.right;
282        }
283    }
284    
285    @Override
286    public Set<Map.Entry<K,V>> entrySet() {
287        Set<Map.Entry<K,V>> es = entrySet;
288        return (es != null ? es : (entrySet = new EntrySet()));
289    }
290    
291    /**
292     * Returns the Value whose Key equals our lookup Key
293     * or null if no such key exists.
294     */
295    public V get(Object k) {
296        TrieEntry<K, V> entry = getEntry(k);
297        return entry != null ? entry.getValue() : null;
298    }
299
300    /**
301     * Returns the entry associated with the specified key in the
302     * PatriciaTrie.  Returns null if the map contains no mapping
303     * for this key.
304     * 
305     * This may throw ClassCastException if the object is not of type K.
306     */
307    TrieEntry<K,V> getEntry(Object k) {
308        K key = asKey(k);
309        if(key == null)
310            return null;
311        
312        int keyLength = length(key);
313        TrieEntry<K,V> entry = getNearestEntryForKey(key, keyLength);
314        return !entry.isEmpty() && key.equals(entry.key) ? entry : null;
315    }
316    
317    /** Gets the key as a 'K'. */
318    @SuppressWarnings("unchecked")
319    protected final K asKey(Object key) {
320        try {
321            return (K)key;
322        } catch(ClassCastException cce) {
323            // Because the type is erased, the cast & return are
324            // actually doing nothing, making this CCE impossible.
325            // However, it's still here on the off-chance it may
326            // work.
327            return null;
328        }
329    }
330    
331    /**
332     * Returns the nearest entry for a given key.  This is useful
333     * for finding knowing if a given key exists (and finding the value
334     * for it), or for inserting the key.
335     * 
336     * The actual get implementation. This is very similar to
337     * selectR but with the exception that it might return the
338     * root Entry even if it's empty.
339     */
340    private TrieEntry<K, V> getNearestEntryForKey(K key, int keyLength) {
341        TrieEntry<K, V> current = root.left;
342        TrieEntry<K, V> path = root;
343        while(true) {
344            if(current.bitIndex <= path.bitIndex)
345                return current;
346            
347            path = current;
348            if(!isBitSet(key, keyLength, current.bitIndex))
349                current = current.left;
350            else
351                current = current.right;
352        }
353    }
354    
355    /**
356     * Returns the Value whose Key has the longest prefix
357     * in common with our lookup key.
358     */
359    @SuppressWarnings("unchecked")
360    public V select(K key) {
361        int keyLength = length(key);
362        TrieEntry[] result = new TrieEntry[1];
363        if (!selectR(root.left, -1, key, keyLength, result)) {
364            TrieEntry<K, V> e = result[0];
365            return e.getValue();
366        }
367        return null;
368    }
369    
370    /**
371     * This is equivalent to the other selectR() method but without
372     * its overhead because we're selecting only one best matching
373     * Entry from the Trie.
374     */
375    private boolean selectR(TrieEntry<K, V> h, int bitIndex, 
376            final K key, final int keyLength, final TrieEntry[] result) {
377        
378        if (h.bitIndex <= bitIndex) {
379            // If we hit the root Node and it is empty
380            // we have to look for an alternative best
381            // matching node.
382            if (!h.isEmpty()) {
383                result[0] = h;
384                return false;
385            }
386            return true;
387        }
388
389        if (!isBitSet(key, keyLength, h.bitIndex)) {
390            if (selectR(h.left, h.bitIndex, key, keyLength, result)) {
391                return selectR(h.right, h.bitIndex, key, keyLength, result);
392            }
393        } else {
394            if (selectR(h.right, h.bitIndex, key, keyLength, result)) {
395                return selectR(h.left, h.bitIndex, key, keyLength, result);
396            }
397        }
398        return false;
399    }
400    
401    @SuppressWarnings("unchecked")
402    public Map.Entry<K,V> select(K key, Cursor<? super K, ? super V> cursor) {
403        int keyLength = length(key);
404        TrieEntry[] result = new TrieEntry[]{ null };
405        selectR(root.left, -1, key, keyLength, cursor, result);
406        return result[0];
407    }
408
409    private boolean selectR(TrieEntry<K,V> h, int bitIndex, 
410            final K key, 
411            final int keyLength,
412            final Cursor<? super K, ? super V> cursor,
413            final TrieEntry[] result) {
414
415        if (h.bitIndex <= bitIndex) {
416            if(!h.isEmpty()) {
417                Cursor.SelectStatus ret = cursor.select(h);
418                switch(ret) {
419                case REMOVE:
420                    throw new UnsupportedOperationException("cannot remove during select");
421                case EXIT:
422                    result[0] = h;
423                    return false; // exit
424                case REMOVE_AND_EXIT:
425                    TrieEntry<K, V> entry = new TrieEntry<K, V>(h.getKey(), h.getValue(), -1);
426                    result[0] = entry;
427                    removeEntry(h);
428                    return false;
429                case CONTINUE:
430                    // fall through.
431                }
432            }
433            return true; // continue
434        }
435
436        if (!isBitSet(key, keyLength, h.bitIndex)) {
437            if (selectR(h.left, h.bitIndex, key, keyLength, cursor, result)) {
438                return selectR(h.right, h.bitIndex, key, keyLength, cursor, result);
439            }
440        } else {
441            if (selectR(h.right, h.bitIndex, key, keyLength, cursor, result)) {
442                return selectR(h.left, h.bitIndex, key, keyLength, cursor, result);
443            }
444        }
445        
446        return false;
447    }
448
449    /**
450     * Returns a view of this Trie of all elements that are
451     * prefixed by the given key.
452     * 
453     * In a fixed-keysize Trie, this is essentially a 'get' operation.
454     * 
455     * For example, if the trie contains 'Lime', 'LimeWire', 
456     * 'LimeRadio', 'Lax', 'Later', 'Lake', and 'Lovely', then
457     * a lookup of 'Lime' would return 'Lime', 'LimeRadio', and 'LimeWire'.
458     * 
459     * The view that this returns is optimized to have a very efficient
460     * Iterator. The firstKey, lastKey & size methods must iterate
461     * over all possible values in order to determine the results. This
462     * information is cached until the Patricia tree changes. All other
463     * methods (except Iterator) must compare the given key to the prefix
464     * to ensure that it is within the range of the view. The Iterator's
465     * remove method must also relocate the subtree that contains the
466     * prefixes if the entry holding the subtree is removed or changes.
467     * Changing the subtree takes O(K) time.
468     * 
469     * @param key
470     */
471    public SortedMap<K, V> getPrefixedBy(K key) {
472        return getPrefixedByBits(key, 0, keyAnalyzer.length(key));
473    }
474
475    /**
476     * Returns a view of this Trie of all elements that are
477     * prefixed by the length of the key.
478     * 
479     * Fixed-keysize Tries will not support this operation
480     * (because all keys will be the same length).
481     * 
482     * For example, if the trie contains 'Lime', 'LimeWire', 
483     * 'LimeRadio', 'Lax', 'Later', 'Lake', and 'Lovely', then
484     * a lookup of 'LimePlastics' with a length of 4 would
485     * return 'Lime', 'LimeRadio', and 'LimeWire'.
486     * 
487     * The view that this returns is optimized to have a very efficient
488     * Iterator.  The firstKey, lastKey & size methods must iterate
489     * over all possible values in order to determine the results.  This
490     * information is cached until the Patricia tree changes.  All other
491     * methods (except Iterator) must compare the given key to the prefix
492     * to ensure that it is within the range of the view.  The Iterator's
493     * remove method must also relocate the subtree that contains the
494     * prefixes if the entry holding the subtree is removed or changes.
495     * Changing the subtree takes O(K) time.
496     *  
497     * @param key
498     * @param length
499     */
500    public SortedMap<K, V> getPrefixedBy(K key, int length) {
501        return getPrefixedByBits(key, 0, length * keyAnalyzer.bitsPerElement());
502    }
503
504    /**
505     * Returns a view of this Trie of all elements that are prefixed
506     * by the key, starting at the given offset and for the given length.
507     * 
508     * Fixed-keysize Tries will not support this operation
509     * (because all keys are the same length).
510     *
511     * For example, if the trie contains 'Lime', 'LimeWire', 
512     * 'LimeRadio', 'Lax', 'Later', 'Lake', and 'Lovely', then
513     * a lookup of 'The Lime Plastics' with an offset of 4 and a 
514     * length of 4 would return 'Lime', 'LimeRadio', and 'LimeWire'.
515     * 
516     * The view that this returns is optimized to have a very efficient
517     * Iterator.  The firstKey, lastKey & size methods must iterate
518     * over all possible values in order to determine the results.  This
519     * information is cached until the Patricia tree changes.  All other
520     * methods (except Iterator) must compare the given key to the prefix
521     * to ensure that it is within the range of the view.  The Iterator's
522     * remove method must also relocate the subtree that contains the
523     * prefixes if the entry holding the subtree is removed or changes.
524     * Changing the subtree takes O(K) time.
525     * 
526     * @param key
527     * @param offset
528     * @param length
529     */
530    public SortedMap<K, V> getPrefixedBy(K key, int offset, int length) {
531        return getPrefixedByBits(key, offset * keyAnalyzer.bitsPerElement(), length * keyAnalyzer.bitsPerElement());
532    }
533
534    /**
535     * Returns a view of this Trie of all elements that are prefixed
536     * by the number of bits in the given Key.
537     * 
538     * Fixed-keysize Tries can support this operation as a way to do
539     * lookups of partial keys.  That is, if the Trie is storing IP
540     * addresses, you can lookup all addresses that begin with
541     * '192.168' by providing the key '192.168.X.X' and a length of 16
542     * would return all addresses that begin with '192.168'.
543     * 
544     * The view that this returns is optimized to have a very efficient
545     * Iterator.  The firstKey, lastKey & size methods must iterate
546     * over all possible values in order to determine the results.  This
547     * information is cached until the Patricia tree changes.  All other
548     * methods (except Iterator) must compare the given key to the prefix
549     * to ensure that it is within the range of the view.  The Iterator's
550     * remove method must also relocate the subtree that contains the
551     * prefixes if the entry holding the subtree is removed or changes.
552     * Changing the subtree takes O(K) time.
553     * 
554     * @param key
555     * @param bitLength
556     */
557    public SortedMap<K, V> getPrefixedByBits(K key, int bitLength) {
558        return getPrefixedByBits(key, 0, bitLength);
559    }
560    
561    /**
562     * Returns a view of this map, with entries containing only those that
563     * are prefixed by a value whose bits matches the bits between 'offset'
564     * and 'length' in the given key.
565     * 
566     * The view that this returns is optimized to have a very efficient
567     * Iterator.  The firstKey, lastKey & size methods must iterate
568     * over all possible values in order to determine the results.  This
569     * information is cached until the Patricia tree changes.  All other
570     * methods (except Iterator) must compare the given key to the prefix
571     * to ensure that it is within the range of the view.  The Iterator's
572     * remove method must also relocate the subtree that contains the
573     * prefixes if the entry holding the subtree is removed or changes.
574     * Changing the subtree takes O(K) time.
575     * 
576     * @param key
577     * @param offset
578     * @param length
579     */
580    private SortedMap<K, V> getPrefixedByBits(K key, int offset, int length) {
581        int offsetLength = offset + length;
582        if (offsetLength > length(key)) {
583            throw new IllegalArgumentException(offset + " + " + length + " > " + length(key));
584        }
585        
586        if(offsetLength == 0)
587            return this;
588        
589        return new PrefixSubMap(key, offset, length);
590    }
591    
592    /**
593     * Returns true if this trie contains the specified Key
594     * 
595     * This may throw ClassCastException if the object is not
596     * of type K.
597     */
598    public boolean containsKey(Object k) {
599        K key = asKey(k);
600        if(key == null)
601            return false;
602        
603        int keyLength = length(key);
604        TrieEntry entry = getNearestEntryForKey(key, keyLength);
605        return !entry.isEmpty() && key.equals(entry.key);
606    }
607    
608    /** Returns true if this Trie contains the specified value. */
609    public boolean containsValue(Object o) {
610        for(V v : values())
611            if(valEquals(v, o))
612                return true;
613        return false;
614    }
615    
616    
617    /**
618     * Removes a Key from the Trie if one exists
619     * 
620     * This may throw ClassCastException if the object is not of type K.
621     * 
622     * @param k the Key to delete
623     * @return Returns the deleted Value
624     */
625    public V remove(Object k) {
626        K key = asKey(k);
627        if(key == null)
628            return null;
629        
630        int keyLength = length(key);        
631        TrieEntry<K, V> current = root.left;
632        TrieEntry<K, V> path = root;
633        while(true) {
634            if(current.bitIndex <= path.bitIndex) {
635                if(!current.isEmpty() && key.equals(current.key))
636                    return removeEntry(current);
637                else
638                    return null;
639            }
640            
641            path = current;
642            if(!isBitSet(key, keyLength, current.bitIndex))
643                current = current.left;
644            else
645                current = current.right;
646        }
647    }
648    
649    /**
650     * Removes a single entry from the Trie.
651     * 
652     * If we found a Key (Entry h) then figure out if it's
653     * an internal (hard to remove) or external Entry (easy 
654     * to remove)
655     */
656    private V removeEntry(TrieEntry<K, V> h) {
657        if (h != root) {
658            if (h.isInternalNode()) {
659                removeInternalEntry(h);
660            } else {
661                removeExternalEntry(h);
662            }
663        }
664        
665        decrementSize();
666        return h.setKeyValue(null, null);
667    }
668    
669    /**
670     * Removes an external entry from the Trie.
671     * 
672     * If it's an external Entry then just remove it.
673     * This is very easy and straight forward.
674     */
675    private void removeExternalEntry(TrieEntry<K, V> h) {
676        if (h == root) {
677            throw new IllegalArgumentException("Cannot delete root Entry!");
678        } else if (!h.isExternalNode()) {
679            throw new IllegalArgumentException(h + " is not an external Entry!");
680        } 
681        
682        TrieEntry<K, V> parent = h.parent;
683        TrieEntry<K, V> child = (h.left == h) ? h.right : h.left;
684        
685        if (parent.left == h) {
686            parent.left = child;
687        } else {
688            parent.right = child;
689        }
690        
691        // either the parent is changing, or the predecessor is changing.
692        if (child.bitIndex > parent.bitIndex) {
693            child.parent = parent;
694        } else {
695            child.predecessor = parent;
696        }
697        
698    }
699    
700    /**
701     * Removes an internal entry from the Trie.
702     * 
703     * If it's an internal Entry then "good luck" with understanding
704     * this code. The Idea is essentially that Entry p takes Entry h's
705     * place in the trie which requires some re-wiring.
706     */
707    private void removeInternalEntry(TrieEntry<K, V> h) {
708        if (h == root) {
709            throw new IllegalArgumentException("Cannot delete root Entry!");
710        } else if (!h.isInternalNode()) {
711            throw new IllegalArgumentException(h + " is not an internal Entry!");
712        } 
713        
714        TrieEntry<K, V> p = h.predecessor;
715        
716        // Set P's bitIndex
717        p.bitIndex = h.bitIndex;
718        
719        // Fix P's parent, predecessor and child Nodes
720        {
721            TrieEntry<K, V> parent = p.parent;
722            TrieEntry<K, V> child = (p.left == h) ? p.right : p.left;
723            
724            // if it was looping to itself previously,
725            // it will now be pointed from it's parent
726            // (if we aren't removing it's parent --
727            //  in that case, it remains looping to itself).
728            // otherwise, it will continue to have the same
729            // predecessor.
730            if(p.predecessor == p && p.parent != h)
731                p.predecessor = p.parent;
732            
733            if (parent.left == p) {
734                parent.left = child;
735            } else {
736                parent.right = child;
737            }
738            
739            if (child.bitIndex > parent.bitIndex) {
740                child.parent = parent;
741            }
742        };
743        
744        // Fix H's parent and child Nodes
745        {         
746            // If H is a parent of its left and right child 
747            // then change them to P
748            if (h.left.parent == h) {
749                h.left.parent = p;
750            }
751            
752            if (h.right.parent == h) {
753                h.right.parent = p;
754            }
755            
756            // Change H's parent
757            if (h.parent.left == h) {
758                h.parent.left = p;
759            } else {
760                h.parent.right = p;
761            }
762        };
763        
764        // Copy the remaining fields from H to P
765        //p.bitIndex = h.bitIndex;
766        p.parent = h.parent;
767        p.left = h.left;
768        p.right = h.right;
769        
770        // Make sure that if h was pointing to any uplinks,
771        // p now points to them.
772        if(isValidUplink(p.left, p))
773            p.left.predecessor = p;
774        if(isValidUplink(p.right, p))
775            p.right.predecessor = p;
776            
777    }
778    
779    /**
780     * Returns the node lexicographically before the given node (or null if none).
781     * 
782     * This follows four simple branches:
783     *  - If the uplink that returned us was a right uplink:
784     *      - If predecessor's left is a valid uplink from predecessor, return it.
785     *      - Else, follow the right path from the predecessor's left.
786     *  - If the uplink that returned us was a left uplink:
787     *      - Loop back through parents until we encounter a node where 
788     *        node != node.parent.left.
789     *          - If node.parent.left is uplink from node.parent:
790     *              - If node.parent.left is not root, return it.
791     *              - If it is root & root isEmpty, return null.
792     *              - If it is root & root !isEmpty, return root.
793     *          - If node.parent.left is not uplink from node.parent:
794     *              - Follow right path for first right child from node.parent.left   
795     * 
796     * @param start
797     */
798    private TrieEntry<K, V> previousEntry(TrieEntry<K, V> start) {
799        if(start.predecessor == null)
800            throw new IllegalArgumentException("must have come from somewhere!");
801        
802        if(start.predecessor.right == start) {
803            if(isValidUplink(start.predecessor.left, start.predecessor)) {
804                return start.predecessor.left;
805            } else {
806                return followRight(start.predecessor.left);
807            }
808        } else {
809            TrieEntry<K, V> node = start.predecessor;
810            while(node.parent != null && node == node.parent.left)
811                node = node.parent;
812            if(node.parent == null) // can be null if we're looking up root.
813                return null;
814            if(isValidUplink(node.parent.left, node.parent)) {
815                if(node.parent.left == root) {
816                    if(root.isEmpty())
817                        return null;
818                    else
819                        return root;
820                } else {
821                    return node.parent.left;
822                }
823            } else {
824                return followRight(node.parent.left);
825            }
826        }
827    }
828    
829    /**
830     * Returns the entry lexicographically after the given entry.
831     * If the given entry is null, returns the first node.
832     */
833    private TrieEntry<K, V> nextEntry(TrieEntry<K, V> node) {
834        if(node == null) {
835            return firstEntry();
836        } else {
837            return nextEntryImpl(node.predecessor, node, null);
838        }
839    }
840    
841    /**
842     * Returns the entry lexicographically after the given entry.
843     * If the given entry is null, returns the first node.
844     * 
845     * This will traverse only within the subtree.  If the given node
846     * is not within the subtree, this will have undefined results.
847     */
848    private TrieEntry<K, V> nextEntryInSubtree(TrieEntry<K, V> node, TrieEntry<K, V> parentOfSubtree) {
849        if(node == null) {
850            return firstEntry();
851        } else {
852            return nextEntryImpl(node.predecessor, node, parentOfSubtree);
853        }
854    }
855    
856    /**
857     * Scans for the next node, starting at the specified point, and using 'previous'
858     * as a hint that the last node we returned was 'previous' (so we know not to return
859     * it again).  If 'tree' is non-null, this will limit the search to the given tree.
860     * 
861     * The basic premise is that each iteration can follow the following steps:
862     * 
863     * 1) Scan all the way to the left.
864     *   a) If we already started from this node last time, proceed to Step 2.
865     *   b) If a valid uplink is found, use it.
866     *   c) If the result is an empty node (root not set), break the scan.
867     *   d) If we already returned the left node, break the scan.
868     *   
869     * 2) Check the right.
870     *   a) If we already returned the right node, proceed to Step 3.
871     *   b) If it is a valid uplink, use it.
872     *   c) Do Step 1 from the right node.
873     *   
874     * 3) Back up through the parents until we encounter find a parent
875     *    that we're not the right child of.
876     *    
877     * 4) If there's no right child of that parent, the iteration is finished.
878     *    Otherwise continue to Step 5.
879     * 
880     * 5) Check to see if the right child is a valid uplink.
881     *    a) If we already returned that child, proceed to Step 6.
882     *       Otherwise, use it.
883     *    
884     * 6) If the right child of the parent is the parent itself, we've
885     *    already found & returned the end of the Trie, so exit.
886     *    
887     * 7) Do Step 1 on the parent's right child.
888     */
889    private TrieEntry<K, V> nextEntryImpl(TrieEntry<K, V> start, TrieEntry<K, V> previous, TrieEntry<K, V> tree) {
890        TrieEntry<K, V> current = start;
891
892        // Only look at the left if this was a recursive or
893        // the first check, otherwise we know we've already looked
894        // at the left.
895        if(previous == null || start != previous.predecessor) {
896            while(!current.left.isEmpty()) {
897                // stop traversing if we've already
898                // returned the left of this node.
899                if(previous == current.left) {
900                    break;
901                }
902                
903                if(isValidUplink(current.left, current)) {
904                    return current.left;
905                }
906                
907                current = current.left;
908            }
909        }
910        
911        // If there's no data at all, exit.
912        if(current.isEmpty()) {
913            return null;
914        }
915        
916        // If we've already returned the left,
917        // and the immediate right is null,
918        // there's only one entry in the Trie
919        // which is stored at the root.
920        //
921        //  / ("")   <-- root
922        //  \_/  \
923        //       null <-- 'current'
924        //
925        if(current.right == null)
926            return null;
927        
928        // If nothing valid on the left, try the right.
929        if(previous != current.right) {
930            // See if it immediately is valid.
931            if(isValidUplink(current.right, current)) {
932                return current.right;
933            }
934            
935            // Must search on the right's side if it wasn't initially valid.
936            return nextEntryImpl(current.right, previous, tree);
937        }
938        
939        // Neither left nor right are valid, find the first parent
940        // whose child did not come from the right & traverse it.
941        while(current == current.parent.right) {
942            // If we're going to traverse to above the subtree, stop.
943            if(current == tree)
944                return null;
945            
946            current = current.parent;
947        }
948
949        // If we're on the top of the subtree, we can't go any higher.
950        if(current == tree)
951            return null;
952        
953        
954        // If there's no right, the parent must be root, so we're done.
955        if(current.parent.right == null) {
956            return null;
957        }
958
959        
960        // If the parent's right points to itself, we've found one.
961        if(previous != current.parent.right && isValidUplink(current.parent.right, current.parent)) {
962            return current.parent.right;
963        }
964        
965        // If the parent's right is itself, there can't be any more nodes.
966        if(current.parent.right == current.parent) {
967            return null;
968        }
969        
970        // We need to traverse down the parent's right's path.
971        return nextEntryImpl(current.parent.right, previous, tree);
972    }
973    
974    /** Returns each entry as a string. */
975    public String toString() {
976        StringBuilder buffer = new StringBuilder();
977        buffer.append("Trie[").append(size()).append("]={\n");
978        for(Iterator<Map.Entry<K, V>> i = newEntryIterator(); i.hasNext(); ) {
979            buffer.append("  ").append(i.next().toString()).append("\n");
980        }
981        buffer.append("}\n");
982        return buffer.toString();
983    }
984    
985    public Map.Entry<K, V> traverse(Cursor<? super K, ? super V> cursor) {
986        TrieEntry<K, V> entry = nextEntry(null);
987        while(entry != null) {
988            TrieEntry<K, V> current = entry;
989            Cursor.SelectStatus ret = cursor.select(current);
990            entry = nextEntry(current);
991            switch(ret) {
992            case EXIT:
993                return current;
994            case REMOVE:
995                removeEntry(current);
996                break; // out of switch, stay in while loop
997            case REMOVE_AND_EXIT:
998                Map.Entry<K, V> value = new TrieEntry<K, V>(current.getKey(), current.getValue(), -1);
999                removeEntry(current);
1000                return value;
1001            case CONTINUE: // do nothing.
1002            }
1003        }
1004        
1005        return null;
1006    }
1007    
1008    /** Returns true if 'next' is a valid uplink coming from 'from'. */
1009    private boolean isValidUplink(TrieEntry<K, V> next, TrieEntry<K, V> from) {            
1010        return next != null && next.bitIndex <= from.bitIndex && !next.isEmpty();
1011    }
1012    
1013    /** Returns true if bitIndex is a valid index */
1014    private static boolean isValidBitIndex(int bitIndex) {
1015        return 0 <= bitIndex && bitIndex <= Integer.MAX_VALUE;
1016    }
1017    
1018    /** Returns true if bitIndex is a NULL_BIT_KEY */
1019    private static boolean isNullBitKey(int bitIndex) {
1020        return bitIndex == KeyAnalyzer.NULL_BIT_KEY;
1021    }
1022    
1023    /** Returns true if bitIndex is a EQUAL_BIT_KEY */
1024    private static boolean isEqualBitKey(int bitIndex) {
1025        return bitIndex == KeyAnalyzer.EQUAL_BIT_KEY;
1026    }
1027    
1028    /** Returns the length of the key, or 0 if the key is null. */
1029    private int length(K key) {
1030        if (key == null) {
1031            return 0;
1032        }
1033        
1034        return keyAnalyzer.length(key);
1035    }
1036    
1037    /**
1038     * Returns whether or not the given bit on the 
1039     * key is set, or false if the key is null
1040     */
1041    private boolean isBitSet(K key, int keyLength, int bitIndex) {
1042        if (key == null) { // root's might be null!
1043            return false;
1044        }
1045        return keyAnalyzer.isBitSet(key, keyLength, bitIndex);
1046    }
1047    
1048    /**
1049     * Utility method for calling
1050     * keyAnalyzer.bitIndex(key, 0, length(key), foundKey, 0, length(foundKey))
1051     */
1052    private int bitIndex(K key, K foundKey) {
1053        return keyAnalyzer.bitIndex(key, 0, length(key), foundKey, 0, length(foundKey));
1054    }
1055    
1056    /** The actual Trie nodes. */
1057    private static class TrieEntry<K,V> implements Map.Entry<K,V>, Serializable {
1058        
1059        private static final long serialVersionUID = 4596023148184140013L;
1060        
1061        private K key;
1062        private V value;
1063        
1064        /** The index this entry is comparing. */
1065        private int bitIndex;
1066        
1067        /** The parent of this entry. */
1068        private TrieEntry<K,V> parent;
1069        /** The left child of this entry. */
1070        private TrieEntry<K,V> left;
1071        /** The right child of this entry. */
1072        private TrieEntry<K,V> right;
1073        /** The entry who uplinks to this entry. */ 
1074        private TrieEntry<K,V> predecessor;
1075        
1076        private TrieEntry(K key, V value, int bitIndex) {
1077            this.key = key;
1078            this.value = value;
1079            
1080            this.bitIndex = bitIndex;
1081            
1082            this.parent = null;
1083            this.left = this;
1084            this.right = null;
1085            this.predecessor = this;
1086        }
1087        
1088        public boolean equals(Object o) {
1089            if(o == this) {
1090                return true;
1091            } else if(o instanceof Map.Entry) {
1092                Map.Entry e = (Map.Entry)o;
1093                Object k1 = getKey();
1094                Object k2 = e.getKey();
1095                if (k1 == k2 || (k1 != null && k1.equals(k2))) {
1096                    Object v1 = getValue();
1097                    Object v2 = e.getValue();
1098                    if (v1 == v2 || (v1 != null && v1.equals(v2))) 
1099                        return true;
1100                }
1101                return false;
1102            } else {
1103                return false;
1104            }
1105        }
1106        
1107        /**
1108         * Whether or not the entry is storing a key.
1109         * Only the root can potentially be empty, all other
1110         * nodes must have a key.
1111         */
1112        public boolean isEmpty() {
1113            return key == null;
1114        }
1115        
1116        public K getKey() {
1117            return key;
1118        }
1119        
1120        public V getValue() {
1121            return value;
1122        }
1123        
1124        public V setValue(V value) {
1125            V o = this.value;
1126            this.value = value;
1127            return o;
1128        }
1129        
1130        /** 
1131         * Replaces the old key and value with the new ones.
1132         * Returns the old vlaue.
1133         */
1134        private V setKeyValue(K key, V value) {
1135            this.key = key;
1136            return setValue(value);
1137        }
1138        
1139        /** Neither the left nor right child is a loopback */
1140        private boolean isInternalNode() {
1141            return left != this && right != this;
1142        }
1143        
1144        /** Either the left or right child is a loopback */
1145        private boolean isExternalNode() {
1146            return !isInternalNode();
1147        }
1148
1149        public String toString() {
1150            StringBuilder buffer = new StringBuilder();
1151            
1152            if (bitIndex == -1) {
1153                buffer.append("RootEntry(");
1154            } else {
1155                buffer.append("Entry(");
1156            }
1157            
1158            buffer.append("key=").append(getKey()).append(" [").append(bitIndex).append("], ");
1159            buffer.append("value=").append(getValue()).append(", ");
1160            //buffer.append("bitIndex=").append(bitIndex).append(", ");
1161            
1162            if (parent != null) {
1163                if (parent.bitIndex == -1) {
1164                    buffer.append("parent=").append("ROOT");
1165                } else {
1166                    buffer.append("parent=").append(parent.getKey()).append(" [").append(parent.bitIndex).append("]");
1167                }
1168            } else {
1169                buffer.append("parent=").append("null");
1170            }
1171            buffer.append(", ");
1172            
1173            if (left != null) {
1174                if (left.bitIndex == -1) {
1175                    buffer.append("left=").append("ROOT");
1176                } else {
1177                    buffer.append("left=").append(left.getKey()).append(" [").append(left.bitIndex).append("]");
1178                }
1179            } else {
1180                buffer.append("left=").append("null");
1181            }
1182            buffer.append(", ");
1183            
1184            if (right != null) {
1185                if (right.bitIndex == -1) {
1186                    buffer.append("right=").append("ROOT");
1187                } else {
1188                    buffer.append("right=").append(right.getKey()).append(" [").append(right.bitIndex).append("]");
1189                }
1190            } else {
1191                buffer.append("right=").append("null");
1192            }
1193            buffer.append(", ");
1194            
1195            if(predecessor != null) {
1196                if(predecessor.bitIndex == -1) {
1197                    buffer.append("predecessor=").append("ROOT");
1198                } else {
1199                    buffer.append("predecessor=").append(predecessor.getKey()).append(" [").append(predecessor.bitIndex).append("]");
1200                }
1201            }
1202            
1203            buffer.append(")");
1204            return buffer.toString();
1205        }
1206    }
1207    
1208    /** 
1209     * Defines the interface to analyze {@link Trie} keys on a bit 
1210     * level. {@code KeyAnalyzer}'s
1211     * methods return the length of the key in bits, whether or not a bit is 
1212     * set, and bits per element in the key. 
1213     * <p>
1214     * Additionally, a method determines if a key is a prefix of another key and
1215     * returns the bit index where one key is different from another key (if 
1216     * the key and found key are equal than the return value is EQUAL_BIT_KEY).
1217     * <p>
1218     * {@code KeyAnalyzer} defines:<br>
1219     * <table cellspace="5">
1220     * <tr><td>NULL_BIT_KEY</td><td>When key's bits are all zero</td></tr>
1221     * <tr><td> EQUAL_BIT_KEY </td><td>When keys are the same </td></tr>
1222     * </table>
1223     */
1224    public static interface KeyAnalyzer<K> extends Comparator<K>, Serializable {
1225        
1226        /** Returned by bitIndex if key's bits are all 0 */
1227        public static final int NULL_BIT_KEY = -1;
1228        
1229        /** 
1230         * Returned by bitIndex if key and found key are
1231         * equal. This is a very very specific case and
1232         * shouldn't happen on a regular basis
1233         */
1234        public static final int EQUAL_BIT_KEY = -2;
1235        
1236        /** 
1237         * Returns the length of the Key in bits. 
1238         */
1239        public int length(K key);
1240        
1241        /** Returns whether or not a bit is set */
1242        public boolean isBitSet(K key, int keyLength, int bitIndex);
1243        
1244        /**
1245         * Returns the n-th different bit between key and found.
1246         * This starts the comparison in key at 'keyStart' and goes
1247         * for 'keyLength' bits, and compares to the found key
1248         * starting at 'foundStart' and going for 'foundLength' bits.
1249         */
1250        public int bitIndex(K key, int keyStart, int keyLength,
1251                            K found, int foundStart, int foundLength);
1252        
1253        /**
1254         * Returns the number of bits per element in the key.
1255         * This is only useful for variable-length keys, such as Strings.
1256         */
1257        public int bitsPerElement();
1258        
1259        /**
1260         * Determines whether or not the given prefix (from offset to length)
1261         * is a prefix of the given key.
1262         */
1263        public boolean isPrefix(K prefix, int offset, int length, K key);
1264    }
1265    
1266    /** An iterator that stores a single TrieEntry. */
1267    private class SingletonIterator implements Iterator<Map.Entry<K, V>> {
1268        private final TrieEntry<K, V> entry;
1269        private int hit = 0;
1270        
1271        public SingletonIterator(TrieEntry<K, V> entry) {
1272            this.entry = entry;
1273        }
1274        
1275        public boolean hasNext() {
1276            return hit == 0;
1277        }
1278
1279        public Map.Entry<K, V> next() {
1280            if(hit != 0)
1281                throw new NoSuchElementException();
1282            hit++;
1283            return entry;
1284        }
1285
1286        public void remove() {
1287            if(hit != 1)
1288                throw new IllegalStateException();
1289            hit++;
1290            PatriciaTrie.this.removeEntry(entry);
1291        }
1292        
1293    }
1294    
1295    /** An iterator for the entries. */
1296    private abstract class NodeIterator<E> implements Iterator<E> {
1297        protected int expectedModCount = modCount;   // For fast-fail 
1298        protected TrieEntry<K, V> next; // the next node to return
1299        protected TrieEntry<K, V> current; // the current entry we're on
1300        
1301        // Starts iteration from the beginning.
1302        protected NodeIterator() {
1303            next = PatriciaTrie.this.nextEntry(null);
1304        }
1305        
1306        // Starts iteration at the given entry.
1307        protected NodeIterator(TrieEntry<K, V> firstEntry) {
1308            next = firstEntry;
1309        }
1310        
1311        public boolean hasNext() {
1312            return next != null;
1313        }
1314        
1315        TrieEntry<K,V> nextEntry() { 
1316            if (modCount != expectedModCount)
1317                throw new ConcurrentModificationException();
1318            TrieEntry<K,V> e = next;
1319            if (e == null) 
1320                throw new NoSuchElementException();
1321            
1322            next = findNext(e);
1323            current = e;
1324            return e;
1325        }
1326        
1327        protected TrieEntry<K, V> findNext(TrieEntry<K, V> prior) {
1328            return PatriciaTrie.this.nextEntry(prior);
1329        }
1330        
1331        public void remove() {
1332            if (current == null)
1333                throw new IllegalStateException();
1334            if (modCount != expectedModCount)
1335                throw new ConcurrentModificationException();
1336            
1337            TrieEntry<K, V> node = current;
1338            current = null;
1339            PatriciaTrie.this.removeEntry(node);
1340            
1341            expectedModCount = modCount;
1342        }
1343    }
1344
1345    private class ValueIterator extends NodeIterator<V> {
1346        public V next() {
1347            return nextEntry().value;
1348        }
1349    }
1350
1351    private class KeyIterator extends NodeIterator<K> {
1352        public K next() {
1353            return nextEntry().getKey();
1354        }
1355    }
1356
1357    private class EntryIterator extends NodeIterator<Map.Entry<K,V>> {
1358        public Map.Entry<K,V> next() {
1359            return nextEntry();
1360        }
1361    }
1362    
1363    /** An iterator for iterating over a prefix search. */
1364    private class PrefixEntryIterator extends NodeIterator<Map.Entry<K, V>> {
1365        // values to reset the subtree if we remove it.
1366        protected final K prefix; 
1367        protected final int offset;
1368        protected final int length;
1369        protected boolean lastOne;
1370        
1371        protected TrieEntry<K, V> subtree; // the subtree to search within
1372        
1373        // Starts iteration at the given entry & search only within the given subtree.
1374        PrefixEntryIterator(TrieEntry<K, V> startScan, K prefix, int offset, int length) {
1375            subtree = startScan;
1376            next = PatriciaTrie.this.followLeft(startScan);
1377            this.prefix = prefix;
1378            this.offset = offset;
1379            this.length = length;
1380        }
1381
1382        public Map.Entry<K,V> next() {
1383            Map.Entry<K, V> entry = nextEntry();
1384            if(lastOne)
1385                next = null;
1386            return entry;
1387        }
1388        
1389        @Override
1390        protected TrieEntry<K, V> findNext(TrieEntry<K, V> prior) {
1391            return PatriciaTrie.this.nextEntryInSubtree(prior, subtree);
1392        }
1393        
1394        @Override
1395        public void remove() {
1396            // If the current entry we're removing is the subtree
1397            // then we need to find a new subtree parent.
1398            boolean needsFixing = false;
1399            int bitIdx = subtree.bitIndex;
1400            if(current == subtree)
1401                needsFixing = true;
1402            
1403            super.remove();
1404            
1405            // If the subtree changed its bitIndex or we
1406            // removed the old subtree, get a new one.
1407            if(bitIdx != subtree.bitIndex || needsFixing)
1408                subtree = subtree(prefix, offset, length);
1409            
1410            // If the subtree's bitIndex is less than the
1411            // length of our prefix, it's the last item
1412            // in the prefix tree.
1413            if(length >= subtree.bitIndex)
1414                lastOne = true;
1415        }
1416        
1417    }
1418    
1419    /** An iterator for submaps. */
1420    private class SubMapEntryIterator extends NodeIterator<Map.Entry<K,V>> {
1421        private final K firstExcludedKey;
1422
1423        SubMapEntryIterator(TrieEntry<K,V> first, TrieEntry<K,V> firstExcluded) {
1424            super(first);
1425            firstExcludedKey = 
1426              (firstExcluded == null ? null : firstExcluded.key);
1427        }
1428
1429        public boolean hasNext() {
1430            return next != null && next.key != firstExcludedKey;
1431        }
1432
1433        public Map.Entry<K,V> next() {
1434            if (next == null || next.key == firstExcludedKey)
1435                throw new NoSuchElementException();
1436            return nextEntry();
1437        }
1438    }
1439
1440    Iterator<K> newKeyIterator()   {
1441        return new KeyIterator();
1442    }
1443    
1444    Iterator<V> newValueIterator()   {
1445        return new ValueIterator();
1446    }
1447    
1448    Iterator<Map.Entry<K,V>> newEntryIterator()   {
1449        return new EntryIterator();
1450    }
1451    
1452    /**
1453     * Each of these fields are initialized to contain an instance of the
1454     * appropriate view the first time this view is requested.  The views are
1455     * stateless, so there's no reason to create more than one of each.
1456     */
1457    private transient volatile Set<K>               keySet = null;
1458    private transient volatile Collection<V>        values = null;
1459    private transient volatile Set<Map.Entry<K,V>>  entrySet = null;
1460    
1461    private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
1462        public Iterator<Map.Entry<K,V>> iterator() {
1463            return newEntryIterator();
1464        }
1465        
1466        public boolean contains(Object o) {
1467            if (!(o instanceof Map.Entry))
1468                return false;
1469            
1470            TrieEntry<K,V> candidate = getEntry(((Map.Entry)o).getKey());
1471            return candidate != null && candidate.equals(o);
1472        }
1473        
1474        public boolean remove(Object o) {
1475            int size = size();
1476            PatriciaTrie.this.remove(o);
1477            return size != size();
1478        }
1479        
1480        public int size() {
1481            return size;
1482        }
1483        
1484        public void clear() {
1485            PatriciaTrie.this.clear();
1486        }
1487    }
1488    
1489    /**
1490     * Returns a set view of the keys contained in this map.  The set is
1491     * backed by the map, so changes to the map are reflected in the set, and
1492     * vice-versa.  The set supports element removal, which removes the
1493     * corresponding mapping from this map, via the {@code Iterator.remove},
1494     * {@code Set.remove}, {@code removeAll}, {@code retainAll}, and
1495     * {@code clear} operations.  It does not support the {@code add} or
1496     * {@code addAll} operations.
1497     *
1498     * @return a set view of the keys contained in this map.
1499     */
1500    public Set<K> keySet() {
1501        Set<K> ks = keySet;
1502        return (ks != null ? ks : (keySet = new KeySet()));
1503    }
1504
1505    private class KeySet extends AbstractSet<K> {
1506        public Iterator<K> iterator() {
1507            return newKeyIterator();
1508        }
1509        public int size() {
1510            return size;
1511        }
1512        public boolean contains(Object o) {
1513            return containsKey(o);
1514        }
1515        public boolean remove(Object o) {
1516            int size = size();
1517            PatriciaTrie.this.remove(o);
1518            return size != size();
1519        }
1520        public void clear() {
1521            PatriciaTrie.this.clear();
1522        }
1523    }
1524    
1525    /**
1526     * Returns a collection view of the values contained in this map. The
1527     * collection is backed by the map, so changes to the map are reflected in
1528     * the collection, and vice-versa. The collection supports element
1529     * removal, which removes the corresponding mapping from this map, via the
1530     * {@code Iterator.remove}, {@code Collection.remove},
1531     * {@code removeAll}, {@code retainAll}, and {@code clear} operations.
1532     * It does not support the {@code add} or {@code addAll} operations.
1533     *
1534     * @return a collection view of the values contained in this map.
1535     */
1536    public Collection<V> values() {
1537        Collection<V> vs = values;
1538        return (vs != null ? vs : (values = new Values()));
1539    }
1540    
1541    /** Test two values for equality.  Works with null values. */
1542    private static boolean valEquals(Object o1, Object o2) {
1543        return (o1==null ? o2==null : o1.equals(o2));
1544    }
1545
1546    private class Values extends AbstractCollection<V> {
1547        public Iterator<V> iterator() {
1548            return newValueIterator();
1549        }
1550        public int size() {
1551            return size;
1552        }
1553        public boolean contains(Object o) {
1554            return containsValue(o);
1555        }
1556        public void clear() {
1557            PatriciaTrie.this.clear();
1558        }
1559        public boolean remove(Object o) {
1560            for(Iterator<V> i =  iterator(); i.hasNext(); ) {
1561                V v = i.next();
1562                if(valEquals(v, o)) {
1563                    i.remove();
1564                    return true;
1565                }
1566            }
1567            return false;
1568        }
1569    }
1570    
1571    /**
1572     * Returns the first entry the Trie is storing.
1573     * 
1574     * This is implemented by going always to the left until
1575     * we encounter a valid uplink. That uplink is the first key.
1576     */
1577    private TrieEntry<K, V> firstEntry() {
1578        // if Trie is empty, no first node.
1579        if(isEmpty())
1580            return null;
1581        
1582        return followLeft(root);
1583    }
1584    
1585    /** Goes left through the tree until it finds a valid node. */
1586    private TrieEntry<K, V> followLeft(TrieEntry<K, V> node) {
1587        while(true) {
1588            TrieEntry<K, V> child = node.left;
1589            // if we hit root and it didn't have a node, go right instead.
1590            if(child.isEmpty())
1591                child = node.right;
1592            
1593            if(child.bitIndex <= node.bitIndex)
1594                return child;
1595            
1596            node = child;
1597        }
1598    }
1599    
1600    /**
1601     * Returns the last entry the Trie is storing.
1602     * <p>
1603     * This is implemented by going always to the right until
1604     * we encounter a valid uplink. That uplink is the last key.
1605     */
1606    private TrieEntry<K, V> lastEntry() {
1607        return followRight(root.left);
1608    }
1609    
1610    /** Traverses down the right path until it finds an uplink. */
1611    protected TrieEntry<K, V> followRight(TrieEntry<K, V> node) {
1612        // if Trie is empty, no last entry.
1613        if(node.right == null)
1614            return null;
1615        
1616        // Go as far right as possible, until we encounter an uplink.
1617        while(node.right.bitIndex > node.bitIndex)
1618            node = node.right;
1619        
1620        return node.right;
1621    }
1622
1623    public K firstKey() {
1624        return firstEntry().getKey();
1625    }
1626
1627    public SortedMap<K, V> headMap(K toKey) {
1628        return new SubMap(null, toKey);
1629    }
1630
1631    public K lastKey() {
1632        TrieEntry<K, V> entry = lastEntry();
1633        if(entry != null)
1634            return entry.getKey();
1635        else
1636            return null;
1637    }
1638
1639    
1640    public SortedMap<K, V> subMap(K fromKey, K toKey) {
1641        return new SubMap(fromKey, toKey);
1642    }
1643
1644    public SortedMap<K, V> tailMap(K fromKey) {
1645        return new SubMap(fromKey, null);
1646    } 
1647    
1648    /**
1649     * Returns an entry strictly higher than the given key,
1650     * or null if no such entry exists.
1651     */
1652    protected TrieEntry<K,V> higherEntry(K key) {
1653        // TODO: Cleanup so that we don't actually have to add/remove from the
1654        //       tree.  (We do it here because there are other well-defined 
1655        //       functions to perform the search.)
1656        int keyLength = length(key);
1657        
1658        if (keyLength == 0) {
1659            if(!root.isEmpty()) {
1660                // If data in root, and more after -- return it.
1661                if(size() > 1) {
1662                    return nextEntry(root);
1663                } else { // If no more after, no higher entry.
1664                    return null;
1665                }
1666            } else {
1667                // Root is empty & we want something after empty, return first.
1668                return firstEntry();
1669            }
1670        }
1671        
1672        TrieEntry<K, V> found = getNearestEntryForKey(key, keyLength);
1673        if (key.equals(found.key))
1674            return nextEntry(found);
1675        
1676        int bitIndex = bitIndex(key, found.key);
1677        if (isValidBitIndex(bitIndex)) {
1678            TrieEntry<K, V> added = new TrieEntry<K, V>(key, null, bitIndex);
1679            addEntry(added, keyLength);
1680            incrementSize(); // must increment because remove will decrement
1681            TrieEntry<K, V> ceil = nextEntry(added);
1682            removeEntry(added);
1683            modCount -= 2; // we didn't really modify it.
1684            return ceil;
1685        } else if (isNullBitKey(bitIndex)) {
1686            if (!root.isEmpty())
1687                return firstEntry();
1688            else if(size() > 1)
1689                return nextEntry(firstEntry());
1690            else
1691                return null;
1692        } else if (isEqualBitKey(bitIndex)) {
1693            return nextEntry(found);
1694        }
1695
1696        // we should have exited above.
1697        throw new IllegalStateException("invalid lookup: " + key);
1698    }
1699    
1700    /**
1701     * Returns a key-value mapping associated with the least key greater
1702     * than or equal to the given key, or null if there is no such key.
1703     */
1704    protected TrieEntry<K,V> ceilingEntry(K key) {
1705        // Basically:
1706        // Follow the steps of adding an entry, but instead...
1707        //
1708        // - If we ever encounter a situation where we found an equal
1709        //   key, we return it immediately.
1710        //
1711        // - If we hit an empty root, return the first iterable item.
1712        //
1713        // - If we have to add a new item, we temporarily add it,
1714        //   find the successor to it, then remove the added item.
1715        //
1716        // These steps ensure that the returned value is either the
1717        // entry for the key itself, or the first entry directly after
1718        // the key.
1719        
1720        // TODO: Cleanup so that we don't actually have to add/remove from the
1721        //       tree.  (We do it here because there are other well-defined 
1722        //       functions to perform the search.)
1723        int keyLength = length(key);
1724        
1725        if (keyLength == 0) {
1726            if(!root.isEmpty())
1727                return root;
1728            else
1729                return firstEntry();
1730        }
1731        
1732        TrieEntry<K, V> found = getNearestEntryForKey(key, keyLength);
1733        if (key.equals(found.key))
1734            return found;
1735        
1736        int bitIndex = bitIndex(key, found.key);
1737        if (isValidBitIndex(bitIndex)) {
1738            TrieEntry<K, V> added = new TrieEntry<K, V>(key, null, bitIndex);
1739            addEntry(added, keyLength);
1740            incrementSize(); // must increment because remove will decrement
1741            TrieEntry<K, V> ceil = nextEntry(added);
1742            removeEntry(added);
1743            modCount -= 2; // we didn't really modify it.
1744            return ceil;
1745        } else if (isNullBitKey(bitIndex)) {
1746            if (!root.isEmpty())
1747                return root;
1748            else
1749                return firstEntry();
1750        } else if (isEqualBitKey(bitIndex)) {
1751            return found;
1752        }
1753
1754        // we should have exited above.
1755        throw new IllegalStateException("invalid lookup: " + key);
1756    }
1757    
1758    /**
1759     * Returns a key-value mapping associated with the greatest key
1760     * strictly less than the given key, or null if there is no such key.
1761     */
1762    protected TrieEntry<K,V> lowerEntry(K key) {
1763        // Basically:
1764        // Follow the steps of adding an entry, but instead...
1765        //
1766        // - If we ever encounter a situation where we found an equal
1767        //   key, we return it's previousEntry immediately.
1768        //
1769        // - If we hit root (empty or not), return null.
1770        //
1771        // - If we have to add a new item, we temporarily add it,
1772        //   find the previousEntry to it, then remove the added item.
1773        //
1774        // These steps ensure that the returned value is always just before
1775        // the key or null (if there was nothing before it).
1776        
1777        // TODO: Cleanup so that we don't actually have to add/remove from the
1778        //       tree.  (We do it here because there are other well-defined 
1779        //       functions to perform the search.)
1780        int keyLength = length(key);
1781        
1782        if (keyLength == 0) {
1783            return null; // there can never be anything before root.
1784        }
1785        
1786        TrieEntry<K, V> found = getNearestEntryForKey(key, keyLength);
1787        if (key.equals(found.key))
1788            return previousEntry(found);
1789        
1790        int bitIndex = bitIndex(key, found.key);
1791        if (isValidBitIndex(bitIndex)) {
1792            TrieEntry<K, V> added = new TrieEntry<K, V>(key, null, bitIndex);
1793            addEntry(added, keyLength);
1794            incrementSize(); // must increment because remove will decrement
1795            TrieEntry<K, V> prior = previousEntry(added);
1796            removeEntry(added);
1797            modCount -= 2; // we didn't really modify it.
1798            return prior;
1799        } else if (isNullBitKey(bitIndex)) {
1800            return null;
1801        } else if (isEqualBitKey(bitIndex)) {
1802            return previousEntry(found);
1803        }
1804
1805        // we should have exited above.
1806        throw new IllegalStateException("invalid lookup: " + key);
1807    }
1808    
1809    /**
1810     * Returns a key-value mapping associated with the greatest key
1811     * less than or equal to the given key, or null if there is no such key.
1812     */
1813    protected TrieEntry<K,V> floorEntry(K key) {        
1814        // TODO: Cleanup so that we don't actually have to add/remove from the
1815        //       tree.  (We do it here because there are other well-defined 
1816        //       functions to perform the search.)
1817        int keyLength = length(key);
1818        
1819        if (keyLength == 0) {
1820            if(!root.isEmpty())
1821                return root;
1822            else
1823                return null;
1824        }
1825        
1826        TrieEntry<K, V> found = getNearestEntryForKey(key, keyLength);
1827        if (key.equals(found.key))
1828            return found;
1829        
1830        int bitIndex = bitIndex(key, found.key);
1831        if (isValidBitIndex(bitIndex)) {
1832            TrieEntry<K, V> added = new TrieEntry<K, V>(key, null, bitIndex);
1833            addEntry(added, keyLength);
1834            incrementSize(); // must increment because remove will decrement
1835            TrieEntry<K, V> floor = previousEntry(added);
1836            removeEntry(added);
1837            modCount -= 2; // we didn't really modify it.
1838            return floor;
1839        } else if (isNullBitKey(bitIndex)) {
1840            if (!root.isEmpty())
1841                return root;
1842            else
1843                return null;
1844        } else if (isEqualBitKey(bitIndex)) {
1845            return found;
1846        }
1847
1848        // we should have exited above.
1849        throw new IllegalStateException("invalid lookup: " + key);
1850    }
1851    
1852    
1853    /**
1854     * Finds the subtree that contains the prefix.
1855     * 
1856     * This is very similar to getR but with the difference that
1857     * we stop the lookup if h.bitIndex > keyLength.
1858     */
1859    private TrieEntry<K, V> subtree(K prefix, int offset, int length) {
1860        TrieEntry<K, V> current = root.left;
1861        TrieEntry<K, V> path = root;
1862        while(true) {
1863            if(current.bitIndex <= path.bitIndex || length < current.bitIndex)
1864                break;
1865            
1866            path = current;
1867            if(!isBitSet(prefix, length+offset, current.bitIndex+offset)) {
1868                current = current.left;
1869            } else {
1870                current = current.right;
1871            }
1872        }        
1873
1874        // Make sure the entry is valid for a subtree.
1875        TrieEntry<K, V> entry = current.isEmpty() ? path : current;
1876        
1877        // If entry is root, it can't be empty.
1878        if (entry.isEmpty())
1879            return null;
1880        
1881        int offsetLength = offset + length;
1882        
1883        // if root && length of root is less than length of lookup,
1884        // there's nothing.
1885        // (this prevents returning the whole subtree if root has an empty
1886        //  string and we want to lookup things with "\0")
1887        if(entry == root && length(entry.getKey()) < offsetLength)
1888            return null;
1889        
1890        // Found key's length-th bit differs from our key
1891        // which means it cannot be the prefix...
1892        if(isBitSet(prefix, offsetLength, offsetLength) != 
1893          isBitSet(entry.key, length(entry.key), length)) {
1894            return null;
1895        }
1896        
1897        // ... or there are less than 'length' equal bits
1898        int bitIndex = keyAnalyzer.bitIndex(prefix, offset, length,
1899                                            entry.key, 0, length(entry.getKey()));
1900        if (bitIndex >= 0 && bitIndex < length)
1901            return null;
1902        
1903        return entry;
1904    }
1905    
1906    /** A submap used for prefix views over the Trie. */
1907    private class PrefixSubMap extends SubMap {
1908        protected final K prefix;
1909        protected final int offset;
1910        protected final int length;        
1911        private transient int keyModCount = 0;
1912        protected int size;
1913        
1914        PrefixSubMap(K prefix, int offset, int length) {
1915            this.prefix = prefix;
1916            this.offset = offset;
1917            this.length = length;
1918            fromInclusive = false;
1919        }
1920        
1921        public K firstKey() {
1922            fixup();
1923            TrieEntry<K,V> e;
1924            if(fromKey == null) {
1925                e = firstEntry();
1926            } else {
1927                e = higherEntry(fromKey);
1928            }
1929            
1930            K first = e != null ? e.getKey() : null;
1931            if (e == null || !keyAnalyzer.isPrefix(prefix, offset, length, first))
1932                throw new NoSuchElementException();
1933            return first;
1934        }
1935
1936        public K lastKey() {
1937            fixup();
1938            TrieEntry<K,V> e;
1939            if(toKey == null) {
1940                e = lastEntry();
1941            } else {
1942                e = lowerEntry(toKey);
1943            }
1944            
1945            K last = e != null ? e.getKey() : null;
1946            if (e == null || !keyAnalyzer.isPrefix(prefix, offset, length, last))
1947                throw new NoSuchElementException();
1948            return last;
1949        }
1950        
1951        protected boolean inRange(K key) {
1952            return keyAnalyzer.isPrefix(prefix, offset, length, key);
1953        }
1954
1955        protected boolean inRange2(K key) {
1956            return keyAnalyzer.isPrefix(prefix, offset, length, key);
1957        }
1958        
1959        protected boolean inToRange(K key, boolean forceInclusive) {
1960            return keyAnalyzer.isPrefix(prefix, offset, length, key);
1961        }
1962        
1963        protected boolean inFromRange(K key, boolean forceInclusive) {
1964            return keyAnalyzer.isPrefix(prefix, offset, length, key);
1965        }
1966        
1967        private void fixup() {
1968            // The trie has changed since we last
1969            // found our toKey / fromKey
1970            if(modCount != keyModCount) {
1971                Iterator<Map.Entry<K, V>> iter = entrySet().iterator();
1972                size = 0;
1973                
1974                Map.Entry<K, V> entry = null;
1975                if(iter.hasNext()) {
1976                    entry = iter.next();
1977                    size = 1;
1978                }
1979                
1980                fromKey = entry == null ? null : entry.getKey();
1981                if(fromKey != null) {
1982                    TrieEntry<K, V> prior = previousEntry((TrieEntry<K, V>)entry);
1983                    fromKey = prior == null ? null : prior.getKey();
1984                }
1985                
1986                toKey = fromKey;
1987                
1988                while(iter.hasNext()) {
1989                    size++;
1990                    entry = iter.next();
1991                }
1992                
1993                toKey = entry == null ? null : entry.getKey();
1994                
1995                if(toKey != null) {
1996                    entry = nextEntry((TrieEntry<K, V>)entry);
1997                    toKey = entry == null ? null : entry.getKey();
1998                }
1999                
2000                keyModCount = modCount;
2001            }
2002        }
2003        
2004        protected Set<Map.Entry<K, V>> newSubMapEntrySet() {
2005            return new PrefixEntrySetView();
2006        }
2007
2008        private class PrefixEntrySetView extends SubMap.EntrySetView {
2009            private TrieEntry<K, V> prefixStart;
2010            private int iterModCount = 0;
2011            
2012            public int size() {
2013                fixup();
2014                return PrefixSubMap.this.size;
2015            }
2016
2017            @SuppressWarnings("unchecked")
2018            public Iterator<Map.Entry<K,V>> iterator() {
2019                if(modCount != iterModCount) {
2020                    prefixStart = subtree(prefix, offset, length);
2021                    iterModCount = modCount;
2022                }
2023                
2024                if(prefixStart == null) {
2025                    return new EmptyIterator();
2026                } else if(length >= prefixStart.bitIndex){
2027                    return new SingletonIterator(prefixStart);
2028                } else {
2029                    return new PrefixEntryIterator(prefixStart, prefix, offset, length);
2030                }
2031            }
2032        }
2033    }
2034    
2035    private class SubMap extends AbstractMap<K,V> implements SortedMap<K,V>, java.io.Serializable {
2036
2037        // TODO: add serialVersionUID
2038        
2039        /** The key to start from, null if the beginning. */
2040        protected K fromKey;
2041        
2042        /** The key to end at, null if till the end. */
2043        protected K toKey;
2044        
2045        /** Whether or not the 'from' is inclusive. */
2046        protected boolean fromInclusive;
2047        
2048        /** Whether or not the 'to' is inclusive. */
2049        protected boolean toInclusive;
2050        
2051        /**
2052         * Constructs a blank SubMap -- this should ONLY be used
2053         * by subclasses that wish to lazily construct their
2054         * fromKey or toKey
2055         */
2056        protected SubMap() {}
2057
2058        SubMap(K fromKey, K toKey) {
2059            if(fromKey == null && toKey == null)
2060                throw new IllegalArgumentException("must have a from or to!");
2061            if(fromKey != null && toKey != null && keyAnalyzer.compare(fromKey, toKey) > 0)
2062                throw new IllegalArgumentException("fromKey > toKey");
2063            this.fromKey = fromKey;
2064            this.toKey = toKey;
2065            fromInclusive = true;
2066        }
2067        
2068        public boolean isEmpty() {
2069            return entrySet().isEmpty();
2070        }
2071
2072        @SuppressWarnings("unchecked")
2073        public boolean containsKey(Object key) {
2074            return inRange((K) key) && PatriciaTrie.this.containsKey(key);
2075        }
2076       
2077        @SuppressWarnings("unchecked")
2078        public V remove(Object key) {
2079            if(!inRange((K)key))
2080                return null;
2081            return PatriciaTrie.this.remove(key);
2082        }
2083
2084        @SuppressWarnings("unchecked")
2085        public V get(Object key) {
2086            if (!inRange((K) key))
2087                return null;
2088            return PatriciaTrie.this.get(key);
2089        }
2090
2091        public V put(K key, V value) {
2092            if (!inRange(key))
2093                throw new IllegalArgumentException("key out of range");
2094            return PatriciaTrie.this.put(key, value);
2095        }
2096
2097        public Comparator<? super K> comparator() {
2098            return keyAnalyzer;
2099        }
2100 
2101        public K firstKey() {
2102            TrieEntry<K,V> e;
2103            if(fromKey == null) {
2104                e = firstEntry();
2105            } else {
2106                if(fromInclusive)
2107                    e = ceilingEntry(fromKey);
2108                else
2109                    e = higherEntry(fromKey);
2110            }
2111            
2112            K first = e != null ? e.getKey() : null;
2113            if (e == null || toKey != null && !inToRange(first, false))
2114                throw new NoSuchElementException();
2115            return first;
2116        }
2117
2118        public K lastKey() {
2119            TrieEntry<K,V> e;
2120            if(toKey == null) {
2121                e = lastEntry();
2122            } else {
2123                if(toInclusive)
2124                    e = floorEntry(toKey);
2125                else
2126                    e = lowerEntry(toKey);
2127            }
2128            
2129            K last = e != null ? e.getKey() : null;
2130            if (e == null || fromKey != null && !inFromRange(last, false))
2131                throw new NoSuchElementException();
2132            return last;
2133        }
2134
2135        private transient Set<Map.Entry<K,V>> entrySet;
2136
2137        public Set<Map.Entry<K,V>> entrySet() {
2138            if(entrySet == null)
2139                entrySet = newSubMapEntrySet();
2140            return entrySet;
2141        }
2142        
2143        protected Set<Map.Entry<K, V>> newSubMapEntrySet() {
2144            return new EntrySetView();
2145        }
2146
2147        class EntrySetView extends AbstractSet<Map.Entry<K,V>> {
2148            private transient int size = -1, sizeModCount;
2149
2150            public int size() {
2151                if (size == -1 || sizeModCount != PatriciaTrie.this.modCount) {
2152                    size = 0;  sizeModCount = PatriciaTrie.this.modCount;
2153                    Iterator i = iterator();
2154                    while (i.hasNext()) {
2155                        size++;
2156                        i.next();
2157                    }
2158                }
2159                return size;
2160            }
2161
2162            public boolean isEmpty() {
2163                return !iterator().hasNext();
2164            }
2165
2166            @SuppressWarnings("unchecked")
2167            public boolean contains(Object o) {
2168                if (!(o instanceof Map.Entry))
2169                    return false;
2170                Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
2171                K key = entry.getKey();
2172                if (!inRange(key))
2173                    return false;
2174                TrieEntry<K, V> node = getEntry(key);
2175                return node != null && 
2176                       valEquals(node.getValue(), entry.getValue());
2177            }
2178
2179            @SuppressWarnings("unchecked")
2180            public boolean remove(Object o) {
2181                if (!(o instanceof Map.Entry))
2182                    return false;
2183                Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
2184                K key = entry.getKey();
2185                if (!inRange(key))
2186                    return false;
2187                TrieEntry<K,V> node = getEntry(key);
2188                if (node!=null && valEquals(node.getValue(),entry.getValue())){
2189                    removeEntry(node);
2190                    return true;
2191                }
2192                return false;
2193            }
2194
2195            public Iterator<Map.Entry<K,V>> iterator() {
2196                return new SubMapEntryIterator(
2197                    (fromKey == null ? firstEntry() : ceilingEntry(fromKey)),
2198                    (toKey   == null ? null         : ceilingEntry(toKey)));
2199            }
2200        }
2201
2202        public SortedMap<K,V> subMap(K fromKey, K toKey) {
2203            if (!inRange2(fromKey))
2204                throw new IllegalArgumentException("fromKey out of range");
2205            if (!inRange2(toKey))
2206                throw new IllegalArgumentException("toKey out of range");
2207            return new SubMap(fromKey, toKey);
2208        }
2209
2210        public SortedMap<K,V> headMap(K toKey) {
2211            if (!inRange2(toKey))
2212                throw new IllegalArgumentException("toKey out of range");
2213            return new SubMap(fromKey, toKey);
2214        }
2215
2216        public SortedMap<K,V> tailMap(K fromKey) {
2217            if (!inRange2(fromKey))
2218                throw new IllegalArgumentException("fromKey out of range");
2219            return new SubMap(fromKey, toKey);
2220        }
2221
2222        protected boolean inRange(K key) {
2223            return (fromKey == null || inFromRange(key, false)) &&
2224                   (toKey   == null || inToRange(key, false));
2225        }
2226
2227        // This form allows the high endpoint (as well as all legit keys)
2228        protected boolean inRange2(K key) {
2229            return (fromKey == null || inFromRange(key, false)) &&
2230                   (toKey   == null || inToRange(key, true));
2231        }
2232        
2233        protected boolean inToRange(K key, boolean forceInclusive) {
2234            int ret = keyAnalyzer.compare(key, toKey);
2235            if(toInclusive || forceInclusive)
2236                return ret <= 0;
2237            else
2238                return ret < 0;
2239        }
2240        
2241        protected boolean inFromRange(K key, boolean forceInclusive) {
2242            int ret = keyAnalyzer.compare(key, fromKey);
2243            if (fromInclusive || forceInclusive)
2244                return ret >= 0;
2245            else
2246                return ret > 0;
2247        }
2248    }
2249    
2250    private static class EmptyIterator implements Iterator {
2251        public boolean hasNext() {
2252            return false;
2253        }
2254
2255        public Object next() {
2256            throw new NoSuchElementException();
2257        }
2258
2259        public void remove() {
2260            throw new IllegalStateException();
2261        }
2262        
2263    }
2264}