// File: zeeev[P]DASVC/bamtools/src/utils/bamtools_filter_engine.h
// Function: bool BamTools::FilterEngine<BamTools::BamAlignmentChecker>::evaluateFilterRules<BamTools::BamAlignment>(BamTools::BamAlignment const&)
bool FilterEngine<FilterChecker>::evaluateFilterRules(const T& query) {
  
    // build ruleQueue if not done before
    if ( !m_isRuleQueueGenerated ) 
        buildRuleQueue();
    
    std::stack<bool> resultStack;
    FilterMap::const_iterator filterIter;
    std::queue<std::string> ruleQueueCopy = m_ruleQueue;
    while ( !ruleQueueCopy.empty() ) {
        const std::string& token = ruleQueueCopy.front();
        
        // token is NOT_OPERATOR
        if ( token == FilterEngine<FilterChecker>::NOT_OPERATOR ) {
            BAMTOOLS_ASSERT_MESSAGE( !resultStack.empty(), "Empty result stack - cannot apply operator: !" );
            resultStack.top() = !resultStack.top();
        }
        
        // token is AND_OPERATOR
        else if ( token == FilterEngine<FilterChecker>::AND_OPERATOR ) {
            BAMTOOLS_ASSERT_MESSAGE( resultStack.size() >= 2 , "Not enough operands - cannot apply operator: &" );
            bool topResult = resultStack.top();
            resultStack.pop();
            resultStack.top() &= topResult;
        }
        
        // token is OR_OPERATOR
        else if ( token == FilterEngine<FilterChecker>::OR_OPERATOR ) {
            BAMTOOLS_ASSERT_MESSAGE( resultStack.size() >= 2 , "Not enough operands - cannot apply operator: |" );
            bool topResult = resultStack.top();
            resultStack.pop();
            resultStack.top() |= topResult;
        }
        
        // token is an operand 
        else {
            // look up PropertyFilter that matches this token 
            filterIter = m_filters.find(token);
            BAMTOOLS_ASSERT_MESSAGE( (filterIter != m_filters.end() ), "Filter mentioned in rule, not found in FilterEngine" );
            const PropertyFilter& filter = (*filterIter).second;
            bool result = m_checker.check(filter, query);
            resultStack.push( result );
        }
        
        // pop token from ruleQueue
        ruleQueueCopy.pop();
    }
    
    // return last result
    BAMTOOLS_ASSERT_MESSAGE( resultStack.size() == 1, "Result stack should only have one value remaining - cannot return result" );
    return resultStack.top();
}

// Assembly:
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rdi, 0x1e0(%rsp)
movq %rsi, 0x1d8(%rsp)
movq 0x1e0(%rsp), %rax
movq %rax, 0x98(%rsp)
testb $0x1, 0xb8(%rax)
jne 0xaf35d
movq 0x98(%rsp), %rdi
callq 0xaf7b0
leaq 0x138(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0xaf900
movq 0x90(%rsp), %rsi
leaq 0x188(%rsp), %rdi
callq 0xaf910
jmp 0xaf389
leaq 0x138(%rsp), %rdi
callq 0xaf940
leaq 0x120(%rsp), %rdi
callq 0xaf9d0
jmp 0xaf3a5
movq 0x98(%rsp), %rsi
addq $0x68, %rsi
leaq 0xd0(%rsp), %rdi
callq 0xaf9f0
jmp 0xaf3c0
jmp 0xaf3c2
leaq 0xd0(%rsp), %rdi
callq 0xafa20
movb %al, 0x8f(%rsp)
jmp 0xaf3d8
movb 0x8f(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xaf3ea
jmp 0xaf738
leaq 0xd0(%rsp), %rdi
callq 0xafa40
movq %rax, 0x80(%rsp)
jmp 0xaf401
movq 0x98(%rsp), %rsi
movq 0x80(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rdi
addq $0x108, %rsi            # imm = 0x108
callq 0x91630
movb %al, 0x7f(%rsp)
jmp 0xaf433
movb 0x7f(%rsp), %al
testb $0x1, %al
jne 0xaf440
jmp 0xaf4f6
callq 0xafa50
jmp 0xaf447
leaq 0x188(%rsp), %rdi
callq 0xafa60
movq %rax, 0x70(%rsp)
jmp 0xaf45b
movq 0x70(%rsp), %rax
movb (%rax), %al
xorb $0x1, %al
movb %al, 0x67(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xafa60
movq %rax, 0x68(%rsp)
jmp 0xaf47c
movq 0x68(%rsp), %rax
movb 0x67(%rsp), %cl
andb $0x1, %cl
movb %cl, (%rax)
jmp 0xaf724
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0x138(%rsp), %rdi
callq 0xaf940
jmp 0xaf4b2
jmp 0xaf79b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
jmp 0xaf78a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x130(%rsp)
movl %eax, 0x12c(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0xa9a30
jmp 0xaf788
movq 0x98(%rsp), %rsi
movq 0xc8(%rsp), %rdi
addq $0xc8, %rsi
callq 0x91630
movb %al, 0x66(%rsp)
jmp 0xaf518
movb 0x66(%rsp), %al
testb $0x1, %al
jne 0xaf525
jmp 0xaf5a5
callq 0xafa50
jmp 0xaf52c
leaq 0x188(%rsp), %rdi
callq 0xafa60
movq %rax, 0x58(%rsp)
jmp 0xaf540
movq 0x58(%rsp), %rax
movb (%rax), %al
andb $0x1, %al
movb %al, 0xc7(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xafa70
jmp 0xaf55f
movzbl 0xc7(%rsp), %eax
andl $0x1, %eax
movl %eax, 0x4c(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xafa60
movq %rax, 0x50(%rsp)
jmp 0xaf582
movq 0x50(%rsp), %rax
movl 0x4c(%rsp), %edx
movb (%rax), %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %edx, %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movb %cl, (%rax)
jmp 0xaf722
movq 0x98(%rsp), %rsi
movq 0xc8(%rsp), %rdi
addq $0xe8, %rsi
callq 0x91630
movb %al, 0x4b(%rsp)
jmp 0xaf5c7
movb 0x4b(%rsp), %al
testb $0x1, %al
jne 0xaf5d4
jmp 0xaf654
callq 0xafa50
jmp 0xaf5db
leaq 0x188(%rsp), %rdi
callq 0xafa60
movq %rax, 0x40(%rsp)
jmp 0xaf5ef
movq 0x40(%rsp), %rax
movb (%rax), %al
andb $0x1, %al
movb %al, 0xc6(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xafa70
jmp 0xaf60e
movzbl 0xc6(%rsp), %eax
andl $0x1, %eax
movl %eax, 0x34(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xafa60
movq %rax, 0x38(%rsp)
jmp 0xaf631
movq 0x38(%rsp), %rax
movl 0x34(%rsp), %edx
movb (%rax), %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %edx, %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movb %cl, (%rax)
jmp 0xaf720
movq 0x98(%rsp), %rdi
movq 0xc8(%rsp), %rsi
callq 0xabc00
movq %rax, 0x28(%rsp)
jmp 0xaf670
movq 0x28(%rsp), %rax
movq %rax, 0xb0(%rsp)
leaq 0xb8(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0xafa80
jmp 0xaf694
movq 0xb8(%rsp), %rax
movq %rax, 0x120(%rsp)
callq 0xafa50
jmp 0xaf6ab
leaq 0x120(%rsp), %rdi
callq 0xafaa0
movq %rax, 0x20(%rsp)
jmp 0xaf6bf
movq 0x98(%rsp), %rdi
movq 0x20(%rsp), %rax
addq $0x20, %rax
movq %rax, 0xa8(%rsp)
addq $0xc0, %rdi
movq 0xa8(%rsp), %rsi
movq 0x1d8(%rsp), %rdx
callq 0xafac0
movb %al, 0x1f(%rsp)
jmp 0xaf6fa
movb 0x1f(%rsp), %al
andb $0x1, %al
movb %al, 0xa7(%rsp)
leaq 0x188(%rsp), %rdi
leaq 0xa7(%rsp), %rsi
callq 0xb08b0
jmp 0xaf71e
jmp 0xaf720
jmp 0xaf722
jmp 0xaf724
leaq 0xd0(%rsp), %rdi
callq 0xb08e0
jmp 0xaf733
jmp 0xaf3c2
callq 0xafa50
jmp 0xaf73f
leaq 0x188(%rsp), %rdi
callq 0xafa60
movq %rax, 0x10(%rsp)
jmp 0xaf753
movq 0x10(%rsp), %rax
movb (%rax), %al
movb %al, 0xf(%rsp)
leaq 0xd0(%rsp), %rdi
callq 0xa9a30
jmp 0xaf76d
leaq 0x188(%rsp), %rdi
callq 0xb08f0
movb 0xf(%rsp), %al
andb $0x1, %al
addq $0x1e8, %rsp            # imm = 0x1E8
retq
jmp 0xaf78a
leaq 0x188(%rsp), %rdi
callq 0xb08f0
jmp 0xaf799
jmp 0xaf79b
movq 0x130(%rsp), %rdi
callq 0x86d80
movq %rax, %rdi
callq 0x91290