src/main/java/org/organicdesign/fp/collections/PersistentTreeMap.java
@Override public ImSortedMap<K,V> subMap(K fromKey, K toKey) {
        int diff = comp.compare(fromKey, toKey);

        if (diff > 0) {
            throw new IllegalArgumentException("fromKey is greater than toKey");
        }
        UnEntry<K,V> last = last();
        K lastKey = last.getKey();
        int compFromKeyLastKey = comp.compare(fromKey, lastKey);

        // If no intersect, return empty. We aren't checking the toKey vs. the firstKey() because
        // that's a single pass through the iterator loop which is probably as cheap as checking
        // here.
        if ( (diff == 0) || (compFromKeyLastKey > 0) )  {
            return new PersistentTreeMap<>(comp, null, 0);
        }
        // If map is entirely contained, just return it.
        if ( (comp.compare(fromKey, firstKey()) <= 0) &&
                    (comp.compare(toKey, lastKey) > 0) ) {
            return this;
        }
        // Don't iterate through entire map for only the last item.
        if (compFromKeyLastKey == 0) {
            return ofComp(comp, Collections.singletonList(last));
        }

        ImSortedMap<K,V> ret = new PersistentTreeMap<>(comp, null, 0);
        UnmodIterator<UnEntry<K,V>> iter = this.iterator();
        while (iter.hasNext()) {
            UnEntry<K,V> next = iter.next();
            K key = next.getKey();
            if (comp.compare(toKey, key) <= 0) {
                break;
            }
            if (comp.compare(fromKey, key) > 0) {
                continue;
            }
            ret = ret.assoc(key, next.getValue());
        }
        return ret;
    }
@Override public ImSortedMap<K,V> subMap(K fromKey, K toKey) {
        int diff = comp.compare(fromKey, toKey);

        if (diff > 0) {
            throw new IllegalArgumentException("fromKey is greater than toKey");
        }
        UnEntry<K,V> last = last();
        K lastKey = last.getKey();
        int compFromKeyLastKey = comp.compare(fromKey, lastKey);

        // If no intersect, return empty. We aren't checking the toKey vs. the firstKey() because
        // that's a single pass through the iterator loop which is probably as cheap as checking
        // here.
        if ( (diff == 0) || (compFromKeyLastKey > 0) )  {
            return new PersistentTreeMap<>(comp, null, 0);
        }
        // If map is entirely contained, just return it.
        if ( (comp.compare(fromKey, firstKey()) <= 0) &&
                    (comp.compare(toKey, lastKey) > 0) ) {
            return this;
        }
        // Don't iterate through entire map for only the last item.
        if (compFromKeyLastKey == 0) {
            return ofComp(comp, Collections.singletonList(last));
        }

        ImSortedMap<K,V> ret = new PersistentTreeMap<>(comp, null, 0);
        UnmodIterator<UnEntry<K,V>> iter = this.iterator();
        while (iter.hasNext()) {
            UnEntry<K,V> next = iter.next();
            K key = next.getKey();
            if (comp.compare(toKey, key) <= 0) {
                break;
            }
            if (comp.compare(fromKey, key) > 0) {
                continue;
            }
            ret = ret.assoc(key, next.getValue());
        }
        return ret;
    }
{@inheritDoc}