@SuppressWarnings({"unchecked", "rawtypes"})
        private @NonNull CompletableFuture<@NonNull ArgumentParseResult<Object>> parse(
                final @NonNull CommandContext<@NonNull C> commandContext,
                final @NonNull CommandInput commandInput
        ) {
            CompletableFuture<ArgumentParseResult<Object>> result = CompletableFuture.completedFuture(null);
            final Set<CommandFlag<?>> parsedFlags = commandContext.computeIfAbsent(PARSED_FLAGS, k -> new HashSet());

            final int remainingTokens = commandInput.remainingTokens();
            for (int i = 0; i <= remainingTokens; i++) {
                result = result.thenCompose(parseResult -> {
                    // The previous flag might have left us with trailing whitespace. We remove it so that we
                    // do not have to account for it throughout the parsing process.
                    commandInput.skipWhitespace();

                    if (parseResult != null || commandInput.isEmpty()) {
                        return CompletableFuture.completedFuture(parseResult);
                    }

                    final String string = commandInput.peekString();

                    if (!string.startsWith("-")) {
                        // If we're not starting a new flag then we're outside the scope of this parser. We exit.
                        return CompletableFuture.completedFuture(ArgumentParseResult.success(FLAG_PARSE_RESULT_OBJECT));
                    }

                    // We're definitely not supplying anything to the flag.
                    this.lastParsedFlag = null;

                    // We figure out which flag we're dealing with.
                    if (string.startsWith("--")) {
                        commandInput.moveCursor(2);
                    } else {
                        commandInput.moveCursor(1);
                    }

                    final String flagName = commandInput.readStringSkipWhitespace();
                    CommandFlag<?> flag = null;

                    if (string.startsWith("--")) {
                        for (final CommandFlag<?> flagCandidate : CommandFlagParser.this.flags) {
                            if (flagName.equalsIgnoreCase(flagCandidate.name())) {
                                flag = flagCandidate;
                                break;
                            }
                        }
                    } else if (flagName.length() == 1) {
                        outer:
                        for (final CommandFlag<?> flagCandidate : CommandFlagParser.this.flags) {
                            for (final String alias : flagCandidate.aliases()) {
                                if (alias.equalsIgnoreCase(flagName)) {
                                    flag = flagCandidate;
                                    break outer;
                                }
                            }
                        }
                    } else {
                        boolean flagFound = false;
                        for (int j = 0; j < flagName.length(); j++) {
                            final String parsedFlag = Character.toString(flagName.charAt(j)).toLowerCase(Locale.ENGLISH);
                            for (final CommandFlag<?> candidateFlag : CommandFlagParser.this.flags) {
                                // Argument flags cannot use the shorthand form in this way.
                                if (candidateFlag.commandComponent() != null) {
                                    continue;
                                }

                                if (!candidateFlag.aliases().contains(parsedFlag)) {
                                    continue;
                                }

                                if (parsedFlags.contains(candidateFlag) && candidateFlag.mode() != CommandFlag.FlagMode.REPEATABLE) {
                                    return this.fail(
                                            new FlagParseException(
                                                    string,
                                                    FailureReason.DUPLICATE_FLAG,
                                                    commandContext
                                            )
                                    );
                                } else if (!commandContext.hasPermission(candidateFlag.permission())) {
                                    return this.fail(
                                            new FlagParseException(
                                                    string,
                                                    FailureReason.NO_PERMISSION,
                                                    commandContext
                                            )
                                    );
                                }

                                commandContext.flags().addPresenceFlag(candidateFlag);
                                parsedFlags.add(candidateFlag);
                                flagFound = true;
                            }
                        }

                        if (!flagFound) {
                            return this.fail(
                                    new FlagParseException(
                                            string,
                                            FailureReason.NO_FLAG_STARTED,
                                            commandContext
                                    )
                            );
                        }

                        // This type of flag can never have a value. We move on to the next flag.
                        return CompletableFuture.completedFuture(null);
                    }

                    if (flag == null) {
                        return this.fail(
                                new FlagParseException(
                                        string,
                                        FailureReason.UNKNOWN_FLAG,
                                        commandContext
                                )
                        );
                    } else if (parsedFlags.contains(flag) && flag.mode() != CommandFlag.FlagMode.REPEATABLE) {
                        return this.fail(
                                new FlagParseException(
                                        string,
                                        FailureReason.DUPLICATE_FLAG,
                                        commandContext
                                )
                        );
                    } else if (!commandContext.hasPermission(flag.permission())) {
                        return this.fail(
                                new FlagParseException(
                                        string,
                                        FailureReason.NO_PERMISSION,
                                        commandContext
                                )
                        );
                    }

                    // The flag has no argument, so we're done.
                    if (flag.commandComponent() == null) {
                        commandContext.remove(FLAG_CURSOR_KEY);
                        commandContext.flags().addPresenceFlag(flag);
                        parsedFlags.add(flag);
                        return CompletableFuture.completedFuture(null);
                    }

                    // If the command input ends with a space then we set lastParsedFlag before checking if the command
                    // input is empty. This is because this means that the sender has actually started
                    // completing the value.
                    if (commandInput.hasRemainingInput() && commandInput.peek() == ' ') {
                        // Indicate that we parsed the flag and that we're trying to populate the value for it.
                        this.lastParsedFlag = string;
                    }

                    // If there is no input (a space cannot be parsed into anything) then
                    // we cannot complete this flag.
                    if (commandInput.isEmpty(true /* ignoreWhitespace */)) {
                        return this.fail(
                                new FlagParseException(
                                        flag.name(),
                                        FailureReason.MISSING_ARGUMENT,
                                        commandContext
                                )
                        );
                    }

                    // Indicate that we parsed the flag and that we're trying to populate the value for it.
                    this.lastParsedFlag = string;

                    // We then attempt to parse the flag.
                    final CommandFlag parsingFlag = flag;
                    final CommandInput commandInputCopy = commandInput.copy();
                    return ((CommandComponent<C>) flag.commandComponent())
                            .parser()
                            .parseFuture(
                                    commandContext,
                                    commandInput
                            ).thenApply(parsedValue -> {
                                if (parsedValue.failure().isPresent() || commandInput.isEmpty() || commandInput.peek() != ' ') {
                                    commandContext.store(FLAG_CURSOR_KEY, commandInputCopy.cursor());
                                }

                                // Forward parsing errors.
                                if (parsedValue.failure().isPresent()) {
                                    return (ArgumentParseResult<Object>) parsedValue;
                                }

                                // We store the parsed flag in the context. We do ugly erasure here because generics :)
                                commandContext.flags().addValueFlag(parsingFlag, (Object) parsedValue.parsedValue().get());
                                // At this point we know the flag parsed successfully.
                                parsedFlags.add(parsingFlag);

                                if (!commandInput.isEmpty(false)) {
                                    if (commandInput.peek() == ' ') {
                                        // We're no longer parsing a flag.
                                        this.lastParsedFlag = null;
                                    }
                                }

                                return null;
                            });
                });
            }

            // We've consumed everything!
            return result.thenApply(r -> r == null ? ArgumentParseResult.success(FLAG_PARSE_RESULT_OBJECT) : r);
        }
Helper class to parse the command input queue into flags
and flag values. On failure the intermediate results
can be obtained, which are used for providing suggestions.
cloud-core/src/main/java/org/incendo/cloud/parser/flag/CommandFlagParser.java