static CorsLogic forAllowedOrigins(Collection<String> allowedOrigins) {
        Set<String> allowedOriginsVerbatim = new HashSet<>();
        List<Pattern> allowedOriginPatterns = new ArrayList<>();
        for (String allowedOrigin : allowedOrigins) {
            if (allowedOrigin.isBlank()) continue;
            if (allowedOrigin.length() > 0) {
                if ("*".equals(allowedOrigin))
                    return new CorsLogic(true, Set.of(), List.of());
                else if (allowedOrigin.contains("*"))
                    allowedOriginPatterns.add(Pattern.compile(allowedOrigin.replace(".", "\\.").replace("*", ".*")));
                else
                    allowedOriginsVerbatim.add(allowedOrigin);
            }
        }
        return new CorsLogic(false, allowedOriginsVerbatim, allowedOriginPatterns);
    }
@Test
    void matches_verbatim_and_pattern() {
        CorsLogic logic = CorsLogic.forAllowedOrigins(List.of("http://my.origin", "http://*.domain.origin", "*://do.main", "*.tld"));
        assertMatches(logic, true,
                "http://my.origin", // Matches verbatim
                "http://any.domain.origin", // Matches first pattern
                "http://any.sub.domain.origin", // Matches first pattern
                "http://do.main", "https://do.main", // Matches second pattern
                "https://any.thing.tld"); // Matches third pattern
        assertMatches(logic, false,
                "https://my.origin", // Different scheme from verbatim
                "http://domain.origin", // Missing subdomain to match the first pattern
                "https://sub.do.main"); // Second pattern, but with subdomain
    }