src/main/java/com/workplacesystems/utilsj/collections/TransactionalBidiTreeMap.java
public FilterableSet<K> keySetByValue() {

        if (setOfKeysByValue == null) {
            setOfKeysByValue = new AbstractFilterableSet<K>() {

                @Override
                public Iterator<K> iterator() {

                    return new TransactionalBidiTreeMapIterator<K>(VALUE) {

                        @Override
                        protected K doGetNext() {
                            return (K)lastReturnedNode.getData(KEY);
                        }
                    };
                }

                @Override
                public int size() {
                    return TransactionalBidiTreeMap.this.size();
                }

                @Override
                public boolean contains(Object o) {
                    return containsKey(o);
                }

                @Override
                public boolean remove(Object o) {

                    int oldnodeCount = nodeCount;

                    TransactionalBidiTreeMap.this.remove(o);

                    return nodeCount != oldnodeCount;
                }

                @Override
                public void clear() {
                    TransactionalBidiTreeMap.this.clear();
                }
            };
        }

        return setOfKeysByValue;
    }
public FilterableSet<K> keySetByValue() {

        if (setOfKeysByValue == null) {
            setOfKeysByValue = new AbstractFilterableSet<K>() {

                @Override
                public Iterator<K> iterator() {

                    return new TransactionalBidiTreeMapIterator<K>(VALUE) {

                        @Override
                        protected K doGetNext() {
                            return (K)lastReturnedNode.getData(KEY);
                        }
                    };
                }

                @Override
                public int size() {
                    return TransactionalBidiTreeMap.this.size();
                }

                @Override
                public boolean contains(Object o) {
                    return containsKey(o);
                }

                @Override
                public boolean remove(Object o) {

                    int oldnodeCount = nodeCount;

                    TransactionalBidiTreeMap.this.remove(o);

                    return nodeCount != oldnodeCount;
                }

                @Override
                public void clear() {
                    TransactionalBidiTreeMap.this.clear();
                }
            };
        }

        return setOfKeysByValue;
    }
Returns a set view of the keys contained in this map.  The set
is backed by the map, so changes to the map are reflected in
the set, and vice-versa. If the map is modified while an
iteration over the set is in progress, the results of the
iteration are undefined. The set supports element removal,
which removes the corresponding mapping from the map, via the
Iterator.remove, Set.remove, removeAll, retainAll, and clear
operations. It does not support the add or addAll
operations.<p>

The difference between this method and keySet is that keySet's
iterator() method returns an iterator that iterates over the
keys in ascending order by key. This method's iterator method
iterates over the keys in ascending order by value.

@return a set view of the keys contained in this map.