ArgParser::parseOptions()
{
    checkCompletion();
    if (! this->bash_completion)
    {
        handleHelpArgs();
    }
    handleArgFileArguments();
    for (cur_arg = 1; cur_arg < argc; ++cur_arg)
    {
        char* arg = argv[cur_arg];
        if (strcmp(arg, "--") == 0)
        {
            // Special case for -- option, which is used to break out
            // of subparsers.
            OptionEntry& oe = (*this->option_table)["--"];
            if (oe.bare_arg_handler)
            {
                (this->*(oe.bare_arg_handler))();
            }
        }
        else if ((arg[0] == '-') && (strcmp(arg, "-") != 0))
        {
            ++arg;
            if (arg[0] == '-')
            {
                // Be lax about -arg vs --arg
                ++arg;
            }
            char* parameter = 0;
            if (strlen(arg) > 0)
            {
                // Prevent --=something from being treated as an empty
                // arg since the empty string in the option table is
                // for positional arguments.
                parameter = const_cast<char*>(strchr(1 + arg, '='));
            }
            if (parameter)
            {
                *parameter++ = 0;
            }

            std::string arg_s(arg);
            if (arg_s.empty() ||
                (arg_s.at(0) == '-') ||
                (0 == this->option_table->count(arg_s)))
            {
                usage(std::string("unknown option --") + arg);
            }

            OptionEntry& oe = (*this->option_table)[arg_s];
            if ((oe.parameter_needed && (0 == parameter)) ||
                ((! oe.choices.empty() &&
                  ((0 == parameter) ||
                   (0 == oe.choices.count(parameter))))))
            {
                std::string message =
                    "--" + arg_s + " must be given as --" + arg_s + "=";
                if (! oe.choices.empty())
                {
                    QTC::TC("qpdf", "qpdf required choices");
                    message += "{";
                    for (std::set<std::string>::iterator iter =
                             oe.choices.begin();
                         iter != oe.choices.end(); ++iter)
                    {
                        if (iter != oe.choices.begin())
                        {
                            message += ",";
                        }
                        message += *iter;
                    }
                    message += "}";
                }
                else if (! oe.parameter_name.empty())
                {
                    QTC::TC("qpdf", "qpdf required parameter");
                    message += oe.parameter_name;
                }
                else
                {
                    // should not be possible
                    message += "option";
                }
                usage(message);
            }
            if (oe.bare_arg_handler)
            {
                (this->*(oe.bare_arg_handler))();
            }
            else if (oe.param_arg_handler)
            {
                (this->*(oe.param_arg_handler))(parameter);
            }
        }
        else if (0 != this->option_table->count(""))
        {
            // The empty string maps to the positional argument
            // handler.
            OptionEntry& oe = (*this->option_table)[""];
            if (oe.param_arg_handler)
            {
                (this->*(oe.param_arg_handler))(arg);
            }
        }
        else
        {
            usage(std::string("unknown argument ") + arg);
        }
    }
    if (this->bash_completion)
    {
        handleCompletion();
    }
    else
    {
        doFinalChecks();
    }
}