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 testBackwardFunction() {
        CustomModel customModel = new CustomModel();
        customModel.addToPriority(If("backward_car_access != car_access", MULTIPLY, "0.5"));
        customModel.addToSpeed(If("true", LIMIT, "100"));
        CustomWeighting.EdgeToDoubleMapping priorityMapping = CustomModelParser.createWeightingParameters(customModel, encodingManager).
                getEdgeToPriorityMapping();

        BaseGraph graph = new BaseGraph.Builder(encodingManager).create();
        EdgeIteratorState edge1 = graph.edge(0, 1).setDistance(100).set(accessEnc, true, false);
        EdgeIteratorState edge2 = graph.edge(1, 2).setDistance(100).set(accessEnc, true, true);

        assertEquals(0.5, priorityMapping.get(edge1, false), 1.e-6);
        assertEquals(1.0, priorityMapping.get(edge2, false), 1.e-6);
    }