// File: /workspace/github_c_makefile_star2_O2/pwelke[P]GraphMiningTools/listCycles.c
// Function: _backtrack
struct ShallowGraph* __backtrack(struct Graph* g, struct Vertex* v, struct Vertex* parent, struct Vertex* s, int allowance,
		struct ShallowGraph* currentPath, struct ShallowGraphPool* sgp) {
	int i,j;
	struct ShallowGraph *path = getShallowGraph(sgp);
	struct ShallowGraph *result = NULL;
	struct VertexList *neighbor, *idx;
	char flag = 0;


	/* while there exists a vertex $ w \in v->neighborhood $ with w > z
	 * s.t. there is a path from w to s which avoids the current path
	 */
	for (neighbor=v->neighborhood; neighbor; neighbor=neighbor->next) {

		/* this "removes" vertices that are too small from adjacency lists
		 * also, dont use the backwards edge to your parent */
		if ((neighbor->endPoint->number >= allowance) && (neighbor->endPoint != parent)) {

			/* " z < w " given some numbering of vertices. I take the one given by ->number.
			 * This only tries to find a path if the first condition holds. should be better,
			 * as the paths will be marked on vertex level. This seems to be not well elaborated
			 * right now..... shit
			 *
			 * z was a strange way to say: for each neighbor of v and even does harm, if incidence
			 * lists are not sorted by endPoint->number */
			if (findPath(neighbor->endPoint, v, s, allowance, path, sgp)) {
				struct Vertex* predecessorInPath = NULL;

				/* the current extension edge should be contained in the path */
				pushEdge(path, shallowCopyEdge(neighbor, sgp->listPool));

				i = 1;

				/* maybe this can be omitted as flag is not global any more*/
				flag = 0;

				/* mark all vertices on the current path as such, the others as others */
				/* TODO this could maybe be made faster by only traversing the vertices that are necessary with dfs */
				for (j=0; j<g->n; ++j) {
					if (g->vertices[j]) {
						g->vertices[j]->d = g->vertices[j]->visited;
					}
				}


				/* add vertices in path to the current path until a choice of ways to reach s is found */
				for (idx=path->edges; idx && (idx->endPoint != s) && !flag; idx=idx->next) {
					struct VertexList *innerVertexNeighbs;

					appendEdge(currentPath, shallowCopyEdge(idx, sgp->listPool));
					idx->endPoint->visited = idx->endPoint->d = 1;


					for (innerVertexNeighbs=idx->endPoint->neighborhood; innerVertexNeighbs; innerVertexNeighbs=innerVertexNeighbs->next) {
						if (innerVertexNeighbs->endPoint->number >= allowance) {
							/* if the endpoint of this edge is not the next vertex on path */
							if (innerVertexNeighbs->endPoint != idx->next->endPoint) {
								/* ...  or the parent */
								if (innerVertexNeighbs->endPoint->number != idx->startPoint->number) {
									/* ... and not visited yet, except if its s */
									if ((innerVertexNeighbs->endPoint->d == 0) || (innerVertexNeighbs->endPoint == s)) {

										/* search for a different way to s than the one given by path */
										flag = __DFS(innerVertexNeighbs->endPoint, idx->endPoint, s, allowance);

										if (flag) break;
									}
								}
							}
						} /* fi allowance */

						/* remember the predecessor on the current path so that recursive call to __backtrack
						 * knows, which edge not to use. */
						predecessorInPath = idx->startPoint;
					}
					++i;
				}


				/* this is where output is produced */
				if (!flag) {
					/* idx points to the edge closing the cycle, which is not yet included in the output */
					struct VertexList* closingEdge = shallowCopyEdge(idx, sgp->listPool);

					/* clone currentPath */
					struct ShallowGraph* clone = getShallowGraph(sgp);
					/* the output of this function is a cycle of shallow graphs, and addComponent
					 * expects its input, to be a cycle, too.
					 */
					clone->next = clone->prev = clone;

					for (idx=currentPath->edges; idx; idx=idx->next) {
						appendEdge(clone, shallowCopyEdge(idx, sgp->listPool));
					}

					appendEdge(clone, closingEdge);

					/* add it to the results list */
					result = addComponent(result, clone);

				} else {

					struct ShallowGraph* x = __backtrack(g, idx->startPoint, predecessorInPath, s, allowance, currentPath, sgp);
					result = addComponent(result, x);
				}


				if (currentPath->edges->startPoint == v) {
					/* if v is the first vertex in the path, dump the whole path */
					struct VertexList* tmp1 = currentPath->edges;
					struct VertexList* tmp2 = currentPath->edges;
					currentPath->edges = NULL;
					currentPath->lastEdge = NULL;
					while(tmp1) {
						tmp1 = tmp1->next;
						tmp2->endPoint->visited = 0;
						dumpVertexList(sgp->listPool, tmp2);
						tmp2=tmp1;
					}
				} else {
					/* go up to v in current path, then delete all following edges and set their visited values to 0.
					 * Also: set the pointer to the last element in path to v */
					for (idx=currentPath->edges; idx; idx=idx->next) {
						if (idx->endPoint == v) {
							struct VertexList* tmp1 = idx->next;
							struct VertexList* tmp2 = idx->next;
							idx->next = NULL;
							currentPath->lastEdge = idx;
							while(tmp1) {
								tmp1 = tmp1->next;
								tmp2->endPoint->visited = 0;
								dumpVertexList(sgp->listPool, tmp2);
								tmp2=tmp1;
							}
							break;
						}
					}
				}

				/* if we go to the next neighbor of v, we want to start a fresh path */
				dumpShallowGraph(sgp, path);
				path = getShallowGraph(sgp);
			}
		}
	}

	/* garbage collection */
	dumpShallowGraph(sgp, path);

	return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %r9, %r13
movl %r8d, %ebp
movq %rcx, 0x18(%rsp)
movq %rdx, %r14
movq %rsi, %r12
movq %rdi, 0x38(%rsp)
movq 0x90(%rsp), %r15
movq %r15, %rdi
callq 0x117e9
movq %rax, 0x10(%rsp)
movq $0x0, 0x28(%rsp)
movq %r12, %rbx
movq 0x8(%rbx), %rbx
testq %rbx, %rbx
je 0x9b3d
movq 0x18(%rbx), %rdi
cmpq %r14, %rdi
je 0x9895
cmpl %ebp, 0x18(%rdi)
jl 0x9895
movq %r12, %rsi
movq 0x18(%rsp), %rdx
movl %ebp, %ecx
movq 0x10(%rsp), %r8
movq %r15, %r9
callq 0x97b9
testb %al, %al
je 0x9895
movq 0x10(%r15), %rsi
movq %rbx, %rdi
callq 0x5a28
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x61e7
movq 0x38(%rsp), %rdi
movl (%rdi), %eax
testl %eax, %eax
movl $0x0, %ecx
cmovlel %ecx, %eax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x9914
movq 0x10(%rdi), %rdx
movq (%rdx,%rcx,8), %rdx
testq %rdx, %rdx
je 0x990f
movl 0x1c(%rdx), %esi
movl %esi, 0x28(%rdx)
incq %rcx
jmp 0x98f7
movq %rbx, 0x20(%rsp)
movq %r12, 0x50(%rsp)
movq %r14, 0x30(%rsp)
movb $0x1, %r15b
movq 0x10(%rsp), %r14
xorl %ebx, %ebx
movq %r13, 0x40(%rsp)
movq (%r14), %r12
testq %r12, %r12
je 0x99ed
movq 0x18(%rsp), %rax
cmpq %rax, 0x18(%r12)
sete %al
movl %r15d, %ecx
notb %cl
orb %al, %cl
testb $0x1, %cl
jne 0x99ed
movq 0x90(%rsp), %rax
movq 0x10(%rax), %rsi
movq %r12, %rdi
callq 0x5a28
movq %r13, %rdi
movq %rax, %rsi
callq 0x6620
movq 0x18(%r12), %r13
pushq $0x1
popq %rax
movl %eax, 0x28(%r13)
movl %eax, 0x1c(%r13)
leaq 0x8(%r12), %r14
movq 0x8(%r13), %r13
testq %r13, %r13
sete %r15b
je 0x99e3
movq 0x18(%r13), %rdi
movl 0x18(%rdi), %eax
cmpl %ebp, %eax
jl 0x99dc
movq (%r14), %rcx
cmpq 0x18(%rcx), %rdi
je 0x99dc
movq 0x10(%r12), %rcx
cmpl 0x18(%rcx), %eax
je 0x99dc
cmpq 0x18(%rsp), %rdi
je 0x99c7
cmpl $0x0, 0x28(%rdi)
jne 0x99dc
movq 0x18(%r12), %rsi
movq 0x18(%rsp), %rdx
movl %ebp, %ecx
callq 0x97d7
testb %al, %al
jne 0x99e3
movq 0x10(%r12), %rbx
jmp 0x998f
movq 0x40(%rsp), %r13
jmp 0x9932
testb $0x1, %r15b
je 0x9a4d
movq 0x90(%rsp), %r15
movq 0x10(%r15), %rsi
movq %r12, %rdi
callq 0x5a28
movq %rax, 0x48(%rsp)
movq %r15, %rdi
callq 0x117e9
movq %rax, %rbx
movq %rax, 0x20(%rax)
movq %rax, 0x18(%rax)
movq %r13, %r12
movq 0x30(%rsp), %r14
movq (%r12), %r12
testq %r12, %r12
je 0x9a80
movq 0x10(%r15), %rsi
movq %r12, %rdi
callq 0x5a28
movq %rbx, %rdi
movq %rax, %rsi
callq 0x6620
addq $0x8, %r12
jmp 0x9a27
movq 0x10(%r12), %rsi
movq 0x90(%rsp), %r15
movq %r15, (%rsp)
movq 0x38(%rsp), %rdi
movq %rbx, %rdx
movq 0x18(%rsp), %rcx
movl %ebp, %r8d
movq %r13, %r9
callq 0x9850
movq %rax, %rbx
movq 0x30(%rsp), %r14
jmp 0x9a8d
movq %rbx, %rdi
movq 0x48(%rsp), %rsi
callq 0x6620
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x656a
movq %rax, 0x28(%rsp)
movq (%r13), %rsi
movq 0x50(%rsp), %r12
cmpq %r12, 0x10(%rsi)
je 0x9af2
movq 0x20(%rsp), %rbx
testq %rsi, %rsi
je 0x9b1e
movq %rsi, %rax
movq 0x8(%rsi), %rsi
cmpq %r12, 0x18(%rax)
jne 0x9ab3
andq $0x0, 0x8(%rax)
movq %rax, 0x8(%r13)
testq %rsi, %rsi
je 0x9b1e
movq 0x8(%rsi), %rbx
movq 0x18(%rsi), %rax
andl $0x0, 0x1c(%rax)
movq 0x10(%r15), %rdi
callq 0x11364
movq %rbx, %rsi
movq 0x20(%rsp), %rbx
jmp 0x9ace
xorps %xmm0, %xmm0
movups %xmm0, (%r13)
movq 0x20(%rsp), %rbx
testq %rsi, %rsi
je 0x9b1e
movq 0x8(%rsi), %rbx
movq 0x18(%rsi), %rax
andl $0x0, 0x1c(%rax)
movq 0x10(%r15), %rdi
callq 0x11364
movq %rbx, %rsi
jmp 0x9afa
movq %r15, %rdi
movq 0x10(%rsp), %rsi
callq 0x1184e
movq %r15, %rdi
callq 0x117e9
movq %rax, 0x10(%rsp)
jmp 0x9895
movq %r15, %rdi
movq 0x10(%rsp), %rsi
callq 0x1184e
movq 0x28(%rsp), %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq