// File: BenLangmead[P]bowtie/./ebwt_search_backtrack.h
// Function: EbwtRangeSourceDriver::initRangeSource(SStringExpandable<char, 25, 2, 0> const&)
virtual void initRangeSource(const BTString& qual) {
		// If seedLen_ is huge, then it will always cover the whole
		// alignment
		assert_eq(len_, qual.length());
		uint32_t s = (seedLen_ > 0 ? min(seedLen_, len_) : len_);
		uint32_t sLeft  = s >> 1;
		uint32_t sRight = s >> 1;
		// If seed has odd length, then nudge appropriate half up by 1
		if((s & 1) != 0) { if(nudgeLeft_) sLeft++; else sRight++; }
		uint32_t rev0Off = cextToDepth(rev0Off_, sRight, s, len_);
		uint32_t rev1Off = cextToDepth(rev1Off_, sRight, s, len_);
		uint32_t rev2Off = cextToDepth(rev2Off_, sRight, s, len_);
		uint32_t rev3Off = cextToDepth(rev3Off_, sRight, s, len_);
		// Truncate the pattern if necessary
		uint32_t qlen = (uint32_t)qual.length();
		if(seed_) {
			if(len_ > s) {
				rs_->setQlen(s);
				qlen = s;
			}
			assert(!rs_->reportExacts());
		}
		// If there are any Ns in the unrevisitable region, then this
		// driver is guaranteed to yield no fruit.
		uint16_t minCost = 0;
		if(rs_->reportExacts()) {
			// Keep minCost at 0
		} else if (!rs_->halfAndHalf() && rev0Off < s) {
			// Exacts not allowed, so there must be at least 1 mismatch
			// outside of the unrevisitable area
			minCost = 1 << 14;
			if(qualOrder_) {
				uint8_t lowQual = 0xff;
				for(uint32_t d = rev0Off; d < s; d++) {
					uint8_t lowAtPos;
					lowAtPos = qual[qlen - d - 1];
					if(lowAtPos < lowQual) lowQual = lowAtPos;
				}
				assert_lt(lowQual, 0xff);
				minCost += mmPenalty(maqPenalty_, phredCharToPhredQual(lowQual));
			}
		} else if(rs_->halfAndHalf() && sRight > 0 && sRight < (s-1)) {
			// Half-and-half constraints are active, so there must be
			// at least 1 mismatch in both halves of the seed
			assert(rs_->halfAndHalf());
			minCost = (seed_ ? 3 : 2) << 14;
			if(qualOrder_) {
				assert(rs_->halfAndHalf() == 2 || rs_->halfAndHalf() == 3);
				uint8_t lowQual1 = 0xff;
				for(uint32_t d = 0; d < sRight; d++) {
					uint8_t lowAtPos;
					lowAtPos = qual[qlen - d - 1];
					if(lowAtPos < lowQual1) lowQual1 = lowAtPos;
				}
				assert_lt(lowQual1, 0xff);
				minCost += mmPenalty(maqPenalty_, phredCharToPhredQual(lowQual1));
				uint8_t lowQual2_1 = 0xff;
				uint8_t lowQual2_2 = 0xff;
				for(uint32_t d = sRight; d < s; d++) {
					uint8_t lowAtPos;
					lowAtPos = qual[qlen - d - 1];
					if(lowAtPos < lowQual2_1) {
						if(lowQual2_1 != 0xff) {
							lowQual2_2 = lowQual2_1;
						}
						lowQual2_1 = lowAtPos;
					} else if(lowAtPos < lowQual2_2) {
						lowQual2_2 = lowAtPos;
					}
				}
				assert_lt(lowQual2_1, 0xff);
				minCost += mmPenalty(maqPenalty_, phredCharToPhredQual(lowQual2_1));
				if(rs_->halfAndHalf() > 2 && lowQual2_2 != 0xff) {
					minCost += mmPenalty(maqPenalty_, phredCharToPhredQual(lowQual2_2));
				}
			}
		}
		if(verbose_) cout << "initRangeSource minCost: " << minCost << endl;
		this->minCostAdjustment_ = minCost;
		rs_->setOffs(sRight,   // depth of far edge of hi-half (only matters where half-and-half is possible)
		             s,        // depth of far edge of lo-half (only matters where half-and-half is possible)
		             rev0Off,  // depth above which we cannot backtrack
		             rev1Off,  // depth above which we may backtrack just once
		             rev2Off,  // depth above which we may backtrack just twice
		             rev3Off); // depth above which we may backtrack just three times
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpl $0x0, 0x1c0(%rax)
jbe 0x48e7f
movq -0x58(%rbp), %rsi
movq %rsi, %rdi
addq $0x1c0, %rdi            # imm = 0x1C0
addq $0x10, %rsi
callq 0x26c20
movl (%rax), %eax
movl %eax, -0x5c(%rbp)
jmp 0x48e89
movq -0x58(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
shrl %eax
movl %eax, -0x18(%rbp)
movl -0x14(%rbp), %eax
shrl %eax
movl %eax, -0x1c(%rbp)
movl -0x14(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x48ecd
movq -0x58(%rbp), %rax
testb $0x1, 0x1c4(%rax)
je 0x48ec2
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x48ecb
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x48ecd
movq -0x58(%rbp), %rdi
movl 0x1c8(%rdi), %esi
movl -0x1c(%rbp), %edx
movl -0x14(%rbp), %ecx
movl 0x10(%rdi), %r8d
callq 0x49a60
movq -0x58(%rbp), %rdi
movl %eax, -0x20(%rbp)
movl 0x1cc(%rdi), %esi
movl -0x1c(%rbp), %edx
movl -0x14(%rbp), %ecx
movl 0x10(%rdi), %r8d
callq 0x49a60
movq -0x58(%rbp), %rdi
movl %eax, -0x24(%rbp)
movl 0x1d0(%rdi), %esi
movl -0x1c(%rbp), %edx
movl -0x14(%rbp), %ecx
movl 0x10(%rdi), %r8d
callq 0x49a60
movq -0x58(%rbp), %rdi
movl %eax, -0x28(%rbp)
movl 0x1d4(%rdi), %esi
movl -0x1c(%rbp), %edx
movl -0x14(%rbp), %ecx
movl 0x10(%rdi), %r8d
callq 0x49a60
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2ef90
movq %rax, %rcx
movq -0x58(%rbp), %rax
movl %ecx, -0x30(%rbp)
testb $0x1, 0x1b0(%rax)
je 0x48f80
movq -0x58(%rbp), %rax
movl 0x10(%rax), %eax
cmpl -0x14(%rbp), %eax
jbe 0x48f7e
movq -0x58(%rbp), %rax
movq 0x1b8(%rax), %rdi
movl -0x14(%rbp), %esi
callq 0x49b00
movl -0x14(%rbp), %eax
movl %eax, -0x30(%rbp)
jmp 0x48f80
movq -0x58(%rbp), %rax
movw $0x0, -0x32(%rbp)
movq 0x1b8(%rax), %rdi
callq 0x49b50
testb $0x1, %al
jne 0x48f9c
jmp 0x48fa1
jmp 0x49250
movq -0x58(%rbp), %rax
movq 0x1b8(%rax), %rdi
callq 0x49b70
cmpl $0x0, %eax
jne 0x49062
movl -0x20(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x49062
movq -0x58(%rbp), %rax
movw $0x4000, -0x32(%rbp)    # imm = 0x4000
testb $0x1, 0x1b2(%rax)
je 0x4905d
movb $-0x1, -0x33(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x49029
movq -0x10(%rbp), %rdi
movl -0x30(%rbp), %eax
subl -0x38(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x49b90
movb (%rax), %al
movb %al, -0x39(%rbp)
movzbl -0x39(%rbp), %eax
movzbl -0x33(%rbp), %ecx
cmpl %ecx, %eax
jge 0x4901c
movb -0x39(%rbp), %al
movb %al, -0x33(%rbp)
jmp 0x4901e
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x48fe7
movq -0x58(%rbp), %rax
movb 0x1b1(%rax), %al
movb %al, -0x5d(%rbp)
movsbl -0x33(%rbp), %edi
callq 0x1fb10
movb -0x5d(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %edi
movzbl %al, %esi
callq 0x1fad0
movzbl %al, %ecx
movzwl -0x32(%rbp), %eax
addl %ecx, %eax
movw %ax, -0x32(%rbp)
jmp 0x4924e
movq -0x58(%rbp), %rax
movq 0x1b8(%rax), %rdi
callq 0x49b70
cmpl $0x0, %eax
je 0x4924c
cmpl $0x0, -0x1c(%rbp)
jbe 0x4924c
movl -0x1c(%rbp), %eax
movl -0x14(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jae 0x4924c
movq -0x58(%rbp), %rax
movb 0x1b0(%rax), %sil
movl $0x2, %ecx
movl $0x3, %edx
testb $0x1, %sil
cmovnel %edx, %ecx
shll $0xe, %ecx
movw %cx, -0x32(%rbp)
testb $0x1, 0x1b2(%rax)
je 0x4924a
movb $-0x1, -0x3a(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jae 0x49113
movq -0x10(%rbp), %rdi
movl -0x30(%rbp), %eax
subl -0x40(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x49b90
movb (%rax), %al
movb %al, -0x41(%rbp)
movzbl -0x41(%rbp), %eax
movzbl -0x3a(%rbp), %ecx
cmpl %ecx, %eax
jge 0x49106
movb -0x41(%rbp), %al
movb %al, -0x3a(%rbp)
jmp 0x49108
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x490d1
movq -0x58(%rbp), %rax
movb 0x1b1(%rax), %al
movb %al, -0x5e(%rbp)
movsbl -0x3a(%rbp), %edi
callq 0x1fb10
movb -0x5e(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %edi
movzbl %al, %esi
callq 0x1fad0
movzbl %al, %ecx
movzwl -0x32(%rbp), %eax
addl %ecx, %eax
movw %ax, -0x32(%rbp)
movb $-0x1, -0x42(%rbp)
movb $-0x1, -0x43(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x48(%rbp)
movl -0x48(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x491be
movq -0x10(%rbp), %rdi
movl -0x30(%rbp), %eax
subl -0x48(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x49b90
movb (%rax), %al
movb %al, -0x49(%rbp)
movzbl -0x49(%rbp), %eax
movzbl -0x42(%rbp), %ecx
cmpl %ecx, %eax
jge 0x4919d
movzbl -0x42(%rbp), %eax
cmpl $0xff, %eax
je 0x49195
movb -0x42(%rbp), %al
movb %al, -0x43(%rbp)
movb -0x49(%rbp), %al
movb %al, -0x42(%rbp)
jmp 0x491b1
movzbl -0x49(%rbp), %eax
movzbl -0x43(%rbp), %ecx
cmpl %ecx, %eax
jge 0x491af
movb -0x49(%rbp), %al
movb %al, -0x43(%rbp)
jmp 0x491b1
jmp 0x491b3
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x49155
movq -0x58(%rbp), %rax
movb 0x1b1(%rax), %al
movb %al, -0x5f(%rbp)
movsbl -0x42(%rbp), %edi
callq 0x1fb10
movb -0x5f(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %edi
movzbl %al, %esi
callq 0x1fad0
movb %al, %cl
movq -0x58(%rbp), %rax
movzbl %cl, %edx
movzwl -0x32(%rbp), %ecx
addl %edx, %ecx
movw %cx, -0x32(%rbp)
movq 0x1b8(%rax), %rdi
callq 0x49b70
cmpl $0x2, %eax
jle 0x49248
movzbl -0x43(%rbp), %eax
cmpl $0xff, %eax
je 0x49248
movq -0x58(%rbp), %rax
movb 0x1b1(%rax), %al
movb %al, -0x60(%rbp)
movsbl -0x43(%rbp), %edi
callq 0x1fb10
movb -0x60(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %edi
movzbl %al, %esi
callq 0x1fad0
movzbl %al, %ecx
movzwl -0x32(%rbp), %eax
addl %ecx, %eax
movw %ax, -0x32(%rbp)
jmp 0x4924a
jmp 0x4924c
jmp 0x4924e
jmp 0x49250
movq -0x58(%rbp), %rax
testb $0x1, 0x1d8(%rax)
je 0x4928b
movq 0x5ed54(%rip), %rdi     # 0xa7fb8
leaq 0x43b04(%rip), %rsi     # 0x8cd6f
callq 0xa5d0
movq %rax, %rdi
movzwl -0x32(%rbp), %esi
callq 0xaab0
movq %rax, %rdi
movq 0x5ece2(%rip), %rsi     # 0xa7f68
callq 0xa640
movq -0x58(%rbp), %rax
movw -0x32(%rbp), %cx
movw %cx, 0xc(%rax)
movq 0x1b8(%rax), %rdi
movl -0x1c(%rbp), %esi
movl -0x14(%rbp), %edx
movl -0x20(%rbp), %ecx
movl -0x24(%rbp), %r8d
movl -0x28(%rbp), %r9d
movl -0x2c(%rbp), %eax
movl %eax, (%rsp)
callq 0x49bb0
addq $0x70, %rsp
popq %rbp
retq