class ServletMessageSupplier extends MessageSupplier implements ServletRequestInfo {

    static @Nullable String maskRequestQueryString(@Nullable String requestQueryString,
            List<Pattern> maskPatterns) {
        if (requestQueryString == null) {
            return null;
        }
        if (maskPatterns.isEmpty()) {
            return requestQueryString;
        }
        StringBuilder sb = new StringBuilder(requestQueryString.length());
        boolean existMaskedParameters = false;
        int keyStartIndex = 0;
        boolean inMaskedValue = false;
        for (int i = 0; i < requestQueryString.length(); i++) {
            char c = requestQueryString.charAt(i);
            switch (c) {
                case '&':
                    sb.append('&');
                    keyStartIndex = sb.length();
                    inMaskedValue = false;
                    break;
                case '=':
                    if (keyStartIndex == -1) {
                        // not in key
                        if (!inMaskedValue) {
                            sb.append(c);
                        }
                    } else {
                        String key = sb.substring(keyStartIndex, sb.length());
                        sb.append('=');
                        // converted to lower case for case-insensitive matching
                        // (patterns are lower case)
                        String keyLowerCase = key.toLowerCase(Locale.ENGLISH);
                        if (DetailCapture.matchesOneOf(keyLowerCase, maskPatterns)) {
                            inMaskedValue = true;
                            sb.append(MASK_TEXT);
                            existMaskedParameters = true;
                        }
                        keyStartIndex = -1;
                    }
                    break;
                default:
                    if (!inMaskedValue) {
                        sb.append(c);
                    }
            }
        }
        if (existMaskedParameters) {
            return sb.toString();
        } else {
            // save the expense of toString() in common case
            return requestQueryString;
        }
    }

    public  ServletMessageSupplier(String requestMethod, String requestContextPath,
            String requestServletPath, @Nullable String requestPathInfo, String requestUri,
            @Nullable String requestQueryString, Map<String, Object> requestHeaders,
            @Nullable RequestHostAndPortDetail requestHostAndPortDetail,
            Map<String, String> sessionAttributeMap);

}