001    /*
002     * This file is part of McIDAS-V
003     *
004     * Copyright 2007-2013
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     */
028    package edu.wisc.ssec.mcidasv.util.trie;
029    
030    import java.io.Serializable;
031    import java.util.AbstractCollection;
032    import java.util.AbstractMap;
033    import java.util.AbstractSet;
034    import java.util.Collection;
035    import java.util.Comparator;
036    import java.util.ConcurrentModificationException;
037    import java.util.Iterator;
038    import java.util.Map;
039    import java.util.NoSuchElementException;
040    import java.util.Set;
041    import 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(...)</code> are suited only to 
069     * variable length keys, whereas <code>getPrefixedByBits(...)</code> 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</code> may throw a 
077     * <code>ClassCastException<code> 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     */
106    public 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</code>'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</code> 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 <tt>Iterator.remove</tt>,
1494         * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
1495         * <tt>clear</tt> operations.  It does not support the <tt>add</tt> or
1496         * <tt>addAll</tt> 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         * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
1531         * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
1532         * It does not support the <tt>add</tt> or <tt>addAll</tt> 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    }