public synchronized V remove( K key )
        throws IOException
    {
        if ( key == null ) {
            throw new IllegalArgumentException( "Argument 'key' is null" );
        }

        BPage<K,V> rootPage = getRoot();
        if ( rootPage == null ) {
            return null;
        }
        boolean dirty = false;
        BPage.RemoveResult<K,V> remove = rootPage.remove( _height, key );
        if ( remove._underflow && rootPage.isEmpty() ) {
            _height -= 1;
            dirty = true;

            // TODO:  check contract for BPages to be removed from recman.
            if ( _height == 0 ) {
                _root = 0;
            } else {
                _root = rootPage.childBPage( _pageSize-1 )._recid;
            }
        }
        if ( remove._value != null ) {
            _entries--;
            dirty = true;
        }
        if ( dirty ) {
            _recman.update( _recid, this );
        }
        if(remove._value!=null)
        	for(RecordListener<K,V> l : recordListeners)
        		l.recordRemoved(key,remove._value);
        return remove._value;
    }