// File: zeeev[P]DASVC/bamtools/src/toolkit/bamtools_resolve.cpp
// Function: BamTools::ResolveTool::ResolveToolPrivate::MakeStats()
bool ResolveTool::ResolveToolPrivate::MakeStats(void) {

    // pull resolver settings from command-line settings
    ReadGroupResolver::SetConfidenceInterval(m_settings->ConfidenceInterval);
    ReadGroupResolver::SetUnusedModelThreshold(m_settings->UnusedModelThreshold);

    // open our BAM reader
    BamReader bamReader;
    if ( !bamReader.Open(m_settings->InputBamFilename) ) {
        cerr << "bamtools resolve ERROR: could not open input BAM file: "
             << m_settings->InputBamFilename << endl;
        return false;
    }

    // retrieve header & parse for read groups
    const SamHeader& header = bamReader.GetHeader();
    ParseHeader(header);

    // open ReadNamesFileWriter
    ResolveTool::ReadNamesFileWriter readNamesWriter;
    if ( !readNamesWriter.Open(m_settings->ReadNamesFilename) ) {
        cerr << "bamtools resolve ERROR: could not open (temp) output read names file: "
             << m_settings->ReadNamesFilename << endl;
        bamReader.Close();
        return false;
    }

    // read through BAM file
    BamAlignment al;
    string readGroup("");
    map<string, ReadGroupResolver>::iterator rgIter;
    map<string, bool>::iterator readNameIter;
    while ( bamReader.GetNextAlignmentCore(al) ) {

        // skip if alignment is not paired, mapped, nor mate is mapped
        if ( !al.IsPaired() || !al.IsMapped() || !al.IsMateMapped() )
            continue;

        // skip if alignment & mate not on same reference sequence
        if ( al.RefID != al.MateRefID ) continue;

        // flesh out the char data, so we can retrieve its read group ID
        al.BuildCharData();

        // get read group from alignment (OK if empty)
        readGroup.clear();
        al.GetTag(READ_GROUP_TAG, readGroup);

        // look up resolver for read group
        rgIter = m_readGroups.find(readGroup);
        if ( rgIter == m_readGroups.end() )  {
            cerr << "bamtools resolve ERROR - unable to calculate stats, unknown read group encountered: "
                 << readGroup << endl;
            bamReader.Close();
            return false;
        }
        ReadGroupResolver& resolver = (*rgIter).second;

        // determine unique-ness of current alignment
        const bool isCurrentMateUnique = ( al.MapQuality >= m_settings->MinimumMapQuality );

        // look up read name
        readNameIter = resolver.ReadNames.find(al.Name);

        // if read name found (current alignment's mate already parsed)
        if ( readNameIter != resolver.ReadNames.end() ) {

            // if both unique mates are unique, store read name & insert size for later
            const bool isStoredMateUnique  = (*readNameIter).second;
            if ( isCurrentMateUnique && isStoredMateUnique ) {

                // save read name in temp file as candidates for later pair marking
                readNamesWriter.Write(readGroup, al.Name);

                // determine model type & store fragment length for stats calculation
                const uint16_t currentModelType = CalculateModelType(al);
                assert( currentModelType != ModelType::DUMMY_ID );
                resolver.Models[currentModelType].push_back( abs(al.InsertSize) );
            }

            // unique or not, remove read name from map
            resolver.ReadNames.erase(readNameIter);
        }

        // if read name not found, store new entry
        else resolver.ReadNames.insert( make_pair<string, bool>(al.Name, isCurrentMateUnique) );
    }

    // close files
    readNamesWriter.Close();
    bamReader.Close();

    // iterate back through read groups
    map<string, ReadGroupResolver>::iterator rgEnd  = m_readGroups.end();
    for ( rgIter = m_readGroups.begin(); rgIter != rgEnd; ++rgIter ) {
        const string& name = (*rgIter).first;
        ReadGroupResolver& resolver = (*rgIter).second;

        // calculate acceptable orientation & insert sizes for this read group
        resolver.DetermineTopModels(name);

        // clear out left over read names
        // (these have mates that did not pass filters or were already removed as non-unique)
        resolver.ReadNames.clear();
    }

    // if we get here, return success
    return true;
}

// Assembly:
subq $0x6e8, %rsp            # imm = 0x6E8
movq %rdi, 0x6d8(%rsp)
movq 0x6d8(%rsp), %rax
movq %rax, 0xd8(%rsp)
movq (%rax), %rdi
addq $0x90, %rdi
callq 0xc8210
movq 0xd8(%rsp), %rax
movq (%rax), %rdi
addq $0xa0, %rdi
callq 0xc8230
leaq 0x6d0(%rsp), %rdi
movq %rdi, 0xe0(%rsp)
callq 0x864d0
movq 0xd8(%rsp), %rax
movq 0xe0(%rsp), %rdi
movq (%rax), %rsi
addq $0x10, %rsi
callq 0x86980
movb %al, 0xef(%rsp)
jmp 0xcac7f
movb 0xef(%rsp), %al
testb $0x1, %al
jne 0xcad1a
jmp 0xcac90
movq 0x9a349(%rip), %rdi     # 0x164fe0
leaq 0x663ec(%rip), %rsi     # 0x13108a
callq 0x86700
movq %rax, 0xd0(%rsp)
jmp 0xcacad
movq 0xd0(%rsp), %rdi
movq 0xd8(%rsp), %rax
movq (%rax), %rsi
addq $0x10, %rsi
callq 0x86640
movq %rax, 0xc8(%rsp)
jmp 0xcacd3
movq 0xc8(%rsp), %rdi
movq 0x9a28e(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xcace9
movb $0x0, 0x6e7(%rsp)
movl $0x1, 0x6c0(%rsp)
jmp 0xcb5d8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
jmp 0xcb5f6
leaq 0x560(%rsp), %rdi
leaq 0x6d0(%rsp), %rsi
callq 0x869b0
jmp 0xcad31
movq 0xd8(%rsp), %rdi
leaq 0x560(%rsp), %rax
movq %rax, 0x6b8(%rsp)
movq 0x6b8(%rsp), %rsi
callq 0xcb620
jmp 0xcad58
leaq 0x360(%rsp), %rdi
callq 0xcfd30
jmp 0xcad67
movq 0xd8(%rsp), %rax
movq (%rax), %rsi
addq $0x70, %rsi
leaq 0x360(%rsp), %rdi
callq 0xc8730
movb %al, 0xc7(%rsp)
jmp 0xcad8c
movb 0xc7(%rsp), %al
testb $0x1, %al
jne 0xcae4f
jmp 0xcad9d
movq 0x9a23c(%rip), %rdi     # 0x164fe0
leaq 0x66317(%rip), %rsi     # 0x1310c2
callq 0x86700
movq %rax, 0xb8(%rsp)
jmp 0xcadba
movq 0xb8(%rsp), %rdi
movq 0xd8(%rsp), %rax
movq (%rax), %rsi
addq $0x70, %rsi
callq 0x86640
movq %rax, 0xb0(%rsp)
jmp 0xcade0
movq 0xb0(%rsp), %rdi
movq 0x9a181(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xcadf6
leaq 0x6d0(%rsp), %rdi
callq 0x860c0
jmp 0xcae05
movb $0x0, 0x6e7(%rsp)
movl $0x1, 0x6c0(%rsp)
jmp 0xcb596
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
jmp 0xcb5c7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
jmp 0xcb5b4
leaq 0x208(%rsp), %rdi
callq 0x86260
jmp 0xcae5e
leaq 0x1e7(%rsp), %rdi
movq %rdi, 0xa8(%rsp)
callq 0x86da0
movq 0xa8(%rsp), %rdx
leaq 0x69df1(%rip), %rsi     # 0x134c73
leaq 0x1e8(%rsp), %rdi
callq 0x86a00
jmp 0xcae91
leaq 0x1e7(%rsp), %rdi
callq 0x867b0
leaq 0x1d8(%rsp), %rdi
callq 0xcf460
jmp 0xcaead
leaq 0x1d0(%rsp), %rdi
callq 0xcfd40
jmp 0xcaebc
jmp 0xcaebe
leaq 0x6d0(%rsp), %rdi
leaq 0x208(%rsp), %rsi
callq 0x86c70
movb %al, 0xa7(%rsp)
jmp 0xcaedc
movb 0xa7(%rsp), %al
testb $0x1, %al
jne 0xcaeec
jmp 0xcb407
leaq 0x208(%rsp), %rdi
callq 0x863d0
movb %al, 0xa6(%rsp)
jmp 0xcaf02
movb 0xa6(%rsp), %al
testb $0x1, %al
jne 0xcaf0f
jmp 0xcaf55
leaq 0x208(%rsp), %rdi
callq 0x860f0
movb %al, 0xa5(%rsp)
jmp 0xcaf25
movb 0xa5(%rsp), %al
testb $0x1, %al
jne 0xcaf32
jmp 0xcaf55
leaq 0x208(%rsp), %rdi
callq 0x86880
movb %al, 0xa4(%rsp)
jmp 0xcaf48
movb 0xa4(%rsp), %al
testb $0x1, %al
jne 0xcaf99
jmp 0xcaf55
jmp 0xcaebe
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
leaq 0x1e7(%rsp), %rdi
callq 0x867b0
jmp 0xcb585
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
jmp 0xcb572
movl 0x2b0(%rsp), %eax
cmpl 0x2d8(%rsp), %eax
je 0xcafae
jmp 0xcaebe
leaq 0x208(%rsp), %rdi
callq 0x86730
jmp 0xcafbd
leaq 0x1e8(%rsp), %rdi
callq 0x86970
jmp 0xcafcc
leaq 0x9ac6d(%rip), %rsi     # 0x165c40
leaq 0x208(%rsp), %rdi
leaq 0x1e8(%rsp), %rdx
callq 0xbe2f0
jmp 0xcafea
movq 0xd8(%rsp), %rdi
addq $0x8, %rdi
leaq 0x1e8(%rsp), %rsi
callq 0xcf770
movq %rax, 0x98(%rsp)
jmp 0xcb00d
movq 0xd8(%rsp), %rdi
movq 0x98(%rsp), %rax
movq %rax, 0x1c8(%rsp)
movq 0x1c8(%rsp), %rax
movq %rax, 0x1d8(%rsp)
addq $0x8, %rdi
callq 0xcf480
movq %rax, 0x90(%rsp)
jmp 0xcb048
movq 0x90(%rsp), %rax
movq %rax, 0x1c0(%rsp)
leaq 0x1d8(%rsp), %rdi
leaq 0x1c0(%rsp), %rsi
callq 0xcf7c0
movb %al, 0x8f(%rsp)
jmp 0xcb076
movb 0x8f(%rsp), %al
testb $0x1, %al
jne 0xcb083
jmp 0xcb0f6
movq 0x99f56(%rip), %rdi     # 0x164fe0
leaq 0x66078(%rip), %rsi     # 0x131109
callq 0x86700
movq %rax, 0x80(%rsp)
jmp 0xcb0a0
movq 0x80(%rsp), %rdi
leaq 0x1e8(%rsp), %rsi
callq 0x86640
movq %rax, 0x78(%rsp)
jmp 0xcb0bc
movq 0x78(%rsp), %rdi
movq 0x99ea8(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xcb0cf
leaq 0x6d0(%rsp), %rdi
callq 0x860c0
jmp 0xcb0de
movb $0x0, 0x6e7(%rsp)
movl $0x1, 0x6c0(%rsp)
jmp 0xcb53e
leaq 0x1d8(%rsp), %rdi
callq 0xcf7e0
movq %rax, 0x70(%rsp)
jmp 0xcb10a
movq 0xd8(%rsp), %rcx
movq 0x70(%rsp), %rax
addq $0x20, %rax
movq %rax, 0x1b8(%rsp)
movzwl 0x2ba(%rsp), %eax
movq (%rcx), %rcx
movzwl 0x98(%rcx), %ecx
subl %ecx, %eax
setge 0x1b7(%rsp)
movq 0x1b8(%rsp), %rdi
addq $0x30, %rdi
leaq 0x208(%rsp), %rsi
callq 0xcfd60
movq %rax, 0x68(%rsp)
jmp 0xcb15f
movq 0x68(%rsp), %rax
movq %rax, 0x1a8(%rsp)
movq 0x1a8(%rsp), %rax
movq %rax, 0x1d0(%rsp)
movq 0x1b8(%rsp), %rdi
addq $0x30, %rdi
callq 0xcfdb0
movq %rax, 0x60(%rsp)
jmp 0xcb194
movq 0x60(%rsp), %rax
movq %rax, 0x1a0(%rsp)
leaq 0x1d0(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0xcfd90
movb %al, 0x5f(%rsp)
jmp 0xcb1bc
movb 0x5f(%rsp), %al
testb $0x1, %al
jne 0xcb1c9
jmp 0xcb2c7
leaq 0x1d0(%rsp), %rdi
callq 0xcfde0
movq %rax, 0x50(%rsp)
jmp 0xcb1dd
movq 0x50(%rsp), %rax
movb 0x20(%rax), %al
andb $0x1, %al
movb %al, 0x19f(%rsp)
testb $0x1, 0x1b7(%rsp)
je 0xcb297
testb $0x1, 0x19f(%rsp)
je 0xcb297
leaq 0x360(%rsp), %rdi
leaq 0x1e8(%rsp), %rsi
leaq 0x208(%rsp), %rdx
callq 0xc8780
jmp 0xcb229
leaq 0x208(%rsp), %rdi
callq 0xc73f0
movw %ax, 0x4e(%rsp)
jmp 0xcb23d
movw 0x4e(%rsp), %ax
movw %ax, 0x19c(%rsp)
movq 0x1b8(%rsp), %rdi
addq $0x18, %rdi
movzwl 0x19c(%rsp), %eax
movl %eax, %esi
callq 0xcf090
movq %rax, 0x40(%rsp)
jmp 0xcb26c
movq 0x40(%rsp), %rdi
movl 0x2e0(%rsp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, 0x198(%rsp)
leaq 0x198(%rsp), %rsi
callq 0xcfe00
jmp 0xcb295
jmp 0xcb297
movq 0x1b8(%rsp), %rdi
addq $0x30, %rdi
movq 0x1d0(%rsp), %rax
movq %rax, 0x190(%rsp)
movq 0x190(%rsp), %rsi
callq 0xcfe30
jmp 0xcb2c2
jmp 0xcb402
movq 0x1b8(%rsp), %rax
addq $0x30, %rax
movq %rax, 0x38(%rsp)
leaq 0x120(%rsp), %rdi
leaq 0x208(%rsp), %rsi
callq 0x86350
jmp 0xcb2ef
movzbl 0x1b7(%rsp), %edx
andl $0x1, %edx
leaq 0x140(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0xcf850
jmp 0xcb311
leaq 0x168(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0xcf890
jmp 0xcb328
movq 0x38(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0xcf800
movb %dl, 0x2f(%rsp)
movq %rax, 0x30(%rsp)
jmp 0xcb345
movb 0x2f(%rsp), %al
movq 0x30(%rsp), %rcx
movq %rcx, 0x110(%rsp)
movb %al, 0x118(%rsp)
leaq 0x168(%rsp), %rdi
callq 0xcf8d0
jmp 0xcb36c
leaq 0x140(%rsp), %rdi
callq 0xcf8e0
jmp 0xcb37b
leaq 0x120(%rsp), %rdi
callq 0x86f68
jmp 0xcb38a
jmp 0xcb402
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
jmp 0xcb3ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
jmp 0xcb3dd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
leaq 0x168(%rsp), %rdi
callq 0xcf8d0
jmp 0xcb3db
jmp 0xcb3dd
leaq 0x140(%rsp), %rdi
callq 0xcf8e0
jmp 0xcb3ec
jmp 0xcb3ee
leaq 0x120(%rsp), %rdi
callq 0x86f68
jmp 0xcb3fd
jmp 0xcb572
jmp 0xcaebe
leaq 0x360(%rsp), %rdi
callq 0xc8700
jmp 0xcb416
leaq 0x6d0(%rsp), %rdi
callq 0x860c0
jmp 0xcb425
movq 0xd8(%rsp), %rdi
addq $0x8, %rdi
callq 0xcf480
movq %rax, 0x20(%rsp)
jmp 0xcb43d
movq 0xd8(%rsp), %rdi
movq 0x20(%rsp), %rax
movq %rax, 0x108(%rsp)
addq $0x8, %rdi
callq 0xcfe60
movq %rax, 0x18(%rsp)
jmp 0xcb462
movq 0x18(%rsp), %rax
movq %rax, 0x100(%rsp)
movq 0x100(%rsp), %rax
movq %rax, 0x1d8(%rsp)
leaq 0x1d8(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0xcfe90
movb %al, 0x17(%rsp)
jmp 0xcb49a
movb 0x17(%rsp), %al
testb $0x1, %al
jne 0xcb4a7
jmp 0xcb52b
leaq 0x1d8(%rsp), %rdi
callq 0xcf7e0
movq %rax, 0x8(%rsp)
jmp 0xcb4bb
movq 0x8(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x1d8(%rsp), %rdi
callq 0xcf7e0
movq %rax, (%rsp)
jmp 0xcb4db
movq (%rsp), %rax
addq $0x20, %rax
movq %rax, 0xf0(%rsp)
movq 0xf0(%rsp), %rdi
movq 0xf8(%rsp), %rsi
callq 0xc77e0
jmp 0xcb502
movq 0xf0(%rsp), %rdi
addq $0x30, %rdi
callq 0xcfeb0
jmp 0xcb515
jmp 0xcb517
leaq 0x1d8(%rsp), %rdi
callq 0xcfec0
jmp 0xcb526
jmp 0xcb47f
movb $0x1, 0x6e7(%rsp)
movl $0x1, 0x6c0(%rsp)
leaq 0x1e8(%rsp), %rdi
callq 0x86f68
jmp 0xcb54d
leaq 0x208(%rsp), %rdi
callq 0x86b30
jmp 0xcb583
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x6c8(%rsp)
movl %eax, 0x6c4(%rsp)
jmp 0xcb585
leaq 0x1e8(%rsp), %rdi
callq 0x86f68
jmp 0xcb581
jmp 0xcb585
jmp 0xcb596
leaq 0x208(%rsp), %rdi
callq 0x86b30
jmp 0xcb594
jmp 0xcb5b4
leaq 0x360(%rsp), %rdi
callq 0xcfef0
jmp 0xcb5a5
leaq 0x560(%rsp), %rdi
callq 0x866e0
jmp 0xcb5c5
leaq 0x360(%rsp), %rdi
callq 0xcfef0
jmp 0xcb5c3
jmp 0xcb5c7
jmp 0xcb5d8
leaq 0x560(%rsp), %rdi
callq 0x866e0
jmp 0xcb5d6
jmp 0xcb5f6
leaq 0x6d0(%rsp), %rdi
callq 0x86790
movb 0x6e7(%rsp), %al
andb $0x1, %al
addq $0x6e8, %rsp            # imm = 0x6E8
retq
leaq 0x6d0(%rsp), %rdi
callq 0x86790
jmp 0xcb605
jmp 0xcb607
movq 0x6c8(%rsp), %rdi
callq 0x86d80
movq %rax, %rdi
callq 0x91290
nopl (%rax)