"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cast_de_nrw_schule_svws_core_adt_map_AVLMap = exports.AVLMap = void 0;
const JavaMapEntry_1 = require("../../../java/util/JavaMapEntry");
const Comparable_1 = require("../../../java/lang/Comparable");
const AVLMapIntervall_1 = require("../../../core/adt/map/AVLMapIntervall");
const Comparator_1 = require("../../../java/util/Comparator");
const NullPointerException_1 = require("../../../java/lang/NullPointerException");
const AVLMapNode_1 = require("../../../core/adt/map/AVLMapNode");
const ClassCastException_1 = require("../../../java/lang/ClassCastException");
const SortedMap_1 = require("../../../java/util/SortedMap");
const JavaObject_1 = require("../../../java/lang/JavaObject");
const IllegalArgumentException_1 = require("../../../java/lang/IllegalArgumentException");
const NoSuchElementException_1 = require("../../../java/util/NoSuchElementException");
const AVLMapSubMap_1 = require("../../../core/adt/map/AVLMapSubMap");
const UnsupportedOperationException_1 = require("../../../java/lang/UnsupportedOperationException");
class AVLMap extends JavaObject_1.JavaObject {
    _infinityMinus = AVLMapIntervall_1.AVLMapIntervall._INFINITY_MINUS;
    _infinityPlus = AVLMapIntervall_1.AVLMapIntervall._INFINITY_PLUS;
    _dummyValue = new Object();
    _sub = new AVLMapSubMap_1.AVLMapSubMap(this, new AVLMapIntervall_1.AVLMapIntervall(this._infinityMinus, false, this._infinityPlus, false), true);
    _comparator;
    _comparatorNatural = { compare: (key1, key2) => {
            if ((key1 === null) || (key2 === null))
                throw new NullPointerException_1.NullPointerException();
            if (!((((key1 instanceof JavaObject_1.JavaObject) && (key1.isTranspiledInstanceOf('java.lang.Comparable')))) && (((key2 instanceof JavaObject_1.JavaObject) && (key2.isTranspiledInstanceOf('java.lang.Comparable'))))))
                throw new ClassCastException_1.ClassCastException();
            let k1 = (0, Comparable_1.cast_java_lang_Comparable)(key1);
            return k1.compareTo(key2);
        } };
    _root = null;
    _allowKeyAlone = false;
    /**
     * Implementation for method overloads of 'constructor'
     */
    constructor(__param0) {
        super();
        if ((typeof __param0 === "undefined")) {
            this._comparator = this._comparatorNatural;
        }
        else if (((typeof __param0 !== "undefined") && ((typeof __param0 !== 'undefined') && (__param0 instanceof Object) && (__param0 !== null) && ('compare' in __param0) && (typeof __param0.compare === 'function')) || (__param0 === null))) {
            let comparator = (0, Comparator_1.cast_java_util_Comparator)(__param0);
            this._comparator = comparator;
        }
        else if (((typeof __param0 !== "undefined") && ((__param0 instanceof JavaObject_1.JavaObject) && (__param0.isTranspiledInstanceOf('java.util.SortedMap'))) || (__param0 === null))) {
            let map = (0, SortedMap_1.cast_java_util_SortedMap)(__param0);
            this._comparator = (0, Comparator_1.cast_java_util_Comparator)(map.comparator());
            this._sub.putAll(map);
        }
        else
            throw new Error('invalid method overload');
    }
    toString() {
        return this._sub.toString();
    }
    /**
     * Bewirkt, dass das Hinzufügen von Keys ohne Value durch {@link AVLMapSubKeySet} erlaubt ist. Die Keys werden
     * auf einen Dummy-Wert gemapped.
     *
     * @param b Falls TRUE, dürfen KEYs ohne VALUE hinzugefügt werden.
     */
    allowKeyAlone(b) {
        this._allowKeyAlone = b;
    }
    equals(o) {
        return JavaObject_1.JavaObject.equalsTranspiler(this._sub, (o));
    }
    hashCode() {
        return JavaObject_1.JavaObject.getTranspilerHashCode(this._sub);
    }
    comparator() {
        return this._sub.comparator();
    }
    firstKey() {
        return this._sub.firstKey();
    }
    lastKey() {
        return this._sub.lastKey();
    }
    keySet() {
        return this._sub.keySet();
    }
    values() {
        return this._sub.values();
    }
    entrySet() {
        return this._sub.entrySet();
    }
    size() {
        return this._sub.size();
    }
    isEmpty() {
        return this._sub.isEmpty();
    }
    containsKey(key) {
        return this._sub.containsKey(key);
    }
    containsValue(value) {
        return this._sub.containsValue(value);
    }
    get(key) {
        return this._sub.get(key);
    }
    put(key, value) {
        return this._sub.put(key, value);
    }
    remove(key) {
        return this._sub.remove(key);
    }
    putAll(m) {
        this._sub.putAll(m);
    }
    clear() {
        this._sub.clear();
    }
    lowerEntry(key) {
        return this._sub.lowerEntry(key);
    }
    lowerKey(key) {
        return this._sub.lowerKey(key);
    }
    floorEntry(key) {
        return this._sub.floorEntry(key);
    }
    floorKey(key) {
        return this._sub.floorKey(key);
    }
    ceilingEntry(key) {
        return this._sub.ceilingEntry(key);
    }
    ceilingKey(key) {
        return this._sub.ceilingKey(key);
    }
    higherEntry(key) {
        return this._sub.higherEntry(key);
    }
    higherKey(key) {
        return this._sub.higherKey(key);
    }
    firstEntry() {
        return this._sub.firstEntry();
    }
    lastEntry() {
        return this._sub.lastEntry();
    }
    pollFirstEntry() {
        return this._sub.pollFirstEntry();
    }
    pollLastEntry() {
        return this._sub.pollLastEntry();
    }
    descendingMap() {
        return this._sub.descendingMap();
    }
    navigableKeySet() {
        return this._sub.navigableKeySet();
    }
    descendingKeySet() {
        return this._sub.descendingKeySet();
    }
    /**
     * Implementation for method overloads of 'subMap'
     */
    subMap(__param0, __param1, __param2, __param3) {
        if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean") && ((typeof __param2 !== "undefined") && (typeof __param2 !== "undefined")) && ((typeof __param3 !== "undefined") && typeof __param3 === "boolean")) {
            let fromKey = __param0;
            let fromInclusive = __param1;
            let toKey = __param2;
            let toInclusive = __param3;
            return this._sub.subMap(fromKey, fromInclusive, toKey, toInclusive);
        }
        else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && (typeof __param1 !== "undefined")) && (typeof __param2 === "undefined") && (typeof __param3 === "undefined")) {
            let fromKey = __param0;
            let toKey = __param1;
            return this._sub.subMap(fromKey, toKey);
        }
        else
            throw new Error('invalid method overload');
    }
    /**
     * Implementation for method overloads of 'headMap'
     */
    headMap(__param0, __param1) {
        if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
            let toKey = __param0;
            let inclusive = __param1;
            return this._sub.headMap(toKey, inclusive);
        }
        else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
            let toKey = __param0;
            return this._sub.headMap(toKey);
        }
        else
            throw new Error('invalid method overload');
    }
    /**
     * Implementation for method overloads of 'tailMap'
     */
    tailMap(__param0, __param1) {
        if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && ((typeof __param1 !== "undefined") && typeof __param1 === "boolean")) {
            let fromKey = __param0;
            let inclusive = __param1;
            return this._sub.tailMap(fromKey, inclusive);
        }
        else if (((typeof __param0 !== "undefined") && (typeof __param0 !== "undefined")) && (typeof __param1 === "undefined")) {
            let fromKey = __param0;
            return this._sub.tailMap(fromKey);
        }
        else
            throw new Error('invalid method overload');
    }
    bcAddEntryReturnBool(e, iv) {
        let old = this.bcAddEntryReturnOldValueOrNull(e.getKey(), e.getValue(), iv);
        return !this._valEquals(old, e.getValue());
    }
    bcAddAllEntries(c, iv) {
        let changed = false;
        for (let entry of c)
            changed = changed || this.bcAddEntryReturnBool(entry, iv);
        return changed;
    }
    bcAddEntryReturnOldValueOrNull(key, value, iv) {
        if (key === null)
            throw new NullPointerException_1.NullPointerException("TreeMap erlaubt keine NULL keys.");
        if (this._isOutOfRange(key, iv))
            throw new IllegalArgumentException_1.IllegalArgumentException("Der Schlüsselwert liegt nicht im gültigen Bereich.");
        if (this._root === null) {
            this._root = new AVLMapNode_1.AVLMapNode(key, value);
            return null;
        }
        let node = this._nodeGetOrNull(key, iv);
        let old = (node === null) ? null : node._val;
        this._root = this._nodePutRecursive(this._root, key, value);
        return old;
    }
    bcAddValue(e, iv) {
        throw new UnsupportedOperationException_1.UnsupportedOperationException();
    }
    bcAddKey(e, iv) {
        if (this._allowKeyAlone === false)
            throw new UnsupportedOperationException_1.UnsupportedOperationException();
        if (this.bcContainsKey(e, iv))
            return false;
        this.bcAddEntryReturnOldValueOrNull(e, this._dummyValue, iv);
        return true;
    }
    bcAddAllKeys(c, iv) {
        let changed = false;
        for (let key of c)
            changed = changed || this.bcAddKey(key, iv);
        return changed;
    }
    bcAddAllEntriesOfMap(map, iv) {
        for (let entry of map.entrySet())
            this.bcAddEntryReturnOldValueOrNull(entry.getKey(), entry.getValue(), iv);
    }
    bcContainsKey(objKey, iv) {
        return this._nodeGetOrNull(objKey, iv) !== null;
    }
    bcContainsAllKeys(c, iv) {
        for (let key of c)
            if (!this.bcContainsKey(key, iv))
                return false;
        return true;
    }
    bcContainsValue(objValue, iv) {
        let value = objValue;
        let n1 = this._nodeFirstOrNull(iv);
        if (n1 === null)
            return false;
        let n2 = this._nodeLastOrNull(iv);
        if (n2 === null)
            return false;
        while (n1 !== n2) {
            if (n1 === null)
                throw new NullPointerException_1.NullPointerException();
            if (this._valEquals(n1._val, value))
                return true;
            n1 = n1._next;
        }
        return this._valEquals(n2._val, value);
    }
    bcContainsAllValues(col, iv) {
        for (let val of col)
            if (!this.bcContainsValue(val, iv))
                return false;
        return true;
    }
    bcContainsEntry(o, iv) {
        if (((o instanceof JavaObject_1.JavaObject) && (o.isTranspiledInstanceOf('java.util.Map.Entry'))) === false)
            return false;
        let e = (0, JavaMapEntry_1.cast_java_util_Map_Entry)(o);
        let node = this._nodeGetOrNull(e.getKey(), iv);
        return (node === null) ? false : this._valEquals(node._val, e.getValue());
    }
    bcContainsAllEntries(c, iv) {
        for (let entry of c)
            if (!this.bcContainsEntry(entry, iv))
                return false;
        return true;
    }
    bcRemoveKeyReturnBool(o, iv) {
        if (!this.bcContainsKey(o, iv))
            return false;
        this.bcRemoveKeyReturnOldValueOrNull(o, iv);
        return true;
    }
    bcRemoveAllKeys(c, iv) {
        let changed = false;
        for (let obj of c)
            changed = changed || this.bcRemoveKeyReturnBool(obj, iv);
        return changed;
    }
    bcRemoveEntry(o, iv) {
        if (!this.bcContainsEntry(o, iv))
            return false;
        if (((o instanceof JavaObject_1.JavaObject) && (o.isTranspiledInstanceOf('java.util.Map.Entry'))) === false)
            return false;
        if (this._root === null)
            throw new NullPointerException_1.NullPointerException();
        let e = (0, JavaMapEntry_1.cast_java_util_Map_Entry)(o);
        this._root = this._nodeRemoveKeyRecursive(this._root, e.getKey());
        return true;
    }
    bcRemoveAllEntries(c, iv) {
        let removedAny = false;
        for (let entry of c)
            removedAny = removedAny || this.bcRemoveEntry(entry, iv);
        return removedAny;
    }
    bcRemoveKeyReturnOldValueOrNull(obj, iv) {
        if (obj === null)
            throw new NullPointerException_1.NullPointerException("TreeMap unterstützt keine NULL-Schlüssel.");
        let key = obj;
        let old = this._nodeGetOrNull(key, iv);
        if (old === null)
            return null;
        if (this._root === null)
            throw new NullPointerException_1.NullPointerException();
        this._root = this._nodeRemoveKeyRecursive(this._root, key);
        return old._val;
    }
    bcPollFirstEntryOrNull(iv) {
        let node = this._nodeFirstOrNull(iv);
        if (node === null)
            return node;
        if (this._root === null)
            throw new NullPointerException_1.NullPointerException();
        this._root = this._nodeRemoveKeyRecursive(this._root, node._key);
        return node;
    }
    bcPollFirstKeyOrNull(iv) {
        let node = this._nodeFirstOrNull(iv);
        if (node === null)
            return null;
        if (this._root === null)
            throw new NullPointerException_1.NullPointerException();
        this._root = this._nodeRemoveKeyRecursive(this._root, node._key);
        return node._key;
    }
    bcPollLastEntryOrNull(iv) {
        let node = this._nodeLastOrNull(iv);
        if (node === null)
            return null;
        if (this._root === null)
            throw new NullPointerException_1.NullPointerException();
        this._root = this._nodeRemoveKeyRecursive(this._root, node._key);
        return node;
    }
    bcPollLastKeyOrNull(iv) {
        let node = this._nodeLastOrNull(iv);
        if (node === null)
            return null;
        if (this._root === null)
            throw new NullPointerException_1.NullPointerException();
        this._root = this._nodeRemoveKeyRecursive(this._root, node._key);
        return node._key;
    }
    bcIsEmpty(iv) {
        return this._nodeFirstOrNull(iv) === null;
    }
    bcGetComparator(iv) {
        return this._comparator;
    }
    bcGetFirstKeyOrException(iv) {
        return this._keyOrExeption(this._nodeFirstOrNull(iv));
    }
    bcGetFirstEntryOrNull(iv) {
        return this._nodeFirstOrNull(iv);
    }
    bcGetLastKeyOrException(iv) {
        return this._keyOrExeption(this._nodeLastOrNull(iv));
    }
    bcGetLastEntryOrNull(iv) {
        return this._nodeLastOrNull(iv);
    }
    bcGetNextEntryOrNull(current, iv) {
        return this._nodeNextOrNull(current, iv);
    }
    bcGetPrevEntryOrNull(current, iv) {
        return this._nodePrevOrNull(current, iv);
    }
    bcGetSize(iv) {
        let n1 = this._nodeFirstOrNull(iv);
        if (n1 === null)
            return 0;
        let n2 = this._nodeLastOrNull(iv);
        if (n2 === null)
            return 0;
        return this._nodeIndexOf(n2._key) - this._nodeIndexOf(n1._key) + 1;
    }
    bcGetValueOfKeyOrNull(objKey, iv) {
        let key = objKey;
        let node = this._nodeGetOrNull(key, iv);
        return (node === null) ? null : node._val;
    }
    bcGetLowerEntryOrNull(key, iv) {
        return this._nodeLowerOrNull(key, iv);
    }
    bcGetLowerKeyOrNull(key, iv) {
        return this._keyOrNull(this._nodeLowerOrNull(key, iv));
    }
    bcGetFloorEntryOrNull(key, iv) {
        return this._nodeFloorOrNull(key, iv);
    }
    bcGetFloorKeyOrNull(key, iv) {
        return this._keyOrNull(this._nodeFloorOrNull(key, iv));
    }
    bcGetCeilingEntryOrNull(key, iv) {
        return this._nodeCeilingOrNull(key, iv);
    }
    bcGetCeilingKeyOrNull(key, iv) {
        return this._keyOrNull(this._nodeCeilingOrNull(key, iv));
    }
    bcGetHigherEntryOrNull(key, iv) {
        return this._nodeHigherOrNull(key, iv);
    }
    bcGetHigherKeyOrNull(key, iv) {
        return this._keyOrNull(this._nodeHigherOrNull(key, iv));
    }
    bcCheckOutOfIntervall(key, inc, iv) {
        if ((key === this._infinityMinus) || (key === this._infinityPlus))
            return false;
        let cmpF = this._compare(key, iv.from);
        if (cmpF < 0)
            return true;
        if ((cmpF === 0) && (!iv.fromInc) && (inc))
            return true;
        let cmpT = this._compare(key, iv.to);
        if (cmpT > 0)
            return true;
        if ((cmpT === 0) && (!iv.toInc) && (inc))
            return true;
        return false;
    }
    _keyOrNull(node) {
        return (node === null) ? null : node._key;
    }
    _valEquals(v1, v2) {
        return (v1 === null) ? v2 === null : JavaObject_1.JavaObject.equalsTranspiler(v1, (v2));
    }
    _keyOrExeption(node) {
        if (node === null)
            throw new NoSuchElementException_1.NoSuchElementException();
        return node._key;
    }
    _compare(key1, key2) {
        if ((key1 === this._infinityMinus) || (key2 === this._infinityPlus))
            return -1;
        if ((key1 === this._infinityPlus) || (key2 === this._infinityMinus))
            return +1;
        return this._comparator.compare(key1, key2);
    }
    _isOutOfRange(key, iv) {
        let cmpKeyFrom = this._compare(key, iv.from);
        if ((cmpKeyFrom < 0) || (cmpKeyFrom === 0) && (!iv.fromInc))
            return true;
        let cmpKeyTo = this._compare(key, iv.to);
        if ((cmpKeyTo > 0) || (cmpKeyTo === 0) && (!iv.toInc))
            return true;
        return false;
    }
    _nodeFirstOrNull(iv) {
        return iv.fromInc ? this._nodeCeilingOrNull(iv.from, iv) : this._nodeHigherOrNull(iv.from, iv);
    }
    _nodeLastOrNull(iv) {
        return iv.toInc ? this._nodeFloorOrNull(iv.to, iv) : this._nodeLowerOrNull(iv.to, iv);
    }
    _nodeCeilingOrNull(key, iv) {
        let node = this._nodeDeepestOrNull(key, iv);
        if (node === null)
            return null;
        let cmpNodeKey = this._compare(node._key, key);
        return cmpNodeKey >= 0 ? node : this._nodeNextOrNull(node, iv);
    }
    _nodeHigherOrNull(key, iv) {
        let node = this._nodeDeepestOrNull(key, iv);
        if (node === null)
            return null;
        let cmpNodeKey = this._compare(node._key, key);
        return cmpNodeKey > 0 ? node : this._nodeNextOrNull(node, iv);
    }
    _nodeFloorOrNull(key, iv) {
        let node = this._nodeDeepestOrNull(key, iv);
        if (node === null)
            return null;
        let cmpNodeKey = this._compare(node._key, key);
        return cmpNodeKey <= 0 ? node : this._nodePrevOrNull(node, iv);
    }
    _nodeLowerOrNull(key, iv) {
        let node = this._nodeDeepestOrNull(key, iv);
        if (node === null)
            return null;
        let cmpNodeKey = this._compare(node._key, key);
        return cmpNodeKey < 0 ? node : this._nodePrevOrNull(node, iv);
    }
    _nodeNextOrNull(node, iv) {
        let next = node._next;
        return (next === null) ? null : this._isOutOfRange(next._key, iv) ? null : next;
    }
    _nodePrevOrNull(node, iv) {
        let prev = node._prev;
        return (prev === null) ? null : this._isOutOfRange(prev._key, iv) ? null : prev;
    }
    _nodeGetOrNull(key, iv) {
        let node = this._nodeDeepestOrNull(key, iv);
        if (node === null)
            return null;
        return this._compare(key, node._key) === 0 ? node : null;
    }
    _nodeIndexOf(key) {
        let current = this._root;
        let index = 0;
        while (true) {
            if (current === null)
                throw new NullPointerException_1.NullPointerException();
            let cmp = this._compare(key, current._key);
            if (cmp < 0) {
                current = current._childL;
                continue;
            }
            let left = current._childL;
            let sizeL = (left === null) ? 0 : left._size;
            if (cmp > 0) {
                index += sizeL + 1;
                current = current._childR;
                continue;
            }
            return index + sizeL;
        }
    }
    _nodeDeepestOrNull(key, iv) {
        let current = this._root;
        let last = null;
        while (current !== null) {
            let cmpToKey = this._compare(iv.to, current._key);
            if ((cmpToKey < 0) || (cmpToKey === 0) && (!iv.toInc)) {
                current = current._childL;
                continue;
            }
            let cmpFromKey = this._compare(iv.from, current._key);
            if ((cmpFromKey > 0) || (cmpFromKey === 0) && (!iv.fromInc)) {
                current = current._childR;
                continue;
            }
            last = current;
            let cmp = this._compare(key, current._key);
            if (cmp < 0) {
                current = current._childL;
                continue;
            }
            if (cmp > 0) {
                current = current._childR;
                continue;
            }
            return current;
        }
        return last;
    }
    _nodePutRecursive(current, key, value) {
        let cmp = this._compare(key, current._key);
        if (cmp === 0) {
            current._val = value;
            return current;
        }
        if (cmp < 0)
            current._childL = (current._childL === null) ? this._nodeCreateLeaf(current._prev, current, key, value) : this._nodePutRecursive(current._childL, key, value);
        else
            current._childR = (current._childR === null) ? this._nodeCreateLeaf(current, current._next, key, value) : this._nodePutRecursive(current._childR, key, value);
        return this._nodeRevalidate(current);
    }
    _nodeCreateLeaf(prev, next, key, value) {
        let child = new AVLMapNode_1.AVLMapNode(key, value);
        if (prev !== null) {
            prev._next = child;
            child._prev = prev;
        }
        if (next !== null) {
            next._prev = child;
            child._next = next;
        }
        return child;
    }
    _nodeRemoveKeyRecursive(current, key) {
        let cmp = this._compare(key, current._key);
        if (cmp < 0) {
            if (current._childL === null)
                throw new NullPointerException_1.NullPointerException();
            current._childL = this._nodeRemoveKeyRecursive(current._childL, key);
            return this._nodeRevalidate(current);
        }
        if (cmp > 0) {
            if (current._childR === null)
                throw new NullPointerException_1.NullPointerException();
            current._childR = this._nodeRemoveKeyRecursive(current._childR, key);
            return this._nodeRevalidate(current);
        }
        if (current._childL === null) {
            this._nodeRemovePrevNext(current);
            return current._childR;
        }
        if (current._childR === null) {
            this._nodeRemovePrevNext(current);
            return current._childL;
        }
        let next = current._next;
        if (next === null)
            throw new NullPointerException_1.NullPointerException();
        current._childR = this._nodeRemoveKeyRecursive(current._childR, next._key);
        return this._nodeRevalidate(this._nodeReplaceReferencesFromAwithB(next, current));
    }
    _nodeReplaceReferencesFromAwithB(a, b) {
        a._childL = b._childL;
        a._childR = b._childR;
        let p = b._prev;
        let n = b._next;
        a._prev = p;
        a._next = n;
        if (p !== null)
            p._next = a;
        if (n !== null)
            n._prev = a;
        return a;
    }
    _nodeRemovePrevNext(current) {
        let nodeP = current._prev;
        let nodeN = current._next;
        if (nodeP !== null)
            nodeP._next = nodeN;
        if (nodeN !== null)
            nodeN._prev = nodeP;
    }
    /**
     * Aktualisiert {@code node} und liefert, wenn es zur Rotation kommt, eine neue Sub-Wurzel.
     *
     * @param node Der Knoten, der revalidiert werden soll.
     *
     * @return node, oder die neue Sub-Wurzel, wenn es zur Rotation kam.
     */
    _nodeRevalidate(node) {
        let heightBalance = this._nodeGetHeightBalance(node);
        if (heightBalance > +1) {
            if (node._childR === null)
                throw new NullPointerException_1.NullPointerException();
            if (this._nodeGetHeightBalance(node._childR) < 0)
                node._childR = this._nodeRotateRight(node._childR);
            return this._nodeRotateLeft(node);
        }
        if (heightBalance < -1) {
            if (node._childL === null)
                throw new NullPointerException_1.NullPointerException();
            if (this._nodeGetHeightBalance(node._childL) > 0)
                node._childL = this._nodeRotateLeft(node._childL);
            return this._nodeRotateRight(node);
        }
        this._nodeRevalidateHeightAndSize(node);
        return node;
    }
    _nodeRotateLeft(nodeM) {
        if (nodeM._childR === null)
            throw new NullPointerException_1.NullPointerException();
        let nodeR = nodeM._childR;
        nodeM._childR = nodeR._childL;
        nodeR._childL = nodeM;
        this._nodeRevalidateHeightAndSize(nodeM);
        this._nodeRevalidateHeightAndSize(nodeR);
        return nodeR;
    }
    _nodeRotateRight(nodeM) {
        if (nodeM._childL === null)
            throw new NullPointerException_1.NullPointerException();
        let nodeL = nodeM._childL;
        nodeM._childL = nodeL._childR;
        nodeL._childR = nodeM;
        this._nodeRevalidateHeightAndSize(nodeM);
        this._nodeRevalidateHeightAndSize(nodeL);
        return nodeL;
    }
    _nodeRevalidateHeightAndSize(node) {
        let sizeL = (node._childL === null) ? 0 : node._childL._size;
        let sizeR = (node._childR === null) ? 0 : node._childR._size;
        node._size = sizeL + sizeR + 1;
        let heightL = (node._childL === null) ? 0 : node._childL._height;
        let heightR = (node._childR === null) ? 0 : node._childR._height;
        node._height = Math.max(heightL, heightR) + 1;
    }
    _nodeGetHeightBalance(node) {
        let heightL = (node._childL === null) ? 0 : node._childL._height;
        let heightR = (node._childR === null) ? 0 : node._childR._height;
        return heightR - heightL;
    }
    isTranspiledInstanceOf(name) {
        return ['java.util.Map', 'de.nrw.schule.svws.core.adt.map.AVLMap', 'java.util.NavigableMap', 'java.util.SortedMap'].includes(name);
    }
}
exports.AVLMap = AVLMap;
function cast_de_nrw_schule_svws_core_adt_map_AVLMap(obj) {
    return obj;
}
exports.cast_de_nrw_schule_svws_core_adt_map_AVLMap = cast_de_nrw_schule_svws_core_adt_map_AVLMap;
//# sourceMappingURL=AVLMap.js.map