// File: zeeev[P]DASVC/bamtools/src/toolkit/bamtools_merge.cpp
// Function: BamTools::MergeTool::MergeToolPrivate::Run()
bool MergeTool::MergeToolPrivate::Run(void) {

    // set to default input if none provided
    if ( !m_settings->HasInput && !m_settings->HasInputFilelist )
        m_settings->InputFiles.push_back(Options::StandardIn());

    // add files in the filelist to the input file list
    if ( m_settings->HasInputFilelist ) {

        ifstream filelist(m_settings->InputFilelist.c_str(), ios::in);
        if ( !filelist.is_open() ) {
            cerr << "bamtools merge ERROR: could not open input BAM file list... Aborting." << endl;
            return false;
        }

        string line;
        while ( getline(filelist, line) )
            m_settings->InputFiles.push_back(line);
    }

    // opens the BAM files (by default without checking for indexes)
    BamMultiReader reader;
    if ( !reader.Open(m_settings->InputFiles) ) {
        cerr << "bamtools merge ERROR: could not open input BAM file(s)... Aborting." << endl;
        return false;
    }

    // retrieve header & reference dictionary info
    std::string mergedHeader = reader.GetHeaderText();
    RefVector references = reader.GetReferenceData();

    // determine compression mode for BamWriter
    bool writeUncompressed = ( m_settings->OutputFilename == Options::StandardOut() &&
                               !m_settings->IsForceCompression );
    BamWriter::CompressionMode compressionMode = BamWriter::Compressed;
    if ( writeUncompressed ) compressionMode = BamWriter::Uncompressed;

    // open BamWriter
    BamWriter writer;
    writer.SetCompressionMode(compressionMode);
    if ( !writer.Open(m_settings->OutputFilename, mergedHeader, references) ) {
        cerr << "bamtools merge ERROR: could not open "
             << m_settings->OutputFilename << " for writing." << endl;
        reader.Close();
        return false;
    }

    // if no region specified, store entire contents of file(s)
    if ( !m_settings->HasRegion ) {
        BamAlignment al;
        while ( reader.GetNextAlignmentCore(al) )
            writer.SaveAlignment(al);
    }

    // otherwise attempt to use region as constraint
    else {

        // if region string parses OK
        BamRegion region;
        if ( Utilities::ParseRegionString(m_settings->Region, reader, region) ) {

            // attempt to find index files
            reader.LocateIndexes();

            // if index data available for all BAM files, we can use SetRegion
            if ( reader.HasIndexes() ) {

                // attempt to use SetRegion(), if failed report error
                if ( !reader.SetRegion(region.LeftRefID,
                                       region.LeftPosition,
                                       region.RightRefID,
                                       region.RightPosition) )
                {
                    cerr << "bamtools merge ERROR: set region failed. Check that REGION describes a valid range"
                         << endl;
                    reader.Close();
                    return false;
                }

                // everything checks out, just iterate through specified region, storing alignments
                BamAlignment al;
                while ( reader.GetNextAlignmentCore(al) )
                    writer.SaveAlignment(al);
            }

            // no index data available, we have to iterate through until we
            // find overlapping alignments
            else {
                BamAlignment al;
                while ( reader.GetNextAlignmentCore(al) ) {
                    if ( (al.RefID >= region.LeftRefID)  && ( (al.Position + al.Length) >= region.LeftPosition ) &&
                         (al.RefID <= region.RightRefID) && ( al.Position <= region.RightPosition) )
                    {
                        writer.SaveAlignment(al);
                    }
                }
            }
        }

        // error parsing REGION string
        else {
            cerr << "bamtools merge ERROR: could not parse REGION - " << m_settings->Region << endl;
            cerr << "Check that REGION is in valid format (see documentation) and that the coordinates are valid"
                 << endl;
            reader.Close();
            writer.Close();
            return false;
        }
    }

    // clean & exit
    reader.Close();
    writer.Close();
    return true;
}

// Assembly:
subq $0x778, %rsp            # imm = 0x778
movq %rdi, 0x768(%rsp)
movq 0x768(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq (%rax), %rax
testb $0x1, (%rax)
jne 0xc2ca4
movq 0xa8(%rsp), %rax
movq (%rax), %rax
testb $0x1, 0x1(%rax)
jne 0xc2ca4
movq 0xa8(%rsp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, 0xa0(%rsp)
callq 0x10f280
movq 0xa0(%rsp), %rdi
movq %rax, %rsi
callq 0x91220
movq 0xa8(%rsp), %rax
movq (%rax), %rax
testb $0x1, 0x1(%rax)
je 0xc2e5e
movq 0xa8(%rsp), %rax
movq (%rax), %rdi
addq $0x20, %rdi
callq 0x86320
movq %rax, %rsi
leaq 0x560(%rsp), %rdi
movq %rdi, 0x90(%rsp)
movl $0x8, %edx
callq 0x86e30
movq 0x90(%rsp), %rdi
callq 0x86c10
movb %al, 0x9f(%rsp)
jmp 0xc2d00
movb 0x9f(%rsp), %al
testb $0x1, %al
jne 0xc2d71
jmp 0xc2d0d
movq 0xa22cc(%rip), %rdi     # 0x164fe0
leaq 0x6d4ac(%rip), %rsi     # 0x1301c7
callq 0x86700
movq %rax, 0x88(%rsp)
jmp 0xc2d2a
movq 0x88(%rsp), %rdi
movq 0xa2237(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xc2d40
movb $0x0, 0x777(%rsp)
movl $0x1, 0x550(%rsp)
jmp 0xc2e27
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
jmp 0xc2e4a
leaq 0x530(%rsp), %rdi
callq 0x86a30
jmp 0xc2d80
jmp 0xc2d82
leaq 0x560(%rsp), %rdi
leaq 0x530(%rsp), %rsi
callq 0x86140
movq %rax, 0x80(%rsp)
jmp 0xc2da1
movq 0x80(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x86b60
movq %rax, 0x78(%rsp)
jmp 0xc2dbf
movq 0x78(%rsp), %rax
cmpq $0x0, %rax
je 0xc2e0d
movq 0xa8(%rsp), %rax
movq (%rax), %rdi
addq $0x8, %rdi
leaq 0x530(%rsp), %rsi
callq 0x91220
jmp 0xc2de8
jmp 0xc2d82
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
leaq 0x530(%rsp), %rdi
callq 0x86f68
jmp 0xc2e48
leaq 0x530(%rsp), %rdi
callq 0x86f68
jmp 0xc2e1c
movl $0x0, 0x550(%rsp)
leaq 0x560(%rsp), %rdi
callq 0x861c0
movl 0x550(%rsp), %eax
testl %eax, %eax
je 0xc2e46
jmp 0xc2e41
jmp 0xc35b7
jmp 0xc2e5e
jmp 0xc2e4a
leaq 0x560(%rsp), %rdi
callq 0x861c0
jmp 0xc2e59
jmp 0xc35c8
leaq 0x528(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x86db0
movq 0xa8(%rsp), %rax
movq 0x68(%rsp), %rdi
movq (%rax), %rsi
addq $0x8, %rsi
callq 0x864a0
movb %al, 0x77(%rsp)
jmp 0xc2e8f
movb 0x77(%rsp), %al
testb $0x1, %al
jne 0xc2ef7
jmp 0xc2e99
movq 0xa2140(%rip), %rdi     # 0x164fe0
leaq 0x6d366(%rip), %rsi     # 0x13020d
callq 0x86700
movq %rax, 0x60(%rsp)
jmp 0xc2eb3
movq 0x60(%rsp), %rdi
movq 0xa20b1(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xc2ec6
movb $0x0, 0x777(%rsp)
movl $0x1, 0x550(%rsp)
jmp 0xc3597
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
jmp 0xc35a6
leaq 0x508(%rsp), %rdi
leaq 0x528(%rsp), %rsi
callq 0x865f0
jmp 0xc2f0e
leaq 0x4f0(%rsp), %rdi
leaq 0x528(%rsp), %rsi
callq 0x862c0
jmp 0xc2f25
movq 0xa8(%rsp), %rax
movq (%rax), %rax
addq $0x40, %rax
movq %rax, 0x50(%rsp)
callq 0x10f290
movq %rax, 0x58(%rsp)
jmp 0xc2f45
movq 0x58(%rsp), %rsi
movq 0x50(%rsp), %rdi
callq 0x91630
movb %al, 0x4f(%rsp)
jmp 0xc2f5a
movb 0x4f(%rsp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, 0x4e(%rsp)
jne 0xc2f6b
jmp 0xc2f7f
movq 0xa8(%rsp), %rax
movq (%rax), %rax
movb 0x3(%rax), %al
xorb $-0x1, %al
movb %al, 0x4e(%rsp)
movb 0x4e(%rsp), %al
andb $0x1, %al
movb %al, 0x4ef(%rsp)
movl $0x0, 0x4e8(%rsp)
testb $0x1, 0x4ef(%rsp)
je 0xc2fe0
movl $0x1, 0x4e8(%rsp)
jmp 0xc2fe0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
jmp 0xc3586
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
jmp 0xc3573
leaq 0x4e0(%rsp), %rdi
callq 0x863f0
jmp 0xc2fef
leaq 0x4e0(%rsp), %rdi
leaq 0x4e8(%rsp), %rsi
callq 0x86280
jmp 0xc3006
movq 0xa8(%rsp), %rax
movq (%rax), %rsi
addq $0x40, %rsi
leaq 0x4e0(%rsp), %rdi
leaq 0x508(%rsp), %rdx
leaq 0x4f0(%rsp), %rcx
callq 0x86bd0
movb %al, 0x4d(%rsp)
jmp 0xc3038
movb 0x4d(%rsp), %al
testb $0x1, %al
jne 0xc30eb
jmp 0xc3046
movq 0xa1f93(%rip), %rdi     # 0x164fe0
leaq 0x6d1fd(%rip), %rsi     # 0x130251
callq 0x86700
movq %rax, 0x40(%rsp)
jmp 0xc3060
movq 0x40(%rsp), %rdi
movq 0xa8(%rsp), %rax
movq (%rax), %rsi
addq $0x40, %rsi
callq 0x86640
movq %rax, 0x38(%rsp)
jmp 0xc3080
movq 0x38(%rsp), %rdi
leaq 0x6c5b9(%rip), %rsi     # 0x12f645
callq 0x86700
movq %rax, 0x30(%rsp)
jmp 0xc3098
movq 0x30(%rsp), %rdi
movq 0xa1ecc(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xc30ab
leaq 0x528(%rsp), %rdi
callq 0x861e0
jmp 0xc30ba
movb $0x0, 0x777(%rsp)
movl $0x1, 0x550(%rsp)
jmp 0xc3535
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
jmp 0xc3553
movq 0xa8(%rsp), %rax
movq (%rax), %rax
testb $0x1, 0x4(%rax)
jne 0xc318b
leaq 0x388(%rsp), %rdi
callq 0x86260
jmp 0xc310f
jmp 0xc3111
leaq 0x528(%rsp), %rdi
leaq 0x388(%rsp), %rsi
callq 0x86190
movb %al, 0x2f(%rsp)
jmp 0xc312c
movb 0x2f(%rsp), %al
testb $0x1, %al
jne 0xc3136
jmp 0xc3172
leaq 0x4e0(%rsp), %rdi
leaq 0x388(%rsp), %rsi
callq 0x86e80
jmp 0xc314d
jmp 0xc3111
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
leaq 0x388(%rsp), %rdi
callq 0x86b30
jmp 0xc3186
leaq 0x388(%rsp), %rdi
callq 0x86b30
jmp 0xc3181
jmp 0xc3504
jmp 0xc3553
movl $0xffffffff, 0x374(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x370(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x36c(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x368(%rsp) # imm = 0xFFFFFFFF
leaq 0x378(%rsp), %rdi
leaq 0x374(%rsp), %rsi
leaq 0x370(%rsp), %rdx
leaq 0x36c(%rsp), %rcx
leaq 0x368(%rsp), %r8
callq 0x915e0
jmp 0xc31e6
movq 0xa8(%rsp), %rax
movq (%rax), %rdi
addq $0x60, %rdi
leaq 0x528(%rsp), %rsi
leaq 0x378(%rsp), %rdx
callq 0x115500
movb %al, 0x2e(%rsp)
jmp 0xc3210
movb 0x2e(%rsp), %al
testb $0x1, %al
jne 0xc321d
jmp 0xc3457
movl $0x1, 0x364(%rsp)
leaq 0x528(%rsp), %rdi
leaq 0x364(%rsp), %rsi
callq 0x86950
jmp 0xc323f
leaq 0x528(%rsp), %rdi
callq 0x864c0
movb %al, 0x2d(%rsp)
jmp 0xc3252
movb 0x2d(%rsp), %al
testb $0x1, %al
jne 0xc325f
jmp 0xc337b
leaq 0x37c(%rsp), %rdx
leaq 0x380(%rsp), %rcx
leaq 0x384(%rsp), %r8
leaq 0x528(%rsp), %rdi
leaq 0x378(%rsp), %rsi
callq 0x86cf0
movb %al, 0x2c(%rsp)
jmp 0xc3292
movb 0x2c(%rsp), %al
testb $0x1, %al
jne 0xc32f0
jmp 0xc329c
movq 0xa1d3d(%rip), %rdi     # 0x164fe0
leaq 0x6cfcd(%rip), %rsi     # 0x130277
callq 0x86700
movq %rax, 0x20(%rsp)
jmp 0xc32b6
movq 0x20(%rsp), %rdi
movq 0xa1cae(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xc32c9
leaq 0x528(%rsp), %rdi
callq 0x861e0
jmp 0xc32d8
movb $0x0, 0x777(%rsp)
movl $0x1, 0x550(%rsp)
jmp 0xc3535
leaq 0x208(%rsp), %rdi
callq 0x86260
jmp 0xc32ff
jmp 0xc3301
leaq 0x528(%rsp), %rdi
leaq 0x208(%rsp), %rsi
callq 0x86190
movb %al, 0x1f(%rsp)
jmp 0xc331c
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0xc3326
jmp 0xc3362
leaq 0x4e0(%rsp), %rdi
leaq 0x208(%rsp), %rsi
callq 0x86e80
jmp 0xc333d
jmp 0xc3301
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x86b30
jmp 0xc3376
leaq 0x208(%rsp), %rdi
callq 0x86b30
jmp 0xc3371
jmp 0xc3452
jmp 0xc3553
leaq 0xb0(%rsp), %rdi
callq 0x86260
jmp 0xc338a
jmp 0xc338c
leaq 0x528(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x86190
movb %al, 0x1e(%rsp)
jmp 0xc33a7
movb 0x1e(%rsp), %al
testb $0x1, %al
jne 0xc33b4
jmp 0xc343c
movl 0x158(%rsp), %eax
cmpl 0x378(%rsp), %eax
jl 0xc3437
movl 0x15c(%rsp), %eax
addl 0xd0(%rsp), %eax
cmpl 0x37c(%rsp), %eax
jl 0xc3437
movl 0x158(%rsp), %eax
cmpl 0x380(%rsp), %eax
jg 0xc3437
movl 0x15c(%rsp), %eax
cmpl 0x384(%rsp), %eax
jg 0xc3437
leaq 0x4e0(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0x86e80
jmp 0xc3412
jmp 0xc3437
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x558(%rsp)
movl %eax, 0x554(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x86b30
jmp 0xc344d
jmp 0xc338c
leaq 0xb0(%rsp), %rdi
callq 0x86b30
jmp 0xc344b
jmp 0xc3452
jmp 0xc3553
jmp 0xc3502
movq 0xa1b82(%rip), %rdi     # 0x164fe0
leaq 0x6ce65(%rip), %rsi     # 0x1302ca
callq 0x86700
movq %rax, 0x10(%rsp)
jmp 0xc3471
movq 0x10(%rsp), %rdi
movq 0xa8(%rsp), %rax
movq (%rax), %rsi
addq $0x60, %rsi
callq 0x86640
movq %rax, 0x8(%rsp)
jmp 0xc3491
movq 0x8(%rsp), %rdi
movq 0xa1ad3(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xc34a4
movq 0xa1b35(%rip), %rdi     # 0x164fe0
leaq 0x6aea2(%rip), %rsi     # 0x12e354
callq 0x86700
movq %rax, (%rsp)
jmp 0xc34bd
movq (%rsp), %rdi
movq 0xa1aa8(%rip), %rsi     # 0x164f70
callq 0x86770
jmp 0xc34cf
leaq 0x528(%rsp), %rdi
callq 0x861e0
jmp 0xc34de
leaq 0x4e0(%rsp), %rdi
callq 0x86410
jmp 0xc34ed
movb $0x0, 0x777(%rsp)
movl $0x1, 0x550(%rsp)
jmp 0xc3535
jmp 0xc3504
leaq 0x528(%rsp), %rdi
callq 0x861e0
jmp 0xc3513
leaq 0x4e0(%rsp), %rdi
callq 0x86410
jmp 0xc3522
movb $0x1, 0x777(%rsp)
movl $0x1, 0x550(%rsp)
leaq 0x4e0(%rsp), %rdi
callq 0x86510
jmp 0xc3544
leaq 0x4f0(%rsp), %rdi
callq 0x91560
jmp 0xc3564
leaq 0x4e0(%rsp), %rdi
callq 0x86510
jmp 0xc3562
jmp 0xc3573
leaq 0x508(%rsp), %rdi
callq 0x86f68
jmp 0xc3584
leaq 0x4f0(%rsp), %rdi
callq 0x91560
jmp 0xc3582
jmp 0xc3586
jmp 0xc3597
leaq 0x508(%rsp), %rdi
callq 0x86f68
jmp 0xc3595
jmp 0xc35a6
leaq 0x528(%rsp), %rdi
callq 0x86150
jmp 0xc35b7
leaq 0x528(%rsp), %rdi
callq 0x86150
jmp 0xc35b5
jmp 0xc35c8
movb 0x777(%rsp), %al
andb $0x1, %al
addq $0x778, %rsp            # imm = 0x778
retq
movq 0x558(%rsp), %rdi
callq 0x86d80
movq %rax, %rdi
callq 0x91290
nopl (%rax)