private void loadYamlTestcase(MappingNode entry, String filename) {
        if (!doingOnlyASingleTest) {
            String testName = null;
            List<String> options = null;
            Map<String, String> expected = new LinkedHashMap<>();
            Map<String, String> headers =  new LinkedHashMap<>();

            for (NodeTuple tuple : entry.getValue()) {
                String name = getKeyAsString(tuple, filename);
                switch (name) {
                    case "name":
                        testName = getValueAsString(tuple, filename);
                        break;
                    case "options":
                        options = getStringValues(tuple.getValueNode(), filename);
                        if (options.contains("only")) {
                            doingOnlyASingleTest = true;
                            analyzerConfig.clearAllTestCases();
                        }
                        break;
                    case "input":
                        for (NodeTuple inputTuple : getValueAsMappingNode(tuple, filename).getValue()) {
                            String inputName = getKeyAsString(inputTuple, filename);
                            switch (inputName) {
                                case "user_agent_string":
                                case USERAGENT_HEADER:
                                    headers.put(USERAGENT_HEADER, getValueAsString(inputTuple, filename));
                                    break;
                                case "name":
                                    LOG.fatal("FOUND TEST NAME IN INPUT SECTION {}", filename);
                                    testName = getValueAsString(inputTuple, filename);
                                    break;
                                default:
                                    headers.put(inputName, getValueAsString(inputTuple, filename));
                                    break;
                            }
                        }
                        break;
                    case "expected":
                        List<NodeTuple> mappings = getValueAsMappingNode(tuple, filename).getValue();
                        for (NodeTuple mapping : mappings) {
                            String key = getKeyAsString(mapping, filename);
                            String value = getValueAsString(mapping, filename);
                            expected.put(key, value);
                        }
                        break;
                    default:
                        // Ignore
                        break;
                }
            }

            final String lowercaseUseragentHeader = USERAGENT_HEADER.toLowerCase(Locale.ROOT);
            require(headers.keySet().stream().map(String::toLowerCase).filter(lowercaseUseragentHeader::equals).count() == 1, entry, filename, "Test is missing input");

            if (testName == null) {
                testName = headers.get(USERAGENT_HEADER);
            }

            int testSourceLineNumber = entry.getStartMark().getLine();
            String testSourceLocation = filename + ':' + testSourceLineNumber;

            TestCase testCase = new TestCase(headers, testSourceLocation, testName);

            if (!expected.isEmpty()) {
                expected.forEach(testCase::expect);
            }
            if (options != null) {
                for (String option: options) {
                    testCase.addOption(option);
                }
            }
            testCase.addMetadata("filename", filename);
            testCase.addMetadata("fileline", String.valueOf(entry.getStartMark().getLine()));

            analyzerConfig.addTestCase(testCase);
        }

    }
/*.yaml";
    private boolean doingOnlyASingleTest = false;

    private final List<String>          mandatoryResources;
    private final List<String>          optionalResources;
    private final AnalyzerConfig.AnalyzerConfigBuilder analyzerConfig;

    // Map from filename to yaml config string.
    private final Map<String, String>          yamlRules;

    private boolean keepTests = true;

    final boolean showLoading;

    // ------------------------------------------

    public ConfigLoader(boolean showLoading) {
        this.showLoading = showLoading;
        mandatoryResources = new ArrayList<>();
        optionalResources  = new ArrayList<>();
        yamlRules          = new LinkedHashMap<>();
        analyzerConfig = AnalyzerConfig.newBuilder();
    }

    public ConfigLoader addResource(List<String> resourceNames, boolean optionalResource) {
        resourceNames.forEach(resource -> this.addResource(resource, optionalResource));
        return this;
    }

    public ConfigLoader addResource(String resourceName, boolean optionalResource){
        if (resourceName== null) {
            throw new InvalidParserConfigurationException("The provided resource name was null.");
        }
        if (resourceName.trim().isEmpty()) {
            throw new InvalidParserConfigurationException("The provided resource name was empty.");
        }
        if (optionalResource) {
            optionalResources.add(resourceName);
        } else {
            mandatoryResources.add(resourceName);
        }
        return this;
    }

    public ConfigLoader addYaml(String configString, String filename) {
        yamlRules.put(filename, configString);
        return this;
    }

    public ConfigLoader keepTests(boolean doWeKeepThem){
        this.keepTests = doWeKeepThem;
        return this;
    }

    public ConfigLoader keepTests(){
        this.keepTests = true;
        return this;
    }

    public ConfigLoader dropTests(){
        this.keepTests = false;
        return this;
    }




    // ------------------------------------------

    public AnalyzerConfig load(){
        mandatoryResources.forEach(resourceString -> loadResources(resourceString, showLoading, false));
        optionalResources.forEach(resourceString -> loadResources(resourceString, showLoading, true));

        Yaml yaml = createYaml();
        yamlRules.forEach(
            (filename, yamlString) -> loadYaml(yaml, new ByteArrayInputStream(yamlString.getBytes(UTF_8)), filename)
        );

        return analyzerConfig.build();
    }

    // ------------------------------------------

    public void loadResources(String resourceString, boolean showLoadMessages, boolean areOptional) {
        long startFiles = System.nanoTime();
        final boolean loadingDefaultResources = DEFAULT_RESOURCES.equals(resourceString);
        Map<String, Resource> resources = findAllResources(resourceString, showLoadMessages, areOptional, loadingDefaultResources);

        doingOnlyASingleTest = false;

        // When using a framework like Quarkus loading resources can fail in mysterious ways.
        // Just trying to open a stream for one of the resources is enough to see if we can continue.
        if (!resources.isEmpty()) {
            Resource resource = resources.entrySet().iterator().next().getValue();
            try (InputStream ignored = resource.getInputStream()) {
                // Just seeing if opening this stream triggers an error.
                // Having a useless statement that references the 'ignored' to avoid checkstyle and compilation warnings.
                LOG.debug("Opening the resource worked. {}", ignored);
            } catch (IOException e) {
                LOG.error("Cannot load the resources (usually classloading problem).");
                LOG.error("- Resource   : {}", resource);
                LOG.error("- Filename   : {}", resource.getFilename());
                LOG.error("- Description: {}", resource.getDescription());
                if (loadingDefaultResources) {
                    LOG.warn("Falling back to the built in list of resources");
                    resources.clear();
                } else {
                    LOG.error("FATAL: Unable to load the specified resources for {}", resourceString);
                    throw new InvalidParserConfigurationException("Error reading resources (" + resourceString + "): " + e.getMessage(), e);
                }
            }
        }

        if (resources.isEmpty()) {
            if (areOptional) {
                LOG.warn("NO optional resources were loaded from expression: {}", resourceString);
            } else {
                LOG.error("NO config files were found matching this expression: {}", resourceString);

                if (loadingDefaultResources) {
                    LOG.warn("Unable to load the default resources, usually caused by classloader problems.");
                    LOG.warn("Retrying with built in list.");
                    PackagedRules.getRuleFileNames().forEach(s -> loadResources(s, false, false));
                } else {
                    LOG.warn("If you are using wildcards in your expression then try explicitly naming all yamls files explicitly.");
                    throw new InvalidParserConfigurationException("There were no resources found for the expression: " + resourceString);
                }
            }
            return;
        }

        // So now we have the resources.
        // Do we keep the tests ?
        if (!keepTests) {
            resources = resources
                .entrySet()
                .stream()
                .filter(entry -> {
                    Resource resource = entry.getValue();
                    if (isTestRulesOnlyFile(resource.getFilename())) {
                        if (showLoadMessages) {
                            try {
                                LOG.info("- Skipping tests only file {} ({} bytes)", resource.getFilename(), resource.contentLength());
                            } catch (IOException e) {
                                // Ignore
                            }
                        }
                        return false;
                    }
                    return true;
                })
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

            if (resources.isEmpty()) {
                return;
            }
        }

        // We need to determine if we are trying to load the yaml files TWICE.
        // This can happen if the library is loaded twice (perhaps even two different versions).
        Set<String> resourceBasenames = resources
            .keySet().stream()
            .map(k -> k.replaceAll("^.
analyzer/src/main/java/nl/basjes/parse/useragent/config/ConfigLoader.java