// File: demon386[P]git-store/./command.hpp
// Function: command::parse_args(int, char**)
po::variables_map parse_args(int argc, char* argv[]) {
    // Inspired by
    // http://www.hitmaroc.net/553491-4141-how-implement-subcommands-using-boost-program-options.html
    po::options_description commands("Subcommands: init,read,write");

    commands.add_options()
        ("help,h", "Help screen")
        ("command", po::value<std::string>(), "subcommand")
        ("subargs", po::value<std::vector<std::string>>(),
         "Positional arguments for subcommands");

    po::positional_options_description pos;
    pos.add("command", 1).
        add("subargs", -1);

    po::variables_map vm;

    po::parsed_options parsed = po::command_line_parser(argc, argv).
        options(commands).
        positional(pos).
        allow_unregistered().
        run();

    po::store(parsed, vm);

    // @todo should exists a better way to judge whether the first positional
    // cmd is given.
    try {
        std::string cmd = vm["command"].as<std::string>();
    } catch(...) {
        std::cout << commands << std::endl;
        std::exit(1);
    }
    std::string cmd = vm["command"].as<std::string>();

    if (!global_command_map().count(cmd)) {
        std::cout << "Unrecognized command: " << cmd << std::endl;
        std::cout << commands << std::endl;
        std::exit(-1);
    } else {
        const auto& callback = std::get<1>(global_command_map().at(cmd));
        po::options_description sub_opts("sub-options for `" + cmd + "`");
        callback(sub_opts);
        sub_opts.add_options()
            ("help,h", "Help screen");

        std::vector<std::string> opts = po::collect_unrecognized(parsed.options, po::include_positional);
        opts.erase(opts.begin());

        try {
            po::store(po::command_line_parser(opts).options(sub_opts).run(), vm);
        } catch (boost::program_options::unknown_option& e) {
            std::cout << "Unknown options!" << std::endl;
            std::cout << sub_opts << std::endl;
            std::exit(1);
        }
        if (vm.count("help")) {
            std::cout << sub_opts << std::endl;
            std::exit(0);
        }
    }
    return vm;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x540, %rsp            # imm = 0x540
movq %rdi, -0x430(%rbp)
movq %rdi, %rax
movq %rax, -0x428(%rbp)
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x420(%rbp)
callq 0xdb50
movq -0x420(%rbp), %rdx
leaq 0xf555(%rip), %rsi      # 0x640cd
leaq -0xb8(%rbp), %rdi
callq 0xd8b0
jmp 0x54b86
leaq 0xbf9b(%rip), %rax      # 0x60b28
movl (%rax), %edx
movl %edx, %ecx
shrl %ecx
leaq -0x98(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x24f80
jmp 0x54ba8
leaq -0xb8(%rbp), %rdi
callq 0xdca8
leaq -0xb9(%rbp), %rdi
callq 0xd6b0
leaq -0x98(%rbp), %rdi
callq 0x251a0
movq %rax, -0x438(%rbp)
jmp 0x54bd5
movq -0x438(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq 0xf500(%rip), %rsi      # 0x640ea
leaq 0xf500(%rip), %rdx      # 0x640f1
leaq -0xd8(%rbp), %rdi
callq 0x24bc0
movq %rax, -0x440(%rbp)
jmp 0x54c06
callq 0x57230
movq %rax, -0x448(%rbp)
jmp 0x54c14
movq -0x448(%rbp), %rdx
movq -0x440(%rbp), %rdi
leaq 0xf4d7(%rip), %rsi      # 0x64100
leaq 0xf4cd(%rip), %rcx      # 0x640fd
callq 0x24e00
movq %rax, -0x450(%rbp)
jmp 0x54c3e
callq 0x57240
movq %rax, -0x458(%rbp)
jmp 0x54c4c
movq -0x458(%rbp), %rdx
movq -0x450(%rbp), %rdi
leaq 0xf4a7(%rip), %rsi      # 0x64108
leaq 0xf4a8(%rip), %rcx      # 0x64110
callq 0x24e00
jmp 0x54c6f
leaq -0x110(%rbp), %rdi
callq 0x34c20
jmp 0x54c7d
leaq 0xf47c(%rip), %rsi      # 0x64100
leaq -0x110(%rbp), %rdi
movl $0x1, %edx
callq 0x34c50
movq %rax, -0x460(%rbp)
jmp 0x54c9e
movq -0x460(%rbp), %rdi
leaq 0xf45c(%rip), %rsi      # 0x64108
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x34c50
jmp 0x54cb8
movq -0x430(%rbp), %rdi
movb $0x0, -0x111(%rbp)
callq 0x448f0
jmp 0x54ccd
movl -0xc(%rbp), %esi
movq -0x18(%rbp), %rdx
leaq -0x1b8(%rbp), %rdi
callq 0x57250
jmp 0x54ce2
leaq -0x1b8(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x57310
movq %rax, -0x468(%rbp)
jmp 0x54cfe
movq -0x468(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x57350
movq %rax, -0x470(%rbp)
jmp 0x54d1a
movq -0x470(%rbp), %rdi
callq 0x57380
movq %rax, -0x478(%rbp)
jmp 0x54d2f
movq -0x478(%rbp), %rsi
leaq -0x140(%rbp), %rdi
callq 0x573b0
jmp 0x54d44
leaq -0x1b8(%rbp), %rdi
callq 0x57470
movq -0x430(%rbp), %rsi
leaq -0x140(%rbp), %rdi
xorl %edx, %edx
callq 0x439f0
jmp 0x54d67
leaq -0x1f9(%rbp), %rdi
movq %rdi, -0x480(%rbp)
callq 0xdb50
movq -0x480(%rbp), %rdx
leaq 0xf378(%rip), %rsi      # 0x64100
leaq -0x1f8(%rbp), %rdi
callq 0xd8b0
jmp 0x54d96
movq -0x430(%rbp), %rdi
leaq -0x1f8(%rbp), %rsi
callq 0x57490
movq %rax, -0x488(%rbp)
jmp 0x54db2
movq -0x488(%rbp), %rdi
callq 0x574c0
movq %rax, -0x490(%rbp)
jmp 0x54dc7
movq -0x490(%rbp), %rsi
leaq -0x1d8(%rbp), %rdi
callq 0xd230
jmp 0x54ddc
leaq -0x1f8(%rbp), %rdi
callq 0xdca8
leaq -0x1f9(%rbp), %rdi
callq 0xd6b0
leaq -0x1d8(%rbp), %rdi
callq 0xdca8
jmp 0x54f6a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x54e37
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0xdca8
leaq -0xb9(%rbp), %rdi
callq 0xd6b0
jmp 0x5563c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x55630
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x55624
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x55618
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0x57470
jmp 0x55618
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x555d6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x54ef9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0xdca8
leaq -0x1f9(%rbp), %rdi
callq 0xd6b0
movq -0xc8(%rbp), %rdi
callq 0xd200
movq 0x39098(%rip), %rdi     # 0x8dfb0
leaq -0x98(%rbp), %rsi
callq 0x25610
movq %rax, -0x498(%rbp)
jmp 0x54f2d
movq -0x498(%rbp), %rdi
movq 0x39035(%rip), %rsi     # 0x8df70
callq 0xd670
jmp 0x54f42
movl $0x1, %edi
callq 0xd770
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
callq 0xda90
jmp 0x54f65
jmp 0x555d6
leaq -0x241(%rbp), %rdi
movq %rdi, -0x4a0(%rbp)
callq 0xdb50
movq -0x4a0(%rbp), %rdx
leaq 0xf175(%rip), %rsi      # 0x64100
leaq -0x240(%rbp), %rdi
callq 0xd8b0
jmp 0x54f99
movq -0x430(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x57490
movq %rax, -0x4a8(%rbp)
jmp 0x54fb5
movq -0x4a8(%rbp), %rdi
callq 0x574c0
movq %rax, -0x4b0(%rbp)
jmp 0x54fca
movq -0x4b0(%rbp), %rsi
leaq -0x220(%rbp), %rdi
callq 0xd230
jmp 0x54fdf
leaq -0x240(%rbp), %rdi
callq 0xdca8
leaq -0x241(%rbp), %rdi
callq 0xd6b0
callq 0x56fa0
movq %rax, -0x4b8(%rbp)
jmp 0x55005
movq -0x4b8(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x574e0
movq %rax, -0x4c0(%rbp)
jmp 0x55021
movq -0x4c0(%rbp), %rax
cmpq $0x0, %rax
jne 0x55114
movq 0x38f77(%rip), %rdi     # 0x8dfb0
leaq 0xf0f5(%rip), %rsi      # 0x64135
callq 0xd610
movq %rax, -0x4c8(%rbp)
jmp 0x5504e
movq -0x4c8(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0xd570
movq %rax, -0x4d0(%rbp)
jmp 0x5506a
movq -0x4d0(%rbp), %rdi
movq 0x38ef8(%rip), %rsi     # 0x8df70
callq 0xd670
jmp 0x5507f
movq 0x38f2a(%rip), %rdi     # 0x8dfb0
leaq -0x98(%rbp), %rsi
callq 0x25610
movq %rax, -0x4d8(%rbp)
jmp 0x5509b
movq -0x4d8(%rbp), %rdi
movq 0x38ec7(%rip), %rsi     # 0x8df70
callq 0xd670
jmp 0x550b0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0xd770
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x550ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x240(%rbp), %rdi
callq 0xdca8
leaq -0x241(%rbp), %rdi
callq 0xd6b0
jmp 0x555d6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x555ca
callq 0x56fa0
movq %rax, -0x4e0(%rbp)
jmp 0x55122
movq -0x4e0(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x57560
movq %rax, -0x4e8(%rbp)
jmp 0x5513e
movq -0x4e8(%rbp), %rdi
callq 0x57540
movq %rax, -0x250(%rbp)
leaq 0xeff4(%rip), %rsi      # 0x6414c
leaq -0x310(%rbp), %rdi
leaq -0x220(%rbp), %rdx
callq 0x267b0
jmp 0x5516d
leaq 0xefe8(%rip), %rdx      # 0x6415c
leaq -0x2f0(%rbp), %rdi
leaq -0x310(%rbp), %rsi
callq 0x1e9e0
jmp 0x55189
leaq 0xb998(%rip), %rax      # 0x60b28
movl (%rax), %edx
movl %edx, %ecx
shrl %ecx
leaq -0x2d0(%rbp), %rdi
leaq -0x2f0(%rbp), %rsi
callq 0x24f80
jmp 0x551ab
leaq -0x2f0(%rbp), %rdi
callq 0xdca8
leaq -0x310(%rbp), %rdi
callq 0xdca8
movq -0x250(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
callq 0x57600
jmp 0x551d8
leaq -0x2d0(%rbp), %rdi
callq 0x251a0
movq %rax, -0x4f0(%rbp)
jmp 0x551ed
movq -0x4f0(%rbp), %rax
movq %rax, -0x318(%rbp)
leaq 0xeee8(%rip), %rsi      # 0x640ea
leaq 0xeee8(%rip), %rdx      # 0x640f1
leaq -0x318(%rbp), %rdi
callq 0x24bc0
jmp 0x55217
leaq -0x330(%rbp), %rdi
leaq -0x140(%rbp), %rsi
xorl %edx, %edx
callq 0x57640
jmp 0x5522e
leaq -0x330(%rbp), %rdi
movq %rdi, -0x500(%rbp)
callq 0x128b0
movq %rax, -0x340(%rbp)
leaq -0x338(%rbp), %rdi
leaq -0x340(%rbp), %rsi
callq 0x128e0
movq -0x500(%rbp), %rdi
movq -0x338(%rbp), %rsi
callq 0x12840
movq %rax, -0x4f8(%rbp)
jmp 0x55277
movq -0x4f8(%rbp), %rax
movq %rax, -0x348(%rbp)
leaq -0x3e8(%rbp), %rdi
leaq -0x330(%rbp), %rsi
callq 0x57790
jmp 0x5529a
leaq -0x3e8(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
callq 0x57310
movq %rax, -0x508(%rbp)
jmp 0x552b6
movq -0x508(%rbp), %rsi
leaq -0x370(%rbp), %rdi
callq 0x573b0
jmp 0x552cb
movq -0x430(%rbp), %rsi
leaq -0x370(%rbp), %rdi
xorl %edx, %edx
callq 0x439f0
jmp 0x552e2
leaq -0x370(%rbp), %rdi
callq 0x2f180
leaq -0x3e8(%rbp), %rdi
callq 0x57470
jmp 0x55472
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x55331
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x2f0(%rbp), %rdi
callq 0xdca8
leaq -0x310(%rbp), %rdi
callq 0xdca8
jmp 0x555ca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x55592
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x55586
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x553c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x553b6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x370(%rbp), %rdi
callq 0x2f180
leaq -0x3e8(%rbp), %rdi
callq 0x57470
movl -0xcc(%rbp), %eax
movl $0x2, %ecx
cmpl %ecx, %eax
jne 0x55586
movq -0xc8(%rbp), %rdi
callq 0xd200
movq %rax, -0x3f0(%rbp)
movq 0x38bc1(%rip), %rdi     # 0x8dfb0
leaq 0xed68(%rip), %rsi      # 0x6415e
callq 0xd610
movq %rax, -0x510(%rbp)
jmp 0x55404
movq -0x510(%rbp), %rdi
movq 0x38b5e(%rip), %rsi     # 0x8df70
callq 0xd670
jmp 0x55419
movq 0x38b90(%rip), %rdi     # 0x8dfb0
leaq -0x2d0(%rbp), %rsi
callq 0x25610
movq %rax, -0x518(%rbp)
jmp 0x55435
movq -0x518(%rbp), %rdi
movq 0x38b2d(%rip), %rsi     # 0x8df70
callq 0xd670
jmp 0x5544a
movl $0x1, %edi
callq 0xd770
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
callq 0xda90
jmp 0x5546d
jmp 0x55586
movq -0x430(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x528(%rbp)
leaq -0x411(%rbp), %rdi
movq %rdi, -0x520(%rbp)
callq 0xdb50
movq -0x520(%rbp), %rdx
leaq 0xecca(%rip), %rsi      # 0x6416f
leaq -0x410(%rbp), %rdi
callq 0xd8b0
jmp 0x554b3
movq -0x528(%rbp), %rdi
leaq -0x410(%rbp), %rsi
callq 0x44d90
movq %rax, -0x530(%rbp)
jmp 0x554cf
leaq -0x410(%rbp), %rdi
callq 0xdca8
leaq -0x411(%rbp), %rdi
callq 0xd6b0
movq -0x530(%rbp), %rax
cmpq $0x0, %rax
je 0x5556c
movq 0x38ab5(%rip), %rdi     # 0x8dfb0
leaq -0x2d0(%rbp), %rsi
callq 0x25610
movq %rax, -0x538(%rbp)
jmp 0x55510
movq -0x538(%rbp), %rdi
movq 0x38a52(%rip), %rsi     # 0x8df70
callq 0xd670
jmp 0x55525
xorl %edi, %edi
callq 0xd770
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
jmp 0x5555e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xc8(%rbp)
movl %eax, -0xcc(%rbp)
leaq -0x410(%rbp), %rdi
callq 0xdca8
leaq -0x411(%rbp), %rdi
callq 0xd6b0
jmp 0x55586
leaq -0x330(%rbp), %rdi
callq 0x11db0
leaq -0x2d0(%rbp), %rdi
callq 0x2d2f0
jmp 0x555a0
leaq -0x330(%rbp), %rdi
callq 0x11db0
leaq -0x2d0(%rbp), %rdi
callq 0x2d2f0
jmp 0x555ca
movb $0x1, -0x111(%rbp)
leaq -0x220(%rbp), %rdi
callq 0xdca8
leaq -0x140(%rbp), %rdi
callq 0x2f180
testb $0x1, -0x111(%rbp)
jne 0x555f0
jmp 0x555e4
leaq -0x220(%rbp), %rdi
callq 0xdca8
leaq -0x140(%rbp), %rdi
callq 0x2f180
jmp 0x55618
movq -0x430(%rbp), %rdi
callq 0x45360
leaq -0x110(%rbp), %rdi
callq 0x57800
leaq -0x98(%rbp), %rdi
callq 0x2d2f0
movq -0x428(%rbp), %rax
addq $0x540, %rsp            # imm = 0x540
popq %rbp
retq
movq -0x430(%rbp), %rdi
callq 0x45360
leaq -0x110(%rbp), %rdi
callq 0x57800
leaq -0x98(%rbp), %rdi
callq 0x2d2f0
movq -0xc8(%rbp), %rdi
callq 0xdb30
movq %rax, %rdi
callq 0x129b0