class OakpalPlan implements JsonObjectConvertible {

    public OakMachine.Builder toOakMachineBuilder(final @Nullable ErrorListener errorListener,
                                                  final @NotNull ClassLoader classLoader) throws Exception {
        final ChecklistPlanner checklistPlanner = new ChecklistPlanner(checklists);
        checklistPlanner.discoverChecklists(classLoader);

        final List<ProgressCheck> allChecks;
        try {
            allChecks = new ArrayList<>(Locator.loadFromCheckSpecs(
                    checklistPlanner.getEffectiveCheckSpecs(checks), classLoader));
        } catch (final Exception e) {
            throw new Exception("Error while loading progress checks.", e);
        }

        final Locale locale = Locale.getDefault();
        for (final ProgressCheck progressCheck : allChecks) {
            initResourceBundle(progressCheck, locale, classLoader);
        }

        return new OakMachine.Builder()
                .withErrorListener(errorListener)
                .withProgressChecks(allChecks)
                .withInitStages(checklistPlanner.getInitStages())
                .withInitStage(toInitStage())
                .withPreInstallUrls(preInstallUrls)
                .withInstallHookPolicy(installHookPolicy)
                .withInstallHookClassLoader(classLoader)
                .withRunModes(new HashSet<>(getRunModes()))
                .withSlingSimulator(DefaultSlingSimulator.instance())
                .withEnablePreInstallHooks(enablePreInstallHooks);
    }

    private  OakpalPlan(final @Nullable URL base,
                       final @Nullable JsonObject originalJson,
                       final @NotNull String name,
                       final @NotNull List<String> runModes,
                       final @NotNull List<String> checklists,
                       final @NotNull List<URL> preInstallUrls,
                       final @NotNull List<JcrNs> jcrNamespaces,
                       final @NotNull List<QNodeTypeDefinition> jcrNodetypes,
                       final @NotNull List<PrivilegeDefinition> jcrPrivileges,
                       final @NotNull List<ForcedRoot> forcedRoots,
                       final @NotNull List<CheckSpec> checks,
                       final boolean enablePreInstallHooks,
                       final @Nullable InstallHookPolicy installHookPolicy,
                       final @NotNull List<URL> repoInitUrls,
                       final @NotNull List<String> repoInits);

}