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