class HttpPathValidator {

    public static void validate(HttpPath httpPath) {
        Path path = Paths.get(httpPath.get());
        Preconditions.checkArgument(
                path.isAbsolute(), "Conjure paths must be absolute, i.e., start with '/': %s", path);
        Preconditions.checkArgument(
                path.getSegments().isEmpty() || !path.isFolder(), "Conjure paths must not end with a '/': %s", path);

        for (String segment : path.getSegments()) {
            Preconditions.checkArgument(
                    SEGMENT_PATTERN.matcher(segment).matches()
                            || PARAM_SEGMENT_PATTERN.matcher(segment).matches()
                            || PARAM_REGEX_SEGMENT_PATTERN.matcher(segment).matches(),
                    "Segment %s of path %s did not match required segment patterns %s or parameter name "
                            + "patterns %s or %s",
                    segment,
                    path,
                    SEGMENT_PATTERN,
                    PARAM_SEGMENT_PATTERN,
                    PARAM_REGEX_SEGMENT_PATTERN);
        }

        // verify that path template variables are unique
        Set<String> templateVars = new HashSet<>();
        new UriTemplate(path.toString()).getTemplateVariables().forEach(var -> {
            Preconditions.checkState(
                    !templateVars.contains(var), "Path parameter %s appears more than once in path %s", var, path);
            templateVars.add(var);
        });

        UriTemplateParser uriTemplateParser = new UriTemplateParser(path.toString());
        Map<String, Pattern> nameToPattern = uriTemplateParser.getNameToPattern();
        List<String> segments = Splitter.on('/').splitToList(uriTemplateParser.getNormalizedTemplate());
        for (int i = 0; i < segments.size(); i++) {
            String segment = segments.get(i);
            if (!(segment.startsWith("{") && segment.endsWith("}"))) {
                // path literal
                continue;
            }

            // variable
            Pattern varPattern = nameToPattern.get(segment.substring(1, segment.length() - 1));
            if (varPattern.equals(UriTemplateParser.TEMPLATE_VALUE_PATTERN)) {
                // no regular expression specified -- OK
                continue;
            }

            // if regular expression was specified, it must be ".+" or ".*" based on invariant previously enforced
            Preconditions.checkState(
                    i == segments.size() - 1 || !varPattern.pattern().equals(".*"),
                    "Path parameter %s in path %s specifies regular expression %s, but this regular "
                            + "expression is only permitted if the path parameter is the last segment",
                    segment,
                    path,
                    varPattern);
        }
    }

    private  HttpPathValidator();

}