// File: GAStudyGroup[P]GPX2/src/cross/gpx/sources/GPX2.cpp
// Function: GPX2::fusion()
void GPX2::fusion()
{// Method to execute the GPX2's Fusion, it will check amongst the unfeasibe partitions and try to transform them to feasible ones
    bool atLeastOneConnected{ false };
    //Keps executing while there are still more than one partition to try to fuse them
    while ((unfeasiblePartitions.size() > 1)) {
        //Check how many partitions are connected, the fusion only happens if the partitions are connected by at least one node
        atLeastOneConnected = GPX2Fusion::unfeasiblePartitionsConnected(unfeasiblePartitions, unitedGraph);
        if (!atLeastOneConnected) {
            break;
        }
        // Counts how many times that one partition connects with other unfeasible partition, that is, the nodes that have a path that goes from one partition to another
        GPX2Fusion::countConnectedPartitions(unfeasiblePartitions);

        // Generates the fusion pairs that will be tried, this method already validates them
        GPX2Fusion::generateFusionPairs(fuseWith, unfeasiblePartitions);

        GPX2Fusion::fusePartitions(fuseWith,
                        unfeasiblePartitions,
                        unitedGraph,
                        red,
                        blue);

        for (auto part : unfeasiblePartitions) {
            part.second->getConnectedTo().clear();
            part.second->getConnections().clear();
        }

        //Checks if the generated partition is feasible, in that case it will be put in the feasible partition list
        GPX2Fusion::checkUnfeasiblePartitions(feasiblePartitions,
                                                unfeasiblePartitions,
                                                red,
                                                blue);
    }
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
movb $0x0, 0x3f(%rsp)
movq 0x8(%rsp), %rdi
addq $0x60, %rdi
callq 0x60b50
cmpq $0x1, %rax
jbe 0x5fcb0
movq 0x8(%rsp), %rsi
movq %rsi, %rdi
addq $0x60, %rdi
addq $0x90, %rsi
callq 0x54350
andb $0x1, %al
movb %al, 0x3f(%rsp)
testb $0x1, 0x3f(%rsp)
jne 0x5fb9a
jmp 0x5fcb0
movq 0x8(%rsp), %rdi
addq $0x60, %rdi
callq 0x52d50
movq 0x8(%rsp), %rsi
movq %rsi, %rdi
addq $0xc0, %rdi
addq $0x60, %rsi
callq 0x53c30
movq 0x8(%rsp), %r8
movq %r8, %rdi
addq $0xc0, %rdi
movq %r8, %rsi
addq $0x60, %rsi
movq %r8, %rdx
addq $0x90, %rdx
movq %r8, %rcx
addq $0xd8, %rcx
addq $0x108, %r8             # imm = 0x108
callq 0x53060
movq 0x8(%rsp), %rax
addq $0x60, %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rdi
callq 0x54cc0
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rdi
callq 0x54d10
movq %rax, 0x20(%rsp)
leaq 0x28(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x54cf0
testb $0x1, %al
jne 0x5fc37
jmp 0x5fc82
leaq 0x28(%rsp), %rdi
callq 0x54d40
movq (%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x8(%rax), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rdi
callq 0x67ee0
movq %rax, %rdi
callq 0x61420
movq 0x18(%rsp), %rdi
callq 0x67e90
movq %rax, %rdi
callq 0x61440
leaq 0x28(%rsp), %rdi
callq 0x552a0
jmp 0x5fc22
movq 0x8(%rsp), %rcx
movq %rcx, %rdi
addq $0x30, %rdi
movq %rcx, %rsi
addq $0x60, %rsi
movq %rcx, %rdx
addq $0xd8, %rdx
addq $0x108, %rcx            # imm = 0x108
callq 0x52b00
jmp 0x5fb58
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)