package com.radix2.algorithms.week5

import com.radix2.algorithms.week4.SymbolTable
import com.radix2.algorithms.week4.put
import java.lang.StringBuilder
import java.util.*

class LLRBTree<K : Comparable<K>, V> : SymbolTable<K, V> {

    private var root: Node<K, V>? = null

    private enum class Color { RED, BLACK }

    private class Node<K, V>(
        var key: K,
        var value: V,
        var left: Node<K, V>? = null,
        var right: Node<K, V>? = null,
        var color: Color = Color.RED
    )

    override fun put(key: K, value: V) {
        root = put(root, Node(key, value))
    }

    override fun get(key: K): V? = get(root, key)?.value

    override fun min(): Pair<K, V>? = min(root)?.let { it.key to it.value }

    override fun max(): Pair<K, V>? = max(root)?.let { it.key to it.value }

    override fun floor(key: K): Pair<K, V>? = floor(root, key)?.let { it.key to it.value }

    override fun ceil(key: K): Pair<K, V>? = ceil(root, key)?.let { it.key to it.value }

    override fun toString(): String = levelOrder(root)

    private fun getNodesAtLevel(root: Node<K, V>?, level: Int, builder: StringBuilder) {
        if (root == null) return

        if (level == 1) {
            builder.append(root.key to root.value)
        }

        getNodesAtLevel(root.left, level - 1, builder)
        getNodesAtLevel(root.right, level - 1, builder)
    }

    private fun height(root: Node<K, V>?): Int {
        if (root == null)
            return 0

        return 1 + kotlin.math.max(height(root.left), height(root.right))
    }

    // M, E, R, C, L, P, X, A, H, S
    // M, E, R, C, L, P, X, A, H, S
    private fun levelOrder(root: Node<K, V>?): String {
        if (root == null)
            return ""

        val queue: Queue<Node<K, V>> = LinkedList()

        queue.add(root)

        return buildString {
            while (!queue.isEmpty()) {
                if (length > 0)
                    append(", ")

                append(queue.peek().key)

                val node = queue.poll()

                if (node.left != null)
                    queue.add(node.left)

                if (node.right != null)
                    queue.add(node.right)
            }
        }
    }

    private fun levelOrder(root: Node<K, V>?, height: Int, builder: StringBuilder) {

        for (i in 1..height) {
            getNodesAtLevel(root, i, builder)
        }
    }

    private fun inOrder(root: Node<K, V>?, builder: StringBuilder) {
        if (root == null)
            return

        inOrder(root.left, builder)

        builder.append(root.key to root.value)

        inOrder(root.right, builder)
    }

    private fun put(root: Node<K, V>?, node: Node<K, V>): Node<K, V>? {
        if (root == null)
            return node

        var trav = root

        val cmp = node.key.compareTo(trav.key)

        when {
            cmp < 0 -> trav.left = put(trav.left, node)

            cmp > 0 -> trav.right = put(trav.right, node)

            else -> trav.value = node.value
        }

        when {
            trav.right.isRed() && !trav.left.isRed() -> trav = rotateLeft(trav)

            trav.left.isRed() && trav.left?.left.isRed() -> trav = rotateRight(trav)

            trav.left.isRed() && trav.right.isRed() -> flipColors(trav)
        }

        return trav
    }

    private fun get(root: Node<K, V>?, key: K): Node<K, V>? {
        if (root == null)
            return null

        val cmp = key.compareTo(root.key)

        return when {
            cmp < 0 -> get(root.left, key)

            cmp > 0 -> get(root.right, key)

            else -> root
        }
    }

    private fun min(root: Node<K, V>?): Node<K, V>? {
        if (root?.left == null)
            return root

        return min(root.left)
    }

    private fun max(root: Node<K, V>?): Node<K, V>? {
        if (root?.right == null)
            return root

        return max(root.right)
    }

    private fun floor(root: Node<K, V>?, key: K): Node<K, V>? {
        if (root == null)
            return null

        val cmp = key.compareTo(root.key)

        return when {
            cmp == 0 -> root

            cmp < 0 -> floor(root.left, key)

            else -> floor(root.right, key) ?: root
        }
    }

    private fun ceil(root: Node<K, V>?, key: K): Node<K, V>? {
        if (root == null)
            return null

        val cmp = key.compareTo(root.key)

        return when {
            cmp == 0 -> root

            cmp < 0 -> ceil(root.left, key) ?: root

            else -> ceil(root.right, key)
        }
    }

    private fun Node<K, V>?.isRed() = (this?.color ?: Color.BLACK) == Color.RED

    private fun rotateLeft(node: Node<K, V>): Node<K, V>? {
        assert(node.isRed())
        val trav = node

        val temp = node.right
        trav.right = temp?.left
        temp?.left = trav
        temp?.color = trav.color
        trav.color = Color.RED
        return temp
    }

    private fun rotateRight(node: Node<K, V>): Node<K, V>? {
        assert(node.isRed())
        val trav = node

        val temp = node.left
        trav.left = temp?.right
        temp?.right = trav
        temp?.color = trav.color
        trav.color = Color.RED
        return temp
    }

    private fun flipColors(node: Node<K, V>) {
        assert(!node.isRed())
        assert(node.left.isRed())
        assert(node.right.isRed())

        node.color = Color.RED
        node.left?.color = Color.BLACK
        node.right?.color = Color.BLACK
    }

    override fun deleteMin() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun rank(key: K): Int {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun size(): Int {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun deleteMax() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun delete(key: K) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

fun main() {
    val rbt = LLRBTree<Char, String?>()
    rbt.put('S')
    rbt.put('E')
    rbt.put('A')
    rbt.put('R')
    rbt.put('C')
    rbt.put('H')
    rbt.put('X')
    rbt.put('M')
    rbt.put('P')
    rbt.put('L')

    println(rbt)
}

Compiled from "LLRBTree.kt"
public final class com.radix2.algorithms.week5.LLRBTreeKt {
  public static final void main();
    Code:
       0: new           #8                  // class com/radix2/algorithms/week5/LLRBTree
       3: dup
       4: invokespecial #11                 // Method com/radix2/algorithms/week5/LLRBTree."<init>":()V
       7: astore_0
       8: aload_0
       9: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
      12: bipush        83
      14: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      17: checkcast     #21                 // class java/lang/Comparable
      20: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
      23: aload_0
      24: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
      27: bipush        69
      29: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      32: checkcast     #21                 // class java/lang/Comparable
      35: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
      38: aload_0
      39: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
      42: bipush        65
      44: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      47: checkcast     #21                 // class java/lang/Comparable
      50: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
      53: aload_0
      54: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
      57: bipush        82
      59: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      62: checkcast     #21                 // class java/lang/Comparable
      65: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
      68: aload_0
      69: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
      72: bipush        67
      74: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      77: checkcast     #21                 // class java/lang/Comparable
      80: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
      83: aload_0
      84: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
      87: bipush        72
      89: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
      92: checkcast     #21                 // class java/lang/Comparable
      95: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
      98: aload_0
      99: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
     102: bipush        88
     104: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     107: checkcast     #21                 // class java/lang/Comparable
     110: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
     113: aload_0
     114: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
     117: bipush        77
     119: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     122: checkcast     #21                 // class java/lang/Comparable
     125: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
     128: aload_0
     129: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
     132: bipush        80
     134: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     137: checkcast     #21                 // class java/lang/Comparable
     140: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
     143: aload_0
     144: checkcast     #13                 // class com/radix2/algorithms/week4/SymbolTable
     147: bipush        76
     149: invokestatic  #19                 // Method java/lang/Character.valueOf:(C)Ljava/lang/Character;
     152: checkcast     #21                 // class java/lang/Comparable
     155: invokestatic  #27                 // Method com/radix2/algorithms/week4/BSTKt.put:(Lcom/radix2/algorithms/week4/SymbolTable;Ljava/lang/Comparable;)V
     158: getstatic     #33                 // Field java/lang/System.out:Ljava/io/PrintStream;
     161: aload_0
     162: invokevirtual #39                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
     165: return

  public static void main(java.lang.String[]);
    Code:
       0: invokestatic  #44                 // Method main:()V
       3: return
}

Compiled from "LLRBTree.kt"
public final class com.radix2.algorithms.week5.LLRBTree<K extends java.lang.Comparable<? super K>, V> implements com.radix2.algorithms.week4.SymbolTable<K, V> {
  private com.radix2.algorithms.week5.LLRBTree$Node<K, V> root;

  public com.radix2.algorithms.week5.LLRBTree();
    Code:
       0: aload_0
       1: invokespecial #11                 // Method java/lang/Object."<init>":()V
       4: return

  public void put(K, V);
    Code:
       0: aload_1
       1: ldc           #19                 // String key
       3: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_0
       8: aload_0
       9: getfield      #29                 // Field root:Lcom/radix2/algorithms/week5/LLRBTree$Node;
      12: new           #31                 // class com/radix2/algorithms/week5/LLRBTree$Node
      15: dup
      16: aload_1
      17: aload_2
      18: aconst_null
      19: aconst_null
      20: aconst_null
      21: bipush        28
      23: aconst_null
      24: invokespecial #34                 // Method com/radix2/algorithms/week5/LLRBTree$Node."<init>":(Ljava/lang/Object;Ljava/lang/Object;Lcom/radix2/algorithms/week5/LLRBTree$Node;Lcom/radix2/algorithms/week5/LLRBTree$Node;Lcom/radix2/algorithms/week5/LLRBTree$Color;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
      27: invokespecial #37                 // Method put:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      30: putfield      #29                 // Field root:Lcom/radix2/algorithms/week5/LLRBTree$Node;
      33: return

  public V get(K);
    Code:
       0: aload_1
       1: ldc           #19                 // String key
       3: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_0
       8: getfield      #29                 // Field root:Lcom/radix2/algorithms/week5/LLRBTree$Node;
      11: aload_1
      12: invokespecial #47                 // Method get:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      15: dup
      16: ifnull        25
      19: invokevirtual #51                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getValue:()Ljava/lang/Object;
      22: goto          27
      25: pop
      26: aconst_null
      27: areturn

  public kotlin.Pair<K, V> min();
    Code:
       0: aload_0
       1: aload_0
       2: getfield      #29                 // Field root:Lcom/radix2/algorithms/week5/LLRBTree$Node;
       5: invokespecial #57                 // Method min:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
       8: dup
       9: ifnull        29
      12: astore_1
      13: iconst_0
      14: istore_2
      15: aload_1
      16: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      19: aload_1
      20: invokevirtual #51                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getValue:()Ljava/lang/Object;
      23: invokestatic  #66                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      26: goto          31
      29: pop
      30: aconst_null
      31: areturn

  public kotlin.Pair<K, V> max();
    Code:
       0: aload_0
       1: aload_0
       2: getfield      #29                 // Field root:Lcom/radix2/algorithms/week5/LLRBTree$Node;
       5: invokespecial #74                 // Method max:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
       8: dup
       9: ifnull        29
      12: astore_1
      13: iconst_0
      14: istore_2
      15: aload_1
      16: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      19: aload_1
      20: invokevirtual #51                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getValue:()Ljava/lang/Object;
      23: invokestatic  #66                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      26: goto          31
      29: pop
      30: aconst_null
      31: areturn

  public kotlin.Pair<K, V> floor(K);
    Code:
       0: aload_1
       1: ldc           #19                 // String key
       3: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_0
       8: getfield      #29                 // Field root:Lcom/radix2/algorithms/week5/LLRBTree$Node;
      11: aload_1
      12: invokespecial #80                 // Method floor:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      15: dup
      16: ifnull        36
      19: astore_2
      20: iconst_0
      21: istore_3
      22: aload_2
      23: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      26: aload_2
      27: invokevirtual #51                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getValue:()Ljava/lang/Object;
      30: invokestatic  #66                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      33: goto          38
      36: pop
      37: aconst_null
      38: areturn

  public kotlin.Pair<K, V> ceil(K);
    Code:
       0: aload_1
       1: ldc           #19                 // String key
       3: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_0
       8: getfield      #29                 // Field root:Lcom/radix2/algorithms/week5/LLRBTree$Node;
      11: aload_1
      12: invokespecial #84                 // Method ceil:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      15: dup
      16: ifnull        36
      19: astore_2
      20: iconst_0
      21: istore_3
      22: aload_2
      23: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      26: aload_2
      27: invokevirtual #51                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getValue:()Ljava/lang/Object;
      30: invokestatic  #66                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      33: goto          38
      36: pop
      37: aconst_null
      38: areturn

  public java.lang.String toString();
    Code:
       0: aload_0
       1: aload_0
       2: getfield      #29                 // Field root:Lcom/radix2/algorithms/week5/LLRBTree$Node;
       5: invokespecial #91                 // Method levelOrder:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Ljava/lang/String;
       8: areturn

  private final void getNodesAtLevel(com.radix2.algorithms.week5.LLRBTree$Node<K, V>, int, java.lang.StringBuilder);
    Code:
       0: aload_1
       1: ifnonnull     5
       4: return
       5: iload_2
       6: iconst_1
       7: if_icmpne     26
      10: aload_3
      11: aload_1
      12: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      15: aload_1
      16: invokevirtual #51                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getValue:()Ljava/lang/Object;
      19: invokestatic  #66                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      22: invokevirtual #100                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      25: pop
      26: aload_0
      27: aload_1
      28: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      31: iload_2
      32: iconst_1
      33: isub
      34: aload_3
      35: invokespecial #106                // Method getNodesAtLevel:(Lcom/radix2/algorithms/week5/LLRBTree$Node;ILjava/lang/StringBuilder;)V
      38: aload_0
      39: aload_1
      40: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      43: iload_2
      44: iconst_1
      45: isub
      46: aload_3
      47: invokespecial #106                // Method getNodesAtLevel:(Lcom/radix2/algorithms/week5/LLRBTree$Node;ILjava/lang/StringBuilder;)V
      50: return

  private final int height(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_1
       1: ifnonnull     6
       4: iconst_0
       5: ireturn
       6: iconst_1
       7: aload_0
       8: aload_1
       9: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      12: invokespecial #117                // Method height:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)I
      15: aload_0
      16: aload_1
      17: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      20: invokespecial #117                // Method height:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)I
      23: invokestatic  #122                // Method java/lang/Math.max:(II)I
      26: iadd
      27: ireturn

  private final java.lang.String levelOrder(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_1
       1: ifnonnull     7
       4: ldc           #125                // String
       6: areturn
       7: new           #127                // class java/util/LinkedList
      10: dup
      11: invokespecial #128                // Method java/util/LinkedList."<init>":()V
      14: checkcast     #130                // class java/util/Queue
      17: astore_2
      18: aload_2
      19: aload_1
      20: invokeinterface #134,  2          // InterfaceMethod java/util/Queue.add:(Ljava/lang/Object;)Z
      25: pop
      26: new           #96                 // class java/lang/StringBuilder
      29: dup
      30: invokespecial #135                // Method java/lang/StringBuilder."<init>":()V
      33: astore_3
      34: aload_3
      35: astore        4
      37: iconst_0
      38: istore        5
      40: aload_2
      41: invokeinterface #139,  1          // InterfaceMethod java/util/Queue.isEmpty:()Z
      46: ifne          137
      49: aload         4
      51: invokevirtual #143                // Method java/lang/StringBuilder.length:()I
      54: ifle          65
      57: aload         4
      59: ldc           #145                // String ,
      61: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      64: pop
      65: aload         4
      67: aload_2
      68: invokeinterface #151,  1          // InterfaceMethod java/util/Queue.peek:()Ljava/lang/Object;
      73: checkcast     #31                 // class com/radix2/algorithms/week5/LLRBTree$Node
      76: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      79: invokevirtual #100                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      82: pop
      83: aload_2
      84: invokeinterface #154,  1          // InterfaceMethod java/util/Queue.poll:()Ljava/lang/Object;
      89: checkcast     #31                 // class com/radix2/algorithms/week5/LLRBTree$Node
      92: astore        6
      94: aload         6
      96: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      99: ifnull        114
     102: aload_2
     103: aload         6
     105: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     108: invokeinterface #134,  2          // InterfaceMethod java/util/Queue.add:(Ljava/lang/Object;)Z
     113: pop
     114: aload         6
     116: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     119: ifnull        40
     122: aload_2
     123: aload         6
     125: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     128: invokeinterface #134,  2          // InterfaceMethod java/util/Queue.add:(Ljava/lang/Object;)Z
     133: pop
     134: goto          40
     137: nop
     138: aload_3
     139: invokevirtual #156                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
     142: areturn

  private final void levelOrder(com.radix2.algorithms.week5.LLRBTree$Node<K, V>, int, java.lang.StringBuilder);
    Code:
       0: iconst_1
       1: istore        4
       3: iload         4
       5: iload_2
       6: if_icmpgt     29
       9: aload_0
      10: aload_1
      11: iload         4
      13: aload_3
      14: invokespecial #106                // Method getNodesAtLevel:(Lcom/radix2/algorithms/week5/LLRBTree$Node;ILjava/lang/StringBuilder;)V
      17: iload         4
      19: iload_2
      20: if_icmpeq     29
      23: iinc          4, 1
      26: goto          9
      29: return

  private final void inOrder(com.radix2.algorithms.week5.LLRBTree$Node<K, V>, java.lang.StringBuilder);
    Code:
       0: aload_1
       1: ifnonnull     5
       4: return
       5: aload_0
       6: aload_1
       7: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      10: aload_2
      11: invokespecial #167                // Method inOrder:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/StringBuilder;)V
      14: aload_2
      15: aload_1
      16: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      19: aload_1
      20: invokevirtual #51                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getValue:()Ljava/lang/Object;
      23: invokestatic  #66                 // Method kotlin/TuplesKt.to:(Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
      26: invokevirtual #100                // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
      29: pop
      30: aload_0
      31: aload_1
      32: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      35: aload_2
      36: invokespecial #167                // Method inOrder:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/StringBuilder;)V
      39: return

  private final com.radix2.algorithms.week5.LLRBTree$Node<K, V> put(com.radix2.algorithms.week5.LLRBTree$Node<K, V>, com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_1
       1: ifnonnull     6
       4: aload_2
       5: areturn
       6: aload_1
       7: astore_3
       8: aload_2
       9: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      12: checkcast     #170                // class java/lang/Comparable
      15: aload_3
      16: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      19: invokeinterface #174,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      24: istore        4
      26: nop
      27: iload         4
      29: ifge          48
      32: aload_3
      33: aload_0
      34: aload_3
      35: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      38: aload_2
      39: invokespecial #37                 // Method put:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      42: invokevirtual #178                // Method com/radix2/algorithms/week5/LLRBTree$Node.setLeft:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)V
      45: goto          77
      48: iload         4
      50: ifle          69
      53: aload_3
      54: aload_0
      55: aload_3
      56: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      59: aload_2
      60: invokespecial #37                 // Method put:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      63: invokevirtual #181                // Method com/radix2/algorithms/week5/LLRBTree$Node.setRight:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)V
      66: goto          77
      69: aload_3
      70: aload_2
      71: invokevirtual #51                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getValue:()Ljava/lang/Object;
      74: invokevirtual #185                // Method com/radix2/algorithms/week5/LLRBTree$Node.setValue:(Ljava/lang/Object;)V
      77: nop
      78: aload_0
      79: aload_3
      80: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      83: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
      86: ifeq          109
      89: aload_0
      90: aload_3
      91: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      94: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
      97: ifne          109
     100: aload_0
     101: aload_3
     102: invokespecial #192                // Method rotateLeft:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
     105: astore_3
     106: goto          179
     109: aload_0
     110: aload_3
     111: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     114: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
     117: ifeq          152
     120: aload_0
     121: aload_3
     122: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     125: dup
     126: ifnull        135
     129: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     132: goto          137
     135: pop
     136: aconst_null
     137: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
     140: ifeq          152
     143: aload_0
     144: aload_3
     145: invokespecial #195                // Method rotateRight:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
     148: astore_3
     149: goto          179
     152: aload_0
     153: aload_3
     154: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     157: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
     160: ifeq          179
     163: aload_0
     164: aload_3
     165: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     168: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
     171: ifeq          179
     174: aload_0
     175: aload_3
     176: invokespecial #198                // Method flipColors:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)V
     179: aload_3
     180: areturn

  private final com.radix2.algorithms.week5.LLRBTree$Node<K, V> get(com.radix2.algorithms.week5.LLRBTree$Node<K, V>, K);
    Code:
       0: aload_1
       1: ifnonnull     6
       4: aconst_null
       5: areturn
       6: aload_2
       7: aload_1
       8: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      11: invokeinterface #174,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      16: istore_3
      17: nop
      18: iload_3
      19: ifge          34
      22: aload_0
      23: aload_1
      24: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      27: aload_2
      28: invokespecial #47                 // Method get:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      31: goto          51
      34: iload_3
      35: ifle          50
      38: aload_0
      39: aload_1
      40: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      43: aload_2
      44: invokespecial #47                 // Method get:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      47: goto          51
      50: aload_1
      51: areturn

  private final com.radix2.algorithms.week5.LLRBTree$Node<K, V> min(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_1
       1: dup
       2: ifnull        11
       5: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
       8: goto          13
      11: pop
      12: aconst_null
      13: ifnonnull     18
      16: aload_1
      17: areturn
      18: aload_0
      19: aload_1
      20: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      23: invokespecial #57                 // Method min:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      26: areturn

  private final com.radix2.algorithms.week5.LLRBTree$Node<K, V> max(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_1
       1: dup
       2: ifnull        11
       5: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
       8: goto          13
      11: pop
      12: aconst_null
      13: ifnonnull     18
      16: aload_1
      17: areturn
      18: aload_0
      19: aload_1
      20: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      23: invokespecial #74                 // Method max:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      26: areturn

  private final com.radix2.algorithms.week5.LLRBTree$Node<K, V> floor(com.radix2.algorithms.week5.LLRBTree$Node<K, V>, K);
    Code:
       0: aload_1
       1: ifnonnull     6
       4: aconst_null
       5: areturn
       6: aload_2
       7: aload_1
       8: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      11: invokeinterface #174,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      16: istore_3
      17: nop
      18: iload_3
      19: ifne          26
      22: aload_1
      23: goto          57
      26: iload_3
      27: ifge          42
      30: aload_0
      31: aload_1
      32: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      35: aload_2
      36: invokespecial #80                 // Method floor:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      39: goto          57
      42: aload_0
      43: aload_1
      44: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      47: aload_2
      48: invokespecial #80                 // Method floor:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      51: dup
      52: ifnonnull     57
      55: pop
      56: aload_1
      57: areturn

  private final com.radix2.algorithms.week5.LLRBTree$Node<K, V> ceil(com.radix2.algorithms.week5.LLRBTree$Node<K, V>, K);
    Code:
       0: aload_1
       1: ifnonnull     6
       4: aconst_null
       5: areturn
       6: aload_2
       7: aload_1
       8: invokevirtual #60                 // Method com/radix2/algorithms/week5/LLRBTree$Node.getKey:()Ljava/lang/Object;
      11: invokeinterface #174,  2          // InterfaceMethod java/lang/Comparable.compareTo:(Ljava/lang/Object;)I
      16: istore_3
      17: nop
      18: iload_3
      19: ifne          26
      22: aload_1
      23: goto          57
      26: iload_3
      27: ifge          48
      30: aload_0
      31: aload_1
      32: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      35: aload_2
      36: invokespecial #84                 // Method ceil:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      39: dup
      40: ifnonnull     57
      43: pop
      44: aload_1
      45: goto          57
      48: aload_0
      49: aload_1
      50: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      53: aload_2
      54: invokespecial #84                 // Method ceil:(Lcom/radix2/algorithms/week5/LLRBTree$Node;Ljava/lang/Comparable;)Lcom/radix2/algorithms/week5/LLRBTree$Node;
      57: areturn

  private final boolean isRed(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_1
       1: dup
       2: ifnull        12
       5: invokevirtual #207                // Method com/radix2/algorithms/week5/LLRBTree$Node.getColor:()Lcom/radix2/algorithms/week5/LLRBTree$Color;
       8: dup
       9: ifnonnull     16
      12: pop
      13: getstatic     #213                // Field com/radix2/algorithms/week5/LLRBTree$Color.BLACK:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      16: getstatic     #216                // Field com/radix2/algorithms/week5/LLRBTree$Color.RED:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      19: if_acmpne     26
      22: iconst_1
      23: goto          27
      26: iconst_0
      27: ireturn

  private final com.radix2.algorithms.week5.LLRBTree$Node<K, V> rotateLeft(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_0
       1: aload_1
       2: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
       5: istore_2
       6: getstatic     #223                // Field kotlin/_Assertions.ENABLED:Z
       9: ifeq          28
      12: iload_2
      13: ifne          28
      16: ldc           #225                // String Assertion failed
      18: astore_3
      19: new           #227                // class java/lang/AssertionError
      22: dup
      23: aload_3
      24: invokespecial #229                // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
      27: athrow
      28: aload_1
      29: astore_2
      30: aload_1
      31: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      34: astore_3
      35: aload_2
      36: aload_3
      37: dup
      38: ifnull        47
      41: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      44: goto          49
      47: pop
      48: aconst_null
      49: invokevirtual #181                // Method com/radix2/algorithms/week5/LLRBTree$Node.setRight:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)V
      52: aload_3
      53: dup
      54: ifnull        64
      57: aload_2
      58: invokevirtual #178                // Method com/radix2/algorithms/week5/LLRBTree$Node.setLeft:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)V
      61: goto          65
      64: pop
      65: aload_3
      66: dup
      67: ifnull        80
      70: aload_2
      71: invokevirtual #207                // Method com/radix2/algorithms/week5/LLRBTree$Node.getColor:()Lcom/radix2/algorithms/week5/LLRBTree$Color;
      74: invokevirtual #233                // Method com/radix2/algorithms/week5/LLRBTree$Node.setColor:(Lcom/radix2/algorithms/week5/LLRBTree$Color;)V
      77: goto          81
      80: pop
      81: aload_2
      82: getstatic     #216                // Field com/radix2/algorithms/week5/LLRBTree$Color.RED:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      85: invokevirtual #233                // Method com/radix2/algorithms/week5/LLRBTree$Node.setColor:(Lcom/radix2/algorithms/week5/LLRBTree$Color;)V
      88: aload_3
      89: areturn

  private final com.radix2.algorithms.week5.LLRBTree$Node<K, V> rotateRight(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_0
       1: aload_1
       2: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
       5: istore_2
       6: getstatic     #223                // Field kotlin/_Assertions.ENABLED:Z
       9: ifeq          28
      12: iload_2
      13: ifne          28
      16: ldc           #225                // String Assertion failed
      18: astore_3
      19: new           #227                // class java/lang/AssertionError
      22: dup
      23: aload_3
      24: invokespecial #229                // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
      27: athrow
      28: aload_1
      29: astore_2
      30: aload_1
      31: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      34: astore_3
      35: aload_2
      36: aload_3
      37: dup
      38: ifnull        47
      41: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      44: goto          49
      47: pop
      48: aconst_null
      49: invokevirtual #178                // Method com/radix2/algorithms/week5/LLRBTree$Node.setLeft:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)V
      52: aload_3
      53: dup
      54: ifnull        64
      57: aload_2
      58: invokevirtual #181                // Method com/radix2/algorithms/week5/LLRBTree$Node.setRight:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)V
      61: goto          65
      64: pop
      65: aload_3
      66: dup
      67: ifnull        80
      70: aload_2
      71: invokevirtual #207                // Method com/radix2/algorithms/week5/LLRBTree$Node.getColor:()Lcom/radix2/algorithms/week5/LLRBTree$Color;
      74: invokevirtual #233                // Method com/radix2/algorithms/week5/LLRBTree$Node.setColor:(Lcom/radix2/algorithms/week5/LLRBTree$Color;)V
      77: goto          81
      80: pop
      81: aload_2
      82: getstatic     #216                // Field com/radix2/algorithms/week5/LLRBTree$Color.RED:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      85: invokevirtual #233                // Method com/radix2/algorithms/week5/LLRBTree$Node.setColor:(Lcom/radix2/algorithms/week5/LLRBTree$Color;)V
      88: aload_3
      89: areturn

  private final void flipColors(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_0
       1: aload_1
       2: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
       5: ifne          12
       8: iconst_1
       9: goto          13
      12: iconst_0
      13: istore_2
      14: getstatic     #223                // Field kotlin/_Assertions.ENABLED:Z
      17: ifeq          36
      20: iload_2
      21: ifne          36
      24: ldc           #225                // String Assertion failed
      26: astore_3
      27: new           #227                // class java/lang/AssertionError
      30: dup
      31: aload_3
      32: invokespecial #229                // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
      35: athrow
      36: aload_0
      37: aload_1
      38: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      41: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
      44: istore_2
      45: getstatic     #223                // Field kotlin/_Assertions.ENABLED:Z
      48: ifeq          67
      51: iload_2
      52: ifne          67
      55: ldc           #225                // String Assertion failed
      57: astore_3
      58: new           #227                // class java/lang/AssertionError
      61: dup
      62: aload_3
      63: invokespecial #229                // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
      66: athrow
      67: aload_0
      68: aload_1
      69: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
      72: invokespecial #189                // Method isRed:(Lcom/radix2/algorithms/week5/LLRBTree$Node;)Z
      75: istore_2
      76: getstatic     #223                // Field kotlin/_Assertions.ENABLED:Z
      79: ifeq          98
      82: iload_2
      83: ifne          98
      86: ldc           #225                // String Assertion failed
      88: astore_3
      89: new           #227                // class java/lang/AssertionError
      92: dup
      93: aload_3
      94: invokespecial #229                // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
      97: athrow
      98: aload_1
      99: getstatic     #216                // Field com/radix2/algorithms/week5/LLRBTree$Color.RED:Lcom/radix2/algorithms/week5/LLRBTree$Color;
     102: invokevirtual #233                // Method com/radix2/algorithms/week5/LLRBTree$Node.setColor:(Lcom/radix2/algorithms/week5/LLRBTree$Color;)V
     105: aload_1
     106: invokevirtual #104                // Method com/radix2/algorithms/week5/LLRBTree$Node.getLeft:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     109: dup
     110: ifnull        122
     113: getstatic     #213                // Field com/radix2/algorithms/week5/LLRBTree$Color.BLACK:Lcom/radix2/algorithms/week5/LLRBTree$Color;
     116: invokevirtual #233                // Method com/radix2/algorithms/week5/LLRBTree$Node.setColor:(Lcom/radix2/algorithms/week5/LLRBTree$Color;)V
     119: goto          123
     122: pop
     123: aload_1
     124: invokevirtual #109                // Method com/radix2/algorithms/week5/LLRBTree$Node.getRight:()Lcom/radix2/algorithms/week5/LLRBTree$Node;
     127: dup
     128: ifnull        140
     131: getstatic     #213                // Field com/radix2/algorithms/week5/LLRBTree$Color.BLACK:Lcom/radix2/algorithms/week5/LLRBTree$Color;
     134: invokevirtual #233                // Method com/radix2/algorithms/week5/LLRBTree$Node.setColor:(Lcom/radix2/algorithms/week5/LLRBTree$Color;)V
     137: goto          141
     140: pop
     141: return

  public void deleteMin();
    Code:
       0: ldc           #238                // String not implemented
       2: astore_1
       3: new           #240                // class kotlin/NotImplementedError
       6: dup
       7: new           #96                 // class java/lang/StringBuilder
      10: dup
      11: invokespecial #135                // Method java/lang/StringBuilder."<init>":()V
      14: ldc           #242                // String An operation is not implemented:
      16: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: aload_1
      20: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      23: invokevirtual #156                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      26: invokespecial #245                // Method kotlin/NotImplementedError."<init>":(Ljava/lang/String;)V
      29: athrow

  public int rank(K);
    Code:
       0: aload_1
       1: ldc           #19                 // String key
       3: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #238                // String not implemented
       8: astore_2
       9: new           #240                // class kotlin/NotImplementedError
      12: dup
      13: new           #96                 // class java/lang/StringBuilder
      16: dup
      17: invokespecial #135                // Method java/lang/StringBuilder."<init>":()V
      20: ldc           #242                // String An operation is not implemented:
      22: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      25: aload_2
      26: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      29: invokevirtual #156                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      32: invokespecial #245                // Method kotlin/NotImplementedError."<init>":(Ljava/lang/String;)V
      35: athrow

  public int size();
    Code:
       0: ldc           #238                // String not implemented
       2: astore_1
       3: new           #240                // class kotlin/NotImplementedError
       6: dup
       7: new           #96                 // class java/lang/StringBuilder
      10: dup
      11: invokespecial #135                // Method java/lang/StringBuilder."<init>":()V
      14: ldc           #242                // String An operation is not implemented:
      16: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: aload_1
      20: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      23: invokevirtual #156                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      26: invokespecial #245                // Method kotlin/NotImplementedError."<init>":(Ljava/lang/String;)V
      29: athrow

  public void deleteMax();
    Code:
       0: ldc           #238                // String not implemented
       2: astore_1
       3: new           #240                // class kotlin/NotImplementedError
       6: dup
       7: new           #96                 // class java/lang/StringBuilder
      10: dup
      11: invokespecial #135                // Method java/lang/StringBuilder."<init>":()V
      14: ldc           #242                // String An operation is not implemented:
      16: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: aload_1
      20: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      23: invokevirtual #156                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      26: invokespecial #245                // Method kotlin/NotImplementedError."<init>":(Ljava/lang/String;)V
      29: athrow

  public void delete(K);
    Code:
       0: aload_1
       1: ldc           #19                 // String key
       3: invokestatic  #25                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: ldc           #238                // String not implemented
       8: astore_2
       9: new           #240                // class kotlin/NotImplementedError
      12: dup
      13: new           #96                 // class java/lang/StringBuilder
      16: dup
      17: invokespecial #135                // Method java/lang/StringBuilder."<init>":()V
      20: ldc           #242                // String An operation is not implemented:
      22: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      25: aload_2
      26: invokevirtual #148                // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      29: invokevirtual #156                // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      32: invokespecial #245                // Method kotlin/NotImplementedError."<init>":(Ljava/lang/String;)V
      35: athrow
}

Compiled from "LLRBTree.kt"
final class com.radix2.algorithms.week5.LLRBTree$Color extends java.lang.Enum<com.radix2.algorithms.week5.LLRBTree$Color> {
  public static final com.radix2.algorithms.week5.LLRBTree$Color RED;

  public static final com.radix2.algorithms.week5.LLRBTree$Color BLACK;

  private static final com.radix2.algorithms.week5.LLRBTree$Color[] $VALUES;

  private static final kotlin.enums.EnumEntries $ENTRIES;

  private com.radix2.algorithms.week5.LLRBTree$Color();
    Code:
       0: aload_0
       1: aload_1
       2: iload_2
       3: invokespecial #10                 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
       6: return

  public static com.radix2.algorithms.week5.LLRBTree$Color[] values();
    Code:
       0: getstatic     #22                 // Field $VALUES:[Lcom/radix2/algorithms/week5/LLRBTree$Color;
       3: invokevirtual #28                 // Method java/lang/Object.clone:()Ljava/lang/Object;
       6: checkcast     #29                 // class "[Lcom/radix2/algorithms/week5/LLRBTree$Color;"
       9: areturn

  public static com.radix2.algorithms.week5.LLRBTree$Color valueOf(java.lang.String);
    Code:
       0: ldc           #2                  // class com/radix2/algorithms/week5/LLRBTree$Color
       2: aload_0
       3: invokestatic  #34                 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       6: checkcast     #2                  // class com/radix2/algorithms/week5/LLRBTree$Color
       9: areturn

  public static kotlin.enums.EnumEntries<com.radix2.algorithms.week5.LLRBTree$Color> getEntries();
    Code:
       0: getstatic     #43                 // Field $ENTRIES:Lkotlin/enums/EnumEntries;
       3: areturn

  private static final com.radix2.algorithms.week5.LLRBTree$Color[] $values();
    Code:
       0: iconst_2
       1: anewarray     #2                  // class com/radix2/algorithms/week5/LLRBTree$Color
       4: astore_0
       5: aload_0
       6: iconst_0
       7: getstatic     #47                 // Field RED:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      10: aastore
      11: aload_0
      12: iconst_1
      13: getstatic     #50                 // Field BLACK:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      16: aastore
      17: aload_0
      18: areturn

  static {};
    Code:
       0: new           #2                  // class com/radix2/algorithms/week5/LLRBTree$Color
       3: dup
       4: ldc           #52                 // String RED
       6: iconst_0
       7: invokespecial #53                 // Method "<init>":(Ljava/lang/String;I)V
      10: putstatic     #47                 // Field RED:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      13: new           #2                  // class com/radix2/algorithms/week5/LLRBTree$Color
      16: dup
      17: ldc           #54                 // String BLACK
      19: iconst_1
      20: invokespecial #53                 // Method "<init>":(Ljava/lang/String;I)V
      23: putstatic     #50                 // Field BLACK:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      26: invokestatic  #56                 // Method $values:()[Lcom/radix2/algorithms/week5/LLRBTree$Color;
      29: putstatic     #22                 // Field $VALUES:[Lcom/radix2/algorithms/week5/LLRBTree$Color;
      32: getstatic     #22                 // Field $VALUES:[Lcom/radix2/algorithms/week5/LLRBTree$Color;
      35: checkcast     #58                 // class "[Ljava/lang/Enum;"
      38: invokestatic  #64                 // Method kotlin/enums/EnumEntriesKt.enumEntries:([Ljava/lang/Enum;)Lkotlin/enums/EnumEntries;
      41: putstatic     #43                 // Field $ENTRIES:Lkotlin/enums/EnumEntries;
      44: return
}

Compiled from "LLRBTree.kt"
final class com.radix2.algorithms.week5.LLRBTree$Node<K, V> {
  private K key;

  private V value;

  private com.radix2.algorithms.week5.LLRBTree$Node<K, V> left;

  private com.radix2.algorithms.week5.LLRBTree$Node<K, V> right;

  private com.radix2.algorithms.week5.LLRBTree$Color color;

  public com.radix2.algorithms.week5.LLRBTree$Node(K, V, com.radix2.algorithms.week5.LLRBTree$Node<K, V>, com.radix2.algorithms.week5.LLRBTree$Node<K, V>, com.radix2.algorithms.week5.LLRBTree$Color);
    Code:
       0: aload         5
       2: ldc           #12                 // String color
       4: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       7: aload_0
       8: invokespecial #21                 // Method java/lang/Object."<init>":()V
      11: aload_0
      12: aload_1
      13: putfield      #25                 // Field key:Ljava/lang/Object;
      16: aload_0
      17: aload_2
      18: putfield      #28                 // Field value:Ljava/lang/Object;
      21: aload_0
      22: aload_3
      23: putfield      #32                 // Field left:Lcom/radix2/algorithms/week5/LLRBTree$Node;
      26: aload_0
      27: aload         4
      29: putfield      #35                 // Field right:Lcom/radix2/algorithms/week5/LLRBTree$Node;
      32: aload_0
      33: aload         5
      35: putfield      #38                 // Field color:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      38: return

  public com.radix2.algorithms.week5.LLRBTree$Node(java.lang.Object, java.lang.Object, com.radix2.algorithms.week5.LLRBTree$Node, com.radix2.algorithms.week5.LLRBTree$Node, com.radix2.algorithms.week5.LLRBTree$Color, int, kotlin.jvm.internal.DefaultConstructorMarker);
    Code:
       0: iload         6
       2: iconst_4
       3: iand
       4: ifeq          9
       7: aconst_null
       8: astore_3
       9: iload         6
      11: bipush        8
      13: iand
      14: ifeq          20
      17: aconst_null
      18: astore        4
      20: iload         6
      22: bipush        16
      24: iand
      25: ifeq          33
      28: getstatic     #45                 // Field com/radix2/algorithms/week5/LLRBTree$Color.RED:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      31: astore        5
      33: aload_0
      34: aload_1
      35: aload_2
      36: aload_3
      37: aload         4
      39: aload         5
      41: invokespecial #47                 // Method "<init>":(Ljava/lang/Object;Ljava/lang/Object;Lcom/radix2/algorithms/week5/LLRBTree$Node;Lcom/radix2/algorithms/week5/LLRBTree$Node;Lcom/radix2/algorithms/week5/LLRBTree$Color;)V
      44: return

  public final K getKey();
    Code:
       0: aload_0
       1: getfield      #25                 // Field key:Ljava/lang/Object;
       4: areturn

  public final void setKey(K);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #25                 // Field key:Ljava/lang/Object;
       5: return

  public final V getValue();
    Code:
       0: aload_0
       1: getfield      #28                 // Field value:Ljava/lang/Object;
       4: areturn

  public final void setValue(V);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #28                 // Field value:Ljava/lang/Object;
       5: return

  public final com.radix2.algorithms.week5.LLRBTree$Node<K, V> getLeft();
    Code:
       0: aload_0
       1: getfield      #32                 // Field left:Lcom/radix2/algorithms/week5/LLRBTree$Node;
       4: areturn

  public final void setLeft(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #32                 // Field left:Lcom/radix2/algorithms/week5/LLRBTree$Node;
       5: return

  public final com.radix2.algorithms.week5.LLRBTree$Node<K, V> getRight();
    Code:
       0: aload_0
       1: getfield      #35                 // Field right:Lcom/radix2/algorithms/week5/LLRBTree$Node;
       4: areturn

  public final void setRight(com.radix2.algorithms.week5.LLRBTree$Node<K, V>);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #35                 // Field right:Lcom/radix2/algorithms/week5/LLRBTree$Node;
       5: return

  public final com.radix2.algorithms.week5.LLRBTree$Color getColor();
    Code:
       0: aload_0
       1: getfield      #38                 // Field color:Lcom/radix2/algorithms/week5/LLRBTree$Color;
       4: areturn

  public final void setColor(com.radix2.algorithms.week5.LLRBTree$Color);
    Code:
       0: aload_1
       1: ldc           #71                 // String <set-?>
       3: invokestatic  #18                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
       6: aload_0
       7: aload_1
       8: putfield      #38                 // Field color:Lcom/radix2/algorithms/week5/LLRBTree$Color;
      11: return
}