// File: gchen98[P]macs/algorithm.cpp
// Function: GraphBuilder::markEdgesAbove(bool, bool, boost::shared_ptr<Edge>&, unsigned int&)
bool GraphBuilder::markEdgesAbove(bool bFirstSample,bool  bCalledFromParent,
EdgePtr & selectedEdge, unsigned int & iSampleIndex){
    if (bFirstSample || bCalledFromParent || !selectedEdge->bInCurrentTree){
        if (!selectedEdge->bInCurrentTree) addEdgeToCurrentTree(selectedEdge);
        NodePtr topNode = selectedEdge->getTopNodeRef();
        double dTopHeight = topNode->getHeight();
        double dproposedOriginHt = localMRCA->getHeight();
        if (dTopHeight>=dproposedOriginHt &&
        topNode->getType()==Node::COAL){
            // If we reach at least as high as proposed MRCA
            // save this edge as the vector
            // so we don't traverse from the bottom
            pTreeEdgesToCoalesceArray[iSampleIndex]=selectedEdge;
            if (bFirstSample){
                if (dTopHeight>dproposedOriginHt)
                    // establish a new proposed MRCA
                    // for susequent samples to try reaching
                    localMRCA = topNode;
                // proceed to the next sampled node
                return true;
            }else{
                if (dTopHeight>dproposedOriginHt){
                    // if we surpassed a MRCA height previously proposed
                    // upgrade the proposed MRCA height
                    localMRCA = topNode;
                    // start over in the loop to sample 0
                    return false;
                }else{
                    if (localMRCA!=topNode){
                        cerr<<"proposed grandMRCA != top Node\n";
                    }
                    // here the current height is EQUAL to the proposed MRCA,
                    // this is good and we can proceed to the next sampled node
                    return true;
                }
            }
        }
        else{
            // if we come across a crossover, there are two edges above,
            // we choose the one with the more recent (larger) tree label
            if (topNode->getType()==Node::XOVER){
                EdgePtr edge0 =topNode->getTopEdgeByIndex(0);
                EdgePtr edge1 =topNode->getTopEdgeByIndex(1);
                int iter0=-1,iter1=-1;
                if (edge0!=NULL) iter0=edge0->iGraphIteration;
                if (edge1!=NULL) iter1=edge1->iGraphIteration;
                if (iter0==-1 && iter1==-1) throw "In mark edges above, both edges above xover were missing";
                EdgePtr & nextEdge = (iter0>iter1)? edge0:edge1;
                return markEdgesAbove(bFirstSample,false,nextEdge,
                iSampleIndex);
            // for other nodes, just choose the single edge above it
            // recursively call this method again
            }else{
                EdgePtr edge = topNode->getTopEdgeByIndex(0);
                return markEdgesAbove(bFirstSample,false,edge,
                iSampleIndex);
            }
        }
    }else{
        // the selected edge was in the current tree already and this is for
        // a sampled node after the first one and was called by this method.
        // the latter condition implies that we previously explored up this
        // node.  in this case, save time and proceed to the next node
        return true;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movb %dl, %al
movb %sil, %dl
movq %rdi, -0x10(%rbp)
andb $0x1, %dl
movb %dl, -0x11(%rbp)
andb $0x1, %al
movb %al, -0x12(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xa0(%rbp)
testb $0x1, -0x11(%rbp)
jne 0x15621
testb $0x1, -0x12(%rbp)
jne 0x15621
movq -0x20(%rbp), %rdi
callq 0x1de60
testb $0x1, 0x12(%rax)
jne 0x15a0f
movq -0x20(%rbp), %rdi
callq 0x1de60
testb $0x1, 0x12(%rax)
jne 0x15640
movq -0xa0(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2a5d0
movq -0x20(%rbp), %rdi
callq 0x1de60
movq %rax, %rdi
callq 0x1e1e0
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
movq %rdi, -0xb0(%rbp)
callq 0x1e2c0
movq -0xb0(%rbp), %rdi
callq 0x1ded0
movq %rax, %rdi
callq 0x1df20
movsd %xmm0, -0xa8(%rbp)
jmp 0x15682
movq -0xa0(%rbp), %rdi
movsd -0xa8(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
addq $0x40, %rdi
callq 0x1ded0
movq %rax, %rdi
callq 0x1df20
movsd %xmm0, -0xb8(%rbp)
jmp 0x156b1
movsd -0xb8(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
movsd -0x38(%rbp), %xmm0
ucomisd -0x50(%rbp), %xmm0
jb 0x157d8
leaq -0x30(%rbp), %rdi
callq 0x1ded0
movq %rax, %rdi
callq 0x1e200
movl %eax, -0xbc(%rbp)
jmp 0x156e7
movl -0xbc(%rbp), %eax
cmpl $0x0, %eax
jne 0x157d8
movq -0xa0(%rbp), %rax
movq -0x20(%rbp), %rsi
movq 0xb8(%rax), %rdi
movq -0x28(%rbp), %rax
movl (%rax), %eax
shlq $0x4, %rax
addq %rax, %rdi
callq 0x1e000
testb $0x1, -0x11(%rbp)
je 0x15765
movsd -0x38(%rbp), %xmm0
ucomisd -0x50(%rbp), %xmm0
jbe 0x15755
movq -0xa0(%rbp), %rdi
addq $0x40, %rdi
leaq -0x30(%rbp), %rsi
callq 0x1e300
jmp 0x15742
jmp 0x15755
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x15a04
movb $0x1, -0x1(%rbp)
movl $0x1, -0x54(%rbp)
jmp 0x159f9
movsd -0x38(%rbp), %xmm0
ucomisd -0x50(%rbp), %xmm0
jbe 0x15797
movq -0xa0(%rbp), %rdi
addq $0x40, %rdi
leaq -0x30(%rbp), %rsi
callq 0x1e300
jmp 0x15787
movb $0x0, -0x1(%rbp)
movl $0x1, -0x54(%rbp)
jmp 0x159f9
movq -0xa0(%rbp), %rdi
addq $0x40, %rdi
leaq -0x30(%rbp), %rsi
callq 0x1e350
testb $0x1, %al
jne 0x157b1
jmp 0x157c8
movq 0x33838(%rip), %rdi     # 0x48ff0
leaq 0x1e570(%rip), %rsi     # 0x33d2f
callq 0x42b0
jmp 0x157c6
jmp 0x157c8
movb $0x1, -0x1(%rbp)
movl $0x1, -0x54(%rbp)
jmp 0x159f9
leaq -0x30(%rbp), %rdi
callq 0x1ded0
movq %rax, %rdi
callq 0x1e200
movl %eax, -0xc0(%rbp)
jmp 0x157f1
movl -0xc0(%rbp), %eax
cmpl $0x1, %eax
jne 0x1597b
leaq -0x30(%rbp), %rdi
callq 0x1ded0
movq %rax, %rsi
leaq -0x68(%rbp), %rdi
xorl %edx, %edx
callq 0x1e390
jmp 0x15819
leaq -0x30(%rbp), %rdi
callq 0x1ded0
movq %rax, %rsi
leaq -0x78(%rbp), %rdi
movl $0x1, %edx
callq 0x1e390
jmp 0x15835
movl $0xffffffff, -0x7c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x80(%rbp) # imm = 0xFFFFFFFF
leaq -0x68(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1e3f0
testb $0x1, %al
jne 0x15856
jmp 0x15878
leaq -0x68(%rbp), %rdi
callq 0x1de60
movl 0x14(%rax), %eax
movl %eax, -0x7c(%rbp)
jmp 0x15878
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x1596d
leaq -0x78(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1e3f0
testb $0x1, %al
jne 0x1588b
jmp 0x1589a
leaq -0x78(%rbp), %rdi
callq 0x1de60
movl 0x14(%rax), %eax
movl %eax, -0x80(%rbp)
cmpl $-0x1, -0x7c(%rbp)
jne 0x158ec
cmpl $-0x1, -0x80(%rbp)
jne 0x158ec
movl $0x8, %edi
callq 0x4130
movq %rax, %rdi
leaq 0x1e495(%rip), %rax     # 0x33d4f
movq %rax, (%rdi)
movq 0x336f4(%rip), %rsi     # 0x48fb8
xorl %eax, %eax
movl %eax, %edx
callq 0x44c0
jmp 0x15a2a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x1e090
jmp 0x1596d
movl -0x7c(%rbp), %eax
cmpl -0x80(%rbp), %eax
jle 0x15901
leaq -0x68(%rbp), %rax
movq %rax, -0xc8(%rbp)
jmp 0x1590e
leaq -0x78(%rbp), %rax
movq %rax, -0xc8(%rbp)
jmp 0x1590e
movq -0xa0(%rbp), %rdi
movq -0xc8(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rcx
movq -0x28(%rbp), %r8
movzbl -0x11(%rbp), %esi
andl $0x1, %esi
xorl %edx, %edx
callq 0x155d0
movb %al, -0xc9(%rbp)
jmp 0x15944
movb -0xc9(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movl $0x1, -0x54(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x1e090
leaq -0x68(%rbp), %rdi
callq 0x1e090
jmp 0x159f9
leaq -0x68(%rbp), %rdi
callq 0x1e090
jmp 0x15a04
leaq -0x30(%rbp), %rdi
callq 0x1ded0
movq %rax, %rsi
leaq -0x98(%rbp), %rdi
xorl %edx, %edx
callq 0x1e390
jmp 0x15997
movq -0xa0(%rbp), %rdi
movq -0x28(%rbp), %r8
movzbl -0x11(%rbp), %esi
andl $0x1, %esi
xorl %edx, %edx
leaq -0x98(%rbp), %rcx
callq 0x155d0
movb %al, -0xca(%rbp)
jmp 0x159bf
movb -0xca(%rbp), %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movl $0x1, -0x54(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x1e090
jmp 0x159f9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x1e090
jmp 0x15a04
leaq -0x30(%rbp), %rdi
callq 0x1e420
jmp 0x15a13
leaq -0x30(%rbp), %rdi
callq 0x1e420
jmp 0x15a21
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xd0, %rsp
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x44e0
nopw (%rax,%rax)