// File: /workspace/github_c_makefile_star2_O3/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 0x893c
movq %rax, %rbx
movq (%r15), %r12
movq %r13, 0x10(%rsp)
movq %r13, %rdi
callq 0x1498d
movq %rax, (%rsp)
movq %r14, 0x8(%rbx)
movq 0x8(%r14), %r13
cmpq %r14, %r13
je 0x6424
movl $0x1, %eax
movq %r13, %rcx
movq 0x10(%rcx), %rdx
movl %eax, 0x28(%rdx)
incl %eax
movq 0x8(%rcx), %rcx
cmpq %r14, %rcx
jne 0x63be
movq 0x18(%r14), %rax
movl $0x0, 0x28(%rax)
cmpq %r14, %r13
je 0x642f
movl 0x10(%r15), %ecx
movl $0x2, %ebp
movl $0x3, %ebx
movq %r12, %rdi
movq %r13, %rsi
movl %ecx, %edx
movl %ebp, %ecx
movl %ebx, %r8d
callq 0x5ebe
movq %rax, %r12
cmpq %r13, %rax
cmovel %ebx, %ebp
incl %ebx
movl 0x10(%r15), %ecx
leal 0x1(%rcx), %esi
movl %ebx, %eax
cltd
idivl %esi
movq 0x8(%r13), %r13
movl %edx, %ebx
cmpq %r14, %r13
jne 0x63ee
jmp 0x6434
movq 0x18(%r14), %rax
movl $0x0, 0x28(%rax)
movl $0x2, %ebp
movq 0x8(%r12), %rax
movq %rax, (%r15)
movq %r12, 0x8(%r15)
movq $0x0, 0x8(%r12)
testq %rax, %rax
movq 0x10(%rsp), %r13
je 0x6622
movq %rax, 0x8(%rsp)
movq 0x18(%rax), %rax
movq 0x8(%rax), %r12
testq %r12, %r12
je 0x6610
xorl %r14d, %r14d
movq 0x10(%r12), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x9900
movl %eax, %ebx
movq 0x18(%r12), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x9900
xorl %ecx, %ecx
cmpl %eax, %ebx
setl %cl
addl %ecx, %r14d
movq 0x8(%r12), %r12
testq %r12, %r12
jne 0x6470
testl %r14d, %r14d
je 0x6610
cmpl $0x1, %r14d
jne 0x654a
movq 0x8(%rsp), %rax
movq 0x18(%rax), %r14
movq 0x8(%r14), %r14
testq %r14, %r14
je 0x6610
movq 0x10(%r14), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x9900
movl %eax, %ebx
movq 0x18(%r14), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x9900
cmpl %eax, %ebx
jge 0x64cc
movq 0x10(%r14), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x9900
movl %eax, %ebx
movq 0x18(%r14), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x9900
movq (%r14), %rcx
movq 0x10(%r13), %r8
movq (%rsp), %rdi
movl %ebx, %esi
movl %eax, %edx
callq 0x628e
jmp 0x6610
movl %r14d, %eax
movq %rax, 0x20(%rsp)
leaq (,%rax,8), %rdi
callq 0x1190
movq %rax, %r12
movq 0x8(%rsp), %rax
movq 0x18(%rax), %rbx
xorl %r13d, %r13d
movq 0x8(%rbx), %rbx
movq 0x10(%rbx), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x9900
movl %eax, 0x24(%rbx)
movq 0x18(%rbx), %rax
movl 0x28(%rax), %edi
subl %ebp, %edi
movl 0x10(%r15), %esi
incl %esi
callq 0x9900
movl %eax, 0x20(%rbx)
cmpl %eax, 0x24(%rbx)
jge 0x65af
movslq %r13d, %r13
movq %rbx, (%r12,%r13,8)
incl %r13d
cmpl %r14d, %r13d
jl 0x656e
movl $0x8, %edx
movq %r12, %rdi
movq %r12, 0x18(%rsp)
movq 0x20(%rsp), %r12
movq %r12, %rsi
leaq -0x728(%rip), %rcx      # 0x5ea8
callq 0x1080
xorl %ebx, %ebx
movq 0x10(%rsp), %r13
movq (%rsp), %r14
movq 0x18(%rsp), %rax
movq (%rax,%rbx,8), %rax
movl 0x24(%rax), %esi
movl 0x20(%rax), %edx
movq (%rax), %rcx
movq 0x10(%r13), %r8
movq %r14, %rdi
callq 0x628e
incq %rbx
cmpq %rbx, %r12
jne 0x65e0
movq 0x18(%rsp), %rdi
callq 0x1030
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rax
testq %rax, %rax
jne 0x6457
movq %r15, %rdi
movq %r13, %rsi
callq 0x5d4a
movq %rax, %r15
movq 0x26991(%rip), %rbx     # 0x2cfc8
movq (%rbx), %rsi
movq %rax, %rdi
callq 0x7142
movq (%rbx), %rsi
movq (%rsp), %r14
movq %r14, %rdi
callq 0x7142
movq (%r14), %rax
movq 0x8(%r15), %rcx
movq %rax, 0x8(%rcx)
movq 0x8(%r14), %rax
movq %rax, 0x8(%r15)
movl 0x10(%r14), %eax
addl %eax, 0x10(%r15)
movq 0x10(%r13), %rdi
callq 0x709c
movq %r15, %rdi
movq %rax, %rsi
callq 0x848a
movq 0x10(%r13), %rdi
callq 0x708a
movq %r15, %rdi
movq %rax, %rsi
callq 0x8916
movq (%rbx), %rcx
leaq 0x19a47(%rip), %rdi     # 0x200e5
movl $0xa, %esi
movl $0x1, %edx
callq 0x1220
movq (%rbx), %rsi
movq %r15, %rdi
callq 0x7142
movq $0x0, (%r14)
movq %r13, %rdi
movq %r14, %rsi
callq 0x149f4
movq %r15, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq