/*
 * 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.javafx2.project;

import java.io.*;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.MessageFormat;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.CRC32;
import java.util.zip.Checksum;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.netbeans.api.annotations.common.CheckForNull;
import org.netbeans.api.annotations.common.NonNull;
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.platform.JavaPlatformManager;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.java.source.*;
import org.netbeans.api.java.source.ClassIndex.SearchKind;
import org.netbeans.api.java.source.ClassIndex.SearchScope;
import org.netbeans.api.project.*;
import org.netbeans.api.project.ant.AntBuildExtender;
import org.netbeans.api.project.ui.OpenProjects;
import org.netbeans.modules.extbrowser.ExtWebBrowser;
import org.netbeans.modules.java.api.common.project.ProjectProperties;
import org.netbeans.modules.java.j2seproject.api.J2SEProjectPlatform;
import org.netbeans.modules.java.j2seproject.api.J2SEPropertyEvaluator;
import org.netbeans.modules.javafx2.platform.api.JavaFXPlatformUtils;
import org.netbeans.modules.javafx2.platform.api.JavaFxRuntimeInclusion;
import org.netbeans.modules.javafx2.project.JavaFXProjectWizardIterator.WizardType;
import org.netbeans.modules.javafx2.project.ui.JSEApplicationClassChooser;
import org.netbeans.spi.project.ProjectIconAnnotator;
import org.netbeans.spi.project.support.ant.AntProjectHelper;
import org.netbeans.spi.project.support.ant.EditableProperties;
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
import org.netbeans.spi.project.support.ant.PropertyUtils;
import org.openide.awt.Notification;
import org.openide.awt.NotificationDisplayer;
import org.openide.cookies.CloseCookie;
import org.openide.execution.NbProcessDescriptor;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities;
import org.openide.util.Lookup;
import org.openide.util.Mutex;
import org.openide.util.MutexException;
import org.openide.util.NbBundle;
import org.openide.util.Parameters;
import org.openide.xml.XMLUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Utility class for JavaFX 2.0+ Project
 * 
 * @author Petr Somol
 */
public final class JFXProjectUtils {

    private static Set<SearchKind> kinds = new HashSet<SearchKind>(Arrays.asList(SearchKind.IMPLEMENTORS));
    private static Set<SearchScope> scopes = new HashSet<SearchScope>(Arrays.asList(SearchScope.SOURCE));
    
    private static final String JFX_BUILD_TEMPLATE = "Templates/JFX/jfx-impl.xml"; //NOI18N
    private static final String CURRENT_EXTENSION = "jfx3";  //NOI18N
    private static final String[] OLD_EXTENSIONS = new String[] {"jfx", "jfx2"}; // NOI18N
    private static final String NBPROJECT = "nbproject"; // NOI18N
    private static final String JFX_BUILD_IMPL_NAME = "jfx-impl"; // NOI18N
    private static final String JFX_BUILD_IMPL_PATH = NBPROJECT + "/" + JFX_BUILD_IMPL_NAME + ".xml";   //NOI18N
    private static volatile String currentJfxImplCRCCache;
    private static final String TRUE = "true"; //NOI18N
    private static final String FALSE = "false"; //NOI18N
    // from J2SEDeployProperties
    private static final String J2SEDEPLOY_EXTENSION = "j2sedeploy";    //NOI18N
    private static final String EXTENSION_BUILD_SCRIPT_PATH = "nbproject/build-native.xml";        //NOI18N
    //Important path types for Java model
    private static final String[] JAVA_PATHS = {
            ClassPath.BOOT, ClassPath.COMPILE, ClassPath.SOURCE,
            JavaClassPathConstants.MODULE_BOOT_PATH, JavaClassPathConstants.MODULE_COMPILE_PATH,
            JavaClassPathConstants.MODULE_CLASS_PATH, /*JavaClassPathConstants.MODULE_SOURCE_PATH*/
    };

    // two deprecated properties, to be auto-cleaned from project.properties if present
    @Deprecated
    public static final String PROPERTY_JAVAFX_RUNTIME = "javafx.runtime"; // NOI18N
    @Deprecated
    public static final String PROPERTY_JAVAFX_SDK = "javafx.sdk"; // NOI18N

    private static final Logger LOGGER = Logger.getLogger("javafx"); // NOI18N
    
    /**
     * Return current name (version) of build-impl.xml "extension spi"
     * where the spi consists of target dependency points between build-impl
     * and jfx-impl.
     * @return name as string
     */
    public static String getCurrentExtensionName() {
        return CURRENT_EXTENSION;
    }

    /**
     * Return list of old names (versions) of build-impl.xml "extension spis". 
     * Used to search for spi version when jfx-impl and build-impl do not match
     * and correct update needs to be determined.
     * @return names as strings
     */
    public static Iterable<? extends String> getOldExtensionNames() {
        return Arrays.asList(OLD_EXTENSIONS);
    }    

    /**
     * Returns list of JavaFX 2.0 JavaScript callback entries.
     * In future should read the list from the current platform
     * (directly from FX SDK or Ant taks).
     * Current list taken from
     * http://javaweb.us.oracle.com/~in81039/new-dt/js-api/Callbacks.html
     * 
     * @param IDE java platform name
     * @return callback entries
     */
    public static Map<String,List<String>/*|null*/> getJSCallbacks(String platformName) {
        final String[][] c = {
            {"onDeployError", "app", "mismatchEvent"}, // NOI18N
            {"onGetNoPluginMessage", "app"}, // NOI18N
            {"onGetSplash", "app"}, // NOI18N
            {"onInstallFinished", "placeholder", "component", "status", "relaunchNeeded"}, // NOI18N
            {"onInstallNeeded", "app", "platform", "cb", "isAutoinstall", "needRelaunch", "launchFunc"}, // NOI18N
            {"onInstallStarted", "placeholder", "component", "isAuto", "restartNeeded"}, // NOI18N
            {"onJavascriptReady", "id"}, // NOI18N
            {"onRuntimeError", "id", "code"} // NOI18N
        };
        Map<String,List<String>/*|null*/> m = new LinkedHashMap<String,List<String>/*|null*/>();
        for(int i = 0; i < c.length; i++) {
            String[] s = c[i];
            assert s.length > 0;
            List<String> l = null;
            if(s.length > 1) {
                l = new ArrayList<String>();
                for(int j = 1; j < s.length; j++) {
                    l.add(s[j]);
                }
            }
            m.put(s[0], l);
        }
        return m;
    }
    
    /**
     * Returns all classpaths relevant for given project. To be used in
     * main class searches.
     * 
     * @param project
     * @return map of classpaths of all project files
     */
    public static Map<FileObject,Map<String,ClassPath>> getClassPathMap(@NonNull Project project) {
        Sources sources = ProjectUtils.getSources(project);
        SourceGroup[] srcGroups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
        final Map<FileObject,Map<String,ClassPath>> classpathMap = new HashMap<>();
        final BitSet requiredPaths = new BitSet(3);
        requiredPaths.set(0, 3, true);
        for (SourceGroup srcGroup : srcGroups) {
            FileObject srcRoot = srcGroup.getRootFolder();
            final Map<String, ClassPath> sgCps = new HashMap<>();
            final BitSet seen = new BitSet(JAVA_PATHS.length);
            for (int i = 0; i < JAVA_PATHS.length; i++) {
                final ClassPath cp = ClassPath.getClassPath(srcRoot, JAVA_PATHS[i]);
                if (cp != null) {
                    sgCps.put(JAVA_PATHS[i], cp);
                    seen.set(i);
                }
            }
            seen.and(requiredPaths);
            if (seen.cardinality() == 3) {
                classpathMap.put(srcRoot, sgCps);
            }
        }
        return classpathMap;
    }

    /**
     * Returns source roots of a project
     * @param project
     * 
     * @return set of fileobjects representing the source roots
     */
    public static Set<FileObject> getSourceRoots(@NonNull Project project) {
        Sources sources = ProjectUtils.getSources(project);
        SourceGroup[] srcGroups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
        final Set<FileObject> sourceRoots = new HashSet<FileObject>();
        for (SourceGroup srcGroup : srcGroups) {
            sourceRoots.add(srcGroup.getRootFolder());
        }
        return sourceRoots;
    }
    
    /**
     * Returns set of names of main classes in the given project
     * 
     * @param project
     * @return set of class names
     */
    public static Set<String> getMainClassNames(@NonNull Project project) {
        final Set<String> mainClassNames = new HashSet<String>();
        FileObject sourceRoots[] = getSourceRoots(project).toArray(new FileObject[0]);
        for (ElementHandle<TypeElement> elemHandle : SourceUtils.getMainClasses(sourceRoots)) {
            mainClassNames.add(elemHandle.getQualifiedName());
        }
        return mainClassNames;
    }
    
    /**
     * Returns set of names of classes of the classType type.
     * 
     * @param classpathMap map of classpaths of all project files
     * @param classType return only classes of this type
     * @return set of class names
     */
    public static Set<String> getAppClassNames(@NonNull Collection<? extends FileObject> roots, final @NonNull String classType) {
        final Set<String> appClassNames = new HashSet<>();
        for (FileObject fo : roots) {
            final ClasspathInfo cpInfo = ClasspathInfo.create(fo);
            final JavaSource js = JavaSource.create(cpInfo);
            if (js != null) {
                try { 
                    js.runUserActionTask(new Task<CompilationController>() {
                        @Override
                        public void run(CompilationController controller) throws Exception {
                            final ClassIndex classIndex = cpInfo.getClassIndex();
                            final Elements elems = controller.getElements();
                            TypeElement fxAppElement = elems.getTypeElement(classType);
                            ElementHandle<TypeElement> appHandle = ElementHandle.create(fxAppElement);
                            Set<ElementHandle<TypeElement>> appHandles = classIndex.getElements(appHandle, kinds, scopes);
                            for (ElementHandle<TypeElement> elemHandle : appHandles) {
                                appClassNames.add(elemHandle.getQualifiedName());
                            }
                        }
                    }, true);
                } catch (Exception e) {

                }
            }
        }
        return appClassNames;
    }


    /** Finds available FX Preloader classes in given JAR files. 
     * Looks for classes specified in the JAR manifest only.
     * 
     * @param jarFile FileObject representing an existing JAR file
     * @param classType return only classes of this type
     * @return set of class names
     */
    public static Set<String> getAppClassNamesInJar(@NonNull FileObject jarFile, final String classType, final String fxrtJarPath) {
        final File jarF = FileUtil.toFile(jarFile);
        if (jarF == null) {
            return null;
        }
        boolean jfxrtExists = false;
        List<URL> toLoad = new ArrayList<URL>();
        try {
            assert jarF.exists();
            toLoad.add(jarF.toURI().toURL());
            final File jfxrt = new File(fxrtJarPath);
            if(jfxrt.exists()) {
                jfxrtExists = true;
            }
            toLoad.add(jfxrt.toURI().toURL());            

        } catch (MalformedURLException ex) {
            return null;
        }        
        URLClassLoader clazzLoader = URLClassLoader.newInstance(toLoad.toArray(new URL[0]));

        final Set<String> appClassNames = new HashSet<String>();
        JarFile jf;
        try {
            jf = new JarFile(jarF);
        } catch (IOException x) {
            return null;
        }
        Enumeration<? extends JarEntry> entries = jf.entries();
        if (entries == null) {
            return null;
        }        
        while(entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            // Relative path of file into the jar
            String classFileName = entry.getName();
            
            if(!classFileName.endsWith(".class")) { // NOI18N
                continue;
            }
            if(classFileName.contains("$")) { // NOI18N
                continue;
            }
            // Complete class name
            String className = classFileName.replace(".class", "").replace('\\', '/').replace('/', '.'); // NOI18N
            
            if(clazzLoader != null && jfxrtExists) {
                // Load class definition from JVM
                Class<?> clazz;
                try {
                    clazz = Class.forName(className, true, clazzLoader);
                    Type t = clazz.getGenericSuperclass();
                    if(t.toString().contains(classType)) {
                        if (className.startsWith(".")) { // NOI18N
                            className = className.substring(1);
                        }
                        appClassNames.add(className);
                    }
                } catch (ClassNotFoundException ex) {
                    return null;
                }
            } else {
                if (className.startsWith(".")) { // NOI18N
                    className = className.substring(1);
                }
                appClassNames.add(className);
            }
        }

        return appClassNames;
    }

    /**
     * Checks if the JFX support is enabled for given project
     * @param prj the project to check
     * @return true if project supports JFX
     */
    public static boolean isFXProject(@NonNull final Project prj) {
        final J2SEPropertyEvaluator ep = prj.getLookup().lookup(J2SEPropertyEvaluator.class);
        if (ep == null) {
            return false;
        }
        return JFXProjectProperties.isTrue(ep.evaluator().getProperty(JFXProjectProperties.JAVAFX_ENABLED));
    }

     /**
     * Checks if the project is a Swing project with JFX support enabled
     * @param prj the project to check
     * @return true if project supports FX in Swing
     */
    public static boolean isFXinSwingProject(@NonNull final Project prj) {
        final J2SEPropertyEvaluator ep = prj.getLookup().lookup(J2SEPropertyEvaluator.class);
        if (ep == null) {
            return false;
        }
        return JFXProjectProperties.isTrue(ep.evaluator().getProperty(JFXProjectProperties.JAVAFX_ENABLED))
                && JFXProjectProperties.isTrue(ep.evaluator().getProperty(JFXProjectProperties.JAVAFX_SWING));
    }

     /**
     * Checks if the project is a JavaFX preloader project. Note that in pre-7.2 NB
     * preloader type had been used for fx-in-swing as workaround, hence the logic below
     * @param prj the project to check
     * @return true if project is JavaFX preloader
     */
    public static boolean isFXPreloaderProject(@NonNull final Project prj) {
        final J2SEPropertyEvaluator ep = prj.getLookup().lookup(J2SEPropertyEvaluator.class);
        if (ep == null) {
            return false;
        }
        return JFXProjectProperties.isTrue(ep.evaluator().getProperty(JFXProjectProperties.JAVAFX_ENABLED))
                && JFXProjectProperties.isTrue(ep.evaluator().getProperty(JFXProjectProperties.JAVAFX_PRELOADER))
                && !JFXProjectProperties.isTrue(ep.evaluator().getProperty(JFXProjectProperties.JAVAFX_SWING));
    }

    /**
     * Checks if the project uses Maven build system
     *
     * @param prj the project to check
     * @return true if is Maven project
     */
    public static boolean isMavenProject(@NonNull final Project prj) {
        FileObject fo = prj.getProjectDirectory();
        if (fo == null || !fo.isValid()) {
            return false;
        }
        fo = fo.getFileObject("pom.xml"); //NOI18N
        return fo != null;
    }

    /**
     * Checks if the project uses Gradle build system
     *
     * @param prj the project to check
     * @return true if is Gradle project
     */
    public static boolean isGradleProject(@NonNull final Project prj) {
        FileObject fo = prj.getProjectDirectory();
        if (fo == null || !fo.isValid()) {
            return false;
        }
        fo = fo.getFileObject("build.gradle"); //NOI18N
        return fo != null;
    }

    public static boolean isMavenFXProject(@NonNull final Project prj) {
        if (isMavenProject(prj)) {
            try {
                FileObject pomXml = prj.getProjectDirectory().getFileObject("pom.xml"); //NOI18N
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse(FileUtil.toFile(pomXml));
                XPathFactory xPathfactory = XPathFactory.newInstance();
                XPath xpath = xPathfactory.newXPath();
                XPathExpression exprJfxrt = xpath.compile("//bootclasspath[contains(text(),'jfxrt')]"); //NOI18N
                XPathExpression exprFxPackager = xpath.compile("//executable[contains(text(),'javafxpackager')]"); //NOI18N
                XPathExpression exprPackager = xpath.compile("//executable[contains(text(),'javapackager')]"); //NOI18N
                boolean jfxrt = (Boolean) exprJfxrt.evaluate(doc, XPathConstants.BOOLEAN);
                boolean packager = (Boolean) exprPackager.evaluate(doc, XPathConstants.BOOLEAN);
                boolean fxPackager = (Boolean) exprFxPackager.evaluate(doc, XPathConstants.BOOLEAN);
                return jfxrt && (packager || fxPackager);
            } catch (XPathExpressionException | ParserConfigurationException | SAXException | IOException ex) {
                LOGGER.log(Level.INFO, "Error while parsing pom.xml.", ex);  //NOI18N
                return false;
            }
        }
        return false;
    }

    /**
     * Checks what Run model is selected in current configuration of JFX Run Project Property panel
     * @param prj the project to check
     * @return string value of JFXProjectProperties.RunAsType type or null meaning JFXProjectProperties.RunAsType.STANDALONE
     */
    public static String getFXProjectRunAs(@NonNull final Project prj) {
        final J2SEPropertyEvaluator ep = prj.getLookup().lookup(J2SEPropertyEvaluator.class);
        if (ep == null) {
            return null;
        }
        return ep.evaluator().getProperty(JFXProjectProperties.RUN_AS);
    }

    /**
     * Finds the relative path to targetFO from sourceFO. 
     * Unlike FileUtil.getRelativePath() does not require targetFO to be within sourceFO sub-tree
     * Returns null if there is no shared parent directory except root.
     * 
     * @param sourceFO file/dir to which the relative path will be related
     * @param targetFO file whose location will be determined with respect to sourceFO
     * @return string relative path leading from sourceFO to targetFO
     */
    public static String getRelativePath(@NonNull final FileObject sourceFO, @NonNull final FileObject targetFO) {
        String path = ""; //NOI18N
        FileObject src = sourceFO;
        FileObject tgt = targetFO;
        String targetName = null;
        if(!src.isFolder()) {
            src = src.getParent();
        }
        if(!tgt.isFolder()) {
            targetName = tgt.getNameExt();
            tgt = tgt.getParent();
        }
        LinkedList<String> srcSplit = new LinkedList<String>();
        LinkedList<String> tgtSplit = new LinkedList<String>();
        while(!src.isRoot()) {
            srcSplit.addFirst(src.getName());
            src = src.getParent();
        }
        while(!tgt.isRoot()) {
            tgtSplit.addFirst(tgt.getName());
            tgt = tgt.getParent();
        }
        boolean share = false;
        while(!srcSplit.isEmpty() && !tgtSplit.isEmpty()) {
            if(srcSplit.getFirst().equals(tgtSplit.getFirst())) {
                srcSplit.removeFirst();
                tgtSplit.removeFirst();
                share = true;
            } else {
                break;
            }
        }
        if(!share) {
            return null;
        }
        for(int left = 0; left < srcSplit.size(); left++) {
            if(left == 0) {
                path += ".."; //NOI18N
            } else {
                path += "/.."; //NOI18N
            }
        }
        while(!tgtSplit.isEmpty()) {
            if(path.isEmpty()) {
                path += tgtSplit.getFirst();
            } else {
                path += "/" + tgtSplit.getFirst(); //NOI18N
            }
            tgtSplit.removeFirst();
        }
        if(targetName != null) {
            if(!path.isEmpty()) {
                path += "/" + targetName; //NOI18N
            } else {
                path += targetName;
            }
        }
        return path;
    }

    /**
     * Finds the file/dir represented by relPath with respect to sourceDir. 
     * Returns null if the file does not exist.
     * 
     * @param sourceDir file/dir to which the relative path is related
     * @param relPath relative path related to sourceDir
     * @return FileObject or null
     */
    public static FileObject getFileObject(@NonNull final FileObject sourceDir, @NonNull final String relPath) {
        String split[] = relPath.split("[\\\\/]+"); //NOI18N
        FileObject src = sourceDir;
        String path = ""; //NOI18N
        boolean back = true;
        if(split[0].equals("..")) {
            for(int i = 0; i < split.length; i++) {
                if(back && split[i].equals("..")) { //NOI18N
                    src = src.getParent();
                    if(src == null) {
                        return null;
                    }
                } else {
                    if(back) {
                        back = false;
                        path = src.getPath();
                    }
                    path += "/" + split[i]; //NOI18N
                }
            }
        } else {
            path = relPath;
        }
        File f = new File(path);
        if(f.exists()) {
            return FileUtil.toFileObject(f);
        }
        return null;
    }

    /**
     * Initialize project properties for JavaFX Application project type
     * @param ep
     * @param type
     * @param platformName
     * @param mainClass
     * @param preloader
     * @throws MissingResourceException 
     */
    static void initializeJavaFXProperties(@NonNull EditableProperties ep, @NonNull WizardType type, String targetPlatformName, @NonNull String mainClass, String preloader) throws MissingResourceException {
        ep.setProperty(JFXProjectProperties.JAVAFX_ENABLED, TRUE); // NOI18N
        ep.setComment(JFXProjectProperties.JAVAFX_ENABLED, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_javafx")}, false); // NOI18N
        ep.setProperty("jnlp.enabled", FALSE); // NOI18N
        ep.setComment("jnlp.enabled", new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_oldjnlp")}, false); // NOI18N
        ep.setProperty(ProjectProperties.COMPILE_ON_SAVE, TRUE); // NOI18N
        ep.setProperty(ProjectProperties.COMPILE_ON_SAVE_UNSUPPORTED_PREFIX + ".javafx", TRUE); // NOI18N
        ep.setProperty(JFXProjectProperties.JAVAFX_BINARY_ENCODE_CSS, FALSE); // NOI18N
        ep.setProperty(JFXProjectProperties.JAVAFX_DEPLOY_INCLUDEDT, TRUE); // NOI18N
        ep.setProperty(JFXProjectProperties.JAVAFX_DEPLOY_EMBEDJNLP, TRUE); // NOI18N
        ep.setProperty(JFXProjectProperties.JAVAFX_REBASE_LIBS, FALSE); // NOI18N
        ep.setComment(JFXProjectProperties.JAVAFX_REBASE_LIBS, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_rebase_libs")}, false); // NOI18N
        ep.setProperty(JFXProjectProperties.JAVAFX_DISABLE_CONCURRENT_RUNS, FALSE); // NOI18N
        ep.setComment(JFXProjectProperties.JAVAFX_DISABLE_CONCURRENT_RUNS, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_disable_concurrent_runs")}, false); // NOI18N
        ep.setProperty(JFXProjectProperties.JAVAFX_ENABLE_CONCURRENT_EXTERNAL_RUNS, FALSE); // NOI18N
        ep.setComment(JFXProjectProperties.JAVAFX_ENABLE_CONCURRENT_EXTERNAL_RUNS, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_enable_concurrent_external_runs")}, false); // NOI18N
        ep.setProperty(JFXProjectProperties.UPDATE_MODE_BACKGROUND, FALSE); // NOI18N
        ep.setComment(JFXProjectProperties.UPDATE_MODE_BACKGROUND, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, type == WizardType.SWING ? "COMMENT_updatemode_swing" : "COMMENT_updatemode")}, false); // NOI18N
        ep.setProperty(JFXProjectProperties.ALLOW_OFFLINE, TRUE); // NOI18N
        if(targetPlatformName == null) {
            targetPlatformName = ep.getProperty(JFXProjectProperties.PLATFORM_ACTIVE);
        }
        Collection<String> extensions = JavaFxRuntimeInclusion.getProjectClassPathExtension(JavaFXPlatformUtils.findJavaPlatform(targetPlatformName));
        if (extensions != null && !extensions.isEmpty()) {
            ep.setProperty(JavaFXPlatformUtils.JAVAFX_CLASSPATH_EXTENSION, JFXProjectUtils.getPaths(extensions));
            ep.setProperty(ProjectProperties.JAVAC_CLASSPATH, new String[]{JavaFXPlatformUtils.getClassPathExtensionProperty()});
        }
        ep.setProperty(ProjectProperties.ENDORSED_CLASSPATH, ""); // NOI18N
        ep.setProperty(JFXProjectProperties.RUN_APP_WIDTH, "800"); // NOI18N
        ep.setProperty(JFXProjectProperties.RUN_APP_HEIGHT, "600"); // NOI18N
        if (type == WizardType.PRELOADER) {
            ep.setProperty(JFXProjectProperties.JAVAFX_PRELOADER, TRUE); // NOI18N
            ep.setComment(JFXProjectProperties.JAVAFX_PRELOADER, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_preloader")}, false); // NOI18N
            ep.setProperty(JFXProjectProperties.PRELOADER_ENABLED, FALSE); // NOI18N
            ep.setComment(JFXProjectProperties.PRELOADER_ENABLED, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_prepreloader")}, false); // NOI18N
        } else {
            ep.setProperty("jar.archive.disabled", TRUE); // NOI18N
            ep.setComment("jar.archive.disabled", new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_oldjar")}, false); // NOI18N
            ep.setProperty(ProjectProperties.MAIN_CLASS, type == WizardType.SWING ? (mainClass == null ? "" : mainClass) : "com.javafx.main.Main"); // NOI18N
            ep.setComment(ProjectProperties.MAIN_CLASS, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_main.class")}, false); // NOI18N
            if (type != WizardType.LIBRARY) {
                ep.setProperty(JFXProjectProperties.MAIN_CLASS, mainClass == null ? "" : mainClass); // NOI18N
                ep.setComment(JFXProjectProperties.MAIN_CLASS, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_main.fxclass")}, false); // NOI18N
            }
            if (preloader != null && preloader.length() > 0) {
                String preloaderProjRelative = "../" + preloader; // NOI18N
                String preloaderJarFileName = preloader + ".jar"; // NOI18N
                String copiedPreloaderJarPath = "${dist.dir}/lib/${" + JFXProjectProperties.PRELOADER_JAR_FILENAME + "}"; // NOI18N
                ep.setProperty(JFXProjectProperties.PRELOADER_ENABLED, TRUE); // NOI18N
                ep.setProperty(JFXProjectProperties.PRELOADER_TYPE, JFXProjectProperties.PreloaderSourceType.PROJECT.getString());
                ep.setComment(JFXProjectProperties.PRELOADER_ENABLED, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_use_preloader")}, false); // NOI18N
                ep.setProperty(JFXProjectProperties.PRELOADER_PROJECT, preloaderProjRelative);
                ep.setProperty(JFXProjectProperties.PRELOADER_CLASS, JavaFXProjectWizardIterator.generatePreloaderClassName(preloader));
                ep.setProperty(JFXProjectProperties.PRELOADER_JAR_PATH, copiedPreloaderJarPath);
                ep.setProperty(JFXProjectProperties.PRELOADER_JAR_FILENAME, preloaderJarFileName);
            } else {
                ep.setProperty(JFXProjectProperties.PRELOADER_ENABLED, FALSE); // NOI18N
                ep.setProperty(JFXProjectProperties.PRELOADER_TYPE, JFXProjectProperties.PreloaderSourceType.NONE.getString());
                ep.setComment(JFXProjectProperties.PRELOADER_ENABLED, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_dontuse_preloader")}, false); // NOI18N
                ep.setProperty(JFXProjectProperties.PRELOADER_PROJECT, ""); // NOI18N
                ep.setProperty(JFXProjectProperties.PRELOADER_CLASS, ""); // NOI18N
                ep.setProperty(JFXProjectProperties.PRELOADER_JAR_PATH, ""); // NOI18N
                ep.setProperty(JFXProjectProperties.PRELOADER_JAR_FILENAME, ""); // NOI18N
            }
            if (type == WizardType.SWING) {
                ep.setProperty(JFXProjectProperties.JAVAFX_SWING, TRUE); // NOI18N
                ep.setComment(JFXProjectProperties.JAVAFX_SWING, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_use_swing")}, false); // NOI18N
            }
        }
        ep.setProperty(JFXProjectProperties.IMPLEMENTATION_VERSION, JFXProjectProperties.IMPLEMENTATION_VERSION_DEFAULT);
        ep.setProperty(JFXProjectProperties.FALLBACK_CLASS, "com.javafx.main.NoJavaFXFallback"); // NOI18N
        // extended manifest entries
        ep.setProperty(JFXProjectProperties.MANIFEST_CUSTOM_CODEBASE, "*"); // NOI18N
        ep.setComment(JFXProjectProperties.MANIFEST_CUSTOM_CODEBASE, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_manifest_custom_codebase")}, false); // NOI18N
        ep.setProperty(JFXProjectProperties.MANIFEST_CUSTOM_PERMISSIONS, ""); // NOI18N
        ep.setComment(JFXProjectProperties.MANIFEST_CUSTOM_PERMISSIONS, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_manifest_custom_permissions")}, false); // NOI18N
        // SE->FX conversion cleanup
        ep.remove(JFXProjectProperties.JAVASE_KEEP_JFXRT_ON_CLASSPATH);
    }

    /**
     * Modify project.properties file to contain all javafx relevant properties with initial values
     * @param project
     * @throws IOException 
     */
    public static void resetJavaFXProjectProperties(@NonNull final Project project, @NonNull final WizardType type, final String targetPlatformName, @NonNull final String mainClass, final String preloader) throws IOException {
        final EditableProperties ep = new EditableProperties(true);
        final FileObject projPropsFO = project.getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH);
        try {
            ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
                @Override
                public Void run() throws Exception {
                    final Lookup lookup = project.getLookup();
                    final J2SEPropertyEvaluator eval = lookup.lookup(J2SEPropertyEvaluator.class);
                    String platformNameToCheck = null;
                    if (eval != null) {
                        String currentPlatformName = eval.evaluator().getProperty(JFXProjectProperties.PLATFORM_ACTIVE);
                        platformNameToCheck = currentPlatformName;
                        JavaPlatform platform = null;
                        if(targetPlatformName == null) {
                            platform = JavaFXPlatformUtils.findJavaPlatform(currentPlatformName);
                        } else {
                            platform = JavaFXPlatformUtils.findJavaPlatform(targetPlatformName);
                        }
                        if(platform == null || !JavaFXPlatformUtils.isJavaFXEnabled(platform)) {
                            platform = JavaFXPlatformUtils.findJavaFXPlatform();
                        }
                        if(platform != null && !JFXProjectProperties.isEqual(currentPlatformName, JavaFXPlatformUtils.getPlatformAntName(platform))) {
                            final J2SEProjectPlatform platformSetter = lookup.lookup(J2SEProjectPlatform.class);
                            if(platformSetter != null) {
                                platformSetter.setProjectPlatform(platform);
                                platformNameToCheck = JavaFXPlatformUtils.getPlatformAntName(platform);
                            }
                        }
                    }
                    final InputStream is = projPropsFO.getInputStream();
                    try {
                        ep.load(is);
                    } finally {
                        if (is != null) {
                            is.close();
                        }
                    }
                    initializeJavaFXProperties(ep, type, platformNameToCheck, mainClass, preloader);
                    OutputStream os = null;
                    FileLock lock = null;
                    try {
                        lock = projPropsFO.lock();
                        os = projPropsFO.getOutputStream(lock);
                        ep.store(os);
                    } finally {
                        if (os != null) {
                            os.close();
                        }
                        if (lock != null) {
                            lock.releaseLock();
                        }
                    }
                    return null;
                }
            });
        } catch (MutexException mux) {
            throw (IOException) mux.getException();
        }
    }

    /**
     * Adds FX specific build script jfx-impl.xml to project build system
     * @param p
     * @param dirFO
     * @param type
     * @throws IOException 
     */
    static void createJfxExtension(Project p, FileObject dirFO, WizardType type) throws IOException {
        FileObject templateFO = FileUtil.getConfigFile("Templates/JFX/jfx-impl.xml"); // NOI18N
        if (templateFO != null) {
            FileObject nbprojectFO = dirFO.getFileObject("nbproject"); // NOI18N
            FileObject jfxBuildFile = FileUtil.copyFile(templateFO, nbprojectFO, "jfx-impl"); // NOI18N
            if (type == JavaFXProjectWizardIterator.WizardType.SWING) {
                FileObject templatesFO = nbprojectFO.getFileObject("templates"); // NOI18N
                if (templatesFO == null) {
                    templatesFO = nbprojectFO.createFolder("templates"); // NOI18N
                }
                FileObject swingTemplateFO1 = FileUtil.getConfigFile("Templates/JFX/FXSwingTemplate.html"); // NOI18N
                if (swingTemplateFO1 != null) {
                    FileUtil.copyFile(swingTemplateFO1, templatesFO, "FXSwingTemplate"); // NOI18N
                }
                FileObject swingTemplateFO2 = FileUtil.getConfigFile("Templates/JFX/FXSwingTemplateApplet.jnlp"); // NOI18N
                if (swingTemplateFO1 != null) {
                    FileUtil.copyFile(swingTemplateFO2, templatesFO, "FXSwingTemplateApplet"); // NOI18N
                }
                FileObject swingTemplateFO3 = FileUtil.getConfigFile("Templates/JFX/FXSwingTemplateApplication.jnlp"); // NOI18N
                if (swingTemplateFO1 != null) {
                    FileUtil.copyFile(swingTemplateFO3, templatesFO, "FXSwingTemplateApplication"); // NOI18N
                }
            }
            JFXProjectUtils.addExtension(p);
        }
    }

    /**
     * Adds dependencies of build-impl targets on jfx-impl targets
     * @param proj
     * @return true if success
     * @throws IOException 
     */
    static boolean addExtension(@NonNull Project proj) throws IOException {
        boolean res = false;
        FileObject projDir = proj.getProjectDirectory();
        FileObject jfxBuildFile = projDir.getFileObject(JFX_BUILD_IMPL_PATH);
        AntBuildExtender extender = proj.getLookup().lookup(AntBuildExtender.class);
        if (extender != null) {
            assert jfxBuildFile != null;
            if (extender.getExtension(CURRENT_EXTENSION) == null) { // NOI18N                
                AntBuildExtender.Extension ext = extender.addExtension(CURRENT_EXTENSION, jfxBuildFile); // NOI18N
                // NOTE: change in dependencies = change of metafile updates API;
                //       do not forget to update CURRENT_EXTENSION and add the old one to OLD_EXTENSIONS
                ext.addDependency("-post-jar", "-jfx-copylibs"); // NOI18N
                ext.addDependency("-post-jar", "-rebase-libs"); //NOI18N
                ext.addDependency("-post-jar", "jfx-deployment"); //NOI18N 
                ext.addDependency("run", "jar"); //NOI18N
                ext.addDependency("debug", "jar");//NOI18N
                ext.addDependency("profile", "jar");//NOI18N
                res = true;
            }
        }
        return res;
    }

    /**
     * Remove SE native packaging extension and build script
     * @param project 
     */
    static void removeSENativeBundlerExtension(@NonNull Project project) throws IOException {
        final AntBuildExtender extender = project.getLookup().lookup(AntBuildExtender.class);
        if (extender != null) {
            AntBuildExtender.Extension extension = extender.getExtension(J2SEDEPLOY_EXTENSION);
            if (extension != null) {
                extender.removeExtension(J2SEDEPLOY_EXTENSION);
            }
            final FileObject buildExFo = project.getProjectDirectory().getFileObject(EXTENSION_BUILD_SCRIPT_PATH);
            if (buildExFo != null) {
                buildExFo.delete();
            }
        }
    }
    
    /**
     * Modify Java Application (SE) project to become JavaFX Application, i.e.,
     * set Application class, create FX build scripts, modify properties,
     * and turn on FX mode by setting property javafx.enabled=true;
     * @param project
     * @throws IOException 
     */
    public static void switchProjectToFX(@NonNull final Project project, @NonNull final JSEApplicationClassChooser chooser) throws IOException {
        final FileObject dirFO = project.getProjectDirectory();
        dirFO.getFileSystem().runAtomicAction(new FileSystem.AtomicAction() {
            @Override
            public void run() throws IOException {
                removeSENativeBundlerExtension(project);
                createJfxExtension(project, dirFO, WizardType.APPLICATION);
                ProjectManager.getDefault().saveProject(project);
                updateJFXExtension(project);
                
                //set main class
                String appClass = chooser.getSelectedExistingClass();
                if(appClass == null) {
                    FileObject dirController = chooser.getCurrentPackageFolder(true);
                    DataFolder packageDataFolder = DataFolder.findFolder(dirController);
                    String newClassName = chooser.getCurrentFileName();
                    if (packageDataFolder != null) {
                        FileObject javaTemplate = FileUtil.getConfigFile("Templates/javafx/FXMain.java"); // NOI18N
                        DataObject dJavaTemplate = DataObject.find(javaTemplate);
                        DataObject dobj = dJavaTemplate.createFromTemplate(packageDataFolder, newClassName);
                    }
                    appClass = chooser.getPackageName() + "." + newClassName; // NOI18N
                }
                resetJavaFXProjectProperties(project, WizardType.APPLICATION, null, appClass, null); // NOI18N
                
                for (ProjectIconAnnotator annotator : Lookup.getDefault().lookupAll(ProjectIconAnnotator.class)) {
                    if(annotator instanceof JFXProjectIconAnnotator) {
                        JFXProjectIconAnnotator fxAnnotator = (JFXProjectIconAnnotator) annotator;
                        fxAnnotator.fireChange(project, true);
                    }
                }
            }
        });
        final String headerTemplate = NbBundle.getMessage(JFXProjectUtils.class, "TXT_SWITCHED_SE_TO_FX_HEADER"); //NOI18N
        final String header = MessageFormat.format(headerTemplate, new Object[] {ProjectUtils.getInformation(project).getDisplayName()});
        final String content = NbBundle.getMessage(JFXProjectUtils.class, "TXT_SWITCHED_SE_TO_FX_CONTENT"); //NOI18N
        Notification notePlatformChange = NotificationDisplayer.getDefault().notify(
                header, 
                ImageUtilities.loadImageIcon("org/netbeans/modules/javafx2/project/ui/resources/jfx_project.png", true), //NOI18N
                content, 
                null, 
                NotificationDisplayer.Priority.LOW, 
                NotificationDisplayer.Category.INFO);
        JFXProjectOpenedHook.addNotification(project, notePlatformChange);
    }
    
    /**
     * Update dependencies of build-impl targets on jfx-impl targets
     * @param project
     * @return
     * @throws IOException 
     */
    public static boolean updateJFXExtension(final Project project) throws IOException {
        boolean changed = modifyBuildXml(project);
        return changed;
    }

    /**
     * Update SE buildscript dependencies on FX buildscript
     * @param proj
     * @return
     * @throws IOException 
     */
    private static boolean modifyBuildXml(Project proj) throws IOException {
        boolean res = false;
        final FileObject buildXmlFO = getBuildXml(proj);
        if (buildXmlFO == null) {
            LOGGER.warning("The project build script does not exist, the project cannot be extended by JFX.");     //NOI18N
            return res;
        }
        Document xmlDoc = null;
        try {
            xmlDoc = XMLUtil.parse(new InputSource(buildXmlFO.toURL().toExternalForm()), false, true, null, null);
        } catch (SAXException ex) {
            Exceptions.printStackTrace(ex);
        }
        if(!addExtension(proj)) {
            LOGGER.log(Level.INFO,
                    "Trying to include JFX build snippet in project type that doesn't support AntBuildExtender API contract."); // NOI18N
        }

        //TODO this piece shall not proceed when the upgrade to j2se-project/4 was cancelled.
        //how to figure..
        Element docElem = xmlDoc.getDocumentElement();
        NodeList nl = docElem.getElementsByTagName("target"); // NOI18N
        boolean changed = false;
        nl = docElem.getElementsByTagName("import"); // NOI18N
        for (int i = 0; i < nl.getLength(); i++) {
            Element e = (Element) nl.item(i);
            if (e.getAttribute("file") != null && JFX_BUILD_IMPL_PATH.equals(e.getAttribute("file"))) { // NOI18N
                e.getParentNode().removeChild(e);
                changed = true;
                break;
            }
        }

        if (changed) {
            final Document fdoc = xmlDoc;
            try {
                ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
                    @Override
                    public Void run() throws Exception {
                        FileLock lock = buildXmlFO.lock();
                        try {
                            OutputStream os = buildXmlFO.getOutputStream(lock);
                            try {
                                XMLUtil.write(fdoc, os, "UTF-8"); // NOI18N
                            } finally {
                                os.close();
                            }
                        } finally {
                            lock.releaseLock();
                        }
                        return null;
                    }
                });
            } catch (MutexException mex) {
                throw (IOException) mex.getException();
            }
        }
        return res;
    }

    /**
     * Get build.xml
     * @param prj
     * @return 
     */
    private static FileObject getBuildXml(final Project prj) {
        final J2SEPropertyEvaluator j2sepe = prj.getLookup().lookup(J2SEPropertyEvaluator.class);
        assert j2sepe != null;
        final PropertyEvaluator eval = j2sepe.evaluator();
        String buildScriptPath = eval.getProperty(JFXProjectProperties.BUILD_SCRIPT);
        if (buildScriptPath == null) {
            buildScriptPath = GeneratedFilesHelper.BUILD_XML_PATH;
        }
        return prj.getProjectDirectory().getFileObject (buildScriptPath);
    }

    /**
     * Update FX build script.
     * @param proj
     * @return
     * @throws IOException 
     */
    public static FileObject updateJfxImpl(final @NonNull Project proj) throws IOException {
        final FileObject projDir = proj.getProjectDirectory();
        final List<FileObject> updates = new ArrayList<FileObject>();
        try {
            ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
                @Override
                public Void run() throws Exception {        
                    projDir.getFileSystem().runAtomicAction(new FileSystem.AtomicAction() {
                        public void run() throws IOException {        
                            if(!JFXProjectUtils.isJFXImplCurrent(proj)) {
                                FileObject updated = JFXProjectUtils.doUpdateJfxImpl(proj);
                                if(updated != null) {
                                    updates.add(updated);
                                }
                            }
                        }
                    });
                    return null;
                }
            });
        } catch (MutexException ex) {
            Exceptions.printStackTrace(ex);
        }
        return updates.isEmpty() ? null : updates.get(0);
    }
    
    /**
     * Checks whether file nbproject/jfx-impl.xml equals current template. 
     * @param proj
     * @return
     * @throws IOException 
     */
    public static boolean isJFXImplCurrent(final @NonNull Project proj) throws IOException {
        Boolean isJfxCurrent = true;
        final FileObject projDir = proj.getProjectDirectory();
        try {
            isJfxCurrent = ProjectManager.mutex().readAccess(new Mutex.ExceptionAction<Boolean>() {
                @Override
                public Boolean run() throws Exception {
                    FileObject jfxBuildFile = projDir.getFileObject(JFX_BUILD_IMPL_PATH); // NOI18N
                    Boolean isCurrent = false;
                    if (jfxBuildFile != null) {
                        final InputStream in = jfxBuildFile.getInputStream();
                        if(in != null) {
                            try {
                                isCurrent = isJfxImplCurrentVer(computeCrc32( in ));
                            } finally {
                                in.close();
                            }
                        }
                    }
                    return isCurrent;
                }
            });
        } catch (MutexException mux) {
            isJfxCurrent = false;
            LOGGER.log(Level.INFO, "Problem reading " + JFX_BUILD_IMPL_PATH, mux.getException()); // NOI18N
        }
        return isJfxCurrent;
    }    

    /**
     * The file nbproject/jfx-impl.xml is backed up and regenerated to the current state
     * and textual commentary is generated to UPDATED.TXT.
     * 
     * @param prj the project to check
     * @return FileObject pointing at generated UPDATED.TXT or null
     */
    static FileObject doUpdateJfxImpl(final @NonNull Project proj) throws IOException {
        FileObject returnFO = null;
        final FileObject projDir = proj.getProjectDirectory();
        try {
            returnFO = ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<FileObject>() {
                @Override
                public FileObject run() throws Exception {
                    FileObject returnFO = null;
                    FileObject jfxBuildFile = projDir.getFileObject(JFX_BUILD_IMPL_PATH); // NOI18N
                    if (jfxBuildFile != null) {
                        // try to close the file just in case the file is already opened in editor
                        DataObject dobj = DataObject.find(jfxBuildFile);
                        CloseCookie closeCookie = dobj.getLookup().lookup(CloseCookie.class);
                        if (closeCookie != null) {
                            closeCookie.close();
                        }
                        closeCookie = null;
                        dobj = null;

                        final FileObject nbproject = projDir.getFileObject(NBPROJECT); //NOI18N
                        final String backupName = FileUtil.findFreeFileName(nbproject, JFX_BUILD_IMPL_NAME + "_backup", "xml"); //NOI18N
                        FileUtil.moveFile(jfxBuildFile, nbproject, backupName);
                        LOGGER.log(Level.INFO, "Old build script file " + JFX_BUILD_IMPL_NAME + ".xml has been renamed to: {0}.xml", backupName); // NOI18N
                        jfxBuildFile = null;

                        try {
                            final File readme = new File (FileUtil.toFile(nbproject), NbBundle.getMessage(JFXProjectUtils.class, "TXT_UPDATED_README_FILE_NAME")); //NOI18N
                            if (!readme.exists()) {
                                readme.createNewFile();
                            }
                            final FileObject readmeFO = FileUtil.toFileObject(readme);
                            returnFO = readmeFO;
                            OutputStream os = null;
                            FileLock lock = null;
                            try {
                                lock = readmeFO.lock();
                                os = readmeFO.getOutputStream(lock);
                                final PrintWriter out = new PrintWriter ( os );
                                try {
                                    final String headerTemplate = NbBundle.getMessage(JFXProjectUtils.class, "TXT_UPDATED_README_FILE_CONTENT_HEADER"); //NOI18N
                                    final String header = MessageFormat.format(headerTemplate, new Object[] {ProjectUtils.getInformation(proj).getDisplayName()});
                                    char[] underline = new char[header.length()];
                                    Arrays.fill(underline, '='); // NOI18N
                                    final String content = NbBundle.getMessage(JFXProjectUtils.class, "TXT_UPDATED_README_FILE_CONTENT"); //NOI18N
                                    out.println(underline);
                                    out.println(header);
                                    out.println(underline);
                                    out.println (MessageFormat.format(content, new Object[] {backupName + ".xml"})); //NOI18N
                                } finally {
                                    if(out != null) {
                                        out.close ();
                                    }
                                }
                            } finally {
                                if (os != null) {
                                    os.close();
                                }
                                if (lock != null) {
                                    lock.releaseLock();
                                }
                            }
                        } catch (IOException ioe) {
                            LOGGER.log(Level.INFO, "Cannot create file readme file. ", ioe); // NOI18N
                        }        
                    }
                    if (jfxBuildFile == null) {
                        FileObject templateFO = FileUtil.getConfigFile(JFX_BUILD_TEMPLATE);
                        if (templateFO != null) {
                            FileUtil.copyFile(templateFO, projDir.getFileObject(NBPROJECT), JFX_BUILD_IMPL_NAME); // NOI18N
                            LOGGER.log(Level.INFO, "Build script " + JFX_BUILD_IMPL_NAME + ".xml has been updated to the latest version supported by this NetBeans installation."); // NOI18N
                        } 
                    }
                    return returnFO;
                } //run()
            });
        } catch(MutexException mux) {
            throw (IOException) mux.getException();
        }
        return returnFO;
    }

    /**
     * Computes CRC code of data from InputStream
     * 
     * @param is InputStream to read data from
     * @return CRC code
     */
    public static String computeCrc32(InputStream is) throws IOException {
        Checksum crc = new CRC32();
        int last = -1;
        int curr;
        while ((curr = is.read()) != -1) {
            if (curr != '\n' && last == '\r') {
                crc.update('\n');
            }
            if (curr != '\r') {
                crc.update(curr);
            }
            last = curr;
        }
        if (last == '\r') {
            crc.update('\n');
        }
        int val = (int)crc.getValue();
        String hex = Integer.toHexString(val);
        while (hex.length() < 8) {
            hex = "0" + hex; // NOI18N
        }
        return hex;
    }

    /**
     * Checks whether crc is the CRC code of current jfx-impl.xml template.
     * 
     * @param crc code to be compared against
     * @return true if crc is the CRC code of current jfx-impl.xml template.
     */
    public static boolean isJfxImplCurrentVer(String crc) throws IOException {
        String _currentJfxImplCRC = currentJfxImplCRCCache;
        if (_currentJfxImplCRC == null) {
            final FileObject template = FileUtil.getConfigFile(JFX_BUILD_TEMPLATE);
            final InputStream in = template.getInputStream();
            if(in != null) {
                try {
                    currentJfxImplCRCCache = _currentJfxImplCRC = computeCrc32(in);
                } finally {
                    in.close();
                }
            }
        }
        return _currentJfxImplCRC.equals(crc);
    }

    public static boolean isProjectOpen(@NonNull Project project) {
        Project[] projects = OpenProjects.getDefault().getOpenProjects();
        if(projects != null) {
            for(Project p : Arrays.asList(projects)) {
                if(p.getProjectDirectory().getPath().equals(project.getProjectDirectory().getPath())) {
                    return true;
                }
            }
        }
        return false;
    }
    
    /**
     * Updates project.properties so that if JFXRT artifacts are explicitly added to
     * compile classpath if they are not on classpath by default. This is a workaround
     * of the fact that JDK1.7 does contain FX RT but does not provide it on classpath.
     * JDK1.8 has FX RT on classpath, but still may not include all relevant artifacts by default
     * and may need this extension.
     * Note that this extension is relevant not only for FX Application projects, but also
     * for SE projects that have the property "keep.javafx.runtime.on.classpath" set 
     * (see SE Deployment category in Project Properties dialog).
     * 
     * @param prj the project to update
     */
    public static void updateClassPathExtension(@NonNull final Project project) throws IOException {
        final boolean hasDefaultJavaFXPlatform[] = new boolean[1];
        final EditableProperties ep = new EditableProperties(true);
        final FileObject projPropsFO = project.getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH);
        if(projPropsFO != null) {
            try {
                ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
                    @Override
                    public Void run() throws Exception {
                        final Lookup lookup = project.getLookup();
                        final J2SEPropertyEvaluator eval = lookup.lookup(J2SEPropertyEvaluator.class);
                        if (eval != null) {
                            // if project has Default_JavaFX_Platform, change it to default Java Platform
                            String platformName = eval.evaluator().getProperty(JFXProjectProperties.PLATFORM_ACTIVE);
                            hasDefaultJavaFXPlatform[0] = JFXProjectProperties.isEqual(platformName, JavaFXPlatformUtils.DEFAULT_JAVAFX_PLATFORM);
                        }
                        if(hasDefaultJavaFXPlatform[0]) {
                            final J2SEProjectPlatform platformSetter = lookup.lookup(J2SEProjectPlatform.class);
                            if(platformSetter != null) {
                                platformSetter.setProjectPlatform(JavaPlatformManager.getDefault().getDefaultPlatform());
                            }
                        }
                        try (InputStream is = projPropsFO.getInputStream()) {
                            ep.load(is);
                        }
                        boolean cpExtUpdated = updateClassPathExtensionProperties(ep);
                        if (cpExtUpdated) {
                            final FileLock lock = projPropsFO.lock();
                            try (OutputStream os =projPropsFO.getOutputStream(lock)) {
                                ep.store(os);
                            } finally {                                                                
                                lock.releaseLock();
                            }
                        }
                        return null;
                    }
                });
            } catch (MutexException mux) {
                throw (IOException) mux.getException();
            }
            if(hasDefaultJavaFXPlatform[0]) {
                final String headerTemplate = NbBundle.getMessage(JFXProjectUtils.class, "TXT_UPDATED_DEFAULT_PLATFORM_HEADER"); //NOI18N
                final String header = MessageFormat.format(headerTemplate, new Object[] {ProjectUtils.getInformation(project).getDisplayName()});
                final String content = NbBundle.getMessage(JFXProjectUtils.class, "TXT_UPDATED_DEFAULT_PLATFORM_CONTENT"); //NOI18N
                Notification notePlatformChange = NotificationDisplayer.getDefault().notify(
                        header, 
                        ImageUtilities.loadImageIcon("org/netbeans/modules/javafx2/project/ui/resources/jfx_project.png", true), //NOI18N
                        content, 
                        null, 
                        NotificationDisplayer.Priority.LOW, 
                        NotificationDisplayer.Category.INFO);
                JFXProjectOpenedHook.addNotification(project, notePlatformChange);
            }
        } else {
            LOGGER.warning("Project metafiles inaccessible - classpath extension could not be verified and updated if needed."); //NOI18N
        }
    }

    /**
     * Update main class property in project metafiles in the current configuration
     * @param project
     * @param mainClass
     * @throws IOException 
     */
    public static void updatePropertyInActiveConfig(@NonNull final Project project, @NonNull final String propName, @NonNull final String propValue) throws IOException {
        final FileObject projectDir = project.getProjectDirectory();
        try {
            ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
                @Override
                public Void run() throws Exception {
                    final EditableProperties cep = new EditableProperties(true);
                    final FileObject configFO = projectDir.getFileObject(JFXProjectConfigurations.CONFIG_PROPERTIES_FILE);
                    if(configFO != null) {
                        final InputStream cis = configFO.getInputStream();
                        try {
                            cep.load(cis);
                        } finally {
                            if (cis != null) {
                                cis.close();
                            }
                        }
                    }
                    String config = cep.getProperty(ProjectProperties.PROP_PROJECT_CONFIGURATION_CONFIG);
                    
                    final FileObject projPropsFO = config == null ? projectDir.getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH) :
                            projectDir.getFileObject(JFXProjectConfigurations.PROJECT_CONFIGS_DIR + 
                            "/" + config + "." + JFXProjectConfigurations.PROPERTIES_FILE_EXT);  //NOI18N
                    assert projPropsFO != null : "Inaccessible file " + JFXProjectConfigurations.PROJECT_CONFIGS_DIR +  //NOI18N
                            "/" + config + "." + JFXProjectConfigurations.PROPERTIES_FILE_EXT;  //NOI18N
                    final InputStream is = projPropsFO.getInputStream();
                    final EditableProperties ep = new EditableProperties(true);
                    try {
                        ep.load(is);
                    } finally {
                        if (is != null) {
                            is.close();
                        }
                    }
                    ep.setProperty(propName, propValue);
                    OutputStream os = null;
                    FileLock lock = null;
                    try {
                        lock = projPropsFO.lock();
                        os = projPropsFO.getOutputStream(lock);
                        ep.store(os);
                    } finally {
                        if (os != null) {
                            os.close();
                        }
                        if (lock != null) {
                            lock.releaseLock();
                        }
                    }
                    return null;
                }
            });
        } catch (MutexException mux) {
            throw (IOException) mux.getException();
        }
    }

    /**
     * Create array of Strings representing path artifacts that can be set to path property;
     * all but the last String gets : appended.
     * @param artifacts
     * @return array of artifacts
     */
    public static String[] getPaths(@NonNull final Collection<String> artifacts) {
        List<String> l = new ArrayList<String>();
        Iterator<String> i = artifacts.iterator();
        while(i.hasNext()) {
            String s = i.next();
            if(i.hasNext()) {
                if(s.endsWith(":")) { //NOI18N
                    l.add(s);
                } else {
                    l.add(s + ":"); //NOI18N
                }
            } else {
                if(s.endsWith(":")) { //NOI18N
                    l.add(s.substring(0, s.length()-1));
                } else {
                    l.add(s);
                }
            }
        }
        return l.toArray(new String[0]);
    }
    
    /**
     * Remove trailing : from array of path artifacts and return the array as collection
     * @param artifacts
     * @return 
     */
    @NonNull
    public static Set<String> getPaths(@NonNull final String[] artifacts) {        
        final Set<String> l = new LinkedHashSet<>();
        for(String artifact : artifacts) {
            if(artifact.endsWith(":")) { //NOI18N
                l.add(artifact.substring(0, artifact.length()-1));
            } else {
                l.add(artifact);
            }
        }
        return l;
    }
    
    /**
     * Filter out artifacts that contain subString
     * @param artifacts
     * @return set without artifacts that contain subString
     */
    private static Set<String> filterOutArtifacts(@NonNull final Collection<String> artifacts, @NonNull String subString) {
        Set<String> result = new LinkedHashSet<String>();
        for(String artifact : artifacts) {
            if(!artifact.contains(subString)) {
                result.add(artifact);
            }
        }
        return result;
    }
    
    /**
     * Returns existing value of a path property, null if it does not exist
     * @param ep EditableProperties
     * @return collection of artifacts or null
     */
    @CheckForNull
    public static Set<String> getExistingProperty(@NonNull final EditableProperties ep, @NonNull String propName) {
        // existing 
        String currentPropVal = ep.getProperty(propName);
        if(currentPropVal != null) {
            return Collections.unmodifiableSet(getPaths(PropertyUtils.tokenizePath(currentPropVal)));
        }
        return null;
    }
    
    /**
     * Returns updated value of classpath property, null if it should not exist
     * @param ep EditableProperties
     * @return collection of artifacts or null
     */
    public static Set<String> getUpdatedCPProperty(@NonNull final EditableProperties ep, boolean extensionPropertyEmpty) {
        boolean extensionNeeded = JFXProjectProperties.isTrue(ep.getProperty(JFXProjectProperties.JAVAFX_ENABLED)) ||
                JFXProjectProperties.isTrue(ep.getProperty(JFXProjectProperties.JAVASE_KEEP_JFXRT_ON_CLASSPATH));
        // existing
        Set<String> existing = getExistingProperty(ep, ProjectProperties.JAVAC_CLASSPATH);
        Set<String> updated = new LinkedHashSet<String>();
        if(existing != null) {
            updated = filterOutArtifacts(existing, "${javafx.runtime}"); // NOI18N
            updated = filterOutArtifacts(updated, JavaFXPlatformUtils.getClassPathExtensionProperty());
        }
        if(extensionNeeded && !extensionPropertyEmpty) {
            updated.add(JavaFXPlatformUtils.getClassPathExtensionProperty());
        }
        return Collections.unmodifiableSet(updated);
    }

    /**
     * Removes the path entry from path.
     * @param path to remove the netry from
     * @param toRemove the entry to be rmeoved from the path
     * @return new path with removed entry
     */
    @NonNull
    public static String removeFromPath(@NonNull final String path, @NonNull final String toRemove) {
        Parameters.notNull("path", path);   //NOI18N
        Parameters.notNull("toRemove", toRemove); //NOI18N
        final StringBuilder sb = new StringBuilder();
        for (String entry : PropertyUtils.tokenizePath(path)) {
            if (toRemove.equals(entry)) {
                continue;
            }
            sb.append(entry);
            sb.append(':'); //NOI18N
        }
        return sb.length() == 0 ?
            sb.toString() :
            sb.substring(0, sb.length()-1);
    }

    /**
     * Returns new value of FX artifacts extension property if it needs to be updated, null otherwise
     * @param ep EditableProperties
     * @return collection of artifacts or null
     */
    public static Set<String> getUpdatedExtensionProperty(@NonNull final EditableProperties ep) throws IllegalArgumentException {
        boolean propertyNeeded = JFXProjectProperties.isTrue(ep.getProperty(JFXProjectProperties.JAVAFX_ENABLED)) ||
                JFXProjectProperties.isTrue(ep.getProperty(JFXProjectProperties.JAVASE_KEEP_JFXRT_ON_CLASSPATH));
        // expected
        Set<String> updated = null;
        if(propertyNeeded) {
            String platformName = ep.getProperty(JFXProjectProperties.PLATFORM_ACTIVE);
            JavaPlatform platform = JavaFXPlatformUtils.findJavaPlatform(platformName);
            if(platform == null) {
                // platform does not exist, thus no extension property update is to take place
                return null;
            }
            updated = JavaFxRuntimeInclusion.getProjectClassPathExtension(platform);
        }
        return updated == null ? null : Collections.unmodifiableSet(updated);
    }

    /**
     * Compares two Set representations of a path property
     * @param set1
     * @param set2
     * @return true if the two sets represent equal existence and values of path properties
     */
    public static boolean pathPropertiesEqual(Set<String> set1, Set<String> set2) {
        if(set1 == null && set2 == null) {
            return true;
        }
        if(set1 == null || set2 == null) {
            return false;
        }
        return set1.containsAll(set2) && set2.containsAll(set1);
    }
    
    /**
     * Checks whether JFXRT artifacts are properly added to classpath and represented 
     * in project.properties if the current Java Platform needs this workaround
     * @param prj the project to check
     * @return true if project properties correctly represent JFXRT artifacts
     */
    public static boolean hasCorrectClassPathExtension(@NonNull final Project project) throws IOException, IllegalArgumentException  {
        final EditableProperties ep = readFromFile(
            project.getProjectDirectory().getFileObject(AntProjectHelper.PROJECT_PROPERTIES_PATH)
                );
        String platformName = ep.getProperty(JFXProjectProperties.PLATFORM_ACTIVE);
        if(JFXProjectProperties.isEqual(platformName, JavaFXPlatformUtils.DEFAULT_JAVAFX_PLATFORM)) {
            // request auto-replace of Default_JavaFX_Platform by default platform
            return false;
        }
        Set<String> existingExt = getExistingProperty(ep, JavaFXPlatformUtils.JAVAFX_CLASSPATH_EXTENSION);
        Set<String> updatedExt = getUpdatedExtensionProperty(ep);
        Set<String> existingCP = getExistingProperty(ep, ProjectProperties.JAVAC_CLASSPATH);
        Set<String> updatedCP = getUpdatedCPProperty(ep, updatedExt == null || updatedExt.isEmpty());
        return pathPropertiesEqual(existingExt, updatedExt) && pathPropertiesEqual(existingCP, updatedCP);
    }
    
    /**
     * Updates EditableProperties so that JFXRT artifacts are explicitly added to
     * compile classpath if they are not on classpath by default. This is a workaround
     * of the fact that JDK1.7 does contain FX RT but does not provide it on classpath.
     * JDK1.8 has FX RT on classpath, but still may not include all relevant artifacts by default
     * and may need this extension.
     * Note that this extension is relevant not only for FX Application projects, but also
     * for SE projects that have the property "keep.javafx.runtime.on.classpath" set 
     * (see SE Deployment category in Project Properties dialog).
     * 
     * @param ep EditableProperties containing properties to be updated
     */
    public static boolean updateClassPathExtensionProperties(@NonNull final EditableProperties ep) {
        boolean changed = false;
        changed = ep.remove(PROPERTY_JAVAFX_RUNTIME) != null ? true : changed;
        changed = ep.remove(PROPERTY_JAVAFX_SDK) != null ? true : changed;
        Collection<String> extendExtProp = getUpdatedExtensionProperty(ep);
        if(extendExtProp != null && !extendExtProp.isEmpty()) {
            Collection<String> currentCpExt = getExistingProperty(ep, JavaFXPlatformUtils.JAVAFX_CLASSPATH_EXTENSION);
            if (!extendExtProp.equals(currentCpExt)) {
                //update javafx.classpath.extension only in case that current value doesn't contain required jars
                ep.setProperty(JavaFXPlatformUtils.JAVAFX_CLASSPATH_EXTENSION, getPaths(extendExtProp));
                changed = true;
            }
        } else {
            changed = ep.remove(JavaFXPlatformUtils.JAVAFX_CLASSPATH_EXTENSION) != null ? true : changed;
            //ep.remove(JFXProjectProperties.JAVASE_KEEP_JFXRT_ON_CLASSPATH);
        }
        Collection<String> extendCPProp = getUpdatedCPProperty(ep, extendExtProp == null || extendExtProp.isEmpty());
        // JAVAC_CLASSPATH to be preserved even if empty (create new project creates it empty by default)
        if(extendCPProp != null) {
            Collection<String> currentJavacCp = getExistingProperty(ep, ProjectProperties.JAVAC_CLASSPATH);
            if (!extendCPProp.equals(currentJavacCp)) {
                ep.setProperty(ProjectProperties.JAVAC_CLASSPATH, getPaths(extendCPProp));
                changed = true;
            }
        }
        // Remove JavaFX endorsed.classpath entries if they are present (#235380, see also #214386)
        final String endorsedCp = ep.get(ProjectProperties.ENDORSED_CLASSPATH);
        if (endorsedCp != null && !endorsedCp.isEmpty()) {
            String[] cpElements = PropertyUtils.tokenizePath(endorsedCp);
            List<String> updatedEndorsedCpList = new ArrayList<String>();
            for (String element : cpElements) {
                if (!element.startsWith("${javafx.runtime}/")) { //NOI18N
                    updatedEndorsedCpList.add(element);
                }
            }
            String[] updatedEndorsedCp = updatedEndorsedCpList.toArray(new String[0]);
            for (int i = 0; i < updatedEndorsedCp.length - 1; i++) {
                updatedEndorsedCp[i] += ":"; //NOI18N
            }
            ep.setProperty(ProjectProperties.ENDORSED_CLASSPATH, updatedEndorsedCp);
            changed = true;
        }
        return changed;
    }

    /**
     * Checks the existence of default configuration for given RUN_AS type.
     * If it does not exist, it is created.
     * 
     * @param proj the project to check
     * @param runAs run type whose default configuration is to be updated
     * @param setBrowserProps if true, adds properties representing an existing browser
     * @return true is any update took place
     */
    public static boolean updateDefaultRunAsConfigFile(final @NonNull FileObject projDir, JFXProjectProperties.RunAsType runAs, boolean setBrowserProps) throws IOException {
        boolean updated = false;
        String configName = runAs.getDefaultConfig();
        String configFile = makeSafe(configName);
        String sharedPath = JFXProjectConfigurations.getSharedConfigFilePath(configFile);
        FileObject sharedCfgFO = projDir.getFileObject(sharedPath);
        final EditableProperties sharedCfgProps = sharedCfgFO != null ?
                readFromFile(sharedCfgFO) : new EditableProperties(true);
        assert sharedCfgProps != null;
        if(sharedCfgProps.isEmpty()) {
            sharedCfgProps.setProperty("$label", configName); // NOI18N
            sharedCfgProps.setComment("$label", new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_run_as_defaults")}, false); // NOI18N
            saveToFile(projDir, sharedPath, sharedCfgProps);
            updated = true;
        }
        String privatePath = JFXProjectConfigurations.getPrivateConfigFilePath(configFile);
        FileObject privateCfgFO = projDir.getFileObject(privatePath);
        final EditableProperties privateCfgProps = privateCfgFO != null ?
                readFromFile(projDir, privatePath) : new EditableProperties(true);
        assert privateCfgProps != null;
        if(privateCfgProps.isEmpty() || setBrowserProps) {
            privateCfgProps.setProperty(JFXProjectProperties.RUN_AS, runAs.getString());
            privateCfgProps.setComment(JFXProjectProperties.RUN_AS, new String[]{"# " + NbBundle.getMessage(JFXProjectUtils.class, "COMMENT_run_as_defaults")}, false); // NOI18N
            if(setBrowserProps) {
                Map<String,String> browserInfo = getDefaultBrowserInfo();
                if(browserInfo != null && !browserInfo.isEmpty()) {
                    for(Map.Entry<String,String> entry : browserInfo.entrySet()) {
                        privateCfgProps.setProperty(JFXProjectProperties.RUN_IN_BROWSER, entry.getKey());
                        privateCfgProps.setProperty(JFXProjectProperties.RUN_IN_BROWSER_PATH, entry.getValue());
                        break;
                    }
                }
            }
            saveToFile(projDir, privatePath, privateCfgProps);       
            updated = true;
        }
        return updated;
    }

    /**
     * @return name and path to default browser
     */
    public static Map<String,String> getDefaultBrowserInfo() {
        Lookup.Result<ExtWebBrowser> allBrowsers = Lookup.getDefault().lookupResult(ExtWebBrowser.class);
        Map<String,String> browserPaths = new HashMap<String, String>();
        for(Lookup.Item<ExtWebBrowser> browser : allBrowsers.allItems()) {
            String name = browser.getDisplayName();
            if(name != null && name.toLowerCase().contains("default")) { // NOI18N
                NbProcessDescriptor proc = browser.getInstance().getBrowserExecutable();
                String path = proc.getProcessName();
                if(JFXProjectProperties.isNonEmpty(path)) {
                    browserPaths.put(name, path);
                }
                break;
            }
        }
        return browserPaths;
    }
    
    /**
     * Returns a copy of existing list of maps, usually used to store application parameters
     * 
     * @param list2Copy
     * @return copy of list2Copy
     */
    public static List<Map<String,String>> copyList(List<Map<String,String>> list2Copy) {
        List<Map<String,String>> list2Return = new ArrayList<Map<String,String>>();
        if(list2Copy != null ) {
            for (Map<String,String> map : list2Copy) {
                list2Return.add(copyMap(map));
            }
        }
        return list2Return;
    }

    /**
     * Returns a copy of existing string map, usually used to store application parameter
     * (keys 'name' and 'value')
     * 
     * @param map2Copy
     * @return copy of map2Copy
     */
    public static Map<String,String> copyMap(Map<String,String> map2Copy) {
        Map<String,String> newMap = new HashMap<String,String>();
        if(map2Copy != null) {
            for(String key : map2Copy.keySet()) {
                String value = map2Copy.get(key);
                newMap.put(key, value);
            }
        }
        return newMap;
    }

    /**
     * Modifies name so that it can be used as file name,
     * i.e., replaces problematic characters.
     * 
     * @param name
     * @return modified name usable as file name
     */
    public static String makeSafe(@NonNull String name) {
        return name.replaceAll("[^a-zA-Z0-9_.-]", "_"); // NOI18N;
    }

    public static EditableProperties readFromFile(final @NonNull Project project, final @NonNull String relativePath) throws IOException {
        final FileObject dirFO = project.getProjectDirectory();
        return readFromFile(dirFO, relativePath);
    }

    public static EditableProperties readFromFile(final @NonNull FileObject dirFO, final @NonNull String relativePath) throws IOException {
        assert dirFO.isFolder();
        final FileObject propsFO = dirFO.getFileObject(relativePath);
        return readFromFile(propsFO);
    }

    public static EditableProperties readFromFile(final @NonNull FileObject propsFO) throws IOException {
        final EditableProperties ep = new EditableProperties(true);
        if(propsFO != null) {
            assert propsFO.isData();
            try {
                ProjectManager.mutex().readAccess(new Mutex.ExceptionAction<Void>() {
                    @Override
                    public Void run() throws Exception {
                        final InputStream is = propsFO.getInputStream();
                        try {
                            ep.load(is);
                        } finally {
                            if (is != null) {
                                is.close();
                            }
                        }
                        return null;
                    }
                });
            } catch (MutexException mux) {
                throw (IOException) mux.getException();
            }
        }
        return ep;
    }

    public static void deleteFile(final @NonNull Project project, final @NonNull String relativePath) throws IOException {
        final FileObject propsFO = project.getProjectDirectory().getFileObject(relativePath);
        deleteFile(propsFO);
    }
    
    public static void deleteFile(final @NonNull FileObject dirFO, final @NonNull String relativePath) throws IOException {
        assert dirFO.isFolder();
        final FileObject propsFO = dirFO.getFileObject(relativePath);
        deleteFile(propsFO);
    }

    public static void deleteFile(final @NonNull FileObject propsFO) throws IOException {
        if(propsFO != null) {
            try {
                ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
                    @Override
                    public Void run() throws Exception {
                        propsFO.delete();
                        return null;
                    }
                });
            } catch (MutexException mux) {
                throw (IOException) mux.getException();
            }       
        }
    }

    public static void saveToFile(final @NonNull Project project, final @NonNull String relativePath, final @NonNull EditableProperties ep) throws IOException {
        FileObject dirFO = project.getProjectDirectory();
        saveToFile(dirFO, relativePath, ep);
    }
    
    public static void saveToFile(final @NonNull FileObject dirFO, final @NonNull String relativePath, final @NonNull EditableProperties ep) throws IOException {
        assert dirFO.isFolder();
        FileObject f = dirFO.getFileObject(relativePath);
        final FileObject propsFO;
        if(f == null) {
            propsFO = FileUtil.createData(dirFO, relativePath);
            assert propsFO != null : "FU.cD must not return null; called on " + dirFO + " + " + relativePath; // #50802  // NOI18N
        } else {
            propsFO = f;
        }
        saveToFile(propsFO, ep);
    }
    
    public static void saveToFile(final @NonNull FileObject propsFO, final @NonNull EditableProperties ep) throws IOException {
        if(propsFO != null) {
            assert propsFO.isData();
            try {
                ProjectManager.mutex().writeAccess(new Mutex.ExceptionAction<Void>() {
                    @Override
                    public Void run() throws Exception {
                        OutputStream os = null;
                        FileLock lock = null;
                        try {
                            lock = propsFO.lock();
                            os = propsFO.getOutputStream(lock);
                            ep.store(os);
                        } finally {
                            if (os != null) {
                                os.close();
                            }
                            if (lock != null) {
                                lock.releaseLock();
                            }
                        }
                        return null;
                    }
                });
            } catch (MutexException mux) {
                throw (IOException) mux.getException();
            }
        }
    }
    
}
