protected function parseTokens(array $tokens) : Request
    {
        $request = new Request();
        $hasParsedCommandName = false;

        while ($token = array_shift($tokens)) {
            if (mb_strpos($token, '--') === 0) {
                $option = $this->parseLongOption($token, $tokens);
                $request->addOptionValue($option[0], $option[1]);
            } elseif (mb_substr($token, 0, 1) === '-') {
                $options = $this->parseShortOption($token);

                foreach ($options as $option) {
                    $request->addOptionValue($option[0], $option[1]);
                }
            } else {
                if (!$hasParsedCommandName) {
                    // We consider this to be the command name
                    $request->setCommandName($token);
                    $hasParsedCommandName = true;
                } else {
                    // We consider this to be an argument
                    $request->addArgumentValue($this->parseArgument($token));
                }
            }
        }

        return $request;
    }