private List<ValidationEvent> validateMember(
            OperationIndex opIndex,
            Model model,
            ServiceShape service,
            OperationShape operation,
            PaginatedTrait trait,
            PropertyValidator validator
    ) {
        String prefix = service != null ? "When bound within the `" + service.getId() + "` service, " : "";
        String memberPath = validator.getMemberPath(opIndex, operation, trait).orElse(null);

        if (memberPath == null) {
            return service != null && validator.isRequiredToBePresent()
                    ? Collections.singletonList(error(operation,
                            trait,
                            String.format(
                                    "%spaginated trait `%s` is not configured",
                                    prefix,
                                    validator.propertyName())))
                    : Collections.emptyList();
        }

        if (!validator.pathsAllowed() && memberPath.contains(".")) {
            return Collections.singletonList(error(operation,
                    trait,
                    String.format(
                            "%spaginated trait `%s` does not allow path values",
                            prefix,
                            validator.propertyName())));
        }

        MemberShape member = validator.getMember(model, opIndex, operation, trait).orElse(null);
        if (member == null) {
            return Collections.singletonList(error(operation,
                    trait,
                    String.format(
                            "%spaginated trait `%s` targets a member `%s` that does not exist",
                            prefix,
                            validator.propertyName(),
                            memberPath)));
        }

        List<ValidationEvent> events = new ArrayList<>();
        if (validator.mustBeOptional() && member.isRequired()) {
            events.add(error(operation,
                    trait,
                    String.format(
                            "%spaginated trait `%s` member `%s` must not be required",
                            prefix,
                            validator.propertyName(),
                            member.getMemberName())));
        }

        Shape target = model.getShape(member.getTarget()).orElse(null);
        if (target != null) {
            if (!validator.validTargets().contains(target.getType())) {
                events.add(error(operation,
                        trait,
                        String.format(
                                "%spaginated trait `%s` member `%s` targets a %s shape, but must target one of "
                                        + "the following: [%s]",
                                prefix,
                                validator.propertyName(),
                                member.getId().getMember().get(),
                                target.getType(),
                                ValidationUtils.tickedList(validator.validTargets()))));
            }
            if (validator.dangerTargets().contains(target.getType())) {
                Set<ShapeType> preferredTargets = new TreeSet<>(validator.validTargets());
                preferredTargets.removeAll(validator.dangerTargets());
                String traitName = validator.propertyName();
                String memberName = member.getId().getMember().get();
                String targetType = target.getType().toString();
                events.add(danger(operation,
                        trait,
                        String.format(
                                "%spaginated trait `%s` member `%s` targets a %s shape, but this is not recommended. "
                                        + "One of [%s] SHOULD be targeted.",
                                prefix,
                                traitName,
                                memberName,
                                targetType,
                                ValidationUtils.tickedList(preferredTargets)),
                        WRONG_SHAPE_TYPE,
                        traitName));
            }
        }

        if (validator.pathsAllowed() && PATH_PATTERN.split(memberPath).length > 2) {
            events.add(warning(operation,
                    trait,
                    String.format(
                            "%spaginated trait `%s` contains a path with more than two parts, which can make your API "
                                    + "cumbersome to use",
                            prefix,
                            validator.propertyName()),
                    DEEPLY_NESTED,
                    validator.propertyName()));
        }

        return events;
    }
Validates paginated traits.

<ul>
    <li>The inputToken and outputToken properties must be set when an
     operation's properties are optionally merged with a service's.</li>
    <li>The items property, if set, must reference a list or map
     output member.</li>
    <li>The pageSize property, if set, should reference an optional integer
     input member. It may, but should not reference an optional byte, short,
     or long.</li>
    <li>The inputToken property should reference an optional string input
     member. It may, but should not reference an optional map.</li>
    <li>The outputToken property should reference an optional string output
     member. It may, but should not reference an optional map.</li>
</ul>
smithy-model/src/main/java/software/amazon/smithy/model/validation/validators/PaginatedTraitValidator.java