// File: /workspace/github_c_makefile_star2_O2/pwelke[P]GraphMiningTools/cs_Outerplanar.c
// Function: _permutateBlock
struct ShallowGraph* __permutateBlock(struct ShallowGraph* cycle, struct ShallowGraphPool* sgp) {
	struct VertexList* start = cycle->edges;
	struct VertexList* end = assertLastPointer(cycle);
	/* best points to the edge before the starting edge of the lex smallest cycle */
	struct VertexList* best = cycle->edges;
	int bestOffset = 2;
	/* return */
	struct ShallowGraph* cString;
	struct ShallowGraph* secondPart = getShallowGraph(sgp);
	/* indices */
	struct VertexList* idx;
	int i;

	/* make actual cycle */
	end->next = start;

	/* give each vertex a number according to its position in cycle */
	for (idx=start->next, i=1; idx!=start; idx=idx->next, ++i) {
		idx->startPoint->d = i;
	}
	start->endPoint->d = 0;

	/* offset=3 as in the first step the permutation starting at edge after the second vertex
	 * in cycle is compared to the permutation starting after the first */
	for (idx = start->next, i=3; idx != start; idx=idx->next, i=(i+1)%(cycle->m + 1)) {
		best = __compareBlockRepresentations(best, idx, cycle->m, bestOffset, i);
		if (best == idx) {
			bestOffset = i;
		}
	}

	/* turn cycle s.t. the shallow graph is lex. smallest */
	cycle->edges = best->next;
	cycle->lastEdge = best;
	best->next = NULL;

	/* compute canonical string of the component */
	for (idx=cycle->edges; idx; idx=idx->next) {
		struct VertexList* e;

		int neighbors = 0;

		struct VertexList** narray1;

		/* count number of diagonals that go from the current vertex to a vertex with a higher
		 * index wrt the current permutation */
		for (e=idx->endPoint->neighborhood; e; e=e->next) {
			if (mod(e->startPoint->d - bestOffset, cycle->m + 1) < mod(e->endPoint->d - bestOffset, cycle->m + 1)) {
				++neighbors;
			}
		}

		/* special cases where current vertices have no or just one incident diagonal */
		if (neighbors == 0) {
			continue; /* the idx loop */
		}

		if (neighbors == 1) {
			/* add edge representation to secondPart. There may be more than one incident diagonals, but just one that
			 * satisfies startpoint < endpoint. This is the edge we are searching. */
			for (e=idx->endPoint->neighborhood; e; e=e->next) {
				if (mod(e->startPoint->d - bestOffset, cycle->m + 1) < mod(e->endPoint->d - bestOffset, cycle->m + 1)) {
					__appendDiagonal(secondPart,
							mod(e->startPoint->d - bestOffset, cycle->m + 1),
							mod(e->endPoint->d - bestOffset, cycle->m + 1),
							e->label,
							sgp->listPool);

					break; /* inner for, there is just one edge */
				}
			}
			continue; /* the idx loop */
		}

		/* otherwise: sort the edges according to their cycle indices modulo the permutation */
		narray1 = malloc(neighbors * sizeof(struct VertexList*));

		for (i=0, e=idx->endPoint->neighborhood; i<neighbors; e=e->next) {
			e->flag = mod(e->startPoint->d - bestOffset, cycle->m + 1);
			e->used = mod(e->endPoint->d - bestOffset, cycle->m + 1);
			if (e->flag < e->used) {
				narray1[i] = e;
				++i;
			}
		}

		qsort(narray1, neighbors, sizeof(struct VertexList*), __compareDiagonals);

		/* append string representation of diagonal */
		for (i=0; i<neighbors; ++i) {
			__appendDiagonal(secondPart, narray1[i]->flag, narray1[i]->used, narray1[i]->label, sgp->listPool);
		}

		/* garbage collection */
		free(narray1);
	}


	cString = canonicalStringOfCycle(cycle, sgp);

	//debug
	printCanonicalString(cString, stdout);
	printCanonicalString(secondPart, stdout);

	cString->lastEdge->next = secondPart->edges;
	cString->lastEdge = secondPart->lastEdge;
	cString->m = cString->m + secondPart->m;
	pushEdge(cString, getInitialisatorEdge(sgp->listPool));
	appendEdge(cString, getTerminatorEdge(sgp->listPool));

	//debug
	fprintf(stdout, "something\n");
	printCanonicalString(cString, stdout);

	/* garbage collection */
	secondPart->edges = NULL;
	dumpShallowGraph(sgp, secondPart);

	return cString;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %r13
movq %rdi, %r15
movq (%rdi), %r14
callq 0x6646
movq %rax, %rbx
movq (%r15), %r12
movq %r13, 0x8(%rsp)
movq %r13, %rdi
callq 0x117e9
movq %rax, 0x10(%rsp)
movq %r14, 0x8(%rbx)
leaq 0x8(%r14), %r13
pushq $0x1
popq %rax
movq %r13, %rcx
movq (%rcx), %rcx
cmpq %r14, %rcx
je 0x4345
movq 0x10(%rcx), %rdx
movl %eax, 0x28(%rdx)
addq $0x8, %rcx
incl %eax
jmp 0x432e
movq 0x18(%r14), %rax
andl $0x0, 0x28(%rax)
pushq $0x3
popq %rbx
pushq $0x2
popq %rbp
movq (%r13), %r13
cmpq %r14, %r13
je 0x438e
movl 0x10(%r15), %edx
movq %r12, %rdi
movq %r13, %rsi
movl %ebp, %ecx
movl %ebx, %r8d
callq 0x3e86
movq %rax, %r12
cmpq %r13, %rax
cmovel %ebx, %ebp
addq $0x8, %r13
incl %ebx
movl 0x10(%r15), %ecx
incl %ecx
movl %ebx, %eax
cltd
idivl %ecx
movl %edx, %ebx
jmp 0x4353
movq 0x8(%r12), %r13
movq %r13, (%r15)
movq %r12, 0x8(%r15)
andq $0x0, 0x8(%r12)
movq 0x10(%rsp), %r12
testq %r13, %r13
je 0x4564
movq 0x18(%r13), %r12
xorl %r14d, %r14d
movq 0x8(%r12), %r12
testq %r12, %r12
je 0x43f7
movq 0x10(%r12), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x752c
movl %eax, %ebx
movq 0x18(%r12), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x752c
xorl %ecx, %ecx
cmpl %eax, %ebx
setl %cl
addl %ecx, %r14d
jmp 0x43b5
testl %r14d, %r14d
movq 0x10(%rsp), %r12
je 0x455b
cmpl $0x1, %r14d
jne 0x4495
movq 0x18(%r13), %r14
movq 0x8(%r14), %r14
testq %r14, %r14
je 0x455b
movq 0x10(%r14), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x752c
movl %eax, %ebx
movq 0x18(%r14), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x752c
cmpl %eax, %ebx
jge 0x4413
movq 0x10(%r14), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x752c
movl %eax, %ebx
movq 0x18(%r14), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x752c
movq (%r14), %rcx
movq 0x8(%rsp), %rdx
movq 0x10(%rdx), %r8
movq %r12, %rdi
movl %ebx, %esi
movl %eax, %edx
callq 0x4200
jmp 0x455b
movl %r14d, %eax
movq %rax, 0x18(%rsp)
leaq (,%rax,8), %rdi
callq 0x1180
movq %r13, %rcx
movq %rax, %r13
movq %rcx, 0x20(%rsp)
movq 0x18(%rcx), %rbx
xorl %r12d, %r12d
cmpl %r14d, %r12d
jae 0x4505
movq 0x8(%rbx), %rbx
movq 0x10(%rbx), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x752c
movl %eax, 0x24(%rbx)
movq 0x18(%rbx), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x752c
movl %eax, 0x20(%rbx)
cmpl %eax, 0x24(%rbx)
jge 0x44bc
movl %r12d, %eax
movq %rbx, (%r13,%rax,8)
incl %r12d
jmp 0x44bc
movq %r13, %rdi
movq 0x18(%rsp), %rsi
pushq $0x8
popq %rdx
leaq -0x6a7(%rip), %rcx      # 0x3e70
callq 0x1080
xorl %ebx, %ebx
movq 0x8(%rsp), %r14
movq 0x10(%rsp), %r12
cmpq %rbx, 0x18(%rsp)
je 0x454e
movq (%r13,%rbx,8), %rax
movl 0x24(%rax), %esi
movl 0x20(%rax), %edx
movq (%rax), %rcx
movq 0x10(%r14), %r8
movq %r12, %rdi
callq 0x4200
incq %rbx
jmp 0x4528
movq %r13, %rdi
callq 0x1030
movq 0x20(%rsp), %r13
movq 0x8(%r13), %r13
jmp 0x43a5
movq %r15, %rdi
movq 0x8(%rsp), %r14
movq %r14, %rsi
callq 0x3d54
movq %rax, %r15
movq 0x25a4a(%rip), %rbx     # 0x29fc8
movq (%rbx), %rsi
movq %rax, %rdi
callq 0x5041
movq (%rbx), %rsi
movq %r12, %rdi
callq 0x5041
movq (%r12), %rax
movq 0x8(%r15), %rcx
movq %rax, 0x8(%rcx)
movq 0x8(%r12), %rax
movq %rax, 0x8(%r15)
movl 0x10(%r12), %eax
addl %eax, 0x10(%r15)
movq 0x10(%r14), %rdi
callq 0x4fac
movq %r15, %rdi
movq %rax, %rsi
callq 0x61e7
movq 0x10(%r14), %rdi
callq 0x4f9a
movq %r15, %rdi
movq %rax, %rsi
callq 0x6620
movq (%rbx), %rcx
leaq 0x18b01(%rip), %rdi     # 0x1d0e5
pushq $0xa
popq %rsi
pushq $0x1
popq %rdx
callq 0x1210
movq (%rbx), %rsi
movq %r15, %rdi
callq 0x5041
andq $0x0, (%r12)
movq %r14, %rdi
movq %r12, %rsi
callq 0x1184e
movq %r15, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq