class BasicParamPreparer implements ParamPreparer {

    @Override
    public PreparedParameter prepare(ParameterFromRepository parameterFromRepository) {
        Parameter parameter = parameterFromRepository.parameter();

        int levelCount = getLevelCount(parameter);
        PreparedLevel[] levels = new PreparedLevel[levelCount];
        Type<?>[] types = new Type<?>[levelCount];
        Matcher[] matchers = new Matcher[levelCount];

        for (int currentLevelIndex = 0; currentLevelIndex < levelCount; currentLevelIndex++) {
            Level level = getLevel(parameter, currentLevelIndex);
            PreparedLevel preparedLevel = levelPreparer.prepare(level);

            levels[currentLevelIndex] = preparedLevel;
            types[currentLevelIndex] = preparedLevel.getType();
            matchers[currentLevelIndex] = preparedLevel.getMatcher();
        }

        PreparedParameter preparedParameter = new PreparedParameter(parameterFromRepository.repositoryName(), parameter, levels);
        preparedParameter.setLevelNameMap(buildLevelNameToIndexMap(preparedParameter));

        if (parameter.isCacheable()) {
            preparedParameter.setIndex(buildIndex(parameter, types, matchers));
        }

        return preparedParameter;
    }

    public  BasicParamPreparer(LevelPreparer levelPreparer);

}