src/main/java/com/workplacesystems/utilsj/collections/TransactionalBidiTreeMap.java
private Object doRemove(final Object o, final int index)
                throws ConcurrentModificationException {

        checkNonNullComparable(o, index);

        String thread_id = getCurrentThreadId();

        Node<K,V>   node = lookupValid(o, index, thread_id);
        Object      rval = null;

        if (validNode(node, thread_id)) {
            if (node != null && node.is(Node.DELETED, null) && !node.is(Node.DELETED, thread_id))
                throw new ConcurrentModificationException();

            rval = node.getData(oppositeIndex(index));

            if (auto_commit || node.is(Node.ADDED, thread_id))
                doRedBlackDelete(node);
            else {
                node.setStatus(Node.DELETED, thread_id);
            }
        }


        return rval;
    }
private Object doRemove(final Object o, final int index)
                throws ConcurrentModificationException {

        checkNonNullComparable(o, index);

        String thread_id = getCurrentThreadId();

        Node<K,V>   node = lookupValid(o, index, thread_id);
        Object      rval = null;

        if (validNode(node, thread_id)) {
            if (node != null && node.is(Node.DELETED, null) && !node.is(Node.DELETED, thread_id))
                throw new ConcurrentModificationException();

            rval = node.getData(oppositeIndex(index));

            if (auto_commit || node.is(Node.ADDED, thread_id))
                doRedBlackDelete(node);
            else {
                node.setStatus(Node.DELETED, thread_id);
            }
        }


        return rval;
    }
common remove logic (remove by key or remove by value)

@param o the key, or value, that we're looking for
@param index KEY or VALUE

@return the key, if remove by value, or the value, if remove by
key. null if the specified key or value could not be
found

@throws ConcurrentModificationException if the node has been
removed by another thread