protected void verifyCalculatorDependencyOrdering() {
        // Verify calculator dependencies ordering
        Set<String> seenCalculatedFields = new HashSet<>();
        for (FieldCalculator fieldCalculator: fieldCalculators) {
            for (String dependency: fieldCalculator.getDependencies()){
                if (allFieldsForWhichACalculatorExists.contains(dependency)) {
                    if (!seenCalculatedFields.contains(dependency)) {
                        throw new InvalidParserConfigurationException(
                            "Calculator ordering is wrong:" +
                                "For " + fieldCalculator.getCalculatedFieldName() +
                                " we need " + dependency + " which is a " +
                                "calculated field but it has not yet been calculated.");
                    }
                }
            }
            seenCalculatedFields.add(fieldCalculator.getCalculatedFieldName());
        }
    }
Parses and analyzes the useragent string provided in the MutableUserAgent instance.
NOTE: This method is internally synchronized because the way the analyzer works is not reentrant.
@param userAgent The MutableUserAgent instance that is to be parsed and that gets all results
@return An ImmutableUserAgent copy of the results that is suitable for further usage and caching.
analyzer/src/main/java/nl/basjes/parse/useragent/analyze/UserAgentStringMatchMaker.java