// File: BenLangmead[P]bowtie/./ebwt_search_backtrack.h
// Function: EbwtRangeSource::initBranch(PathManager&)
virtual void
	initBranch(PathManager& pm) {
		assert(curEbwt_ != NULL);
		assert_gt(qry_->length(), 0);
		assert_leq(qlen_, qry_->length());
		assert_geq(qual_->length(), qry_->length());
		const Ebwt& ebwt = *ebwt_;
		int ftabChars = ebwt._eh._ftabChars;
		this->foundRange = false;
		int nsInSeed = 0; int nsInFtab = 0;
		ASSERT_ONLY(allTops_.clear());
		if(skippingThisRead_) {
			this->done = true;
			return;
		}
		if(qlen_ < 4) {
			uint32_t maxmms = 0;
			if(offRev0_ != offRev1_) maxmms = 1;
			if(offRev1_ != offRev2_) maxmms = 2;
			if(offRev2_ != offRev3_) maxmms = 3;
			if(qlen_ <= maxmms) {
				if(!quiet_) {
					ThreadSafe _ts(&gLock);
					cerr << "Warning: Read (" << (*name_) << ") is less than " << (maxmms+1) << " characters long; skipping..." << endl;
				}
				this->done = true;
				skippingThisRead_ = true;
				return;
			}
		}
		if(!tallyNs(nsInSeed, nsInFtab)) {
			// No alignments are possible because of the distribution
			// of Ns in the read in combination with the backtracking
			// constraints.
			return;
		}
		// icost = total cost penalty (major bits = stratum, minor bits =
		// quality penalty) incurred so far by partial alignment
		uint16_t icost = (seedRange_.valid()) ? seedRange_.cost : 0;
		// iham = total quality penalty incurred so far by partial alignment
		uint16_t iham = (seedRange_.valid() && qualOrder_) ? (seedRange_.cost & ~0xc000): 0;
		assert_leq(iham, qualLim_);
		// m = depth beyond which ftab must not extend or else we might
		// miss some legitimate paths
		uint32_t m = min<uint32_t>(offRev0_, (uint32_t)qlen_);
		// Let skipInvalidExact = true if using the ftab would be a
		// waste because it would jump directly to an alignment we
		// couldn't use.
		bool ftabSkipsToEnd = (qlen_ == (uint32_t)ftabChars);
		bool skipInvalidExact = (!reportExacts_ && ftabSkipsToEnd);

		// If it's OK to use the ftab...
		if(nsInFtab == 0 && m >= (uint32_t)ftabChars && !skipInvalidExact) {
			// Use the ftab to jump 'ftabChars' chars into the read
			// from the right
			uint32_t ftabOff = calcFtabOff();
			TIndexOffU top = ebwt.ftabHi(ftabOff);
			TIndexOffU bot = ebwt.ftabLo(ftabOff+1);
			if(qlen_ == (uint32_t)ftabChars && bot > top) {
				// We found a range with 0 mismatches immediately.  Set
				// fields to indicate we found a range.
				assert(reportExacts_);
				curRange_.top     = top;
				curRange_.bot     = bot;
				curRange_.stratum = (icost >> 14);
				curRange_.cost    = icost;
				curRange_.numMms  = 0;
				curRange_.ebwt    = ebwt_;
				curRange_.fw      = fw_;
				curRange_.mms.clear(); // no mismatches
				curRange_.refcs.clear(); // no mismatches
				// Lump in the edits from the partial alignment
				addPartialEdits();
				assert(curRange_.repOk());
				// no need to do anything with curRange_.refcs
				this->foundRange  = true;
				//this->done = true;
				return;
			} else if (bot > top) {
				// We have a range to extend
				assert_leq(top, ebwt._eh._len);
				assert_leq(bot, ebwt._eh._len);
				Branch *b = pm.bpool.alloc();
				if(b == NULL) {
					assert(pm.empty());
					return;
				}
				if(!b->init(
				        pm.rpool, pm.epool, pm.bpool.lastId(), (uint32_t)qlen_,
				        offRev0_, offRev1_, offRev2_, offRev3_,
				        0, ftabChars, icost, iham, top, bot,
				        ebwt._eh, ebwt._ebwt))
				{
					// Negative result from b->init() indicates we ran
					// out of best-first chunk memory
					assert(pm.empty());
					return;
				}
				assert(!b->curtailed_);
				assert(!b->exhausted_);
				assert_gt(b->depth3_, 0);
				pm.push(b); // insert into priority queue
				assert(!pm.empty());
			} else {
				// The arrows are already closed within the
				// unrevisitable region; give up
			}
		} else {
			// We can't use the ftab, so we start from the rightmost
			// position and use _fchr
			Branch *b = pm.bpool.alloc();
			if(b == NULL) {
				assert(pm.empty());
				return;
			}
			if(!b->init(pm.rpool, pm.epool, pm.bpool.lastId(), (uint32_t)qlen_,
			        offRev0_, offRev1_, offRev2_, offRev3_,
			        0, 0, icost, iham, 0, 0, ebwt._eh, ebwt._ebwt))
			{
				// Negative result from b->init() indicates we ran
				// out of best-first chunk memory
				assert(pm.empty());
				return;
			}
			assert(!b->curtailed_);
			assert(!b->exhausted_);
			assert_gt(b->depth3_, 0);
			pm.push(b); // insert into priority queue
			assert(!pm.empty());
		}
		return;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movq %rdi, -0x30(%rbp)
movq %rsi, -0x38(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x98(%rbp)
movq 0x68(%rax), %rcx
movq %rcx, -0x40(%rbp)
movq -0x40(%rbp), %rcx
movl 0x124(%rcx), %ecx
movl %ecx, -0x44(%rbp)
movb $0x0, 0x9(%rax)
movl $0x0, -0x48(%rbp)
movl $0x0, -0x4c(%rbp)
testb $0x1, 0x178(%rax)
je 0x3ec47
movq -0x98(%rbp), %rax
movb $0x1, 0x8(%rax)
jmp 0x3f2aa
movq -0x98(%rbp), %rax
cmpq $0x4, 0x50(%rax)
jae 0x3edc1
movq -0x98(%rbp), %rcx
movl $0x0, -0x50(%rbp)
movl 0x74(%rcx), %eax
cmpl 0x78(%rcx), %eax
je 0x3ec76
movl $0x1, -0x50(%rbp)
movq -0x98(%rbp), %rcx
movl 0x78(%rcx), %eax
cmpl 0x7c(%rcx), %eax
je 0x3ec8c
movl $0x2, -0x50(%rbp)
movq -0x98(%rbp), %rcx
movl 0x7c(%rcx), %eax
cmpl 0x80(%rcx), %eax
je 0x3eca5
movl $0x3, -0x50(%rbp)
movq -0x98(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x50(%rbp), %ecx
cmpq %rcx, %rax
ja 0x3edbf
movq -0x98(%rbp), %rax
testb $0x1, 0xb5(%rax)
jne 0x3eda8
leaq 0x6c681(%rip), %rsi     # 0xab358
leaq -0x58(%rbp), %rdi
callq 0x2f3b0
movq 0x69309(%rip), %rdi     # 0xa7ff0
leaq 0x4df4a(%rip), %rsi     # 0x8cc38
callq 0xa5d0
movq %rax, -0xa0(%rbp)
jmp 0x3ecfc
movq -0xa0(%rbp), %rdi
movq -0x98(%rbp), %rax
movq 0x60(%rax), %rsi
callq 0x2c0d0
movq %rax, -0xa8(%rbp)
jmp 0x3ed1c
movq -0xa8(%rbp), %rdi
leaq 0x4df1e(%rip), %rsi     # 0x8cc48
callq 0xa5d0
movq %rax, -0xb0(%rbp)
jmp 0x3ed38
movq -0xb0(%rbp), %rdi
movl -0x50(%rbp), %esi
incl %esi
callq 0xa810
movq %rax, -0xb8(%rbp)
jmp 0x3ed52
movq -0xb8(%rbp), %rdi
leaq 0x4def8(%rip), %rsi     # 0x8cc58
callq 0xa5d0
movq %rax, -0xc0(%rbp)
jmp 0x3ed6e
movq -0xc0(%rbp), %rdi
movq 0x691ec(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x3ed83
leaq -0x58(%rbp), %rdi
callq 0x2f3e0
jmp 0x3eda8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x2f3e0
jmp 0x3f2bc
movq -0x98(%rbp), %rax
movb $0x1, 0x8(%rax)
movb $0x1, 0x178(%rax)
jmp 0x3f2aa
jmp 0x3edc1
movq -0x98(%rbp), %rdi
leaq -0x48(%rbp), %rsi
leaq -0x4c(%rbp), %rdx
callq 0x407d0
testb $0x1, %al
jne 0x3edde
jmp 0x3f2aa
movq -0x98(%rbp), %rdi
addq $0x118, %rdi            # imm = 0x118
callq 0x40360
testb $0x1, %al
jne 0x3edf7
jmp 0x3ee0d
movq -0x98(%rbp), %rax
movzwl 0x120(%rax), %eax
movl %eax, -0xc4(%rbp)
jmp 0x3ee17
xorl %eax, %eax
movl %eax, -0xc4(%rbp)
jmp 0x3ee17
movq -0x98(%rbp), %rdi
movl -0xc4(%rbp), %eax
movw %ax, -0x66(%rbp)
addq $0x118, %rdi            # imm = 0x118
callq 0x40360
testb $0x1, %al
jne 0x3ee3a
jmp 0x3ee65
movq -0x98(%rbp), %rax
testb $0x1, 0x85(%rax)
je 0x3ee65
movq -0x98(%rbp), %rax
movzwl 0x120(%rax), %eax
andl $0xffff3fff, %eax       # imm = 0xFFFF3FFF
movl %eax, -0xc8(%rbp)
jmp 0x3ee6f
xorl %eax, %eax
movl %eax, -0xc8(%rbp)
jmp 0x3ee6f
movq -0x98(%rbp), %rax
movl -0xc8(%rbp), %ecx
movw %cx, -0x68(%rbp)
movq %rax, %rdi
addq $0x74, %rdi
movq 0x50(%rax), %rax
movl %eax, -0x70(%rbp)
leaq -0x70(%rbp), %rsi
callq 0x26c20
movq -0x98(%rbp), %rcx
movl (%rax), %eax
movl %eax, -0x6c(%rbp)
movq 0x50(%rcx), %rax
movl -0x44(%rbp), %edx
cmpq %rdx, %rax
sete %al
andb $0x1, %al
movb %al, -0x71(%rbp)
xorl %eax, %eax
testb $0x1, 0x8c(%rcx)
movb %al, -0xc9(%rbp)
jne 0x3eecf
movb -0x71(%rbp), %al
movb %al, -0xc9(%rbp)
movb -0xc9(%rbp), %al
andb $0x1, %al
movb %al, -0x72(%rbp)
cmpl $0x0, -0x4c(%rbp)
jne 0x3f167
movl -0x6c(%rbp), %eax
cmpl -0x44(%rbp), %eax
jb 0x3f167
testb $0x1, -0x72(%rbp)
jne 0x3f167
movq -0x98(%rbp), %rdi
callq 0x40960
movl %eax, -0x78(%rbp)
movq -0x40(%rbp), %rdi
movl -0x78(%rbp), %esi
callq 0x409f0
movl %eax, -0x7c(%rbp)
movq -0x40(%rbp), %rdi
movl -0x78(%rbp), %esi
addl $0x1, %esi
callq 0x40a40
movl %eax, %ecx
movq -0x98(%rbp), %rax
movl %ecx, -0x80(%rbp)
movq 0x50(%rax), %rax
movl -0x44(%rbp), %ecx
cmpq %rcx, %rax
jne 0x3efe3
movl -0x80(%rbp), %eax
cmpl -0x7c(%rbp), %eax
jbe 0x3efe3
movq -0x98(%rbp), %rdi
movl -0x7c(%rbp), %eax
movl %eax, 0xb8(%rdi)
movl -0x80(%rbp), %eax
movl %eax, 0xbc(%rdi)
movzwl -0x66(%rbp), %eax
sarl $0xe, %eax
movl %eax, 0xc4(%rdi)
movw -0x66(%rbp), %ax
movw %ax, 0xc0(%rdi)
movl $0x0, 0xc8(%rdi)
movq 0x68(%rdi), %rax
movq %rax, 0x110(%rdi)
movb 0x70(%rdi), %al
andb $0x1, %al
movb %al, 0xcc(%rdi)
addq $0xb8, %rdi
addq $0x18, %rdi
callq 0x401d0
movq -0x98(%rbp), %rdi
addq $0xb8, %rdi
addq $0x38, %rdi
callq 0x401f0
movq -0x98(%rbp), %rdi
callq 0x40a90
movq -0x98(%rbp), %rax
movb $0x1, 0x9(%rax)
jmp 0x3f2aa
movl -0x80(%rbp), %eax
cmpl -0x7c(%rbp), %eax
jbe 0x3f15e
movq -0x38(%rbp), %rdi
addq $0x38, %rdi
callq 0x40ba0
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
jne 0x3f012
jmp 0x3f2aa
movq -0x88(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x38(%rbp), %rax
addq $0x98, %rax
movq %rax, -0xf0(%rbp)
movq -0x38(%rbp), %rax
addq $0xf8, %rax
movq %rax, -0xe8(%rbp)
movq -0x38(%rbp), %rdi
addq $0x38, %rdi
callq 0x40ea0
movq -0xf8(%rbp), %rdi
movq -0xf0(%rbp), %rsi
movq -0xe8(%rbp), %rdx
movl %eax, %ecx
movq -0x98(%rbp), %rax
movq 0x50(%rax), %r8
movl 0x74(%rax), %r9d
movl 0x78(%rax), %r10d
movw %r10w, -0xdc(%rbp)
movl 0x7c(%rax), %r10d
movw %r10w, -0xda(%rbp)
movl 0x80(%rax), %eax
movw %ax, %r13w
movl -0x44(%rbp), %eax
movw %ax, %r12w
movw -0x66(%rbp), %r15w
movw -0x68(%rbp), %r14w
movl -0x7c(%rbp), %ebx
movl -0x80(%rbp), %r11d
movq -0x40(%rbp), %r10
addq $0xf8, %r10
movq -0x40(%rbp), %rax
movq 0xb8(%rax), %rax
movq %rax, -0xd8(%rbp)
xorl %eax, %eax
xorl %eax, %eax
movw -0xdc(%rbp), %ax
movzwl %r9w, %r9d
movzwl %ax, %eax
movl %eax, (%rsp)
movw -0xda(%rbp), %ax
movzwl %ax, %eax
movl %eax, 0x8(%rsp)
movq -0xd8(%rbp), %rax
movzwl %r13w, %r13d
movl %r13d, 0x10(%rsp)
movl $0x0, 0x18(%rsp)
movzwl %r12w, %r12d
movl %r12d, 0x20(%rsp)
movzwl %r15w, %r15d
movl %r15d, 0x28(%rsp)
movzwl %r14w, %r14d
movl %r14d, 0x30(%rsp)
movl %ebx, 0x38(%rsp)
movl %r11d, 0x40(%rsp)
movq %r10, 0x48(%rsp)
movq %rax, 0x50(%rsp)
movq $0x0, 0x58(%rsp)
callq 0x40c40
testb $0x1, %al
jne 0x3f14c
jmp 0x3f2aa
movq -0x38(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x40ec0
jmp 0x3f160
jmp 0x3f160
jmp 0x3f162
jmp 0x3f2a8
movq -0x38(%rbp), %rdi
addq $0x38, %rdi
callq 0x40ba0
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
jne 0x3f18a
jmp 0x3f2aa
movq -0x90(%rbp), %rax
movq %rax, -0x110(%rbp)
movq -0x38(%rbp), %rax
addq $0x98, %rax
movq %rax, -0x108(%rbp)
movq -0x38(%rbp), %rax
addq $0xf8, %rax
movq %rax, -0x100(%rbp)
movq -0x38(%rbp), %rdi
addq $0x38, %rdi
callq 0x40ea0
movq -0x110(%rbp), %rdi
movq -0x108(%rbp), %rsi
movq -0x100(%rbp), %rdx
movl %eax, %ecx
movq -0x98(%rbp), %rax
movq 0x50(%rax), %r8
movl 0x74(%rax), %r9d
movl 0x78(%rax), %r10d
movw %r10w, %r12w
movl 0x7c(%rax), %r10d
movw %r10w, %r15w
movl 0x80(%rax), %eax
movw %ax, %r14w
movw -0x66(%rbp), %bx
movw -0x68(%rbp), %r11w
movq -0x40(%rbp), %r10
addq $0xf8, %r10
movq -0x40(%rbp), %rax
movq 0xb8(%rax), %rax
xorl %r13d, %r13d
xorl %r13d, %r13d
movzwl %r9w, %r9d
movzwl %r12w, %r12d
movl %r12d, (%rsp)
movzwl %r15w, %r15d
movl %r15d, 0x8(%rsp)
movzwl %r14w, %r14d
movl %r14d, 0x10(%rsp)
movl $0x0, 0x18(%rsp)
movl $0x0, 0x20(%rsp)
movzwl %bx, %ebx
movl %ebx, 0x28(%rsp)
movzwl %r11w, %r11d
movl %r11d, 0x30(%rsp)
movl $0x0, 0x38(%rsp)
movl $0x0, 0x40(%rsp)
movq %r10, 0x48(%rsp)
movq %rax, 0x50(%rsp)
movq $0x0, 0x58(%rsp)
callq 0x40c40
testb $0x1, %al
jne 0x3f298
jmp 0x3f2aa
movq -0x38(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq 0x40ec0
jmp 0x3f2aa
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0xab60
nopw %cs:(%rax,%rax)
nop