// File: /workspace/github_c_makefile_star2_O3/pwelke[P]GraphMiningTools/cactustree.c
// Function: cactusTreeSubIso
int cactusTreeSubIso(struct Graph * graph, struct Graph *pattern, struct GraphPool *gPool, struct ShallowGraphPool *sgPool){

    struct ShallowGraph *bComponents = listBiconnectedComponents(graph, sgPool);
    int numComponents =0;
    
    // Setting distances to vertex_0.
    struct ShallowGraph *shlp, **rootedComponents;
    struct Graph *componentTree;
    struct VertexList *lhlp;
    struct Vertex ** representatives;
    struct Vertex * componentRepresentative, *rootRepresentative;
    struct Characteristics *res;
    int i = 0;
    representatives = malloc(graph->n * sizeof(struct Vertex *));
    //TODO remove debug
    /*
    printf("MAIN\n");
    for(shlp=bComponents;shlp;shlp=shlp->next){
        printf("Component: %i\n", numComponents++);
        for(lhlp=shlp->edges; lhlp; lhlp=lhlp->next){
            printf ("\t(%i, %i)",lhlp->startPoint->number,lhlp->endPoint->number);
        }
        printf("\n");
    }
    //TODO remove when debug is removed
    numComponents=0;
    */
    if(representatives == NULL){
        //TODO clean up
        return 0;
    }
    for(;i<graph->n;++i){
        representatives[i]=NULL;
        graph->vertices[i]->d=-1;
    }
    for(shlp=bComponents;shlp;shlp=shlp->next){
        ++numComponents;
        componentRepresentative = shlp->edges->startPoint;
        rootRepresentative = representatives[shlp->edges->startPoint->number];
        //We will initialize the LUT from old graph vertices to component numbers.
        for(lhlp=shlp->edges; lhlp; lhlp=lhlp->next){
            representatives[lhlp->endPoint->number]=componentRepresentative;
        }
        //Now reset the representative for the root as we may have set it.
        //This way the representative of a component root will only be set during processing of another component,
        //where it is not a root.
        representatives[shlp->edges->startPoint->number]=rootRepresentative;

    }
    //set entries in the LUT
    //and set all roots to unvisited.
    i=-1;
    for(shlp=bComponents;shlp;shlp=shlp->next){
        if(shlp->edges->startPoint->d< 0) shlp->edges->startPoint->d=++i;
        shlp->edges->startPoint->visited=0;
    }
    //printf("Allocating component tree\n");

    rootedComponents=calloc(numComponents,sizeof(struct ShallowGraph *));
    componentTree=computeComponentTree(representatives, bComponents, numComponents, rootedComponents, gPool);
    free(representatives);
    res=processRootTree(componentTree->vertices[graph->vertices[0]->d], graph, rootedComponents, pattern, gPool, sgPool);
    for(i=0;i<numComponents;++i)
       dumpShallowGraphCycle(sgPool, rootedComponents[i]);
    free(rootedComponents);
    dumpGraph(gPool,componentTree);
    if(hasSolution(res)){
        freeCharacteristics(res);
        return 1;
    }
    freeCharacteristics(res);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, %r14
movq %rdx, 0x10(%rsp)
movq %rsi, %r12
movq %rdi, %rbx
movq %rcx, %rsi
callq 0xb23b
movq %rax, 0x20(%rsp)
movq %rbx, 0x8(%rsp)
movslq (%rbx), %r15
leaq (,%r15,8), %rbx
movq %rbx, %rdi
callq 0x1190
testq %rax, %rax
je 0x3f3c
movq %rax, %r13
movq %r12, 0x18(%rsp)
testl %r15d, %r15d
jle 0x3df4
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rbp
xorl %r12d, %r12d
movq %r13, %rdi
xorl %esi, %esi
movq %rbx, %rdx
callq 0x10d0
movq (%rbp,%r12,8), %rax
movl $0xffffffff, 0x28(%rax) # imm = 0xFFFFFFFF
incq %r12
cmpq %r12, %r15
jne 0x3de0
movq 0x20(%rsp), %r12
xorl %r15d, %r15d
testq %r12, %r12
je 0x3e6a
movq %r12, %rax
incl %r15d
movq (%rax), %rcx
movq 0x10(%rcx), %rsi
movslq 0x18(%rsi), %rdx
movq (%r13,%rdx,8), %rdi
movq 0x18(%rcx), %r8
movslq 0x18(%r8), %r8
movq %rsi, (%r13,%r8,8)
movq 0x8(%rcx), %rcx
testq %rcx, %rcx
jne 0x3e17
movq %rdi, (%r13,%rdx,8)
movq 0x18(%rax), %rax
testq %rax, %rax
jne 0x3e04
testq %r12, %r12
je 0x3e6a
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %r12, %rcx
movq (%rcx), %rdx
movq 0x10(%rdx), %rdx
cmpl $0x0, 0x28(%rdx)
jns 0x3e5a
incl %eax
movl %eax, 0x28(%rdx)
movl $0x0, 0x1c(%rdx)
movq 0x18(%rcx), %rcx
testq %rcx, %rcx
jne 0x3e48
movl %r15d, %ebx
movl $0x8, %esi
movq %rbx, %rdi
callq 0x1120
movq %rax, %rbp
movq %r13, %rdi
movq %r12, %rsi
movl %r15d, %edx
movq %rax, %rcx
movq 0x10(%rsp), %r12
movq %r12, %r8
callq 0x3f5c
movq %r13, %rdi
movq %rax, %r13
callq 0x1030
movq 0x10(%r13), %rax
movq 0x8(%rsp), %rsi
movq 0x10(%rsi), %rcx
movq (%rcx), %rcx
movslq 0x28(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
movq %rbp, %rdx
movq 0x18(%rsp), %rcx
movq %r12, %r8
movq %r14, %r9
callq 0x401f
movq %rax, %r12
testl %r15d, %r15d
je 0x3eec
xorl %r15d, %r15d
movq (%rbp,%r15,8), %rsi
movq %r14, %rdi
callq 0x14a56
incq %r15
cmpq %r15, %rbx
jne 0x3ed7
movq %rbp, %rdi
callq 0x1030
movq 0x10(%rsp), %rdi
movq %r13, %rsi
callq 0x14700
testq %r12, %r12
je 0x3f34
movq %r12, %rax
movslq 0x4(%rax), %rcx
testq %rcx, %rcx
jle 0x3f2b
movq 0x8(%rax), %rdx
xorl %esi, %esi
movq (%rdx,%rsi,8), %rdi
cmpq $0x0, (%rdi,%rsi,8)
jne 0x3f40
incq %rsi
cmpq %rsi, %rcx
jne 0x3f18
movq 0x10(%rax), %rax
testq %rax, %rax
jne 0x3f09
movq %r12, %rdi
callq 0x41e4
xorl %eax, %eax
jmp 0x3f4d
movq %r12, %rdi
callq 0x41e4
movl $0x1, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq