// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq 0xa8(%rdi), %rax
cmpb $0x1, 0x9(%rax)
jne 0x2fe19
movb 0x8(%rax), %cl
cmpb $0x1, 0x21(%rbx)
jne 0x2fe04
testb $0x1, %cl
jne 0x2fe04
cmpb $0x0, 0x20(%rbx)
je 0x2ff51
testb $0x1, %cl
jne 0x2fe19
movw $0xffff, 0xa(%rax)      # imm = 0xFFFF
movzwl 0x22(%rbx), %eax
cmpw 0xa(%rbx), %ax
ja 0x2fe3c
cmpb $0x0, 0x21(%rbx)
je 0x2fe45
movq 0xa8(%rbx), %rdi
cmpb $0x0, 0x20(%rbx)
jne 0x2fe4c
movw $0xffff, 0x22(%rbx)     # imm = 0xFFFF
movzwl 0xa(%rdi), %eax
cmpw 0xa(%rbx), %ax
jbe 0x2fe4c
movw %ax, 0xa(%rbx)
jmp 0x2ff4c
movq 0xa8(%rbx), %rdi
leaq 0x18(%rbx), %r14
movzwl 0x22(%rbx), %ebp
cmpw 0xa(%rdi), %bp
jbe 0x2ff01
movb 0x8(%rdi), %al
testb %al, %al
jne 0x2fe75
movq (%rdi), %rax
callq *0x20(%rax)
movq 0xa8(%rbx), %rdi
movb 0x8(%rdi), %al
testb $0x1, %al
je 0x2fee0
movq (%rdi), %rax
callq *0x30(%rax)
movq %rax, 0xc0(%rbx)
movq 0xa8(%rbx), %rax
movb $0x0, 0x8(%rax)
movq 0x10(%rbx), %rdi
movq 0xc0(%rbx), %rax
movzwl 0x8(%rax), %eax
movw %ax, 0xc(%rbx)
callq 0x306ce
movq 0xc0(%rbx), %rcx
movzwl 0x8(%rcx), %ecx
movw %cx, 0xa(%rax)
movq 0xc0(%rbx), %rdx
movzwl 0x8(%rdx), %ecx
movw %cx, 0x22(%rbx)
movq %r14, %rdi
movq %rax, %rsi
callq 0x307e8
cmpb $0x1, 0x20(%rbx)
jne 0x2fee0
movb $0x1, 0x8(%rbx)
movb $0x0, 0x20(%rbx)
movq 0xa8(%rbx), %rax
movzwl 0xa(%rax), %eax
cmpw 0xa(%rbx), %ax
jbe 0x2ff4c
movw %ax, 0xa(%rbx)
cmpb $0x0, 0x21(%rbx)
jne 0x2ff4c
movzwl 0x22(%rbx), %ecx
jmp 0x2ff42
movb 0x20(%rbx), %al
testb %al, %al
jne 0x2ff22
cmpl $0x3, %esi
movl $0x2, %eax
cmovgel %esi, %eax
movq 0x18(%rbx), %rcx
movq %r14, %rdi
movl %eax, %esi
callq *0x28(%rcx)
movb 0x20(%rbx), %al
testb $0x1, %al
je 0x2ff2e
movb $0x1, 0x8(%rbx)
movb $0x0, 0x20(%rbx)
movzwl 0x22(%rbx), %eax
cmpw %bp, %ax
jbe 0x2ff4c
movq 0xa8(%rbx), %rcx
movzwl 0xa(%rcx), %ecx
cmpw %ax, %cx
cmovael %eax, %ecx
movw %cx, 0xa(%rbx)
popq %rbx
popq %r14
popq %rbp
retq
movb $0x1, 0x9(%rbx)
jmp 0x2ff4c
nop