// File: zeeev[P]DASVC/bamtools/src/api/internal/bam/BamMultiReader_p.cpp
// Function: BamTools::Internal::BamMultiReaderPrivate::CreateAlignmentCache()
IMultiMerger* BamMultiReaderPrivate::CreateAlignmentCache(void) {

    // if no merge order set explicitly, use SAM header to lookup proper order
    if ( !m_hasUserMergeOrder ) {

        // fetch SamHeader from BAM files
        SamHeader header = GetHeader();

        // if BAM files are sorted by position
        if ( header.SortOrder == Constants::SAM_HD_SORTORDER_COORDINATE )
            m_mergeOrder = BamMultiReader::MergeByCoordinate;

        // if BAM files are sorted by read name
        else if ( header.SortOrder == Constants::SAM_HD_SORTORDER_QUERYNAME )
            m_mergeOrder = BamMultiReader::MergeByName;

        // otherwise, sorting is either "unknown" or marked as "unsorted"
        else
            m_mergeOrder = BamMultiReader::RoundRobinMerge;
    }

    // use current merge order to create proper 'multi-merger'
    switch ( m_mergeOrder ) {

        // merge BAM files by position
        case BamMultiReader::MergeByCoordinate :
            return new MultiMerger<Algorithms::Sort::ByPosition>();

        // merge BAM files by read name
        case BamMultiReader::MergeByName :
            return new MultiMerger<Algorithms::Sort::ByName>();

        // sorting is "unknown", "unsorted" or "ignored"... so use unsorted merger
        case BamMultiReader::RoundRobinMerge :
            return new MultiMerger<Algorithms::Sort::Unsorted>();

        // unknown merge order, can't create merger
        default:
            return 0;
    }
}

// Assembly:
subq $0x1b8, %rsp            # imm = 0x1B8
movq %rdi, 0x1a8(%rsp)
movq 0x1a8(%rsp), %rax
movq %rax, 0x28(%rsp)
testb $0x1, 0x20(%rax)
jne 0x9ee4c
movq 0x28(%rsp), %rsi
leaq 0x50(%rsp), %rdi
callq 0x73cb0
leaq 0x70(%rsp), %rdi
leaq 0x79b3f(%rip), %rsi     # 0x118900
callq 0x74120
movb %al, 0x27(%rsp)
jmp 0x9edcc
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0x9edd6
jmp 0x9edfe
movq 0x28(%rsp), %rax
movl $0x1, 0x24(%rax)
jmp 0x9ee3b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
leaq 0x50(%rsp), %rdi
callq 0x766b0
jmp 0x9ee47
leaq 0x70(%rsp), %rdi
leaq 0x79b16(%rip), %rsi     # 0x118920
callq 0x74120
movb %al, 0x26(%rsp)
jmp 0x9ee15
movb 0x26(%rsp), %al
testb $0x1, %al
jne 0x9ee1f
jmp 0x9ee2d
movq 0x28(%rsp), %rax
movl $0x2, 0x24(%rax)
jmp 0x9ee39
movq 0x28(%rsp), %rax
movl $0x0, 0x24(%rax)
jmp 0x9ee3b
leaq 0x50(%rsp), %rdi
callq 0x766b0
jmp 0x9ee4c
jmp 0x9efab
movq 0x28(%rsp), %rax
movl 0x24(%rax), %eax
movl %eax, 0x20(%rsp)
testl %eax, %eax
je 0x9ef45
jmp 0x9ee62
movl 0x20(%rsp), %eax
subl $0x1, %eax
je 0x9ee7b
jmp 0x9ee6d
movl 0x20(%rsp), %eax
subl $0x2, %eax
je 0x9eee3
jmp 0x9ef8f
movl $0x38, %edi
callq 0x76970
movq %rax, 0x18(%rsp)
movl $0x0, 0x3c(%rsp)
leaq 0x40(%rsp), %rdi
leaq 0x3c(%rsp), %rsi
callq 0x7c620
jmp 0x9eea3
movq 0x18(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x71780
jmp 0x9eeb4
movq 0x18(%rsp), %rax
movq %rax, 0x1b0(%rsp)
jmp 0x9ef9b
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
callq 0x764d0
jmp 0x9efab
movl $0x38, %edi
callq 0x76970
movq %rax, 0x10(%rsp)
movl $0x0, 0x34(%rsp)
leaq 0x38(%rsp), %rdi
leaq 0x34(%rsp), %rsi
callq 0x76dc0
jmp 0x9ef0b
movq 0x10(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x740c0
jmp 0x9ef1c
movq 0x10(%rsp), %rax
movq %rax, 0x1b0(%rsp)
jmp 0x9ef9b
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
callq 0x764d0
jmp 0x9efab
movl $0x58, %edi
callq 0x76970
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x8(%rsp)
leaq 0x33(%rsp), %rsi
callq 0x77480
jmp 0x9ef66
movq 0x8(%rsp), %rax
movq %rax, 0x1b0(%rsp)
jmp 0x9ef9b
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
callq 0x764d0
jmp 0x9efab
movq $0x0, 0x1b0(%rsp)
movq 0x1b0(%rsp), %rax
addq $0x1b8, %rsp            # imm = 0x1B8
retq
movq 0x48(%rsp), %rdi
callq 0x7b550
movq %rax, %rdi
callq 0x88ef0
nopl (%rax)