class CorsMatcher implements Matcher {

    private String allowOrigin;

    private String exposeHeaders;

    private int maxAge = -1;

    private Boolean allowCredentials;

    private Set<HttpConstants.HTTP_METHOD> allowMethods;

    private String allowHeaders;

    /** {@inheritDoc} */
    @Override
    public boolean matches(final CallContext ctx) {<FILL_FUNCTION_BODY>}
}

        val webContext = ctx.webContext();

        CommonHelper.assertNotBlank("allowOrigin", allowOrigin);

        webContext.setResponseHeader(HttpConstants.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, allowOrigin);

        if (CommonHelper.isNotBlank(exposeHeaders)) {
            webContext.setResponseHeader(HttpConstants.ACCESS_CONTROL_EXPOSE_HEADERS_HEADER, exposeHeaders);
        }

        if (maxAge != -1) {
            webContext.setResponseHeader(HttpConstants.ACCESS_CONTROL_MAX_AGE_HEADER, Pac4jConstants.EMPTY_STRING + maxAge);
        }

        if (allowCredentials != null && allowCredentials) {
            webContext.setResponseHeader(HttpConstants.ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER, allowCredentials.toString());
        }

        if (allowMethods != null) {
            val methods = allowMethods.stream().map(Enum::toString).collect(Collectors.joining(", "));
            webContext.setResponseHeader(HttpConstants.ACCESS_CONTROL_ALLOW_METHODS_HEADER, methods);
        }

        if (CommonHelper.isNotBlank(allowHeaders)) {
            webContext.setResponseHeader(HttpConstants.ACCESS_CONTROL_ALLOW_HEADERS_HEADER, allowHeaders);
        }

        return true;
    
<no_super_class>