class DefaultToolchainsBuilder implements ToolchainsBuilder {

    private final MavenToolchainsMerger toolchainsMerger = new MavenToolchainsMerger();

    @Override
    public ToolchainsBuilderResult build(ToolchainsBuilderRequest request) throws ToolchainsBuilderException {
        List<BuilderProblem> problems = new ArrayList<>();

        Source globalSource = request.getGlobalToolchainsSource().orElse(null);
        PersistedToolchains global = readToolchains(globalSource, request, problems);

        Source userSource = request.getUserToolchainsSource().orElse(null);
        PersistedToolchains user = readToolchains(userSource, request, problems);

        PersistedToolchains effective = toolchainsMerger.merge(user, global, false, null);

        if (hasErrors(problems)) {
            throw new ToolchainsBuilderException("Error building toolchains", problems);
        }

        return new DefaultToolchainsBuilderResult(effective, problems);
    }

    private boolean hasErrors(List<BuilderProblem> problems) {
        if (problems != null) {
            for (BuilderProblem problem : problems) {
                if (BuilderProblem.Severity.ERROR.compareTo(problem.getSeverity()) >= 0) {
                    return true;
                }
            }
        }

        return false;
    }

    private PersistedToolchains readToolchains(
            Source toolchainsSource, ToolchainsBuilderRequest request, List<BuilderProblem> problems) {<FILL_FUNCTION_BODY>}

    private PersistedToolchains interpolate(
            PersistedToolchains toolchains, ToolchainsBuilderRequest request, List<BuilderProblem> problems) {

        RegexBasedInterpolator interpolator = new RegexBasedInterpolator();

        interpolator.addValueSource(new MapBasedValueSource(request.getSession().getUserProperties()));

        interpolator.addValueSource(new MapBasedValueSource(request.getSession().getSystemProperties()));

        try {
            interpolator.addValueSource(new EnvarBasedValueSource());
        } catch (IOException e) {
            problems.add(new DefaultBuilderProblem(
                    null,
                    -1,
                    -1,
                    e,
                    "Failed to use environment variables for interpolation: " + e.getMessage(),
                    BuilderProblem.Severity.WARNING));
        }

        return new MavenToolchainsTransformer(value -> {
                    try {
                        return value != null ? interpolator.interpolate(value) : null;
                    } catch (InterpolationException e) {
                        problems.add(new DefaultBuilderProblem(
                                null,
                                -1,
                                -1,
                                e,
                                "Failed to interpolate toolchains: " + e.getMessage(),
                                BuilderProblem.Severity.WARNING));
                        return value;
                    }
                })
                .visit(toolchains);
    }

    /**
     * Collects the output of the toolchains builder.
     *
     */
    static class DefaultToolchainsBuilderResult implements ToolchainsBuilderResult {

        private final PersistedToolchains effectiveToolchains;

        private final List<BuilderProblem> problems;

        DefaultToolchainsBuilderResult(PersistedToolchains effectiveToolchains, List<BuilderProblem> problems) {
            this.effectiveToolchains = effectiveToolchains;
            this.problems = (problems != null) ? problems : new ArrayList<>();
        }

        @Override
        public PersistedToolchains getEffectiveToolchains() {
            return effectiveToolchains;
        }

        @Override
        public List<BuilderProblem> getProblems() {
            return problems;
        }
    }
}

        if (toolchainsSource == null) {
            return PersistedToolchains.newInstance();
        }

        PersistedToolchains toolchains;

        try {
            try {
                InputStream is = toolchainsSource.openStream();
                if (is == null) {
                    return PersistedToolchains.newInstance();
                }
                toolchains = request.getSession()
                        .getService(ToolchainsXmlFactory.class)
                        .read(XmlReaderRequest.builder()
                                .inputStream(is)
                                .location(toolchainsSource.getLocation())
                                .strict(true)
                                .build());
            } catch (XmlReaderException e) {
                InputStream is = toolchainsSource.openStream();
                if (is == null) {
                    return PersistedToolchains.newInstance();
                }
                toolchains = request.getSession()
                        .getService(ToolchainsXmlFactory.class)
                        .read(XmlReaderRequest.builder()
                                .inputStream(is)
                                .location(toolchainsSource.getLocation())
                                .strict(false)
                                .build());
                Location loc = e.getCause() instanceof XMLStreamException xe ? xe.getLocation() : null;
                problems.add(new DefaultBuilderProblem(
                        toolchainsSource.getLocation(),
                        loc != null ? loc.getLineNumber() : -1,
                        loc != null ? loc.getColumnNumber() : -1,
                        e,
                        e.getMessage(),
                        BuilderProblem.Severity.WARNING));
            }
        } catch (XmlReaderException e) {
            Location loc = e.getCause() instanceof XMLStreamException xe ? xe.getLocation() : null;
            problems.add(new DefaultBuilderProblem(
                    toolchainsSource.getLocation(),
                    loc != null ? loc.getLineNumber() : -1,
                    loc != null ? loc.getColumnNumber() : -1,
                    e,
                    "Non-parseable toolchains " + toolchainsSource.getLocation() + ": " + e.getMessage(),
                    BuilderProblem.Severity.FATAL));
            return PersistedToolchains.newInstance();
        } catch (IOException e) {
            problems.add(new DefaultBuilderProblem(
                    toolchainsSource.getLocation(),
                    -1,
                    -1,
                    e,
                    "Non-readable toolchains " + toolchainsSource.getLocation() + ": " + e.getMessage(),
                    BuilderProblem.Severity.FATAL));
            return PersistedToolchains.newInstance();
        }

        toolchains = interpolate(toolchains, request, problems);

        return toolchains;
    
<no_super_class>