/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.java.j2semodule;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.annotations.common.NullAllowed;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.classpath.JavaClassPathConstants;
import org.netbeans.api.java.platform.JavaPlatform;
import org.netbeans.api.java.project.classpath.ProjectClassPathModifier;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectManager;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.api.project.Sources;
import org.netbeans.api.project.ant.AntBuildExtender;
import org.netbeans.modules.java.api.common.ModuleRoots;
import org.netbeans.modules.java.api.common.Roots;
import org.netbeans.modules.java.api.common.SourceRoots;
import org.netbeans.modules.java.api.common.ant.UpdateHelper;
import org.netbeans.modules.java.api.common.classpath.ClassPathModifier;
import org.netbeans.modules.java.api.common.classpath.MultiModuleClassPathProvider;
import org.netbeans.modules.java.api.common.project.JavaActionProvider;
import org.netbeans.modules.java.api.common.project.MultiModuleActionProviderBuilder;
import org.netbeans.modules.java.api.common.project.ProjectConfigurations;
import org.netbeans.modules.java.api.common.project.ProjectHooks;
import org.netbeans.modules.java.api.common.project.ProjectOperations;
import org.netbeans.modules.java.api.common.project.ProjectProperties;
import org.netbeans.modules.java.api.common.project.PropertyEvaluatorProvider;
import org.netbeans.modules.java.api.common.project.ui.LogicalViewProviders;
import org.netbeans.modules.java.api.common.queries.QuerySupport;
import org.netbeans.modules.java.api.common.util.CommonProjectUtils;
import org.netbeans.modules.java.j2semodule.ui.customizer.CustomizerProviderImpl;
import org.netbeans.modules.java.j2semodule.ui.customizer.J2SECompositePanelProvider;
import org.netbeans.modules.java.j2semodule.ui.customizer.J2SEModularProjectProperties;
import org.netbeans.spi.java.project.support.ExtraSourceJavadocSupport;
import org.netbeans.spi.java.project.support.LookupMergerSupport;
import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
import org.netbeans.spi.project.ActionProvider;
import org.netbeans.spi.project.AuxiliaryConfiguration;
import org.netbeans.spi.project.ant.AntBuildExtenderFactory;
import org.netbeans.spi.project.support.LookupProviderSupport;
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
import org.netbeans.spi.project.support.ant.AntBasedProjectRegistration;
import org.netbeans.spi.project.support.ant.AntProjectHelper;
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
import org.netbeans.spi.project.support.ant.ReferenceHelper;
import org.netbeans.spi.project.ui.PrivilegedTemplates;
import org.netbeans.spi.project.ui.RecommendedTemplates;
import org.netbeans.spi.project.ui.support.UILookupMergerSupport;
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
import org.netbeans.spi.whitelist.support.WhiteListQueryMergerSupport;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.Mutex;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import org.openide.util.HelpCtx;
import org.openide.util.Pair;
import org.openide.util.Parameters;
import org.openide.util.Utilities;
/**
 * Represents one plain J2SE modular project.
 * @author Jesse Glick, et al.
 */
@AntBasedProjectRegistration(
    type=J2SEModularProject.TYPE,
    iconResource="org/netbeans/modules/java/j2semodule/ui/resources/j2seModuleProject.png", // NOI18N
    sharedName=J2SEModularProject.PROJECT_CONFIGURATION_NAME,
    sharedNamespace= J2SEModularProject.PROJECT_CONFIGURATION_NAMESPACE,
    privateName=J2SEModularProject.PRIVATE_CONFIGURATION_NAME,
    privateNamespace= J2SEModularProject.PRIVATE_CONFIGURATION_NAMESPACE
)
public final class J2SEModularProject implements Project {

    public static final String TYPE = "org.netbeans.modules.java.j2semodule"; // NOI18N
    static final String PROJECT_CONFIGURATION_NAME = "data"; // NOI18N
    public static final String PROJECT_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/j2se-modular-project/1"; // NOI18N
    static final String PRIVATE_CONFIGURATION_NAME = "data"; // NOI18N
    static final String PRIVATE_CONFIGURATION_NAMESPACE = "http://www.netbeans.org/ns/j2se-modular-project-private/1"; // NOI18N

    private static final String[] EXTENSIBLE_TARGETS = new String[] {
        "-do-init",             //NOI18N
        "-init-check",          //NOI18N
        "-post-clean",          //NOI18N
        "-pre-pre-compile",     //NOI18N
        "-do-compile",          //NOI18N
        "-do-compile-single",   //NOI18N
        "jar",                  //NOI18N
        "-post-jar",            //NOI18N
        "run",                  //NOI18N
        "debug",                //NOI18N
        "profile",              //NOI18N
    };
    private static final Icon J2SE_MODULE_PROJECT_ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/java/j2semodule/ui/resources/j2seModuleProject.png", false); // NOI18N
    private static final Logger LOG = Logger.getLogger(J2SEModularProject.class.getName());

    private final AuxiliaryConfiguration aux;
    private final AntProjectHelper helper;
    private final PropertyEvaluator eval;
    private final ReferenceHelper refHelper;
    private final GeneratedFilesHelper genFilesHelper;
    private Lookup lookup;
    private final UpdateHelper updateHelper;
    private SourceRoots sourceRoots;
    private SourceRoots testRoots;
    private ModuleRoots moduleRoots;
    private ModuleRoots testModuleRoots;
    private final MultiModuleClassPathProvider cpProvider;
    private final ClassPathModifier cpMod;
    private MainClassUpdater mainClassUpdater;
    private AntBuildExtender buildExtender;

    /**
     * @see J2SEProject.ProjectXmlSavedHookImpl#projectXmlSaved()
     */
    private final ThreadLocal<Boolean> projectPropertiesSave;

    @SuppressWarnings("LeakingThisInConstructor")
    public J2SEModularProject(AntProjectHelper helper) throws IOException {
        this.projectPropertiesSave = new ThreadLocal<Boolean>() {
            @Override
            protected Boolean initialValue() {
                return Boolean.FALSE;
            }
        };
        this.helper = helper;
        aux = helper.createAuxiliaryConfiguration();
        UpdateProjectImpl updateProject = new UpdateProjectImpl(this, helper, aux);
        this.updateHelper = new UpdateHelper(updateProject, helper);
        eval = ProjectConfigurations.createPropertyEvaluator(this, helper);
        for (int v = 2; v < 10; v++) {
            if (aux.getConfigurationFragment("data", "http://www.netbeans.org/ns/j2se-modular-project/" + v, true) != null) { // NOI18N
                throw Exceptions.attachLocalizedMessage(new IOException("too new"), // NOI18N
                        NbBundle.getMessage(J2SEModularProject.class, "J2SEModularProject.too_new", FileUtil.getFileDisplayName(helper.getProjectDirectory())));
            }
        }
        refHelper = new ReferenceHelper(helper, aux, evaluator());
        buildExtender = AntBuildExtenderFactory.createAntExtender(new J2SEModularExtenderImplementation(), refHelper);
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);

        this.cpProvider = MultiModuleClassPathProvider.Builder.newInstance(
                helper,
                evaluator(),
                getModuleRoots(),
                getSourceRoots(),
                getTestModuleRoots(),
                getTestSourceRoots())
                .build();
        this.cpMod = new ClassPathModifier(this, this.updateHelper, evaluator(), refHelper, null, createClassPathModifierCallback(), null);
        lookup = createLookup(aux, newProjectOperationsCallback(this, updateProject));
    }

    private ClassPathModifier.Callback createClassPathModifierCallback() {
        return new ClassPathModifier.Callback() {
            @Override
            public String getClassPathProperty(SourceGroup sg, String type) {
                assert sg != null : "SourceGroup cannot be null";  //NOI18N
                assert type != null : "Type cannot be null";  //NOI18N
                final String[] classPathProperty = getClassPathProvider().getPropertyName (sg, type);
                if (classPathProperty == null || classPathProperty.length == 0) {
                    throw new UnsupportedOperationException ("Modification of [" + sg.getRootFolder().getPath() +", " + type + "] is not supported"); //NOI18N
                }
                return classPathProperty[0];
            }

            @Override
            public String getElementName(String classpathProperty) {
                return null;
            }
        };
    }

    /**
     * Returns the project directory
     * @return the directory the project is located in
     */
    @Override
    public FileObject getProjectDirectory() {
        return helper.getProjectDirectory();
    }

    @Override
    public String toString() {
        return "J2SEModularProject[" + FileUtil.getFileDisplayName(getProjectDirectory()) + "]"; // NOI18N
    }
        
    public PropertyEvaluator evaluator() {
        assert eval != null;
        return eval;
    }

    public ReferenceHelper getReferenceHelper () {
        return this.refHelper;
    }

    public UpdateHelper getUpdateHelper() {
        return this.updateHelper;
    }

    @Override
    public Lookup getLookup() {
        return lookup;
    }

    public AntProjectHelper getAntProjectHelper() {
        return helper;
    }

    private Lookup createLookup(final AuxiliaryConfiguration aux, final ProjectOperations.Callback opsCallback) {
        final PlatformChangedHook platformChangedHook = new PlatformChangedHook();
        final FileEncodingQueryImplementation encodingQuery = QuerySupport.createFileEncodingQuery(evaluator(), ProjectProperties.SOURCE_ENCODING);
        Sources src;
        final Lookup base = Lookups.fixed(J2SEModularProject.this,
            //REVIEWED FOR MODULAR PROJECT
            QuerySupport.createProjectInformation(updateHelper, this, J2SE_MODULE_PROJECT_ICON),
            aux,
            helper.createCacheDirectoryProvider(),
            helper.createAuxiliaryProperties(),
            LookupMergerSupport.createClassPathProviderMerger(cpProvider),
            QuerySupport.createMultiModuleSourceForBinaryQuery(helper, evaluator(), getModuleRoots(), getSourceRoots(), getTestModuleRoots(), getTestSourceRoots()),
            QuerySupport.createMultiModuleBinaryForSourceQuery(helper, evaluator(), getModuleRoots(), getSourceRoots(), getTestModuleRoots(), getTestSourceRoots()),
            QuerySupport.createMultiModuleJavadocForBinaryQuery(helper, evaluator(), getModuleRoots(), getSourceRoots()),
            ProjectHooks.createProjectXmlSavedHookBuilder(eval, updateHelper, genFilesHelper).
                    setBuildImplTemplate(J2SEModularProject.class.getResource("resources/build-impl.xsl")).    //NOI18N
                    setBuildTemplate(J2SEModularProject.class.getResource("resources/build.xsl")).             //NOI18N
                    setOverrideModifiedBuildImplPredicate(new Callable<Boolean>(){
                        @Override
                        public Boolean call() throws Exception {
                            return projectPropertiesSave.get();
                        }
                    }).
                    build(),
            UILookupMergerSupport.createProjectOpenHookMerger(ProjectHooks.createProjectOpenedHookBuilder(this, eval, updateHelper, genFilesHelper, cpProvider).
                        addClassPathType(ClassPath.BOOT).
                        addClassPathType(ClassPath.COMPILE).
                        addClassPathType(ClassPath.SOURCE).
                        addClassPathType(JavaClassPathConstants.MODULE_COMPILE_PATH).   //For DefaultClassPathProvider
                        setBuildImplTemplate(J2SEModularProject.class.getResource("resources/build-impl.xsl")).    //NOI18N
                        setBuildTemplate(J2SEModularProject.class.getResource("resources/build.xsl")).             //NOI18N
                        addOpenPostAction(newStartMainUpdaterAction()).
//                        addOpenPostAction(newWebServicesAction()).
//                        addOpenPostAction(newMissingPropertiesAction()).
//                        addOpenPostAction(newUpdateCopyLibsAction()).
                        addClosePostAction(newStopMainUpdaterAction()).
                        build()),
            QuerySupport.createSourceLevelQuery2(evaluator()),
                    src = QuerySupport.createSources(this, helper, evaluator(),
                    getSourceRoots(),
                    getTestSourceRoots(),
                    getModuleRoots(),
                    getTestModuleRoots(),
                    Roots.nonSourceRoots(ProjectProperties.BUILD_DIR, ProjectProperties.DIST_DIR)),
            QuerySupport.createMultiModuleGroupQuery(helper, eval,  src,
                    getSourceRoots(),
                    getTestSourceRoots(),
                    getModuleRoots(),
                    getTestModuleRoots()),
            new RecommendedTemplatesImpl(getProjectDirectory()),
            UILookupMergerSupport.createPrivilegedTemplatesMerger(),
            UILookupMergerSupport.createRecommendedTemplatesMerger(),
            LookupProviderSupport.createSourcesMerger(),
            encodingQuery,
            QuerySupport.createTemplateAttributesProvider(helper, encodingQuery),
            QuerySupport.createCompilerOptionsQuery(eval, ProjectProperties.JAVAC_COMPILERARGS),
            LookupMergerSupport.createCompilerOptionsQueryMerger(),
            ExtraSourceJavadocSupport.createExtraSourceQueryImplementation(this, helper, evaluator()),
            LookupMergerSupport.createSFBLookupMerger(),
            ExtraSourceJavadocSupport.createExtraJavadocQueryImplementation(this, helper, evaluator()),
            LookupMergerSupport.createJFBLookupMerger(),
            QuerySupport.createAnnotationProcessingQuery(this.helper, this.evaluator(), ProjectProperties.ANNOTATION_PROCESSING_ENABLED, ProjectProperties.ANNOTATION_PROCESSING_ENABLED_IN_EDITOR, ProjectProperties.ANNOTATION_PROCESSING_RUN_ALL_PROCESSORS, ProjectProperties.ANNOTATION_PROCESSING_PROCESSORS_LIST, ProjectProperties.ANNOTATION_PROCESSING_SOURCE_OUTPUT, ProjectProperties.ANNOTATION_PROCESSING_PROCESSOR_OPTIONS),
            LookupProviderSupport.createActionProviderMerger(),
            LogicalViewProviders.createBuilder(
                this,
                eval,
                "org-netbeans-modules-java-j2semodule").   //NOI18N
                setHelpCtx(new HelpCtx("org.netbeans.modules.java.j2semodule.ui.J2SEModularLogicalViewProvider.J2SEModularLogicalViewRootNode")).    //NOI18N
                setCompileOnSaveBadge(newCoSBadge()).
                build(),
            QuerySupport.createModuleInfoAccessibilityQuery(
                    getModuleRoots(),
                    getSourceRoots(),
                    getTestModuleRoots(),
                    getTestSourceRoots()),
            QuerySupport.createMultiModuleAntArtifactProvider(
                    helper,
                    evaluator(),
                    getModuleRoots(),
                    getSourceRoots()),
            QuerySupport.createSharabilityQuery2(
                    helper,
                    evaluator(),
                    getModuleRoots(),
                    getTestModuleRoots()),
            refHelper.createSubprojectProvider(),
            new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper, this.genFilesHelper),
            newActionProvider(),
            ProjectOperations.createBuilder(this, evaluator(), updateHelper, refHelper, getModuleRoots(), getTestModuleRoots()).
                    addDataFiles("manifest.mf","master-application.jnlp","master-applet.jnlp","master-component.jnlp","preview-application.html","preview-applet.html").    //NOI18N
                    addMetadataFiles("xml-resources","catalog.xml").    //NOI18N
                    addPreservedPrivateProperties(ProjectProperties.APPLICATION_ARGS, ProjectProperties.RUN_WORK_DIR, ProjectProperties.COMPILE_ON_SAVE, ProjectProperties.DO_JLINK, ProjectProperties.JLINK_STRIP).
                    addUpdatedNameProperty(J2SEModularProjectProperties.APPLICATION_TITLE, "{0}", false).  //NOI18N
                    addUpdatedNameProperty(ProjectProperties.DIST_JLINK_OUTPUT, "$'{'"+ProjectProperties.DIST_JLINK_DIR+"'}'/{0}", true).    //NOI18N
                    addUpdatedNameProperty(ProjectProperties.JLINK_LAUNCHER_NAME, "{0}", true).    //NOI18N
                    setCallback(opsCallback).
                    build(),
            new CoSAwareFileBuiltQueryImpl(QuerySupport.createMultiModuleFileBuiltQuery(
                    helper,
                    evaluator(),
                    getModuleRoots(),
                    getSourceRoots(),
                    getTestModuleRoots(),
                    getTestSourceRoots()), this),
            QuerySupport.createMultiModuleUnitTestForSourceQuery(
                    getModuleRoots(),
                    getSourceRoots(),
                    getTestModuleRoots(),
                    getTestSourceRoots()),
            ProjectConfigurations.createConfigurationProviderBuilder(this, evaluator(), updateHelper).
                    addConfigurationsAffectActions(ActionProvider.COMMAND_RUN, ActionProvider.COMMAND_DEBUG).
                    setCustomizerAction(newConfigCustomizerAction()).
                    build(),
            WhiteListQueryMergerSupport.createWhiteListQueryMerger(),
            UILookupMergerSupport.createProjectProblemsProviderMerger(),
            new PropertyEvaluatorProviderImpl(evaluator()),
            QuerySupport.createMultiModuleUnitTestsCompilerOptionsQuery(
                    this,
                    getModuleRoots(),
                    getSourceRoots(),
                    getTestModuleRoots(),
                    getTestSourceRoots()),
            BrokenReferencesSupport.createReferenceProblemsProvider(
                    helper,
                    refHelper,
                    evaluator(),
                    platformChangedHook,
                    J2SEModularProjectUtil.getBreakableProperties(
                            getSourceRoots(),
                            getTestSourceRoots()),
                    new String[] {
                            ProjectProperties.PLATFORM_ACTIVE
            }),
            BrokenReferencesSupport.createPlatformVersionProblemProvider(
                    helper,
                    evaluator(),
                    platformChangedHook,
                    CommonProjectUtils.J2SE_PLATFORM_TYPE,
                    J2SEModularProjectUtil.MIN_SOURCE_LEVEL,
                    ProjectProperties.PLATFORM_ACTIVE,
                    ProjectProperties.JAVAC_SOURCE,
                    ProjectProperties.JAVAC_TARGET),
            new ProjectPlatformProviderImpl(this),
            ProjectClassPathModifier.extenderForModifier(cpMod),
            buildExtender,
            cpMod,
            new J2SEModularPersistenceProvider(this, cpProvider)
            //UNKNOWN FOR MODULAR PROJECT
//            J2SEFileWizardIterator.create()
        );
        lookup = base; // in case LookupProvider's call Project.getLookup
        return LookupProviderSupport.createCompositeLookup(base, "Projects/org-netbeans-modules-java-j2semodule/Lookup"); //NOI18N
    }

    private MultiModuleClassPathProvider getClassPathProvider () {
        return this.cpProvider;
    }

    public ClassPathModifier getProjectClassPathModifier () {
        return this.cpMod;
    }

    // Package private methods -------------------------------------------------

    /**
     * Returns the source roots of this project
     * @return project's source roots
     */
    public synchronized SourceRoots getSourceRoots() {
        if (this.sourceRoots == null) { //Local caching, no project metadata access
            this.sourceRoots = SourceRoots.create(updateHelper, evaluator(), getReferenceHelper(),
                    J2SEModularProject.PROJECT_CONFIGURATION_NAMESPACE, "source-roots", false, "src.{0}{1}.dir"); //NOI18N
        }
        return this.sourceRoots;
    }

    public synchronized SourceRoots getTestSourceRoots() {
        if (this.testRoots == null) { //Local caching, no project metadata access
            this.testRoots = SourceRoots.create(updateHelper, evaluator(), getReferenceHelper(),
                    J2SEModularProject.PROJECT_CONFIGURATION_NAMESPACE, "test-roots", true, "test.{0}{1}.dir"); //NOI18N
        }
        return this.testRoots;
    }

    public synchronized ModuleRoots getModuleRoots() {
        if (this.moduleRoots == null) { //Local caching, no project metadata access
            this.moduleRoots = ModuleRoots.create(updateHelper, evaluator(), getReferenceHelper(),
                    J2SEModularProject.PROJECT_CONFIGURATION_NAMESPACE, "source-roots", false, "src.{0}{1}.dir"); //NOI18N
        }
        return this.moduleRoots;
    }

    public synchronized ModuleRoots getTestModuleRoots() {
        if (this.testModuleRoots == null) { //Local caching, no project metadata access
            this.testModuleRoots = ModuleRoots.create(updateHelper, evaluator(), getReferenceHelper(),
                    J2SEModularProject.PROJECT_CONFIGURATION_NAMESPACE, "test-roots", true, "test.{0}{1}.dir"); //NOI18N
        }
        return this.testModuleRoots;
    }

    File getTestClassesDirectory() {
        String testClassesDir = evaluator().getProperty(ProjectProperties.BUILD_TEST_CLASSES_DIR);
        if (testClassesDir == null) {
            return null;
        }
        return helper.resolveFile(testClassesDir);
    }

    // Currently unused (but see #47230):
    /** Store configured project name. */
    public void setName(final String name) {
        ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() {
            @Override
            public Void run() {
                Element data = updateHelper.getPrimaryConfigurationData(true);
                // XXX replace by XMLUtil when that has findElement, findText, etc.
                NodeList nl = data.getElementsByTagNameNS(J2SEModularProject.PROJECT_CONFIGURATION_NAMESPACE, "name");
                Element nameEl;
                if (nl.getLength() == 1) {
                    nameEl = (Element) nl.item(0);
                    NodeList deadKids = nameEl.getChildNodes();
                    while (deadKids.getLength() > 0) {
                        nameEl.removeChild(deadKids.item(0));
                    }
                } else {
                    nameEl = data.getOwnerDocument().createElementNS(J2SEModularProject.PROJECT_CONFIGURATION_NAMESPACE, "name");
                    data.insertBefore(nameEl, /* OK if null */data.getChildNodes().item(0));
                }
                nameEl.appendChild(data.getOwnerDocument().createTextNode(name));
                updateHelper.putPrimaryConfigurationData(data, true);
                return null;
            }
        });
    }


    /**
     * J2SEProjectProperties helper method to notify ProjectXmlSavedHookImpl about customizer save
     * @see J2SEProject.ProjectXmlSavedHookImpl#projectXmlSaved()
     * @param value true = active
     */
    public void setProjectPropertiesSave(boolean value) {
        this.projectPropertiesSave.set(value);
    }

    @NonNull
    private ActionProvider newActionProvider() {
        return MultiModuleActionProviderBuilder.newInstance(
                this, getUpdateHelper(), evaluator(),
                getSourceRoots(), getTestSourceRoots(), cpProvider)
                .setCompileOnSaveOperationsProvider(() -> {
                        return J2SEModularProjectUtil.isCompileOnSaveEnabled(this) ?
                            EnumSet.of(JavaActionProvider.CompileOnSaveOperation.UPDATE, JavaActionProvider.CompileOnSaveOperation.EXECUTE) :
                            Collections.emptySet();
                })
                .build();
    }

    private static final class RecommendedTemplatesImpl implements RecommendedTemplates, PrivilegedTemplates {

        // List of primarily supported templates
        private static final String[] PROJECT_TEMPLATES = new String[] {
            "java-modules",         // NOI18N
            "simple-files"          // NOI18N
        };

        private static final String[] MODULE_TEMPLATES = new String[] {
            "java-classes",         // NOI18N
            "java-main-class",      // NOI18N
            "java-forms",           // NOI18N
            "gui-java-application", // NOI18N
            "java-beans",           // NOI18N
            "persistence",          // NOI18N
            "oasis-XML-catalogs",   // NOI18N
            "XML",                  // NOI18N
            "ant-script",           // NOI18N
            "ant-task",             // NOI18N
            "web-service-clients",  // NOI18N
            "REST-clients",         // NOI18N
            "wsdl",                 // NOI18N
            // "servlet-types",     // NOI18N
            // "web-types",         // NOI18N
            "junit",                // NOI18N
            // "MIDP",              // NOI18N
            "simple-files"          // NOI18N
        };

        private static final String[] PRIVILEGED_PROJECT_NAMES = new String[] {
            "Templates/J2SEModule/module-info.java" // NOI18N
        };

        private static final String[] PRIVILEGED_MODULE_NAMES = new String[] {
            "Templates/Classes/Class.java", // NOI18N
            "Templates/Classes/Package", // NOI18N
            "Templates/Classes/Interface.java", // NOI18N
            "Templates/GUIForms/JPanel.java", // NOI18N
            "Templates/GUIForms/JFrame.java", // NOI18N
            "Templates/Persistence/Entity.java", // NOI18N
            "Templates/Persistence/RelatedCMP", // NOI18N
            "Templates/WebServices/WebServiceClient"   // NOI18N
        };
        
        private final FileObject projectDir;

        private RecommendedTemplatesImpl(FileObject projectDir) {
            this.projectDir = projectDir;
        }

        @Override
        public String[] getRecommendedTypes() {
            return isProject() ? PROJECT_TEMPLATES : MODULE_TEMPLATES;
        }

        @Override
        public String[] getPrivilegedTemplates() {
            return isProject() ? PRIVILEGED_PROJECT_NAMES : PRIVILEGED_MODULE_NAMES;
        }
        
        private boolean isProject() {
            return projectDir == Utilities.actionsGlobalContext().lookup(FileObject.class);
        }
    }

    private class J2SEModularExtenderImplementation implements AntBuildExtenderImplementation {
        //add targets here as required by the external plugins..
        @Override
        public List<String> getExtensibleTargets() {
            return Arrays.asList(EXTENSIBLE_TARGETS);
        }

        @Override
        public Project getOwningProject() {
            return J2SEModularProject.this;
        }

    }

    private static final DocumentBuilder db;
    static {
        try {
            db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            throw new AssertionError(e);
        }
    }
//    private static Document createNewDocument() {
//        // #50198: for thread safety, use a separate document.
//        // Using XMLUtil.createDocument is much too slow.
//        synchronized (db) {
//            return db.newDocument();
//        }
//    }
//
//
    @NonNull
    private Runnable newStartMainUpdaterAction() {
        return () -> {
            //register updater of main.class
            //the updater is active only on the opened projects
            mainClassUpdater = new MainClassUpdater (
                    J2SEModularProject.this,
                    evaluator(),
                    updateHelper,
                    getSourceRoots(),
                    ProjectProperties.MAIN_CLASS);
            mainClassUpdater.start();
        };
    }

    @NonNull
    private Runnable newStopMainUpdaterAction() {
        return () -> {
            if (mainClassUpdater != null) {
                mainClassUpdater.stop();
                mainClassUpdater = null;
            }
        };
    }
//
//    @NonNull
//    private Runnable newWebServicesAction() {
//        return new Runnable() {
//            private final String JAX_RPC_NAMESPACE="http://www.netbeans.org/ns/j2se-project/jax-rpc"; //NOI18N
//            private final String JAX_RPC_CLIENTS="web-service-clients"; //NOI18N
//            private final String JAX_RPC_CLIENT="web-service-client"; //NOI18N
//            @Override
//            public void run() {
//                //remove jaxws.endorsed.dir property
//                EditableProperties ep = updateHelper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
//                ep.remove("jaxws.endorsed.dir");
//                // move web-service-clients one level up from in project.xml
//                // WS should be part of auxiliary configuration
//                Element data = helper.getPrimaryConfigurationData(true);
//                NodeList nodes = data.getElementsByTagName(JAX_RPC_CLIENTS);
//                if(nodes.getLength() > 0) {
//                    Element oldJaxRpcClients = (Element) nodes.item(0);
//                    Document doc = createNewDocument();
//                    Element newJaxRpcClients = doc.createElementNS(JAX_RPC_NAMESPACE, JAX_RPC_CLIENTS);
//                    NodeList childNodes = oldJaxRpcClients.getElementsByTagName(JAX_RPC_CLIENT);
//                    for (int i=0;i<childNodes.getLength();i++) {
//                        Element oldJaxRpcClient = (Element) childNodes.item(i);
//                        Element newJaxRpcClient = doc.createElementNS(JAX_RPC_NAMESPACE, JAX_RPC_CLIENT);
//                        NodeList nodeProps = oldJaxRpcClient.getChildNodes();
//                        for (int j=0;j<nodeProps.getLength();j++) {
//                            Node n = nodeProps.item(j);
//                            if (n instanceof Element) {
//                                Element oldProp = (Element) n;
//                                Element newProp = doc.createElementNS(JAX_RPC_NAMESPACE, oldProp.getLocalName());
//                                String text = oldProp.getTextContent();
//                                newProp.setTextContent(text);
//                                newJaxRpcClient.appendChild(newProp);
//                            }
//                        }
//                        newJaxRpcClients.appendChild(newJaxRpcClient);
//                    }
//                    aux.putConfigurationFragment(newJaxRpcClients, true);
//                    data.removeChild(oldJaxRpcClients);
//                    helper.putPrimaryConfigurationData(data, true);
//                }
//                updateHelper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep);
//            }
//        };
//    }
//
//    @NonNull
//    private Runnable newMissingPropertiesAction() {
//        return new Runnable() {
//            @Override
//            public void run() {
//                final EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
//                if (!ep.containsKey(ProjectProperties.INCLUDES)) {
//                    ep.setProperty(ProjectProperties.INCLUDES, "**"); // NOI18N
//                }
//                if (!ep.containsKey(ProjectProperties.EXCLUDES)) {
//                    ep.setProperty(ProjectProperties.EXCLUDES, ""); // NOI18N
//                }
//                if (!ep.containsKey("build.generated.sources.dir")) { // NOI18N
//                    ep.setProperty("build.generated.sources.dir", "${build.dir}/generated-sources"); // NOI18N
//                }
//                J2SEProjectBuilder.createDefaultModuleProperties(
//                        ep,
//                        testRoots.getRoots().length > 0);
//                helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, ep);
//            }
//        };
//    }
//
//    @NonNull
//    private Runnable newUpdateCopyLibsAction() {
//        return new Runnable() {
//            private final String LIB_COPY_LIBS = "CopyLibs"; //NOI18N
//            private final String PROP_VERSION = "version";   //NOI18N
//            private final String VOL_CP = "classpath";       //NOI18N
//
//            @Override
//            public void run() {
//                final LibraryManager projLibManager = refHelper.getProjectLibraryManager();
//                if (projLibManager == null) {
//                    return;
//                }
//                final Library globalCopyLibs = LibraryManager.getDefault().getLibrary(LIB_COPY_LIBS);
//                final Library projectCopyLibs = projLibManager.getLibrary(LIB_COPY_LIBS);
//                if (globalCopyLibs == null || projectCopyLibs == null) {
//                    return;
//                }
//                final String globalStr = globalCopyLibs.getProperties().get(PROP_VERSION);
//                if (globalStr == null) {
//                    return;
//                }
//                try {
//                    final SpecificationVersion globalVersion = new SpecificationVersion(globalStr);
//                    final String projectStr = projectCopyLibs.getProperties().get(PROP_VERSION);
//                    if (projectStr != null && globalVersion.compareTo(new SpecificationVersion(projectStr)) <= 0) {
//                        return;
//                    }
//
//                    final List<URL> content = projectCopyLibs.getContent(VOL_CP);
//                    projLibManager.removeLibrary(projectCopyLibs);
//                    final FileObject projLibLoc = URLMapper.findFileObject(projLibManager.getLocation());
//                    if (projLibLoc != null) {
//                        final FileObject libFolder = projLibLoc.getParent();
//                        boolean canDelete = libFolder.canWrite();
//                        FileObject container = null;
//                        for (URL u : content) {
//                            FileObject fo = toFile(u);
//                            if (fo != null) {
//                                canDelete &= fo.canWrite();
//                                if (container == null) {
//                                    container = fo.getParent();
//                                    canDelete &= container.canWrite();
//                                    canDelete &= LIB_COPY_LIBS.equals(container.getName());
//                                    canDelete &= libFolder.equals(container.getParent());
//                                } else {
//                                    canDelete &= container.equals(fo.getParent());
//                                }
//                            }
//                        }
//                        if (canDelete && container != null) {
//                            container.delete();
//                        }
//                    }
//                    refHelper.copyLibrary(globalCopyLibs);
//
//                } catch (IllegalArgumentException iae) {
//                    LOG.log(
//                            Level.WARNING,
//                            "Cannot update {0} due to invalid version.", //NOI18N
//                            projectCopyLibs.getDisplayName());
//                } catch (IOException ioe) {
//                    Exceptions.printStackTrace(ioe);
//                }
//            }
//
//            @CheckForNull
//            private FileObject toFile(@NonNull final URL url) {
//                final URL file = FileUtil.getArchiveFile(url);
//                return URLMapper.findFileObject(file != null ? file : url);
//            }
//        };
//    }
//
    @NonNull
    private Runnable newConfigCustomizerAction() {
        return () -> {
            J2SEModularProject.this.getLookup().lookup(CustomizerProviderImpl.class).
                showCustomizer(J2SECompositePanelProvider.RUN);
        };
    }

    @NonNull
    private LogicalViewProviders.CompileOnSaveBadge newCoSBadge() {
        return new LogicalViewProviders.CompileOnSaveBadge() {
            @Override
            public boolean isBadgeVisible() {
                return !J2SEModularProjectUtil.isCompileOnSaveEnabled(J2SEModularProject.this) &&
                    J2SEModularProjectUtil.isCompileOnSaveSupported(J2SEModularProject.this);
            }
            @Override
            public boolean isImportant(@NonNull final String propertyName) {
                return ProjectProperties.COMPILE_ON_SAVE.equals(propertyName) ||
                propertyName.startsWith(ProjectProperties.COMPILE_ON_SAVE_UNSUPPORTED_PREFIX);
            }
        };
    }

    @NonNull
    private static ProjectOperations.Callback newProjectOperationsCallback (
        @NonNull final J2SEModularProject project,
        @NonNull final UpdateProjectImpl projectUpdate) {
        return new ProjectOperations.Callback() {
            @Override
            public void beforeOperation(@NonNull final ProjectOperations.Callback.Operation operation) {
            }
            @Override
            @SuppressWarnings("fallthrough")
            public void afterOperation(
                    @NonNull final ProjectOperations.Callback.Operation operation,
                    @NullAllowed final String newName,
                    @NullAllowed final Pair<File, Project> oldProject) {
                switch (operation) {
                    case COPY:
                        projectUpdate.setTransparentUpdate(true);
                    case MOVE:
                    case RENAME:
                        project.setName(newName);
                }
            }
        };
    }

    private static final class PropertyEvaluatorProviderImpl implements PropertyEvaluatorProvider {
        private final PropertyEvaluator eval;

        PropertyEvaluatorProviderImpl(@NonNull final PropertyEvaluator eval) {
            Parameters.notNull("eval", eval);   //NOI18N
            this.eval = eval;
        }

        @NonNull
        @Override
        public PropertyEvaluator getPropertyEvaluator() {
            return this.eval;
        }
    }

    private final class PlatformChangedHook implements BrokenReferencesSupport.PlatformUpdatedCallBack {
        @Override
        public void platformPropertyUpdated(@NonNull final JavaPlatform platform) {
            ProjectPlatformProviderImpl.updateProjectXml(platform, updateHelper);
        }
    }
}
