// File: readmapping[P]alfalfa/src/mapper.cpp
// Function: findOrAlignMateToAlignment(sparseSA const&, read_t&, read_t&, bool, align_opt const&, paired_opt const&, std::vector<lis_t, std::allocator<lis_t>>&, int, std::vector<alnScoreInfo_t, std::allocator<alnScoreInfo_t>>&, int)
inline void findOrAlignMateToAlignment(const sparseSA& sa, read_t & alignmentMate, read_t & windowMate, 
        bool alnMateFirst, const align_opt & alnOptions, const paired_opt & pairedOpt, 
        vector<lis_t> & lisIntervalsWindow, int minScore, vector<alnScoreInfo_t> & windowAlns,
        int alignmentIndex){
    alignment_t * aln = alignmentMate.alignments[alignmentIndex];
    //FIND WINDOW
    long refB, refE;
    bool fw;
    int Plength = windowMate.sequence.length();
    dpWindow(aln->refB, aln->refE, alnMateFirst, !aln->flag.test(4), Plength, pairedOpt, refB, refE, fw);
    //CHECK IF AN ALIGNMENT ALREADY EXISTS IN THIS WINDOW
    if(alnOptions.print >= 4) cerr << "find window for aligment of mate " << (alnMateFirst ? "1" : "2") << " on strand " << (aln->flag.test(4) ? "R" : "F") << " and position " << aln->refB << endl;
    int windowMatePos = bestAlignmentInWindow(windowMate, windowAlns, alnMateFirst, refB, refE, fw);
    if(alnOptions.print >= 2) cerr << "#WINDOWLIST " << (windowMatePos>=0) << endl;
    int windowCount = 1;
    if(windowMatePos < 0){
        if(alnOptions.print >= 4) cerr << "found no existing concordant alignment" << endl;
        //TRY TO FIND LIS THAT IS CONCORDANT AND EXTEND THAT
        int editDist = (int)(alnOptions.errorPercent*Plength)+1;
        int lisPos = bestLISInWindow(lisIntervalsWindow, editDist, refB, refE, fw);
        if(lisPos >= 0){
            if(alnOptions.print >= 4) cerr << "found existing concordant LIS" << endl;
            //TRY TO EXTEND THIS LIS
            const vector<match_t> & matchVector = lisIntervalsWindow[lisPos].matches;
            long chrStart, chrEnd;
            sa.getChromBounds(matchVector[0].ref, chrStart, chrEnd);
            size_t extendCount = windowMate.alignments.size();
            extendAlignmentChain(sa.S, lisIntervalsWindow[lisPos].fw ? windowMate.sequence : windowMate.rcSequence, 
                    matchVector, editDist, minScore, Plength*0.01, alnOptions, chrStart, chrEnd, windowMate, lisIntervalsWindow[lisPos].fw);
            if(windowMate.alignments.size() > extendCount){
                lisIntervalsWindow[lisPos].extended = true;
                windowMatePos = extendCount;
                windowCount = windowMate.alignments.size() - extendCount;
            }
        }
        if(alnOptions.print >= 2) cerr << "#WINDOWALIGN " << (windowMatePos >= 0) << endl;
    }
    if(windowMatePos < 0 && pairedOpt.pairedRescue){
        if(alnOptions.print >= 4) cerr << "found no existing concordant LIS or alignment" << endl;
        //TRY TO ALIGN IN WINDOW
        int tLen = refE-refB+1;
        uint8_t * target = (uint8_t *)malloc(tLen);
        for (int j = 0; j < tLen; ++j) // convert to the nt4 encoding
            target[j] = Utils::ORDVALUE[(size_t)sa.S[refB+j]];
        int xtra = KSW_XSTART | (Plength * alnOptions.match < 250? KSW_XBYTE : 0);
        kswr_t alnResult = ksw_align(Plength, fw ? windowMate.readP : windowMate.rcReadP, tLen, 
                target, 5, alnOptions.mat, alnOptions.openGap, alnOptions.extendGap, xtra, 0);
        free(target);
        if(alnResult.score > minScore){
            alignment_t * newAln = new alignment_t();
            newAln->alignmentScore = alnResult.score;
            newAln->qB = alnResult.qb;
            newAln->qE = alnResult.qe;
            newAln->refB = refB + alnResult.tb;
            newAln->refE = refB + alnResult.te;
            newAln->refLength = alnResult.te - alnResult.tb + 1;
            newAln->flag.set(4, !fw);
            windowMate.alignments.push_back(newAln);
            windowMatePos = windowMate.alignments.size()-1;
        }
    }
    if(windowMatePos >= 0){
        if(alnOptions.print >= 4) cerr << "found concordant alignment" << endl;
        for(int i = 0; i < windowCount; i++){
            windowAlns.push_back(alnScoreInfo_t(!alnMateFirst,windowMatePos+i,windowMate.alignments[windowMatePos+i]->alignmentScore));
            //PAIR ALIGNMENTS, SUCCES
            if(alnMateFirst)
                setPaired(sa, alignmentMate, windowMate, alignmentIndex, windowMatePos+i, true);
            else
                setPaired(sa, windowMate, alignmentMate, windowMatePos+i, alignmentIndex, true);
        }
    }
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x1b0, %rsp            # imm = 0x1B0
movb %cl, %al
movl 0x1e8(%rsp), %ecx
movq 0x1e0(%rsp), %rcx
movl 0x1d8(%rsp), %ecx
movq 0x1d0(%rsp), %rcx
movq %rdi, 0x1a8(%rsp)
movq %rsi, 0x1a0(%rsp)
movq %rdx, 0x198(%rsp)
andb $0x1, %al
movb %al, 0x197(%rsp)
movq %r8, 0x188(%rsp)
movq %r9, 0x180(%rsp)
movq 0x1a0(%rsp), %rdi
addq $0xb0, %rdi
movslq 0x1e8(%rsp), %rsi
callq 0xdae0
movq (%rax), %rax
movq %rax, 0x178(%rsp)
movq 0x198(%rsp), %rdi
addq $0x20, %rdi
callq 0x8630
movl %eax, 0x160(%rsp)
movq 0x178(%rsp), %rax
movq (%rax), %rax
movq %rax, 0xc0(%rsp)
movq 0x178(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xc8(%rsp)
movb 0x197(%rsp), %al
movb %al, 0xbf(%rsp)
movq 0x178(%rsp), %rdi
addq $0x40, %rdi
movl $0x4, %esi
callq 0xe340
movb 0xbf(%rsp), %cl
movq 0xc0(%rsp), %rdi
movq 0xc8(%rsp), %rsi
xorb $-0x1, %al
movl 0x160(%rsp), %r8d
movq 0x180(%rsp), %r9
movq %rsp, %rdx
leaq 0x167(%rsp), %r10
movq %r10, 0x10(%rdx)
leaq 0x168(%rsp), %r10
movq %r10, 0x8(%rdx)
leaq 0x170(%rsp), %r10
movq %r10, (%rdx)
movzbl %cl, %edx
andl $0x1, %edx
movzbl %al, %ecx
andl $0x1, %ecx
callq 0x43fa0
movq 0x188(%rsp), %rax
cmpl $0x4, 0x78(%rax)
jl 0x530af
movq 0x44031(%rip), %rdi     # 0x96ff0
leaq 0x2b194(%rip), %rsi     # 0x7e15a
callq 0x8360
movq %rax, 0xb0(%rsp)
testb $0x1, 0x197(%rsp)
je 0x52fee
leaq 0x2606c(%rip), %rax     # 0x79050
movq %rax, 0xa8(%rsp)
jmp 0x52fff
leaq 0x2b2e0(%rip), %rax     # 0x7e2d5
movq %rax, 0xa8(%rsp)
jmp 0x52fff
movq 0xb0(%rsp), %rdi
movq 0xa8(%rsp), %rsi
callq 0x8360
movq %rax, %rdi
leaq 0x2b15e(%rip), %rsi     # 0x7e17c
callq 0x8360
movq %rax, 0xa0(%rsp)
movq 0x178(%rsp), %rdi
addq $0x40, %rdi
movl $0x4, %esi
callq 0xe340
testb $0x1, %al
jne 0x53047
jmp 0x53058
leaq 0x2b13a(%rip), %rax     # 0x7e188
movq %rax, 0x98(%rsp)
jmp 0x53069
leaq 0x2b12b(%rip), %rax     # 0x7e18a
movq %rax, 0x98(%rsp)
jmp 0x53069
movq 0xa0(%rsp), %rdi
movq 0x98(%rsp), %rsi
callq 0x8360
movq %rax, %rdi
leaq 0x2b104(%rip), %rsi     # 0x7e18c
callq 0x8360
movq %rax, %rdi
movq 0x178(%rsp), %rax
movq (%rax), %rsi
callq 0x8790
movq %rax, %rdi
movq 0x43f06(%rip), %rsi     # 0x96fb0
callq 0x83b0
movq 0x198(%rsp), %rdi
movq 0x1e0(%rsp), %rsi
movb 0x197(%rsp), %dl
movq 0x170(%rsp), %rcx
movq 0x168(%rsp), %r8
movb 0x167(%rsp), %al
andb $0x1, %dl
andb $0x1, %al
movzbl %dl, %edx
movzbl %al, %r9d
callq 0x441f0
movl %eax, 0x15c(%rsp)
movq 0x188(%rsp), %rax
cmpl $0x2, 0x78(%rax)
jl 0x5313e
movq 0x43ee6(%rip), %rdi     # 0x96ff0
leaq 0x2b109(%rip), %rsi     # 0x7e21a
callq 0x8360
movq %rax, %rdi
cmpl $0x0, 0x15c(%rsp)
setge %al
movzbl %al, %esi
andl $0x1, %esi
callq 0x8760
movq %rax, %rdi
movq 0x43e77(%rip), %rsi     # 0x96fb0
callq 0x83b0
movl $0x1, 0x158(%rsp)
cmpl $0x0, 0x15c(%rsp)
jge 0x5348c
movq 0x188(%rsp), %rax
cmpl $0x4, 0x78(%rax)
jl 0x53187
movq 0x43e84(%rip), %rdi     # 0x96ff0
leaq 0x2b576(%rip), %rsi     # 0x7e6e9
callq 0x8360
movq %rax, %rdi
movq 0x43e2e(%rip), %rsi     # 0x96fb0
callq 0x83b0
movq 0x188(%rsp), %rax
movsd 0x30(%rax), %xmm0
cvtsi2sdl 0x160(%rsp), %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
addl $0x1, %eax
movl %eax, 0x154(%rsp)
movq 0x1d0(%rsp), %rdi
movl 0x154(%rsp), %esi
movq 0x170(%rsp), %rdx
movq 0x168(%rsp), %rcx
movb 0x167(%rsp), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x53960
movl %eax, 0x150(%rsp)
cmpl $0x0, 0x150(%rsp)
jl 0x53441
movq 0x188(%rsp), %rax
cmpl $0x4, 0x78(%rax)
jl 0x53225
movq 0x43de6(%rip), %rdi     # 0x96ff0
leaq 0x2b4ff(%rip), %rsi     # 0x7e710
callq 0x8360
movq %rax, %rdi
movq 0x43d90(%rip), %rsi     # 0x96fb0
callq 0x83b0
movq 0x1d0(%rsp), %rdi
movslq 0x150(%rsp), %rsi
callq 0x4c850
addq $0x20, %rax
movq %rax, 0x148(%rsp)
movq 0x1a8(%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x148(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x4c8f0
movq 0x88(%rsp), %rdi
movq (%rax), %rsi
leaq 0x140(%rsp), %rdx
leaq 0x138(%rsp), %rcx
callq 0x4e1b0
movq 0x198(%rsp), %rdi
addq $0xb0, %rdi
callq 0xdac0
movq %rax, 0x130(%rsp)
movq 0x1a8(%rsp), %rax
addq $0x50, %rax
movq %rax, 0x90(%rsp)
movq 0x1d0(%rsp), %rdi
movslq 0x150(%rsp), %rsi
callq 0x4c850
testb $0x1, 0x4(%rax)
je 0x532e8
movq 0x198(%rsp), %rax
addq $0x20, %rax
movq %rax, 0x80(%rsp)
jmp 0x532fc
movq 0x198(%rsp), %rax
addq $0x60, %rax
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x58(%rsp)
movl 0x154(%rsp), %eax
movl %eax, 0x64(%rsp)
movl 0x1d8(%rsp), %eax
movl %eax, 0x68(%rsp)
cvtsi2sdl 0x160(%rsp), %xmm0
movsd 0x265ab(%rip), %xmm1    # 0x798e8
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x6c(%rsp)
movq 0x188(%rsp), %r14
movq 0x140(%rsp), %rbx
movq 0x138(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x198(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x1d0(%rsp), %rdi
movslq 0x150(%rsp), %rsi
callq 0x4c850
movq 0x90(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
movl 0x64(%rsp), %ecx
movl 0x68(%rsp), %r8d
movl 0x6c(%rsp), %r9d
movq 0x70(%rsp), %r11
movq 0x78(%rsp), %r10
movb 0x4(%rax), %al
andb $0x1, %al
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movq %r11, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movzbl %al, %eax
movl %eax, 0x20(%rsp)
callq 0x3f5b0
movq 0x198(%rsp), %rdi
addq $0xb0, %rdi
callq 0xdac0
cmpq 0x130(%rsp), %rax
jbe 0x5343f
movq 0x1d0(%rsp), %rdi
movslq 0x150(%rsp), %rsi
callq 0x4c850
movb $0x1, 0x18(%rax)
movq 0x130(%rsp), %rax
movl %eax, 0x15c(%rsp)
movq 0x198(%rsp), %rdi
addq $0xb0, %rdi
callq 0xdac0
subq 0x130(%rsp), %rax
movl %eax, 0x158(%rsp)
jmp 0x53441
movq 0x188(%rsp), %rax
cmpl $0x2, 0x78(%rax)
jl 0x5348a
movq 0x43b9a(%rip), %rdi     # 0x96ff0
leaq 0x2ae00(%rip), %rsi     # 0x7e25d
callq 0x8360
movq %rax, %rdi
cmpl $0x0, 0x15c(%rsp)
setge %al
movzbl %al, %esi
andl $0x1, %esi
callq 0x8760
movq %rax, %rdi
movq 0x43b2b(%rip), %rsi     # 0x96fb0
callq 0x83b0
jmp 0x5348c
cmpl $0x0, 0x15c(%rsp)
jge 0x537c7
movq 0x180(%rsp), %rax
testb $0x1, 0x14(%rax)
je 0x537c7
movq 0x188(%rsp), %rax
cmpl $0x4, 0x78(%rax)
jl 0x534dc
movq 0x43b2f(%rip), %rdi     # 0x96ff0
leaq 0x2b266(%rip), %rsi     # 0x7e72e
callq 0x8360
movq %rax, %rdi
movq 0x43ad9(%rip), %rsi     # 0x96fb0
callq 0x83b0
movq 0x168(%rsp), %rax
subq 0x170(%rsp), %rax
addq $0x1, %rax
movl %eax, 0x12c(%rsp)
movslq 0x12c(%rsp), %rdi
callq 0x8560
movq %rax, 0x120(%rsp)
movl $0x0, 0x11c(%rsp)
movl 0x11c(%rsp), %eax
cmpl 0x12c(%rsp), %eax
jge 0x5357f
movq 0x1a8(%rsp), %rdi
addq $0x50, %rdi
movq 0x170(%rsp), %rsi
movslq 0x11c(%rsp), %rax
addq %rax, %rsi
callq 0x8410
movsbq (%rax), %rcx
leaq 0x2b24a(%rip), %rax     # 0x7e7a0
movb (%rax,%rcx), %dl
movq 0x120(%rsp), %rax
movslq 0x11c(%rsp), %rcx
movb %dl, (%rax,%rcx)
movl 0x11c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x11c(%rsp)
jmp 0x53517
movl 0x160(%rsp), %edx
movq 0x188(%rsp), %rax
imull (%rax), %edx
xorl %eax, %eax
movl $0x10000, %ecx          # imm = 0x10000
cmpl $0xfa, %edx
cmovll %ecx, %eax
orl $0x80000, %eax          # imm = 0x80000
movl %eax, 0x118(%rsp)
movl 0x160(%rsp), %eax
movl %eax, 0x4c(%rsp)
testb $0x1, 0x167(%rsp)
je 0x535d8
movq 0x198(%rsp), %rax
movq 0xa0(%rax), %rax
movq %rax, 0x40(%rsp)
jmp 0x535ec
movq 0x198(%rsp), %rax
movq 0xa8(%rax), %rax
movq %rax, 0x40(%rsp)
movl 0x4c(%rsp), %esi
movq 0x40(%rsp), %rdx
movl 0x12c(%rsp), %ecx
movq 0x120(%rsp), %r8
movq 0x188(%rsp), %rbx
addq $0x10, %rbx
movq 0x188(%rsp), %rax
movl 0x8(%rax), %r11d
movq 0x188(%rsp), %rax
movl 0xc(%rax), %r10d
movl 0x118(%rsp), %eax
leaq 0xfc(%rsp), %rdi
movl $0x5, %r9d
xorl %ebp, %ebp
movq %rbx, (%rsp)
movl %r11d, 0x8(%rsp)
movl %r10d, 0x10(%rsp)
movl %eax, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
callq 0x76270
movq 0x120(%rsp), %rdi
callq 0x8470
movl 0xfc(%rsp), %eax
cmpl 0x1d8(%rsp), %eax
jle 0x537c5
movl $0x100, %edi            # imm = 0x100
callq 0x8380
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x38(%rsp)
callq 0x4dd90
jmp 0x5369c
movq 0x38(%rsp), %rax
movq %rax, 0xf0(%rsp)
movl 0xfc(%rsp), %ecx
movq 0xf0(%rsp), %rax
movl %ecx, 0x70(%rax)
movl 0x114(%rsp), %ecx
movq 0xf0(%rsp), %rax
movl %ecx, 0x10(%rax)
movl 0x104(%rsp), %ecx
movq 0xf0(%rsp), %rax
movl %ecx, 0x14(%rax)
movq 0x170(%rsp), %rcx
movslq 0x110(%rsp), %rax
addq %rax, %rcx
movq 0xf0(%rsp), %rax
movq %rcx, (%rax)
movq 0x170(%rsp), %rcx
movslq 0x100(%rsp), %rax
addq %rax, %rcx
movq 0xf0(%rsp), %rax
movq %rcx, 0x8(%rax)
movl 0x100(%rsp), %ecx
subl 0x110(%rsp), %ecx
addl $0x1, %ecx
movq 0xf0(%rsp), %rax
movl %ecx, 0x98(%rax)
movq 0xf0(%rsp), %rdi
addq $0x40, %rdi
movb 0x167(%rsp), %al
xorb $-0x1, %al
movzbl %al, %edx
andl $0x1, %edx
movl $0x4, %esi
callq 0xe640
movq 0x198(%rsp), %rdi
addq $0xb0, %rdi
leaq 0xf0(%rsp), %rsi
callq 0x4dfc0
movq 0x198(%rsp), %rdi
addq $0xb0, %rdi
callq 0xdac0
subq $0x1, %rax
movl %eax, 0x15c(%rsp)
jmp 0x537c5
movq 0x38(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe8(%rsp)
movl %eax, 0xe4(%rsp)
movl $0x100, %esi            # imm = 0x100
callq 0x8390
jmp 0x53950
jmp 0x537c7
cmpl $0x0, 0x15c(%rsp)
jl 0x53944
movq 0x188(%rsp), %rax
cmpl $0x4, 0x78(%rax)
jl 0x53805
movq 0x43806(%rip), %rdi     # 0x96ff0
leaq 0x2af6b(%rip), %rsi     # 0x7e75c
callq 0x8360
movq %rax, %rdi
movq 0x437b0(%rip), %rsi     # 0x96fb0
callq 0x83b0
movl $0x0, 0xe0(%rsp)
movl 0xe0(%rsp), %eax
cmpl 0x158(%rsp), %eax
jge 0x53942
movq 0x1e0(%rsp), %rax
movq %rax, 0x30(%rsp)
movb 0x197(%rsp), %al
xorb $-0x1, %al
movb %al, 0x2f(%rsp)
movl 0x15c(%rsp), %eax
addl 0xe0(%rsp), %eax
movl %eax, 0x28(%rsp)
movq 0x198(%rsp), %rdi
addq $0xb0, %rdi
movl 0x15c(%rsp), %eax
addl 0xe0(%rsp), %eax
movslq %eax, %rsi
callq 0xdae0
movl 0x28(%rsp), %edx
movq %rax, %rcx
movb 0x2f(%rsp), %al
movq (%rcx), %rcx
movl 0x70(%rcx), %ecx
movzbl %al, %esi
andl $0x1, %esi
leaq 0xd4(%rsp), %rdi
callq 0x4e660
movq 0x30(%rsp), %rdi
leaq 0xd4(%rsp), %rsi
callq 0x4e630
testb $0x1, 0x197(%rsp)
je 0x538f1
movq 0x1a8(%rsp), %rdi
movq 0x1a0(%rsp), %rsi
movq 0x198(%rsp), %rdx
movl 0x1e8(%rsp), %ecx
movl 0x15c(%rsp), %r8d
addl 0xe0(%rsp), %r8d
movl $0x1, %r9d
callq 0x43b50
jmp 0x5392a
movq 0x1a8(%rsp), %rdi
movq 0x198(%rsp), %rsi
movq 0x1a0(%rsp), %rdx
movl 0x15c(%rsp), %ecx
addl 0xe0(%rsp), %ecx
movl 0x1e8(%rsp), %r8d
movl $0x1, %r9d
callq 0x43b50
jmp 0x5392c
movl 0xe0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe0(%rsp)
jmp 0x53810
jmp 0x53944
addq $0x1b0, %rsp            # imm = 0x1B0
popq %rbx
popq %r14
popq %rbp
retq
movq 0xe8(%rsp), %rdi
callq 0x8730
nopl (%rax)