public Iterator<Map.Entry<K, V>> iterator() {
            return new GroupEntryIterator( mForward, mGroup, mComp );
        }

    }


    private final class AllValues extends AbstractCollection<V> {

        private final boolean               mForward;
        private final Comparable<? super V> mComp;

        AllValues( boolean forward, Comparable<? super V> comp ) {
            mForward = forward;
            mComp = comp;
        }


        public int size() {
            if( mComp == null ) {
                return mAllCount;
            } else {
                Iterator<V> iter  = iterator();
                int         count = 0;

                while( iter.hasNext() ) {
                    iter.next();
                    count++;
                }

                return count;
            }
        }

        public boolean contains( Object value ) {
            if( mComp != null && mComp.compareTo( (V)value ) != 0 ) { return false; }

            return findNodeThatContains( value ) != null;
        }

        public boolean remove( Object value ) {
            if( mComp != null && mComp.compareTo( (V)value ) != 0 ) { return false; }

            Node<K, V> node = findNodeThatContains( value );
            if( node == null ) { return false; }

            removeNodeCompletely( node, true );
            return true;
        }

        public void clear() {
            if( mComp == null ) {
                GroupMap.this.clear();
                return;
            }

            Iterator<V> iter = iterator();

            while( iter.hasNext() ) {
                iter.next();
                iter.remove();
            }
        }

        public Iterator<V> iterator() {
            return new AllValueIterator( mForward, mComp );
        }

    }


    private final class GroupValues extends AbstractCollection<V> {

        private final boolean               mForward;
        private final G                     mGroup;
        private final Comparable<? super V> mComp;

        GroupValues( boolean forward, G group, Comparable<? super V> comp ) {
            mForward = forward;
            mGroup = group;
            mComp = comp;
        }


        public int size() {
            if( mComp == null ) {
                return GroupMap.this.size( mGroup );
            } else {
                Iterator<V> iter  = iterator();
                int         count = 0;

                while( iter.hasNext() ) {
                    iter.next();
                    count++;
                }

                return count;
            }
        }

        public boolean contains( Object value ) {
            if( mComp != null && mComp.compareTo( (V)value ) != 0 ) { return false; }

            return findNodeThatContains( mGroup, value ) != null;
        }

        public boolean remove( Object value ) {
            if( mComp != null && mComp.compareTo( (V)value ) != 0 ) { return false; }

            Node<K, V> node = findNodeThatContains( mGroup, value );
            if( node == null ) { return false; }

            removeNodeCompletely( node, true );
            return true;
        }

        public void clear() {
            if( mComp == null ) {
                GroupMap.this.clear( mGroup );
                return;
            }

            Iterator<V> iter = iterator();

            while( iter.hasNext() ) {
                iter.next();
                iter.remove();
            }
        }

        public Iterator<V> iterator() {
            return new GroupValueIterator( mForward, mGroup, mComp );
        }

    }


    private final class Groups extends AbstractSet<G> {

        public int size() {
            return mGroupCount;
        }

        public boolean contains( Object group ) {
            return findGroupNode( group ) != null;
        }

        public boolean remove( Object group ) {
            GroupNode<K, V> node = findGroupNode( group );
            if( node == null ) { return false; }

            GroupMap.this.clear( (G)node.mGroup );
            return true;
        }

        public void clear() {
            GroupMap.this.clear();
        }

        public Iterator<G> iterator() {
            return new GroupTableIterator();
        }