class ParametersUtil {

    public static Map<String, ParametersMap> buildSearchParametersMapFromBundle(Bundle bundle) {
        Map<String, ParametersMap> typeToParamMap = new HashMap<>();

        for (Bundle.Entry entry : bundle.getEntry()) {
            SearchParameter parameter = entry.getResource().as(SearchParameter.class);

            // Conditional Logging intentionally avoids forming of the String.
            if (log.isLoggable(Level.FINE)) {
                log.fine(String.format(LOG_PARAMETERS, parameter.getCode().getValue()));
            }

            if (parameter.getExpression() == null || !parameter.getExpression().hasValue()) {
                if (log.isLoggable(Level.FINE)) {
                    log.fine(String.format(MISSING_EXPRESSION, parameter.getCode().getValue()));
                }
            } else {
                /*
                 * In R4, SearchParameter changes from a single Base resource to an array.
                 * As Base is an array, there are going be potential collisions in the map.
                 */
                List<ResourceType> types = parameter.getBase();
                for (ResourceType type : types) {
                    String base = type.getValue();

                    ParametersMap map = typeToParamMap.get(base);
                    if (map == null) {
                        map = new ParametersMap();
                        typeToParamMap.put(base, map);
                    }

                    // check and warn if the parameter name and code do not agree.
                    String code = parameter.getCode().getValue();
                    String name = parameter.getName().getValue();
                    checkAndWarnForIssueWithCodeAndName(code, name);

                    // add the map entry with keys for both the code and the url
                    map.insert(code, parameter);
                }
            }
        }

        // Return an unmodifiable copy, lest there be side effects.
        return Collections.unmodifiableMap(typeToParamMap);
    }

    private  ParametersUtil();

}