// File: /workspace/github_c_makefile_star2_O0/CarlosLunaMota[P]BinaryTrees/BinaryTrees.c
// Function: rb_tree_intersection
rb_tree *rb_tree_intersection(const rb_tree *tree_1, const rb_tree *tree_2) {

    rb_tree *tree = NULL;
    rb_node *pred_1;
    rb_node *node_1;
    rb_node *pred_2;
    rb_node *node_2;
    void    *data;
    int      comp;

    // Sanity check:
    assert(tree_1 != NULL);
    assert(tree_2 != NULL);

    // Special case: Both trees are the same
    if (tree_1 == tree_2) { return rb_tree_copy(tree_1); }

    // Create a new tree:    
    tree = new_rb_tree(tree_1->comp);
    if (tree == NULL) { return NULL; }

    // Special case: Some of them is empty
    if (rb_tree_is_empty(tree_1) == YES) { return tree; }
    if (rb_tree_is_empty(tree_2) == YES) { return tree; }

    // Go to the smallest element of tree_1 while right-threading your path:
    node_1 = tree_1->root;
    if (node_1 != NULL) {
        while (node_1->left != NULL) {
            pred_1 = node_1->left;
            while (pred_1->right != NULL) { pred_1 = pred_1->right; }
            pred_1->right = node_1;
            node_1        = node_1->left;
        }
    }

    // Go to the smallest element of tree_2 while right-threading your path:
    node_2 = tree_2->root;
    if (node_2 != NULL) {
        while (node_2->left != NULL) {
            pred_2 = node_2->left;
            while (pred_2->right != NULL) { pred_2 = pred_2->right; }
            pred_2->right = node_2;
            node_2        = node_2->left;
        }
    }

    // Until we have exhausted at least one of the trees:
    while (node_1 != NULL && node_2 != NULL) {

        // compare both nodes:
        comp = (tree->comp)(node_1->data, node_2->data);

        if (comp < 0) {

            // advance node_1 //////////////////////////////////////////////////
            node_1 = node_1->right;
            if (node_1 != NULL) {
                while (node_1->left != NULL) {
                    pred_1 = node_1->left;
                    while (pred_1->right != NULL && pred_1->right != node_1) {
                        pred_1 = pred_1->right;
                    }
                    if (pred_1->right == NULL) {
                        pred_1->right = node_1;
                        node_1        = node_1->left;
                    } else {
                        pred_1->right = NULL;
                        break;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////

        } else if (comp > 0) {

            // advance node_2 //////////////////////////////////////////////////
            node_2 = node_2->right;
            if (node_2 != NULL) {
                while (node_2->left != NULL) {
                    pred_2 = node_2->left;
                    while (pred_2->right != NULL && pred_2->right != node_2) {
                        pred_2 = pred_2->right;
                    }
                    if (pred_2->right == NULL) {
                        pred_2->right = node_2;
                        node_2        = node_2->left;
                    } else {
                        pred_2->right = NULL;
                        break;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////

        } else {

            // insert node_1->data in tree /////////////////////////////////////
            data = node_1->data;
            data = rb_tree_insert_max(tree, data);
            assert(data == NULL);
            ////////////////////////////////////////////////////////////////////

            // advance node_1 //////////////////////////////////////////////////
            node_1 = node_1->right;
            if (node_1 != NULL) {
                while (node_1->left != NULL) {
                    pred_1 = node_1->left;
                    while (pred_1->right != NULL && pred_1->right != node_1) {
                        pred_1 = pred_1->right;
                    }
                    if (pred_1->right == NULL) {
                        pred_1->right = node_1;
                        node_1        = node_1->left;
                    } else {
                        pred_1->right = NULL;
                        break;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////

            // advance node_2 //////////////////////////////////////////////////
            node_2 = node_2->right;
            if (node_2 != NULL) {
                while (node_2->left != NULL) {
                    pred_2 = node_2->left;
                    while (pred_2->right != NULL && pred_2->right != node_2) {
                        pred_2 = pred_2->right;
                    }
                    if (pred_2->right == NULL) {
                        pred_2->right = node_2;
                        node_2        = node_2->left;
                    } else {
                        pred_2->right = NULL;
                        break;
                    }
                }
            }
            ////////////////////////////////////////////////////////////////////
        }
    }

    // We need to traverse tree_1 completely to restore the modified pointers:
    while (node_1 != NULL) {

        // advance node_1 //////////////////////////////////////////////////////
        node_1 = node_1->right;
        if (node_1 != NULL) {
            while (node_1->left != NULL) {
                pred_1 = node_1->left;
                while (pred_1->right != NULL && pred_1->right != node_1) {
                    pred_1 = pred_1->right;
                }
                if (pred_1->right == NULL) {
                    pred_1->right = node_1;
                    node_1        = node_1->left;
                } else {
                    pred_1->right = NULL;
                    break;
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////
    }

    // We need to traverse tree_2 completely to restore the modified pointers:
    while (node_2 != NULL) {

        // advance node_2 //////////////////////////////////////////////////////
        node_2 = node_2->right;
        if (node_2 != NULL) {
            while (node_2->left != NULL) {
                pred_2 = node_2->left;
                while (pred_2->right != NULL && pred_2->right != node_2) {
                    pred_2 = pred_2->right;
                }
                if (pred_2->right == NULL) {
                    pred_2->right = node_2;
                    node_2        = node_2->left;
                } else {
                    pred_2->right = NULL;
                    break;
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////
    }

    // Return the resulting tree:
    return tree;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x127e1
jmp 0x12800
leaq 0x3d1d(%rip), %rdi      # 0x16505
leaq 0x3a0d(%rip), %rsi      # 0x161fc
movl $0xe34, %edx            # imm = 0xE34
leaq 0x41f6(%rip), %rcx      # 0x169f1
callq 0x1060
cmpq $0x0, -0x18(%rbp)
je 0x12809
jmp 0x12828
leaq 0x3d3d(%rip), %rdi      # 0x1654d
leaq 0x39e5(%rip), %rsi      # 0x161fc
movl $0xe35, %edx            # imm = 0xE35
leaq 0x41ce(%rip), %rcx      # 0x169f1
callq 0x1060
movq -0x10(%rbp), %rax
cmpq -0x18(%rbp), %rax
jne 0x12844
movq -0x10(%rbp), %rdi
callq 0xfed0
movq %rax, -0x8(%rbp)
jmp 0x12e08
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xfe40
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x12869
movq $0x0, -0x8(%rbp)
jmp 0x12e08
movq -0x10(%rbp), %rdi
callq 0x10ae0
cmpl $0x1, %eax
jne 0x12884
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x12e08
movq -0x18(%rbp), %rdi
callq 0x10ae0
cmpl $0x1, %eax
jne 0x1289f
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x12e08
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x128ff
jmp 0x128b3
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x128fd
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x128e3
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x128ca
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x128b3
jmp 0x128ff
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x1295f
jmp 0x12913
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x1295d
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x12943
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x1292a
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x12913
jmp 0x1295f
jmp 0x12961
xorl %eax, %eax
cmpq $0x0, -0x30(%rbp)
movb %al, -0x4d(%rbp)
je 0x12978
cmpq $0x0, -0x40(%rbp)
setne %al
movb %al, -0x4d(%rbp)
movb -0x4d(%rbp), %al
testb $0x1, %al
jne 0x12984
jmp 0x12c96
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rcx), %rdi
movq -0x40(%rbp), %rcx
movq (%rcx), %rsi
callq *%rax
movl %eax, -0x4c(%rbp)
cmpl $0x0, -0x4c(%rbp)
jge 0x12a51
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x12a4c
jmp 0x129c2
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x12a4a
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x4e(%rbp)
je 0x129fb
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x30(%rbp), %rax
setne %al
movb %al, -0x4e(%rbp)
movb -0x4e(%rbp), %al
testb $0x1, %al
jne 0x12a04
jmp 0x12a12
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x129d9
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x12a37
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x12a45
movq -0x28(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x12a4a
jmp 0x129c2
jmp 0x12a4c
jmp 0x12c91
cmpl $0x0, -0x4c(%rbp)
jle 0x12b03
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x12afe
jmp 0x12a74
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x12afc
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x4f(%rbp)
je 0x12aad
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x40(%rbp), %rax
setne %al
movb %al, -0x4f(%rbp)
movb -0x4f(%rbp), %al
testb $0x1, %al
jne 0x12ab6
jmp 0x12ac4
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x12a8b
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x12ae9
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x12af7
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x12afc
jmp 0x12a74
jmp 0x12afe
jmp 0x12c8f
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x100a0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x12b28
jmp 0x12b47
leaq 0x3c2a(%rip), %rdi      # 0x16759
leaq 0x36c6(%rip), %rsi      # 0x161fc
movl $0xe8d, %edx            # imm = 0xE8D
leaq 0x3eaf(%rip), %rcx      # 0x169f1
callq 0x1060
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x12bea
jmp 0x12b60
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x12be8
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x50(%rbp)
je 0x12b99
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x30(%rbp), %rax
setne %al
movb %al, -0x50(%rbp)
movb -0x50(%rbp), %al
testb $0x1, %al
jne 0x12ba2
jmp 0x12bb0
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x12b77
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x12bd5
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x12be3
movq -0x28(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x12be8
jmp 0x12b60
jmp 0x12bea
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x12c8d
jmp 0x12c03
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x12c8b
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x51(%rbp)
je 0x12c3c
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x40(%rbp), %rax
setne %al
movb %al, -0x51(%rbp)
movb -0x51(%rbp), %al
testb $0x1, %al
jne 0x12c45
jmp 0x12c53
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x12c1a
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x12c78
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x12c86
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x12c8b
jmp 0x12c03
jmp 0x12c8d
jmp 0x12c8f
jmp 0x12c91
jmp 0x12961
jmp 0x12c98
cmpq $0x0, -0x30(%rbp)
je 0x12d4b
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x12d46
jmp 0x12cbc
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x12d44
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x52(%rbp)
je 0x12cf5
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x30(%rbp), %rax
setne %al
movb %al, -0x52(%rbp)
movb -0x52(%rbp), %al
testb $0x1, %al
jne 0x12cfe
jmp 0x12d0c
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x12cd3
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x12d31
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x12d3f
movq -0x28(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x12d44
jmp 0x12cbc
jmp 0x12d46
jmp 0x12c98
jmp 0x12d4d
cmpq $0x0, -0x40(%rbp)
je 0x12e00
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x12dfb
jmp 0x12d71
movq -0x40(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x12df9
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x53(%rbp)
je 0x12daa
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x40(%rbp), %rax
setne %al
movb %al, -0x53(%rbp)
movb -0x53(%rbp), %al
testb $0x1, %al
jne 0x12db3
jmp 0x12dc1
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x12d88
movq -0x38(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x12de6
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x12df4
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0x12df9
jmp 0x12d71
jmp 0x12dfb
jmp 0x12d4d
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)