src/main/java/com/workplacesystems/utilsj/collections/TransactionalBidiTreeMap.java
@Override
    public V put(final K key, final V value)
            throws ClassCastException, NullPointerException,
                   IllegalArgumentException, ConcurrentModificationException {

        checkKeyAndValue(key, value);

        Node<K,V> node = rootNode[KEY];

        String thread_id = getCurrentThreadId();

        if (node == null) {
            Node<K,V> root = new Node<K,V>(key, value);

            rootNode[KEY]   = root;
            rootNode[VALUE] = root;

            if (!auto_commit)
                root.setStatus(Node.ADDED, thread_id);

            grow();
        } else {
            while (true) {
                int cmp = compare(Node.ADDED, key, node.getStatus(), node.getData(KEY), KEY);

                if (cmp == 0) {
                    if (nextEqualValid(getFloorEqualNode(node, KEY), KEY, thread_id) != null)
                    {
                        String debug_message = "Cannot store a duplicate key (\"" + key + "\") in this Map";
                        log.debug (debug_message);             
                        throw new IllegalArgumentException(debug_message); 
                    }
                    
                    if (node.is(Node.ADDED, null))
                        throw new ConcurrentModificationException();
                    
                    if (node.getRight(KEY) != null) {
                        node = node.getRight(KEY);
                    } else if (node.getLeft(KEY) != null) {
                        node = node.getLeft(KEY);
                    } else {
                        Node<K,V> newNode = new Node<K,V>(key, value);

                        insertValue(newNode, thread_id);
                        node.setRight(newNode, KEY);
                        newNode.setParent(node, KEY);
                        doRedBlackInsert(newNode, KEY);
                        grow();

                        if (!auto_commit)
                            newNode.setStatus(Node.ADDED, thread_id);

                        break;
                    }
                } else if (cmp < 0) {
                    if (node.getLeft(KEY) != null) {
                        node = node.getLeft(KEY);
                    } else {
                        Node<K,V> newNode = new Node<K,V>(key, value);

                        insertValue(newNode, thread_id);
                        node.setLeft(newNode, KEY);
                        newNode.setParent(node, KEY);
                        doRedBlackInsert(newNode, KEY);
                        grow();

                        if (!auto_commit)
                            newNode.setStatus(Node.ADDED, thread_id);

                        break;
                    }
                } else {    // cmp > 0
                    if (node.getRight(KEY) != null) {
                        node = node.getRight(KEY);
                    } else {
                        Node<K,V> newNode = new Node<K,V>(key, value);

                        insertValue(newNode, thread_id);
                        node.setRight(newNode, KEY);
                        newNode.setParent(node, KEY);
                        doRedBlackInsert(newNode, KEY);
                        grow();

                        if (!auto_commit)
                            newNode.setStatus(Node.ADDED, thread_id);

                        break;
                    }
                }
            }
        }

        return null;
    }
@Override
    public V put(final K key, final V value)
            throws ClassCastException, NullPointerException,
                   IllegalArgumentException, ConcurrentModificationException {

        checkKeyAndValue(key, value);

        Node<K,V> node = rootNode[KEY];

        String thread_id = getCurrentThreadId();

        if (node == null) {
            Node<K,V> root = new Node<K,V>(key, value);

            rootNode[KEY]   = root;
            rootNode[VALUE] = root;

            if (!auto_commit)
                root.setStatus(Node.ADDED, thread_id);

            grow();
        } else {
            while (true) {
                int cmp = compare(Node.ADDED, key, node.getStatus(), node.getData(KEY), KEY);

                if (cmp == 0) {
                    if (nextEqualValid(getFloorEqualNode(node, KEY), KEY, thread_id) != null)
                    {
                        String debug_message = "Cannot store a duplicate key (\"" + key + "\") in this Map";
                        log.debug (debug_message);             
                        throw new IllegalArgumentException(debug_message); 
                    }
                    
                    if (node.is(Node.ADDED, null))
                        throw new ConcurrentModificationException();
                    
                    if (node.getRight(KEY) != null) {
                        node = node.getRight(KEY);
                    } else if (node.getLeft(KEY) != null) {
                        node = node.getLeft(KEY);
                    } else {
                        Node<K,V> newNode = new Node<K,V>(key, value);

                        insertValue(newNode, thread_id);
                        node.setRight(newNode, KEY);
                        newNode.setParent(node, KEY);
                        doRedBlackInsert(newNode, KEY);
                        grow();

                        if (!auto_commit)
                            newNode.setStatus(Node.ADDED, thread_id);

                        break;
                    }
                } else if (cmp < 0) {
                    if (node.getLeft(KEY) != null) {
                        node = node.getLeft(KEY);
                    } else {
                        Node<K,V> newNode = new Node<K,V>(key, value);

                        insertValue(newNode, thread_id);
                        node.setLeft(newNode, KEY);
                        newNode.setParent(node, KEY);
                        doRedBlackInsert(newNode, KEY);
                        grow();

                        if (!auto_commit)
                            newNode.setStatus(Node.ADDED, thread_id);

                        break;
                    }
                } else {    // cmp > 0
                    if (node.getRight(KEY) != null) {
                        node = node.getRight(KEY);
                    } else {
                        Node<K,V> newNode = new Node<K,V>(key, value);

                        insertValue(newNode, thread_id);
                        node.setRight(newNode, KEY);
                        newNode.setParent(node, KEY);
                        doRedBlackInsert(newNode, KEY);
                        grow();

                        if (!auto_commit)
                            newNode.setStatus(Node.ADDED, thread_id);

                        break;
                    }
                }
            }
        }

        return null;
    }
@ Override public V put ( final K key , final V value ) throws ClassCastException , NullPointerException , IllegalArgumentException , ConcurrentModificationException { checkKeyAndValue ( key , value ) ; Node < K , V > node = rootNode [ KEY ] ; String thread_id = getCurrentThreadId ( ) ; if ( node == null ) { Node < K , V > root = new Node < K , V > ( key , value ) ; rootNode [ KEY ] = root ; rootNode [ VALUE ] = root ; if ( ! auto_commit ) root . setStatus ( Node . ADDED , thread_id ) ; grow ( ) ; } else { while ( true ) { int cmp = compare ( Node . ADDED , key , node . getStatus ( ) , node . getData ( KEY ) , KEY ) ; if ( cmp == 0 ) { if ( nextEqualValid ( getFloorEqualNode ( node , KEY ) , KEY , thread_id ) != null ) { String debug_message = "Cannot store a duplicate key (\"" + key + "\") in this Map" ; log . debug ( debug_message ) ; throw new IllegalArgumentException ( debug_message ) ; } if ( node . is ( Node . ADDED , null ) ) throw new ConcurrentModificationException ( ) ; if ( node . getRight ( KEY ) != null ) { node = node . getRight ( KEY ) ; } else if ( node . getLeft ( KEY ) != null ) { node = node . getLeft ( KEY ) ; } else { Node < K , V > newNode = new Node < K , V > ( key , value ) ; insertValue ( newNode , thread_id ) ; node . setRight ( newNode , KEY ) ; newNode . setParent ( node , KEY ) ; doRedBlackInsert ( newNode , KEY ) ; grow ( ) ; if ( ! auto_commit ) newNode . setStatus ( Node . ADDED , thread_id ) ; break ; } } else if ( cmp < 0 ) { if ( node . getLeft ( KEY ) != null ) { node = node . getLeft ( KEY ) ; } else { Node < K , V > newNode = new Node < K , V > ( key , value ) ; insertValue ( newNode , thread_id ) ; node . setLeft ( newNode , KEY ) ; newNode . setParent ( node , KEY ) ; doRedBlackInsert ( newNode , KEY ) ; grow ( ) ; if ( ! auto_commit ) newNode . setStatus ( Node . ADDED , thread_id ) ; break ; } } else { // cmp > 0
 if ( node . getRight ( KEY ) != null ) { node = node . getRight ( KEY ) ; } else { Node < K , V > newNode = new Node < K , V > ( key , value ) ; insertValue ( newNode , thread_id ) ; node . setRight ( newNode , KEY ) ; newNode . setParent ( node , KEY ) ; doRedBlackInsert ( newNode , KEY ) ; grow ( ) ; if ( ! auto_commit ) newNode . setStatus ( Node . ADDED , thread_id ) ; break ; } } } } return null ; }
Associates the specified value with the specified key in this
map.

@param key key with which the specified value is to be
associated.
@param value value to be associated with the specified key.

@return null

@throws ClassCastException if the class of the specified key
or value prevents it from being
stored in this map.
@throws NullPointerException if the specified key or value
is null
@throws IllegalArgumentException if the key duplicates an
existing key, or if the
value duplicates an
existing value
Associates the specified value with the specified key in this map .