public static CustomWeighting.Parameters createWeightingParameters(CustomModel customModel, EncodedValueLookup lookup) {
        String key = customModel.toString();
        Class<?> clazz = customModel.isInternal() ? INTERNAL_CACHE.get(key) : null;
        if (CACHE_SIZE > 0 && clazz == null)
            clazz = CACHE.get(key);
        if (clazz == null) {
            clazz = createClazz(customModel, lookup);
            if (customModel.isInternal()) {
                INTERNAL_CACHE.put(key, clazz);
                if (INTERNAL_CACHE.size() > 100) {
                    CACHE.putAll(INTERNAL_CACHE);
                    INTERNAL_CACHE.clear();
                    LoggerFactory.getLogger(CustomModelParser.class).warn("Internal cache must stay small but was "
                            + INTERNAL_CACHE.size() + ". Cleared it. Misuse of CustomModel::internal?");
                }
            } else if (CACHE_SIZE > 0) {
                CACHE.put(key, clazz);
            }
        }

        try {
            // The class does not need to be thread-safe as we create an instance per request
            CustomWeightingHelper prio = (CustomWeightingHelper) clazz.getDeclaredConstructor().newInstance();
            prio.init(customModel, lookup, CustomModel.getAreasAsMap(customModel.getAreas()));
            return new CustomWeighting.Parameters(
                    prio::getSpeed, prio::calcMaxSpeed,
                    prio::getPriority, prio::calcMaxPriority,
                    customModel.getDistanceInfluence() == null ? 0 : customModel.getDistanceInfluence(),
                    customModel.getHeadingPenalty() == null ? Parameters.Routing.DEFAULT_HEADING_PENALTY : customModel.getHeadingPenalty());
        } catch (ReflectiveOperationException ex) {
            throw new IllegalArgumentException("Cannot compile expression " + ex.getMessage(), ex);
        }
    }
@Test
    void testPriority() {
        EdgeIteratorState primary = graph.edge(0, 1).setDistance(10).
                set(roadClassEnc, PRIMARY).set(avgSpeedEnc, 80).set(accessEnc, true, true);
        EdgeIteratorState secondary = graph.edge(1, 2).setDistance(10).
                set(roadClassEnc, SECONDARY).set(avgSpeedEnc, 70).set(accessEnc, true, true);
        EdgeIteratorState tertiary = graph.edge(1, 2).setDistance(10).
                set(roadClassEnc, TERTIARY).set(avgSpeedEnc, 70).set(accessEnc, true, true);

        CustomModel customModel = new CustomModel();
        customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "0.5"));
        customModel.addToPriority(ElseIf("road_class == SECONDARY", MULTIPLY, "0.7"));
        customModel.addToPriority(Else(MULTIPLY, "0.9"));
        customModel.addToPriority(If("road_environment != FERRY", MULTIPLY, "0.8"));
        customModel.addToSpeed(If("true", LIMIT, "100"));
        CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager).getEdgeToPriorityMapping();

        assertEquals(0.5 * 0.8, priorityMapping.get(primary, false), 0.01);
        assertEquals(0.7 * 0.8, priorityMapping.get(secondary, false), 0.01);
        assertEquals(0.9 * 0.8, priorityMapping.get(tertiary, false), 0.01);

        // force integer value
        customModel = new CustomModel();
        customModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, "1"));
        customModel.addToPriority(If("road_class == SECONDARY", MULTIPLY, "0.9"));
        customModel.addToSpeed(If("true", LIMIT, "100"));
        priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager).getEdgeToPriorityMapping();
        assertEquals(1, priorityMapping.get(primary, false), 0.01);
        assertEquals(0.9, priorityMapping.get(secondary, false), 0.01);
    }