// File: /workspace/github_c_makefile_star2_O2/pwelke[P]GraphMiningTools/listComponents.c
// Function: partitionIntoForestAndCycles
struct Graph* partitionIntoForestAndCycles(struct ShallowGraph* list, struct Graph *original, struct GraphPool* gp, struct ShallowGraphPool *sgp) {

	struct Graph *forest = getGraph(gp);
	struct Graph *cycles = NULL;
	int i;
	int componentNumber = 0;

	/* create create empty forest with same vertex set as original */
	if (!(setVertexNumber(forest, original->n))) {
		printf("Error allocating vertex arrays for forest or cycles in graph %i\n", original->number);
		dumpGraph(gp, forest);
		dumpGraph(gp, cycles);
		return NULL;
	}

	for (i=0; i<original->n; ++i) {
		forest->vertices[i] = shallowCopyVertex(original->vertices[i], gp->vertexPool);
	}


	while (1) {
		if (list->m == 1) {
			/* add the edge contained in this graph to the forest */
			struct VertexList* rev;

			/* update start and endPoint to the new copies of these vertices */
			list->edges->startPoint = forest->vertices[list->edges->startPoint->number];
			list->edges->endPoint = forest->vertices[list->edges->endPoint->number];

			/* add edge to incidence list of its new startpoint */
			addEdge(list->edges->startPoint, list->edges);

			/* clone edge and reverse it */
			rev = shallowCopyEdge(list->edges, gp->listPool);
			rev->startPoint = list->edges->endPoint;
			rev->endPoint = list->edges->startPoint;
			addEdge(rev->startPoint, rev);

			/* pop edge */
			list->edges = NULL;

			/* update edge count of forest */
			forest->m += 1;

		} else {
			struct Graph* newCycle = getGraph(gp);

			/* TODO bad thing: o(n) for each biconnected component */
			setVertexNumber(newCycle, original->n);

			/* append the graph to the list of cycle unions, encode the biconnected component
			 * some edge belongs to in ->used */
			while (list->edges) {
				struct VertexList *rev; 
				struct VertexList *curr = list->edges;

				/* add vertices on the fly */
				if(newCycle->vertices[curr->startPoint->number] == NULL) {
					newCycle->vertices[curr->startPoint->number] = shallowCopyVertex(curr->startPoint, gp->vertexPool);
				}
				if(newCycle->vertices[curr->endPoint->number] == NULL) {
					newCycle->vertices[curr->endPoint->number] = shallowCopyVertex(curr->endPoint, gp->vertexPool);
				}

				/* update start and endPoint to the new copies of these vertices */
				curr->startPoint = newCycle->vertices[list->edges->startPoint->number];
				curr->endPoint = newCycle->vertices[list->edges->endPoint->number];

				/* pop curr (has to be done before appending it to its new list) */
				list->edges = curr->next;

				/* set indicator of biconnected component */
				curr->used = componentNumber;

				/* add edge to incidence list of its new startpoint */
				addEdge(curr->startPoint, curr);

				/* clone edge and reverse it */
				rev = shallowCopyEdge(curr, gp->listPool);
				rev->startPoint = curr->endPoint;
				rev->endPoint = curr->startPoint;
				addEdge(rev->startPoint, rev);

				/* update edge count of cycles */
				newCycle->m += 1;
			}
			++componentNumber;

			/* add the new cyclic component to the list of biconnected components */
			newCycle->next = cycles;
			cycles = newCycle;

		}

		/* breaking condition and iteration of list pointer, dumping of sucked out ShallowGraphs */
		if (list->next) {
			list = list->next;
			dumpShallowGraph(sgp, list->prev);
		} else {
			/* if there is no next element, the current element has to be dumped and the loop has to end */
			dumpShallowGraph(sgp, list);
			break;
		}
	}

	/* it may happen, that cycles == NULL, if the input graph is a forest, nevertheless
	 * forest != NULL in any case */
	forest->next = cycles;
	return forest;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rcx, 0x8(%rsp)
movq %rdx, %rbx
movq %rsi, %r12
movq %rdi, %r13
movq %rdx, %rdi
callq 0x11619
movq %rax, %rbp
movl (%r12), %esi
movq %rax, %rdi
callq 0x5c80
testq %rax, %rax
je 0x921f
xorl %r14d, %r14d
movslq (%r12), %rax
cmpq %rax, %r14
jge 0x9077
movq 0x10(%r12), %rax
movq (%rax,%r14,8), %rdi
movq 0x10(%rbx), %rsi
callq 0x5a70
movq 0x10(%rbp), %rcx
movq %rax, (%rcx,%r14,8)
incq %r14
jmp 0x904f
xorl %r14d, %r14d
movq $0x0, (%rsp)
movq %rbp, 0x10(%rsp)
cmpl $0x1, 0x10(%r13)
jne 0x90f1
movq 0x10(%rbp), %rax
movq (%r13), %rsi
movq 0x10(%rsi), %rcx
movq 0x18(%rsi), %rdx
movslq 0x18(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
movq %rdi, 0x10(%rsi)
movslq 0x18(%rdx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x18(%rsi)
callq 0x5b2c
movq (%r13), %rdi
movq 0x18(%rbx), %rsi
callq 0x5a28
movq (%r13), %rcx
movq 0x18(%rcx), %rdi
movq %rdi, 0x10(%rax)
movq 0x10(%rcx), %rcx
movq %rcx, 0x18(%rax)
movq %rax, %rsi
callq 0x5b2c
andq $0x0, (%r13)
incl 0x4(%rbp)
jmp 0x91e9
movq %rbx, %rdi
callq 0x11619
movq %rax, %rbp
movl (%r12), %esi
movq %rax, %rdi
callq 0x5c80
movq (%r13), %r15
testq %r15, %r15
je 0x91d5
movq 0x10(%rbp), %rax
movq 0x10(%r15), %rdi
movslq 0x18(%rdi), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x9145
movq 0x10(%rbx), %rsi
callq 0x5a70
movq 0x10(%rbp), %rcx
movq 0x10(%r15), %rdx
movslq 0x18(%rdx), %rdx
movq %rax, (%rcx,%rdx,8)
movq 0x10(%rbp), %rax
movq 0x18(%r15), %rdi
movslq 0x18(%rdi), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x9171
movq 0x10(%rbx), %rsi
callq 0x5a70
movq 0x10(%rbp), %rcx
movq 0x18(%r15), %rdx
movslq 0x18(%rdx), %rdx
movq %rax, (%rcx,%rdx,8)
movq 0x10(%rbp), %rax
movq (%r13), %rcx
movq 0x10(%rcx), %rdx
movslq 0x18(%rdx), %rdx
movq (%rax,%rdx,8), %rdi
movq %rdi, 0x10(%r15)
movq 0x18(%rcx), %rcx
movslq 0x18(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x18(%r15)
movq 0x8(%r15), %rax
movq %rax, (%r13)
movl %r14d, 0x20(%r15)
movq %r15, %rsi
callq 0x5b2c
movq 0x18(%rbx), %rsi
movq %r15, %rdi
callq 0x5a28
movq 0x18(%r15), %rdi
movq %rdi, 0x10(%rax)
movq 0x10(%r15), %rcx
movq %rcx, 0x18(%rax)
movq %rax, %rsi
callq 0x5b2c
incl 0x4(%rbp)
jmp 0x9108
incl %r14d
movq (%rsp), %rax
movq %rax, 0x18(%rbp)
movq %rbp, (%rsp)
movq 0x10(%rsp), %rbp
movq 0x18(%r13), %r15
testq %r15, %r15
je 0x9208
movq 0x20(%r15), %rsi
movq 0x8(%rsp), %rdi
callq 0x1184e
movq %r15, %r13
jmp 0x9087
movq 0x8(%rsp), %rdi
movq %r13, %rsi
callq 0x1184e
movq (%rsp), %rax
movq %rax, 0x18(%rbp)
jmp 0x9249
movl 0x8(%r12), %esi
leaq 0x14204(%rip), %rdi     # 0x1d42f
xorl %eax, %eax
callq 0x10b0
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x1166e
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1166e
xorl %ebp, %ebp
movq %rbp, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq