// File: BenLangmead[P]bowtie/./ebwt_search_backtrack.h
// Function: EbwtSeededRangeSourceDriver::advanceImpl(int)
virtual void advanceImpl(int until) {
		assert(!this->done);
		assert(!this->foundRange);
		assert_gt(rsFull_.minCost, 0);
		// Advance the seed range source
		if(rsSeed_->done && rsFull_.done &&
		   !rsSeed_->foundRange && !rsFull_.foundRange)
		{
			this->done = true;
			return;
		}
		if(rsSeed_->done && !rsSeed_->foundRange) {
			rsSeed_->minCost = 0xffff;
			if(rsFull_.minCost > this->minCost) {
				this->minCost = rsFull_.minCost;
				// Cost changed, so return
				return;
			}
		}
		if(rsFull_.done && !rsFull_.foundRange) {
			rsFull_.minCost = 0xffff;
			if(rsSeed_->minCost > this->minCost) {
				this->minCost = rsSeed_->minCost;
				// Cost changed, so return
				return;
			}
		}
		assert(rsSeed_->minCost != 0xffff || rsFull_.minCost != 0xffff);
		// Extend a partial alignment
		ASSERT_ONLY(uint16_t oldMinCost = this->minCost);
		assert_eq(this->minCost, min<uint16_t>(rsSeed_->minCost, rsFull_.minCost));
		bool doFull = rsFull_.minCost <= rsSeed_->minCost;
		if(!doFull) {
			// Advance the partial-alignment generator
			assert_eq(rsSeed_->minCost, this->minCost);
			if(!rsSeed_->foundRange) {
				rsSeed_->advance(until);
			}
			if(rsSeed_->foundRange) {
				assert_eq(this->minCost, rsSeed_->range().cost);
				assert_eq(oldMinCost, rsSeed_->range().cost);
				seedRange_ = &rsSeed_->range();
				rsSeed_->foundRange = false;
				assert_geq(seedRange_->cost, this->minCostAdjustment_);
				this->minCostAdjustment_ = seedRange_->cost;
				assert_gt(seedRange_->numMms, 0);
				// Keep the range for the hi-half partial alignment so
				// that the driver can (a) modify the pattern string
				// and (b) modify results from the RangeSource to
				// include these edits.
				EbwtRangeSourceDriver *partial = rsFact_->create();
				partial->minCost = seedRange_->cost;
				rsFull_.minCost = seedRange_->cost;
				rsFull_.addSource(partial, seedRange_);
				if(rsFull_.foundRange) {
					this->foundRange = true;
					rsFull_.foundRange = false;
					assert(rsFull_.range().repOk());
					assert_eq(range().cost, oldMinCost);
				}
			}
			if(rsSeed_->minCost > this->minCost) {
				this->minCost = rsSeed_->minCost;
				if(!rsFull_.done) {
					this->minCost = min(this->minCost, rsFull_.minCost);
					assert_eq(this->minCost, min<uint16_t>(rsSeed_->minCost, rsFull_.minCost));
				}
			}
		} else {
			// Extend a full alignment
			assert(!rsFull_.done);
			assert(!rsFull_.foundRange);
			uint16_t oldFullCost = rsFull_.minCost;
			if(!rsFull_.foundRange) {
				rsFull_.advance(until);
			}
			// Found a minimum-cost range
			if(rsFull_.foundRange) {
				this->foundRange = true;
				rsFull_.foundRange = false;
				assert(rsFull_.range().repOk());
				assert_eq(range().cost, oldMinCost);
			}
			assert_geq(rsFull_.minCost, oldFullCost);
			// Did the min cost change?
			if(rsFull_.minCost > oldFullCost) {
				// If a range was found, hold on to it and save it for
				// later.  Update the minCost.
				assert(!rsSeed_->done || rsSeed_->minCost == 0xffff);
				this->minCost = min(rsFull_.minCost, rsSeed_->minCost);
			}
		}
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
movq 0xa8(%rax), %rax
testb $0x1, 0x9(%rax)
je 0x4a046
movq -0x28(%rbp), %rax
testb $0x1, 0x21(%rax)
je 0x4a046
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rax
testb $0x1, 0x8(%rax)
jne 0x4a046
movq -0x28(%rbp), %rax
testb $0x1, 0x20(%rax)
jne 0x4a046
movq -0x28(%rbp), %rax
movb $0x1, 0x9(%rax)
jmp 0x4a2b3
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rax
testb $0x1, 0x9(%rax)
je 0x4a098
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rax
testb $0x1, 0x8(%rax)
jne 0x4a098
movq -0x28(%rbp), %rcx
movq 0xa8(%rcx), %rax
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movzwl 0x22(%rcx), %eax
movzwl 0xa(%rcx), %ecx
cmpl %ecx, %eax
jle 0x4a096
movq -0x28(%rbp), %rax
movw 0x22(%rax), %cx
movw %cx, 0xa(%rax)
jmp 0x4a2b3
jmp 0x4a098
movq -0x28(%rbp), %rax
testb $0x1, 0x21(%rax)
je 0x4a0e3
movq -0x28(%rbp), %rax
testb $0x1, 0x20(%rax)
jne 0x4a0e3
movq -0x28(%rbp), %rcx
movw $0xffff, 0x22(%rcx)     # imm = 0xFFFF
movq 0xa8(%rcx), %rax
movzwl 0xa(%rax), %eax
movzwl 0xa(%rcx), %ecx
cmpl %ecx, %eax
jle 0x4a0e1
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rcx
movw 0xa(%rcx), %cx
movw %cx, 0xa(%rax)
jmp 0x4a2b3
jmp 0x4a0e3
movq -0x28(%rbp), %rcx
movzwl 0x22(%rcx), %eax
movq 0xa8(%rcx), %rcx
movzwl 0xa(%rcx), %ecx
cmpl %ecx, %eax
setle %al
andb $0x1, %al
movb %al, -0xd(%rbp)
testb $0x1, -0xd(%rbp)
jne 0x4a23c
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rax
testb $0x1, 0x8(%rax)
jne 0x4a12f
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rdi
movl -0xc(%rbp), %esi
movq (%rdi), %rax
callq *0x20(%rax)
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rax
testb $0x1, 0x8(%rax)
je 0x4a1e2
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0xc0(%rax)
movq 0xa8(%rax), %rcx
movb $0x0, 0x8(%rcx)
movq 0xc0(%rax), %rcx
movw 0x8(%rcx), %cx
movw %cx, 0xc(%rax)
movq 0x10(%rax), %rdi
callq 0x4b1b0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, -0x18(%rbp)
movq 0xc0(%rax), %rcx
movw 0x8(%rcx), %dx
movq -0x18(%rbp), %rcx
movw %dx, 0xa(%rcx)
movq 0xc0(%rax), %rcx
movw 0x8(%rcx), %cx
movw %cx, 0x22(%rax)
movq %rax, %rdi
addq $0x18, %rdi
movq -0x18(%rbp), %rsi
movq 0xc0(%rax), %rdx
callq 0x4b320
movq -0x28(%rbp), %rax
testb $0x1, 0x20(%rax)
je 0x4a1e0
movq -0x28(%rbp), %rax
movb $0x1, 0x8(%rax)
movb $0x0, 0x20(%rax)
jmp 0x4a1e2
movq -0x28(%rbp), %rcx
movq 0xa8(%rcx), %rax
movzwl 0xa(%rax), %eax
movzwl 0xa(%rcx), %ecx
cmpl %ecx, %eax
jle 0x4a23a
movq -0x28(%rbp), %rax
movq 0xa8(%rax), %rcx
movw 0xa(%rcx), %cx
movw %cx, 0xa(%rax)
testb $0x1, 0x21(%rax)
jne 0x4a238
movq -0x28(%rbp), %rsi
movq %rsi, %rdi
addq $0xa, %rdi
addq $0x18, %rsi
addq $0xa, %rsi
callq 0x4b3c0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movw (%rcx), %cx
movw %cx, 0xa(%rax)
jmp 0x4a23a
jmp 0x4a2b3
movq -0x28(%rbp), %rax
movw 0x22(%rax), %cx
movw %cx, -0x1a(%rbp)
testb $0x1, 0x20(%rax)
jne 0x4a25e
movq -0x28(%rbp), %rdi
addq $0x18, %rdi
movl -0xc(%rbp), %esi
callq 0x4a620
movq -0x28(%rbp), %rax
testb $0x1, 0x20(%rax)
je 0x4a274
movq -0x28(%rbp), %rax
movb $0x1, 0x8(%rax)
movb $0x0, 0x20(%rax)
movq -0x28(%rbp), %rax
movzwl 0x22(%rax), %eax
movzwl -0x1a(%rbp), %ecx
cmpl %ecx, %eax
jle 0x4a2b1
movq -0x28(%rbp), %rax
movq %rax, %rdi
addq $0x18, %rdi
addq $0xa, %rdi
movq 0xa8(%rax), %rsi
addq $0xa, %rsi
callq 0x4b3c0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movw (%rcx), %cx
movw %cx, 0xa(%rax)
jmp 0x4a2b3
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax)