@Override
    public @NonNull CommandComponent<C> assembleArgument(
            final @NonNull SyntaxFragment syntaxFragment,
            final @NonNull ArgumentDescriptor descriptor
    ) {
        final Parameter parameter = descriptor.parameter();
        final Collection<Annotation> annotations = Arrays.asList(parameter.getAnnotations());
        final TypeToken<?> token = TypeToken.get(parameter.getParameterizedType());
        final ParserParameters parameters = this.annotationParser.manager().parserRegistry()
                .parseAnnotations(token, annotations);
        /* Create the argument parser */
        final ArgumentParser<C, ?> parser;
        if (GenericTypeReflector.isSuperType(Either.class, token.getType())) {
            final TypeToken<?> primaryType = TypeToken.get(GenericTypeReflector.getTypeParameter(
                    parameter.getParameterizedType(),
                    Either.class.getTypeParameters()[0]
            ));
            final TypeToken<?> fallbackType = TypeToken.get(GenericTypeReflector.getTypeParameter(
                    parameter.getParameterizedType(),
                    Either.class.getTypeParameters()[1]
            ));
            final ParserDescriptor<C, ?> primary = this.annotationParser.manager()
                    .parserRegistry()
                    .createParser(primaryType, parameters)
                    .map(primaryParser -> ParserDescriptor.of(primaryParser, (TypeToken) primaryType))
                    .orElseThrow(() -> new IllegalArgumentException(
                            String.format(
                                    "Parameter '%s' "
                                            + "has parser 'Either<%s, ?>' but no parser exists "
                                            + "for that type",
                                    parameter.getName(),
                                    token.getType().getTypeName()
                            )));
            final ParserDescriptor<C, ?> fallback = this.annotationParser.manager()
                    .parserRegistry()
                    .createParser(fallbackType, parameters)
                    .map(fallbackParser -> ParserDescriptor.of(fallbackParser, (TypeToken) fallbackType))
                    .orElseThrow(() -> new IllegalArgumentException(
                            String.format(
                                    "Parameter '%s' "
                                            + "has parser 'Either<?, %s>' but no parser exists "
                                            + "for that type",
                                    parameter.getName(),
                                    token.getType().getTypeName()
                            )));
            parser = EitherParser.eitherParser(primary, fallback).parser();
        } else if (descriptor.parserName() == null) {
            parser = this.annotationParser.manager().parserRegistry()
                    .createParser(token, parameters)
                    .orElseThrow(() -> new IllegalArgumentException(
                            String.format(
                                    "Parameter '%s' "
                                            + "has parser '%s' but no parser exists "
                                            + "for that type",
                                    parameter.getName(),
                                    token.getType().getTypeName()
                            )));
        } else {
            parser = this.annotationParser.manager().parserRegistry()
                    .createParser(this.annotationParser.processString(descriptor.parserName()), parameters)
                    .orElseThrow(() -> new IllegalArgumentException(
                            String.format(
                                    "Parameter '%s' "
                                            + "has parser '%s' but no parser exists "
                                            + "for that type",
                                    parameter.getName(),
                                    token.getType().getTypeName()
                            )));
        }
        /* Check whether the corresponding method parameter actually exists */
        final String argumentName = this.annotationParser.processString(descriptor.name());
        if (syntaxFragment.argumentMode() == ArgumentMode.LITERAL) {
            throw new IllegalArgumentException(String.format(
                    "Invalid command argument '%s': Missing syntax mapping", argumentName));
        }

        @SuppressWarnings("rawtypes") final CommandComponent.Builder componentBuilder = CommandComponent.builder();
        componentBuilder.commandManager(this.annotationParser.manager())
                .valueType(parameter.getType())
                .name(argumentName)
                .parser(parser)
                .required(syntaxFragment.argumentMode() == ArgumentMode.REQUIRED);

        /* Check for Completions annotation */
        final Completions completions = parameter.getDeclaredAnnotation(Completions.class);
        if (completions != null) {
            final List<Suggestion> suggestions = Arrays.stream(
                    completions.value().replace(" ", "").split(",")
            ).map(Suggestion::suggestion).collect(Collectors.toList());
            componentBuilder.suggestionProvider(SuggestionProvider.suggesting(suggestions));
        } else if (descriptor.suggestions() != null) {
            final String suggestionProviderName = this.annotationParser.processString(descriptor.suggestions());
            final Optional<SuggestionProvider<C>> suggestionsFunction =
                    this.annotationParser.manager().parserRegistry().getSuggestionProvider(suggestionProviderName);
            componentBuilder.suggestionProvider(
                    suggestionsFunction.orElseThrow(() ->
                            new IllegalArgumentException(String.format(
                                    "There is no suggestion provider with name '%s'. Did you forget to register it?",
                                    suggestionProviderName
                            )))
            );
        }

        if (descriptor.description() != null) {
            componentBuilder.description(descriptor.description());
        }

        if (syntaxFragment.argumentMode() == ArgumentMode.OPTIONAL && descriptor.defaultValue() != null) {
            componentBuilder.defaultValue(descriptor.defaultValue());
        }

        for (final Annotation annotation : annotations) {
            @SuppressWarnings("rawtypes") final PreprocessorMapper preprocessorMapper =
                    this.annotationParser.preprocessorMappers().get(annotation.annotationType());
            if (preprocessorMapper != null) {
                final ComponentPreprocessor<C> preprocessor = (ComponentPreprocessor<C>) preprocessorMapper.mapAnnotation(
                        annotation
                );
                componentBuilder.preprocessor(preprocessor);
            }
        }

        return componentBuilder.build();
    }
Creates a new argument assembler.

@param annotationParser annotation parser instance
cloud-annotations/src/main/java/org/incendo/cloud/annotations/assembler/ArgumentAssemblerImpl.java