// File: WShabti-Team[P]WShabtiPict/wshabtilib/api/model.cpp
// Function: pictcore::Model::processExclusions(std::vector<pictcore::Combination*, std::allocator<pictcore::Combination*>>&)
void Model::processExclusions( ComboCollection& vecCombo )
{
    // Sort every parameter's collection of combinations to prepare for set intersection
    for( vector<Parameter*>::iterator ip = m_parameters.begin(); ip != m_parameters.end(); ++ip )
    {
        ( *ip )->SortCombinations();
    }

    for( ExclusionCollection::iterator iexcl = m_exclusions.begin(); iexcl != m_exclusions.end(); ++iexcl )
    {
        // paranoia; shouldn't happen
        assert( !iexcl->empty() );
        if( iexcl->empty() ) continue;

        // form the intersection of the combinations associated with each of the
        //  parameters that make up this exclusion
        ComboCollection intersection;
        Exclusion::iterator iexclterm = iexcl->begin();
        Parameter* sourceParam = iexclterm->first;
        ComboCollection::const_iterator posCandidate = sourceParam->GetCombinationBegin();
        while( true )
        {
            // We're going around and around...
            if( iexcl->end() == ++iexclterm )
            {
                iexclterm = iexcl->begin();
            }

            if( iexclterm->first == sourceParam )
            {
                intersection.push_back( *posCandidate );
                if( ++posCandidate == sourceParam->GetCombinationEnd() ) break;
            }
            // find next >= in this param
            ComboCollection::const_iterator posLB = lower_bound( iexclterm->first->GetCombinationBegin(),
                                                                 iexclterm->first->GetCombinationEnd(),
                                                                 *posCandidate, CombinationPtrSortPred() );
            if( iexclterm->first->GetCombinationEnd() == posLB ) break;
            
            // if >, reset candidate and source
            if( *posLB != *posCandidate )
            {
                posCandidate = posLB;
                sourceParam = iexclterm->first;
            }
        }
        // If the result is empty, make a new combination from the exclusion,
        // mark all of its members satisfied, and make sure all the parameters in the new
        // combination still have sorted combination collections.
        if( intersection.empty() )
        {
            Combination *pNewCombo = new Combination( this );
            int size = 1;
            for( Exclusion::iterator ix = iexcl->begin(); ix != iexcl->end(); ++ix )
            {
                pNewCombo->PushParameter( ( ix->first ) );
                ix->first->LinkCombination( pNewCombo );
                ix->first->SortCombinations();
                size *= ix->first->GetValueCount();
            }
            // Set size of combination's bit vector
            pNewCombo->SetMapSize( size, COVERED );
            vecCombo.push_back( pNewCombo );
            intersection.push_back( pNewCombo );
        }

        for( ComboCollection::iterator ic = intersection.begin(); ic != intersection.end(); ++ic )
        {
            // all exclusions must be applied to the combo and not just the current one
            for( ExclusionCollection::iterator ie = m_exclusions.begin(); ie != m_exclusions.end(); ++ie )
            {
                ( *ic )->ApplyExclusion( const_cast<Exclusion&> ( *ie ) );
            }
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
addq $0x8, %rdi
callq 0x8c90
movq %rax, -0x18(%rbp)
movq -0xf8(%rbp), %rdi
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x20(%rbp)
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x16902
jmp 0x1691e
leaq -0x18(%rbp), %rdi
callq 0x8d30
movq (%rax), %rdi
callq 0x1d390
leaq -0x18(%rbp), %rdi
callq 0x8d70
jmp 0x168db
movq -0xf8(%rbp), %rdi
addq $0x20, %rdi
callq 0xaf20
movq %rax, -0x28(%rbp)
movq -0xf8(%rbp), %rdi
addq $0x20, %rdi
callq 0xab70
movq %rax, -0x30(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0xaf50
testb $0x1, %al
jne 0x1695c
jmp 0x16ed7
leaq -0x28(%rbp), %rdi
callq 0xaed0
movq %rax, %rdi
callq 0xaf00
xorb $-0x1, %al
testb $0x1, %al
jne 0x16975
jmp 0x16977
jmp 0x16996
leaq 0x4df1f(%rip), %rdi     # 0x6489d
leaq 0x4dcbc(%rip), %rsi     # 0x64641
movl $0x481, %edx            # imm = 0x481
leaq 0x4df1c(%rip), %rcx     # 0x648ad
callq 0x7450
leaq -0x28(%rbp), %rdi
callq 0xaed0
movq %rax, %rdi
callq 0xaf00
testb $0x1, %al
jne 0x169ad
jmp 0x169b2
jmp 0x16ebe
leaq -0x48(%rbp), %rdi
callq 0x1ccd0
leaq -0x28(%rbp), %rdi
callq 0xaed0
movq %rax, %rdi
callq 0xb030
movq %rax, -0x100(%rbp)
jmp 0x169d5
movq -0x100(%rbp), %rax
movq %rax, -0x50(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x9160
movq (%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
callq 0x1d3e0
movq %rax, -0x108(%rbp)
jmp 0x16a02
movq -0x108(%rbp), %rax
movq %rax, -0x70(%rbp)
jmp 0x16a0f
leaq -0x28(%rbp), %rdi
callq 0xaed0
movq %rax, %rdi
callq 0xb060
movq %rax, -0x110(%rbp)
jmp 0x16a29
movq -0x110(%rbp), %rax
movq %rax, -0x78(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x9210
movq %rax, %rsi
leaq -0x78(%rbp), %rdi
callq 0xaa50
testb $0x1, %al
jne 0x16a4f
jmp 0x16a8f
leaq -0x28(%rbp), %rdi
callq 0xaed0
movq %rax, %rdi
callq 0xb030
movq %rax, -0x118(%rbp)
jmp 0x16a69
movq -0x118(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0x16a8f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x16ecc
leaq -0x50(%rbp), %rdi
callq 0x9160
movq (%rax), %rax
cmpq -0x68(%rbp), %rax
jne 0x16b08
leaq -0x70(%rbp), %rdi
callq 0x1d420
movq %rax, %rsi
leaq -0x48(%rbp), %rdi
callq 0x1b6a0
jmp 0x16ab8
leaq -0x70(%rbp), %rdi
callq 0x1d480
movq %rax, -0x128(%rbp)
movq -0x68(%rbp), %rdi
callq 0x1d4a0
movq %rax, -0x120(%rbp)
jmp 0x16ada
movq -0x128(%rbp), %rdi
movq -0x120(%rbp), %rax
movq %rax, -0x88(%rbp)
leaq -0x88(%rbp), %rsi
callq 0x1d440
testb $0x1, %al
jne 0x16b01
jmp 0x16b06
jmp 0x16c1f
jmp 0x16b08
leaq -0x50(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0x1d3e0
movq %rax, -0x130(%rbp)
jmp 0x16b22
movq -0x130(%rbp), %rax
movq %rax, -0x98(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0x1d4a0
movq %rax, -0x138(%rbp)
jmp 0x16b4a
movq -0x138(%rbp), %rax
movq %rax, -0xa0(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x1d420
movq %rax, %rdx
movq -0x98(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0x1d4e0
movq %rax, -0x140(%rbp)
jmp 0x16b80
movq -0x140(%rbp), %rax
movq %rax, -0x90(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0x1d4a0
movq %rax, -0x148(%rbp)
jmp 0x16ba8
movq -0x148(%rbp), %rax
movq %rax, -0xb0(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x1d440
testb $0x1, %al
jne 0x16bcf
jmp 0x16bd1
jmp 0x16c1f
leaq -0x90(%rbp), %rdi
callq 0x1d420
movq (%rax), %rax
movq %rax, -0x150(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x1d420
movq %rax, %rcx
movq -0x150(%rbp), %rax
cmpq (%rcx), %rax
je 0x16c1a
movq -0x90(%rbp), %rax
movq %rax, -0x70(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x9160
movq (%rax), %rax
movq %rax, -0x68(%rbp)
jmp 0x16a0d
leaq -0x48(%rbp), %rdi
callq 0x1d530
testb $0x1, %al
jne 0x16c31
jmp 0x16ddc
movl $0x40, %edi
callq 0x75e0
movq %rax, -0x158(%rbp)
jmp 0x16c44
movq -0xf8(%rbp), %rsi
movq -0x158(%rbp), %rdi
callq 0x8b60
jmp 0x16c59
movq -0x158(%rbp), %rax
movq %rax, -0xb8(%rbp)
movl $0x1, -0xbc(%rbp)
leaq -0x28(%rbp), %rdi
callq 0xaed0
movq %rax, %rdi
callq 0xb030
movq %rax, -0x160(%rbp)
jmp 0x16c8b
movq -0x160(%rbp), %rax
movq %rax, -0xc8(%rbp)
leaq -0x28(%rbp), %rdi
callq 0xaed0
movq %rax, %rdi
callq 0xb060
movq %rax, -0x168(%rbp)
jmp 0x16cb3
movq -0x168(%rbp), %rax
movq %rax, -0xd0(%rbp)
leaq -0xc8(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x9130
testb $0x1, %al
jne 0x16cdd
jmp 0x16d9d
movq -0xb8(%rbp), %rax
movq %rax, -0x170(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x9160
movq -0x170(%rbp), %rdi
movq (%rax), %rsi
callq 0x1b7d0
jmp 0x16d08
leaq -0xc8(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
movq -0xb8(%rbp), %rsi
callq 0x1b740
jmp 0x16d25
leaq -0xc8(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0x1d390
jmp 0x16d3b
leaq -0xc8(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0x8eb0
movl %eax, -0x174(%rbp)
jmp 0x16d57
movl -0x174(%rbp), %eax
imull -0xbc(%rbp), %eax
movl %eax, -0xbc(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x9210
jmp 0x16c99
movq -0x158(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x40, %esi
callq 0x7600
jmp 0x16ecc
movq -0xb8(%rbp), %rdi
movl -0xbc(%rbp), %esi
movl $0x1, %edx
callq 0x7f60
jmp 0x16db6
movq -0x10(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x1b6a0
jmp 0x16dc8
leaq -0x48(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x1b6a0
jmp 0x16dda
jmp 0x16ddc
leaq -0x48(%rbp), %rdi
callq 0x1b860
movq %rax, -0xd8(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x1b8d0
movq %rax, -0xe0(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x1b890
testb $0x1, %al
jne 0x16e18
jmp 0x16eb5
movq -0xf8(%rbp), %rdi
addq $0x20, %rdi
callq 0xaf20
movq %rax, -0xe8(%rbp)
movq -0xf8(%rbp), %rdi
addq $0x20, %rdi
callq 0xab70
movq %rax, -0xf0(%rbp)
leaq -0xe8(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0xaf50
testb $0x1, %al
jne 0x16e5f
jmp 0x16ea2
leaq -0xd8(%rbp), %rdi
callq 0x1b900
movq (%rax), %rax
movq %rax, -0x180(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0xafa0
movq -0x180(%rbp), %rdi
movq %rax, %rsi
callq 0x88f0
jmp 0x16e92
jmp 0x16e94
leaq -0xe8(%rbp), %rdi
callq 0xb000
jmp 0x16e2f
jmp 0x16ea4
leaq -0xd8(%rbp), %rdi
callq 0x1b940
jmp 0x16dec
leaq -0x48(%rbp), %rdi
callq 0x1cd40
leaq -0x28(%rbp), %rdi
callq 0xb000
jmp 0x16932
leaq -0x48(%rbp), %rdi
callq 0x1cd40
jmp 0x16ee0
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x79d0
nopl (%rax)