changeset 6951:35a1fc49c131

RT-36724 - JavaFX Packager Renaming Summary: Move java code around to new packages.
author Danno Ferrin (shemnon) <danno.ferrin@oracle.com>
date Mon, 28 Apr 2014 21:28:19 -0600
parents a419baadd1be
children 88d025a21446
files build.gradle modules/fxpackager/src/main/java/com/oracle/bundlers/AbstractBundler.java modules/fxpackager/src/main/java/com/oracle/bundlers/BasicBundlers.java modules/fxpackager/src/main/java/com/oracle/bundlers/Bundler.java modules/fxpackager/src/main/java/com/oracle/bundlers/BundlerParamInfo.java modules/fxpackager/src/main/java/com/oracle/bundlers/Bundlers.java modules/fxpackager/src/main/java/com/oracle/bundlers/EnumeratedBundlerParam.java modules/fxpackager/src/main/java/com/oracle/bundlers/InvalidBundlerParamException.java modules/fxpackager/src/main/java/com/oracle/bundlers/JreUtils.java modules/fxpackager/src/main/java/com/oracle/bundlers/StandardBundlerParam.java modules/fxpackager/src/main/java/com/oracle/bundlers/mac/MacAppStoreBundler.java modules/fxpackager/src/main/java/com/oracle/bundlers/mac/MacBaseInstallerBundler.java modules/fxpackager/src/main/java/com/oracle/bundlers/mac/MacDaemonBundler.java modules/fxpackager/src/main/java/com/oracle/bundlers/mac/MacPKGBundler.java modules/fxpackager/src/main/java/com/oracle/bundlers/windows/WindowsBundlerParam.java modules/fxpackager/src/main/java/com/oracle/tools/packager/AbstractBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/BasicBundlers.java modules/fxpackager/src/main/java/com/oracle/tools/packager/Bundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/BundlerParamInfo.java modules/fxpackager/src/main/java/com/oracle/tools/packager/Bundlers.java modules/fxpackager/src/main/java/com/oracle/tools/packager/ConfigException.java modules/fxpackager/src/main/java/com/oracle/tools/packager/EnumeratedBundlerParam.java modules/fxpackager/src/main/java/com/oracle/tools/packager/IOUtils.java modules/fxpackager/src/main/java/com/oracle/tools/packager/InvalidBundlerParamException.java modules/fxpackager/src/main/java/com/oracle/tools/packager/JreUtils.java modules/fxpackager/src/main/java/com/oracle/tools/packager/Log.java modules/fxpackager/src/main/java/com/oracle/tools/packager/RelativeFileSet.java modules/fxpackager/src/main/java/com/oracle/tools/packager/StandardBundlerParam.java modules/fxpackager/src/main/java/com/oracle/tools/packager/UnsupportedPlatformException.java modules/fxpackager/src/main/java/com/oracle/tools/packager/linux/LinuxAppBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/linux/LinuxDebBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/linux/LinuxResources.java modules/fxpackager/src/main/java/com/oracle/tools/packager/linux/LinuxRpmBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacAppBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacAppStoreBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacBaseInstallerBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacDaemonBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacDmgBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacPkgBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacResources.java modules/fxpackager/src/main/java/com/oracle/tools/packager/windows/WinAppBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/windows/WinExeBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/windows/WinMsiBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/windows/WinResources.java modules/fxpackager/src/main/java/com/oracle/tools/packager/windows/WinServiceBundler.java modules/fxpackager/src/main/java/com/oracle/tools/packager/windows/WindowsBundlerParam.java modules/fxpackager/src/main/java/com/sun/javafx/tools/ant/AntLog.java modules/fxpackager/src/main/java/com/sun/javafx/tools/ant/DeployFXTask.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/DeployParams.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/Log.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/Main.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/PackagerLib.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/BundleParams.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/ConfigException.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/IOUtils.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/LinuxAppBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/LinuxDebBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/LinuxRPMBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/MacAppBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/MacDMGBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/RelativeFileSet.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/UnsupportedPlatformException.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/WinAppBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/WinExeBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/WinMsiBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/packager/bundlers/WinServiceBundler.java modules/fxpackager/src/main/java/com/sun/javafx/tools/resource/linux/LinuxResources.java modules/fxpackager/src/main/java/com/sun/javafx/tools/resource/mac/MacResources.java modules/fxpackager/src/main/java/com/sun/javafx/tools/resource/windows/WinResources.java modules/fxpackager/src/main/resources/com/oracle/bundlers/AbstractBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/StandardBundlerParam.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/linux/LinuxAppBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/linux/LinuxDebBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/linux/LinuxRpmBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/mac/MacAppBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/mac/MacAppStoreBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/mac/MacBaseInstallerBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/mac/MacDMGBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/mac/MacDaemonBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/mac/MacPKGBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/windows/WinAppBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/windows/WinExeBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/windows/WinMsiBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/windows/WinServiceBundler.properties modules/fxpackager/src/main/resources/com/oracle/bundlers/windows/WindowsBundlerParam.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/AbstractBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/StandardBundlerParam.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/LinuxAppBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/LinuxDebBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/LinuxRpmBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/javalogo_white_16.png modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/javalogo_white_32.png modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/javalogo_white_48.png modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.control modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.copyright modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.deb.init.script modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.desktop modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.postinst modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.postrm modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.preinst modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.prerm modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.rpm.init.script modules/fxpackager/src/main/resources/com/oracle/tools/packager/linux/template.spec modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/DMGsetup.scpt modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/GenericApp.icns modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/GenericAppHiDPI.icns modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/Info.plist.template modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/MacAppBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/MacAppStore.entitlements modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/MacAppStoreBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/MacAppStore_Inherit.entitlements modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/MacBaseInstallerBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/MacDaemonBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/MacDmgBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/MacPkgBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/background_dmg.png modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/background_pkg.png modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/launchd.plist.template modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/lic_template.plist modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/postinstall.template modules/fxpackager/src/main/resources/com/oracle/tools/packager/mac/preinstall.template modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/WinAppBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/WinExeBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/WinMsiBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/WinServiceBundler.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/WindowsBundlerParam.properties modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/icon_inno_setup.bmp modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/javalogo_white_16.ico modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/javalogo_white_32.ico modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/javalogo_white_48.ico modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/template.iss modules/fxpackager/src/main/resources/com/oracle/tools/packager/windows/template.wxs modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/javalogo_white_16.png modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/javalogo_white_32.png modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/javalogo_white_48.png modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.control modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.copyright modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.deb.init.script modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.desktop modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.postinst modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.postrm modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.preinst modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.prerm modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.rpm.init.script modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/linux/template.spec modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/DMGsetup.scpt modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/GenericApp.icns modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/GenericAppHiDPI.icns modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/Info.plist.template modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/MacAppStore.entitlements modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/MacAppStore_Inherit.entitlements modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/background_dmg.png modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/background_pkg.png modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/launchd.plist.template modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/lic_template.plist modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/postinstall.template modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/mac/preinstall.template modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/windows/icon_inno_setup.bmp modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/windows/javalogo_white_16.ico modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/windows/javalogo_white_32.ico modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/windows/javalogo_white_48.ico modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/windows/template.iss modules/fxpackager/src/main/resources/com/sun/javafx/tools/resource/windows/template.wxs modules/fxpackager/src/test/java/com/oracle/bundlers/BundlersTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/linux/LinuxAppBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/linux/LinuxDebBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/linux/LinuxRpmBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/mac/MacAppBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/mac/MacAppStoreBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/mac/MacDMGBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/mac/MacDaemonBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/mac/MacPKGBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/windows/RuntimeFlagsParserTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/windows/WinAppBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/windows/WinEXEBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/windows/WinMSIBundlerTest.java modules/fxpackager/src/test/java/com/oracle/bundlers/windows/WinServiceBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/BundleParamsTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/BundlersTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/CLITest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/linux/LinuxAppBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/linux/LinuxDebBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/linux/LinuxRpmBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacAppBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacAppStoreBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacDaemonBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacDmgBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/mac/MacPkgBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/windows/RuntimeFlagsParserTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/windows/WinAppBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/windows/WinExeBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/windows/WinMsiBundlerTest.java modules/fxpackager/src/test/java/com/oracle/tools/packager/windows/WinServiceBundlerTest.java modules/fxpackager/src/test/java/com/sun/javafx/tools/packager/CLITest.java modules/fxpackager/src/test/java/com/sun/javafx/tools/packager/bundlers/BundleParamsTest.java modules/fxpackager/src/test/java/com/sun/javafx/tools/packager/bundlers/WinMsiBundlerTest.java
diffstat 196 files changed, 12927 insertions(+), 12976 deletions(-) [+]
line wrap: on
line diff
--- a/build.gradle	Thu May 01 11:16:36 2014 +1200
+++ b/build.gradle	Mon Apr 28 21:28:19 2014 -0600
@@ -1741,7 +1741,7 @@
             doLast {
                 copy {
                     from "$buildDir/native/WinLauncher/WinLauncher.exe"
-                    into "$buildDir/classes/main/com/sun/javafx/tools/resource/windows"
+                    into "$buildDir/classes/main/com/oracle/tools/packager/windows"
                 }
             }
         }
@@ -1757,7 +1757,7 @@
             doLast {
                 copy {
                     from "$buildDir/native/WinLauncherSvc/WinLauncherSvc.exe"
-                    into "$buildDir/classes/main/com/sun/javafx/tools/resource/windows"
+                    into "$buildDir/classes/main/com/oracle/tools/packager/windows"
                 }
             }
         }
@@ -1773,7 +1773,7 @@
             doLast {
                 copy {
                     from "$buildDir/native/IconSwap/IconSwap.exe"
-                    into "$buildDir/classes/main/com/sun/javafx/tools/resource/windows"
+                    into "$buildDir/classes/main/com/oracle/tools/packager/windows"
                 }
             }
         }
@@ -1784,7 +1784,7 @@
             task compileLauncher(type: CCTask, group: "Build") {
                 description = "Compiles native sources for the application co-bundle launcher"
                 matches = ".*\\.m"
-                output(file("$buildDir/classes/main/com/sun/javafx/tools/resource/mac"))
+                output(file("$buildDir/classes/main/com/oracle/tools/packager/mac"))
                 params.addAll(MAC.launcher.ccFlags)
                 source file("src/main/native/launcher/mac")
                 compiler = MAC.launcher.compiler
@@ -1807,7 +1807,7 @@
                 linker = LINUX.launcher.linker
                 linkParams.addAll(LINUX.launcher.linkFlags)
                 objectDir = file("$buildDir/native/launcher")
-                lib = file("$buildDir/classes/main/com/sun/javafx/tools/resource/linux/JavaAppLauncher")
+                lib = file("$buildDir/classes/main/com/oracle/tools/packager/linux/JavaAppLauncher")
             }
             jar.dependsOn linkTask;
         }
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/AbstractBundler.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-import com.oracle.bundlers.windows.WindowsBundlerParam;
-import com.sun.javafx.tools.packager.Log;
-import com.sun.javafx.tools.packager.bundlers.ConfigException;
-import com.sun.javafx.tools.packager.bundlers.IOUtils;
-import com.sun.javafx.tools.packager.bundlers.RelativeFileSet;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.text.MessageFormat;
-import java.util.*;
-
-import static com.oracle.bundlers.StandardBundlerParam.*;
-
-public abstract class AbstractBundler implements Bundler {
-
-    private static final ResourceBundle I18N =
-            ResourceBundle.getBundle("com.oracle.bundlers.AbstractBundler");
-
-    public static final BundlerParamInfo<File> IMAGES_ROOT = new WindowsBundlerParam<>(
-            I18N.getString("param.images-root.name"),
-            I18N.getString("param.images-root.description"),
-            "imagesRoot",
-            File.class,
-            params -> new File(BUILD_ROOT.fetchFrom(params), "images"),
-            (s, p) -> null);
-
-    //do not use file separator -
-    // we use it for classpath lookup and there / are not platform specific
-    public final static String BUNDLER_PREFIX = "package/";
-
-    protected static final String JAVAFX_LAUNCHER_CLASS = "com.javafx.main.Main";
-
-    protected Class baseResourceLoader = null;
-    
-    //helper method to test if required files are present in the runtime
-    public void testRuntime(Map<String, ? super Object> p, String[] file) throws ConfigException {
-        RelativeFileSet runtime = RUNTIME.fetchFrom(p);
-        if (runtime == null) {
-            return; //null runtime is ok (request to use system)
-        }
-        Set<String> rfiles = runtime.getIncludedFiles();
-        for (String aFile : file) {
-            if (rfiles.contains(aFile)) {
-                return;
-            }
-        }
-        throw new ConfigException(
-                MessageFormat.format(I18N.getString("error.jre-missing-file"), Arrays.toString(file)),
-                I18N.getString("error.jre-missing-file.advice"));
-    }
-
-    protected void fetchResource(
-            String publicName, String category,
-            String defaultName, File result, boolean verbose)
-            throws IOException {
-        URL u = locateResource(publicName, category, defaultName, verbose);
-        if (u != null) {
-            IOUtils.copyFromURL(u, result);
-        } else {
-            if (verbose) {
-                Log.info(MessageFormat.format(I18N.getString("message.using-default-resource"), category == null ? "" : "[" + category + "] ", publicName));
-            }
-        }
-    }
-
-    protected void fetchResource(
-            String publicName, String category,
-            File defaultFile, File result, boolean verbose)
-            throws IOException {
-        URL u = locateResource(publicName, category, null, verbose);
-        if (u != null) {
-            IOUtils.copyFromURL(u, result);
-        } else {
-            IOUtils.copyFile(defaultFile, result);
-            if (verbose) {
-                Log.info(MessageFormat.format(I18N.getString("message.using-default-resource-from-file"), category == null ? "" : "[" + category + "] ", defaultFile.getAbsoluteFile()));
-            }
-        }
-    }
-
-    private URL locateResource(String publicName, String category,
-                               String defaultName, boolean verbose) throws IOException {
-        URL u = null;
-        boolean custom = false;
-        if (publicName != null) {
-            u = baseResourceLoader.getClassLoader().getResource(publicName);
-            custom = (u != null);
-        }
-        if (u == null && defaultName != null) {
-            u = baseResourceLoader.getResource(defaultName);
-        }
-        String msg = null;
-        if (custom) {
-            msg = MessageFormat.format(I18N.getString("message.using-custom-resource-from-classpath"), category == null ? "" : "[" + category + "] ", publicName);
-        } else if (u != null) {
-            msg = MessageFormat.format(I18N.getString("message.using-default-resource-from-classpath"), category == null ? "" : "[" + category + "] ", publicName);
-        }
-        if (verbose && u != null) {
-            Log.info(msg);
-        }
-        return u;
-    }
-
-    protected String preprocessTextResource(String publicName, String category,
-                                            String defaultName, Map<String, String> pairs,
-                                            boolean verbose) throws IOException {
-        URL u = locateResource(publicName, category, defaultName, verbose);
-        InputStream inp = u.openStream();
-        if (inp == null) {
-            throw new RuntimeException("Jar corrupt? No "+defaultName+" resource!");
-        }
-
-        //read fully into memory
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        byte[] buffer = new byte[1024];
-        int length;
-        while ((length = inp.read(buffer)) != -1) {
-            baos.write(buffer, 0, length);
-        }
-
-        //substitute
-        String result = new String(baos.toByteArray());
-        for (Map.Entry<String, String> e : pairs.entrySet()) {
-            if (e.getValue() != null) {
-                result = result.replace(e.getKey(), e.getValue());
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return getName();
-    }
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/BasicBundlers.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-import com.oracle.bundlers.mac.MacAppStoreBundler;
-import com.oracle.bundlers.mac.MacPKGBundler;
-import com.sun.javafx.tools.packager.bundlers.LinuxAppBundler;
-import com.sun.javafx.tools.packager.bundlers.LinuxDebBundler;
-import com.sun.javafx.tools.packager.bundlers.LinuxRPMBundler;
-import com.sun.javafx.tools.packager.bundlers.MacAppBundler;
-import com.sun.javafx.tools.packager.bundlers.MacDMGBundler;
-import com.sun.javafx.tools.packager.bundlers.WinAppBundler;
-import com.sun.javafx.tools.packager.bundlers.WinExeBundler;
-import com.sun.javafx.tools.packager.bundlers.WinMsiBundler;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.ServiceLoader;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * A basic bundlers collection that loads the OpenJFX default bundlers.
- * Loads the bundlers common to OpenJFX.
- * <UL>
- *     <LI>Windows file image</LI>
- *     <LI>Mac .app</LI>
- *     <LI>Linux file image</LI>
- *     <LI>Windows MSI</LI>
- *     <LI>Windows EXE</LI>
- *     <LI>Mac DMG</LI>
- *     <LI>Mac PKG</LI>
- *     <LI>Linux DEB</LI>
- *     <LI>Linux RPM</LI>
- *
- * </UL>
- */
-public class BasicBundlers implements Bundlers {
-
-    boolean defaultsLoaded = false;
-
-    private Collection<Bundler> bundlers = new CopyOnWriteArrayList<>();
-
-    public Collection<Bundler> getBundlers() {
-        return Collections.unmodifiableCollection(bundlers);
-    }
-
-    public Collection<Bundler> getBundlers(String type) {
-        if (type == null) return Collections.emptySet();
-        switch (type) {
-            case "NONE":
-                return Collections.emptySet();
-            case "ALL":
-                return getBundlers();
-            default:
-                return Arrays.asList(getBundlers().stream()
-                        .filter(b -> type.equals(b.getBundleType()))
-                        .toArray(Bundler[]::new));
-        }
-    }
-
-    /**
-     * A list of the "standard" parameters that bundlers should support
-     * or fall back to when their specific parameters are not used.
-     * @return an unmodifieable collection of the standard parameters.
-     */
-    public Collection<BundlerParamInfo> getStandardParameters() {
-        //TODO enumerate the stuff in BundleParams
-        return null;
-    }
-
-    /**
-     * Loads the bundlers common to OpenJFX.
-     * <UL>
-     *     <LI>Windows file image</LI>
-     *     <LI>Mac .app</LI>
-     *     <LI>Linux file image</LI>
-     *     <LI>Windows MSI</LI>
-     *     <LI>Windows EXE</LI>
-     *     <LI>Mac DMG</LI>
-     *     <LI>Mac PKG</LI>
-     *     <LI>Linux DEB</LI>
-     *     <LI>Linux RPM</LI>
-     *
-     * </UL>
-     */
-    public void loadDefaultBundlers() {
-        if (defaultsLoaded) return;
-
-        bundlers.add(new WinAppBundler());
-        bundlers.add(new WinExeBundler());
-        bundlers.add(new WinMsiBundler());
-
-        bundlers.add(new LinuxAppBundler());
-        bundlers.add(new LinuxDebBundler());
-        bundlers.add(new LinuxRPMBundler());
-
-        bundlers.add(new MacAppBundler());
-        bundlers.add(new MacDMGBundler());
-        bundlers.add(new MacPKGBundler());
-        bundlers.add(new MacAppStoreBundler());
-
-        //bundlers.add(new JNLPBundler());
-
-        defaultsLoaded = true;
-    }
-
-    /**
-     * Loads bundlers from the META-INF/services direct
-     */
-    public void loadBundlersFromServices(ClassLoader cl) {
-        ServiceLoader<Bundler> loader = ServiceLoader.load(Bundler.class, cl);
-        for (Bundler aLoader : loader) {
-            bundlers.add(aLoader);
-        }
-    }
-
-    public void loadBundler(Bundler bundler) {
-        bundlers.add(bundler);
-    }
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/Bundler.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-import com.sun.javafx.tools.packager.bundlers.ConfigException;
-import com.sun.javafx.tools.packager.bundlers.UnsupportedPlatformException;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.Map;
-
-public interface Bundler {
-
-
-    /**
-     * @return User Friendly name of this bundler.
-     */
-    String getName();
-
-    /**
-     * @return A more verbose description of the bundler.
-     */
-    String getDescription();
-
-    /**
-     * @return Command line identifier of the bundler.  Should be unique.
-     */
-    String getID();
-
-    /**
-     * @return The bundle type of the bundle that is created by this bundler.
-     */
-    String getBundleType();
-
-    /**
-     * The parameters that this bundler uses to generate it's bundle.
-     * @return immutable collection
-     */
-    Collection<BundlerParamInfo<?>> getBundleParameters();
-
-    /**
-     * Determines if this bundler will execute with the given parameters.
-     *
-     * @param params The parameters to be validate.  Validation may modify
-     *               the map, so if you are going to be using the same map
-     *               across multiple bundlers you should pass in a deep copy.
-     * @return true if valid
-     * @throws UnsupportedPlatformException If the bundler cannot run on this
-     *         platform (i.e. creating mac apps on windows)
-     * @throws ConfigException If the configuration params are incorrect.  The
-     *         exception may contain advice on how to modify the params map
-     *         to make it valid.
-     */
-    boolean validate(Map<String, ? super Object> params) throws UnsupportedPlatformException, ConfigException;
-
-    /**
-     * Creates a bundle from existing content.
-     *
-     * If a call to {@link #validate(java.util.Map)} date} returns true with the
-     * parameters map, then you can expect a valid output.  However if an exception
-     * was thrown out of validate or it returned false then you should not
-     * expect sensible results from this call.  It may or may not return a value,
-     * and it may or may not throw an exception.  But any output should not
-     * be considered valid or sane.
-     *
-     * @param params The parameters as specified by getBundleParameters.
-     *               Keyed by the id from the ParamInfo.  Execution may
-     *               modify the map, so if you are going to be using the
-     *               same map across multiple bundlers you should pass
-     *               in a deep copy.
-     * @param outputParentDir
-     *   The parent dir that the returned bundle will be placed in.
-     * @return The resulting bundled file
-     *
-     * For a bundler that produces a single artifact file this will be the
-     * location of that artifact (.exe file, .deb file, etc)
-     *
-     * For a bundler that produces a specific directory format output this will
-     * be the location of that specific directory (.app file, etc).
-     *
-     * For a bundler that produce multiple files, this will be a parent
-     * directory of those files (linux and windows images), whose name is not
-     * relevant to the result.
-     *
-     * @throws java.lang.IllegalArgumentException for any of the following
-     * reasons:
-     *  <ul>
-     *      <li>A required parameter is not found in the params list, for
-     *      example missing the main class.</li>
-     *      <li>A parameter has the wrong type of an object, for example a
-     *      String where a File is required</li>
-     *      <li>Bundler specific incompatibilities with the parameters, for
-     *      example a bad version number format or an application id with
-     *      forward slashes.</li>
-     *  </ul>
-     */
-    public File execute(Map<String, ? super Object> params, File outputParentDir);
-
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/BundlerParamInfo.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-import java.util.Map;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-
-public class BundlerParamInfo<T> {
-
-    /**
-     * The user friendly name of the parameter
-     */
-    String name;
-
-    /**
-     * A more verbose description of the parameter
-     */
-    String description;
-
-    /**
-     * The command line and hashmap name of the parameter
-     */
-    String id;
-
-    /**
-     * Type of the parameter.  Typically String.class
-     */
-    Class<T> valueType;
-
-    /**
-     * If the value is not set, and no fallback value is found, the parameter uses the value returned by the producer.
-     */
-    Function<Map<String, ? super Object>, T> defaultValueFunction;
-
-    /**
-     * An optional string converter for command line arguments.
-     */
-    BiFunction<String, Map<String, ? super Object>, T> stringConverter;
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public String getID() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public Class<T> getValueType() {
-        return valueType;
-    }
-
-    public void setValueType(Class<T> valueType) {
-        this.valueType = valueType;
-    }
-
-    public Function<Map<String, ? super Object>, T> getDefaultValueFunction() {
-        return defaultValueFunction;
-    }
-
-    public void setDefaultValueFunction(Function<Map<String, ? super Object>, T> defaultValueFunction) {
-        this.defaultValueFunction = defaultValueFunction;
-    }
-
-    public BiFunction<String, Map<String, ? super Object>,T> getStringConverter() {
-        return stringConverter;
-    }
-
-    public void setStringConverter(BiFunction<String, Map<String, ? super Object>, T> stringConverter) {
-        this.stringConverter = stringConverter;
-    }
-
-    @SuppressWarnings("unchecked")
-    public final T fetchFrom(Map<String, ? super Object> params) {
-        Object o = params.get(getID());
-        if (o instanceof String && getStringConverter() != null) {
-            return getStringConverter().apply((String)o, params);
-        }
-
-        Class klass = getValueType();
-        if (klass.isInstance(o)) {
-            return (T) o;
-        }
-        if (o != null) {
-            throw new IllegalArgumentException("Param " + getID() + " should be of type " + getValueType() + " but is a " + o.getClass());
-        }
-        if (params.containsKey(getID())) {
-            // explicit nulls are allowed
-            return null;
-        }
-
-        if (getDefaultValueFunction() != null) {
-            T result =  getDefaultValueFunction().apply(params);
-            if (result != null) {
-                params.put(getID(), result);
-            }
-            return result;
-        }
-
-        // ultimate fallback
-        return null;
-    }
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/Bundlers.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
-
-public interface Bundlers {
-
-    /**
-     * This convenience method will call {@link #createBundlersInstance(ClassLoader)}
-     * with the classloader that this Bundlers is loaded from.
-     *
-     * @return an instance of Bundlers loaded and configured from the current ClassLoader.
-     */
-    public static Bundlers createBundlersInstance() {
-        return createBundlersInstance(Bundlers.class.getClassLoader());
-    }
-
-    /**
-     * This convenience method will automatically load a Bundlers instance
-     * from either META-INF/services or the default
-     * {@link com.oracle.bundlers.BasicBundlers} if none are found in
-     * the services meta-inf.
-     *
-     * After instantiating the bundlers instance it will load the default
-     * bundlers via {@link #loadDefaultBundlers()} as well as requesting
-     * the services loader to load any other bundelrs via
-     * {@link #loadBundlersFromServices(ClassLoader)}.
-
-     *
-     * @param servicesClassLoader the classloader to search for
-     *                            META-INF/service registered bundlers
-     * @return an instance of Bundlers loaded and configured from the specified ClassLoader
-     */
-    public static Bundlers createBundlersInstance(ClassLoader servicesClassLoader) {
-        ServiceLoader<Bundlers> bundlersLoader = ServiceLoader.load(Bundlers.class, servicesClassLoader);
-        Bundlers bundlers = null;
-        Iterator<Bundlers> iter = bundlersLoader.iterator();
-        if (iter.hasNext()) {
-            bundlers = iter.next();
-        }
-        if (bundlers == null) {
-            bundlers = new BasicBundlers();
-        }
-
-        bundlers.loadDefaultBundlers();
-        bundlers.loadBundlersFromServices(servicesClassLoader);
-        return bundlers;
-    }
-
-    /**
-     * Returns all of the preconfigured, requested, and manually
-     * configured bundlers loaded with this instance.
-     *
-     * @return  a read-only collection of the requested bundlers
-     */
-    Collection<Bundler> getBundlers();
-
-    /**
-     * Returns all of the preconfigured, requested, and manually
-     * configured bundlers loaded with this instance that are of
-     * a specific BundleType, such as disk images, installers, or
-     * remote installers.
-     *
-     * @return a read-only collection of the requested bundlers
-     */
-    Collection<Bundler> getBundlers(String type);
-
-    /**
-     * A list of the "standard" parameters that bundlers should support
-     * or fall back to when their specific parameters are not used.
-     *
-     * @return an unmodifiable collection of the standard parameters.
-     */
-    Collection<BundlerParamInfo> getStandardParameters();
-
-    /**
-     * Loads the bundlers common to the JDK.  A typical implementation
-     * would load:
-     * <UL>
-     *     <LI>Windows file image</LI>
-     *     <LI>Mac .app</LI>
-     *     <LI>Linux file image</LI>
-
-     *     <LI>Windows MSI</LI>
-     *     <LI>Windows EXE</LI>
-     *     <LI>Mac DMG</LI>
-     *     <LI>Linux DEB</LI>
-     *     <LI>Linux RPM</LI>
-     *
-     * </UL>
-     *
-     * This method is called from the {@link #createBundlersInstance(ClassLoader)}
-     * and {@link #createBundlersInstance()} methods.
-     */
-    void loadDefaultBundlers();
-
-    /**
-     * Loads bundlers from the META-INF/services directly.
-     *
-     * This method is called from the {@link #createBundlersInstance(ClassLoader)}
-     * and {@link #createBundlersInstance()} methods.
-     */
-    void loadBundlersFromServices(ClassLoader cl);
-
-    /**
-     * Loads a specific bundler into the set of bundlers.
-     * Useful for a manually configured bundler.
-     *
-     * @param bundler the specific bundler to add
-     */
-    void loadBundler(Bundler bundler);
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/EnumeratedBundlerParam.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-import java.util.*;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-
-/**
- * 
- * The idea for this Param is that is contains a list of possible values which the IDE
- * can display and then choose the appropriate value for. For instance the Mac has a
- * predefined set of categories which can be applied to LSApplicationCategoryType which
- * is required for the mac app store.
- */
-public class EnumeratedBundlerParam<T> extends BundlerParamInfo<T> {
-    //Not sure if this is the correct order, my idea is that from and IDE's perspective
-    //the string to display to the user is the key and then the value is some type of
-    //object (although probably a String in most cases)
-    private Map<String, T> possibleValues;
-    private boolean strict;
-
-    public EnumeratedBundlerParam(String name,
-                                  String description,
-                                  String id,
-                                  Class<T> valueType,
-                                  Function<Map<String, ? super Object>, T> defaultValueFunction,
-                                  BiFunction<String, Map<String, ? super Object>, T> stringConverter,
-                                  Map<String, T> possibleValues,
-                                  boolean strict) {
-        this.name = name;
-        this.description = description;
-        this.id = id;
-        this.valueType = valueType;
-        this.defaultValueFunction = defaultValueFunction;
-        this.stringConverter = stringConverter;
-        this.possibleValues = possibleValues;
-        this.strict = strict;
-    }
-
-    public boolean isInPossibleValues(T value) {
-        return possibleValues.values().contains(value);
-    }
-
-    //Having the displayable values as the keys seems a bit wacky
-    public Set<String> getDisplayableKeys() {
-        return Collections.unmodifiableSet(possibleValues.keySet());
-    }
-
-    public boolean isStrict() {
-        return strict;
-    }
-
-    public boolean isLoose() {
-        return !isStrict();
-    }
-
-    public T validatedFetchFrom(Map<String, ? super Object> params)
-            throws InvalidBundlerParamException {
-        if (isStrict()) {
-            T value = fetchFrom(params);
-            if (!isInPossibleValues(value)) {
-                throw new InvalidBundlerParamException("Parameter " + value.toString() + " not in valid set of values for BundlerParam " + name);
-            }
-            return value;
-        }
-        return fetchFrom(params);
-    }
-
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/InvalidBundlerParamException.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-public class InvalidBundlerParamException extends RuntimeException {
-    public InvalidBundlerParamException(String message) {
-        super(message);
-    }
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/JreUtils.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-import com.sun.javafx.tools.packager.bundlers.IOUtils;
-import com.sun.javafx.tools.packager.bundlers.RelativeFileSet;
-
-import java.io.File;
-import java.util.HashSet;
-import java.util.Set;
-
-public class JreUtils {
-
-    public static class Rule {
-        String regex;
-        boolean includeRule;
-        Type type;
-        enum Type {SUFFIX, PREFIX, SUBSTR, REGEX}
-
-        private Rule(String regex, boolean includeRule, Type type) {
-            this.regex = regex;
-            this.type = type;
-            this.includeRule = includeRule;
-        }
-
-        boolean match(String str) {
-            if (type == Type.SUFFIX) {
-                return str.endsWith(regex);
-            }
-            if (type == Type.PREFIX) {
-                return str.startsWith(regex);
-            }
-            if (type == Type.SUBSTR) {
-                return str.contains(regex);
-            }
-            return str.matches(regex);
-        }
-
-        boolean treatAsAccept() {return includeRule;}
-
-        public static Rule suffix(String s) {
-            return new Rule(s, true, Type.SUFFIX);
-        }
-        public static Rule suffixNeg(String s) {
-            return new Rule(s, false, Type.SUFFIX);
-        }
-        static Rule prefix(String s) {
-            return new Rule(s, true, Type.PREFIX);
-        }
-        public static Rule prefixNeg(String s) {
-            return new Rule(s, false, Type.PREFIX);
-        }
-        static Rule substr(String s) {
-            return new Rule(s, true, Type.SUBSTR);
-        }
-        public static Rule substrNeg(String s) {
-            return new Rule(s, false, Type.SUBSTR);
-        }
-    }
-
-    public static boolean shouldExclude(File baseDir, File f, Rule ruleset[]) {
-        if (ruleset == null) {
-            return false;
-        }
-
-        String fname = f.getAbsolutePath().toLowerCase().substring(
-                baseDir.getAbsolutePath().length());
-        //first rule match defines the answer
-        for (Rule r: ruleset) {
-            if (r.match(fname)) {
-                return !r.treatAsAccept();
-            }
-        }
-        //default is include
-        return false;
-    }
-
-    public static void walk(File base, File root, Rule ruleset[], Set<File> files) {
-        if (!root.isDirectory()) {
-            if (root.isFile()) {
-                files.add(root);
-            }
-            return;
-        }
-
-        File[] lst = root.listFiles();
-        if (lst != null) {
-            for (File f : lst) {
-                //ignore symbolic links!
-                if (IOUtils.isNotSymbolicLink(f) && !shouldExclude(base, f, ruleset)) {
-                    if (f.isDirectory()) {
-                        walk(base, f, ruleset, files);
-                    } else if (f.isFile()) {
-                        //add to list
-                        files.add(f);
-                    }
-                }
-            }
-        }
-    }
-
-    public static RelativeFileSet extractJreAsRelativeFileSet(String root, JreUtils.Rule[] ruleset) {
-        File baseDir = new File(root);
-
-        Set<File> lst = new HashSet<>();
-
-        walk(baseDir, baseDir, ruleset, lst);
-
-        return new RelativeFileSet(baseDir, lst);
-    }
-
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/StandardBundlerParam.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,565 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers;
-
-import com.sun.javafx.tools.packager.Log;
-import com.sun.javafx.tools.packager.PackagerLib;
-import com.sun.javafx.tools.packager.bundlers.BundleParams;
-import com.sun.javafx.tools.packager.bundlers.ConfigException;
-import com.sun.javafx.tools.packager.bundlers.RelativeFileSet;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.nio.file.Files;
-import java.text.MessageFormat;
-import java.util.*;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
-public class StandardBundlerParam<T> extends BundlerParamInfo<T> {
-
-    private static final ResourceBundle I18N =
-            ResourceBundle.getBundle("com.oracle.bundlers.StandardBundlerParam");
-
-    public StandardBundlerParam(String name, String description, String id,
-                                Class<T> valueType,
-                                Function<Map<String, ? super Object>, T> defaultValueFunction,
-                                BiFunction<String, Map<String, ? super Object>, T> stringConverter) {
-        this.name = name;
-        this.description = description;
-        this.id = id;
-        this.valueType = valueType;
-        this.defaultValueFunction = defaultValueFunction;
-        this.stringConverter = stringConverter;
-    }
-
-    public static final StandardBundlerParam<RelativeFileSet> RUNTIME =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.runtime.name"),
-                    I18N.getString("param.runtime.description"),
-                    BundleParams.PARAM_RUNTIME,
-                    RelativeFileSet.class,
-                    params -> null,
-                    (s, p) -> null
-            );
-
-    public static final StandardBundlerParam<RelativeFileSet> APP_RESOURCES =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.app-resources.name"),
-                    I18N.getString("param.app-resource.description"),
-                    BundleParams.PARAM_APP_RESOURCES,
-                    RelativeFileSet.class,
-                    null, // no default.  Required parameter
-                    null // no string translation, tool must provide complex type
-            );
-
-    public static final StandardBundlerParam<File> ICON =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.icon-file.name"),
-                    I18N.getString("param.icon-file.description"),
-                    BundleParams.PARAM_ICON,
-                    File.class,
-                    params -> null,
-                    (s, p) -> new File(s)
-            );
-
-
-    public static final StandardBundlerParam<String> MAIN_CLASS =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.main-class.name"),
-                    I18N.getString("param.main-class.description"),
-                    BundleParams.PARAM_APPLICATION_CLASS,
-                    String.class,
-                    params -> {
-                        extractMainClassInfoFromAppResources(params);
-                        return (String) params.get(BundleParams.PARAM_APPLICATION_CLASS);
-                    },
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<String> APP_NAME =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.app-name.name"),
-                    I18N.getString("param.app-name.description"),
-                    BundleParams.PARAM_NAME,
-                    String.class,
-                    params -> {
-                        String s = MAIN_CLASS.fetchFrom(params);
-                        if (s == null) return null;
-
-                        int idx = s.lastIndexOf(".");
-                        if (idx >= 0) {
-                            return s.substring(idx+1);
-                        }
-                        return s;
-                    },
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<String> VENDOR =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.vendor.name"),
-                    I18N.getString("param.vendor.description"),
-                    BundleParams.PARAM_VENDOR,
-                    String.class,
-                    params -> I18N.getString("param.vendor.default"),
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<String> CATEGORY =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.category.name"),
-                    I18N.getString("param.category.description"),
-                    BundleParams.PARAM_CATEGORY,
-                    String.class,
-                    params -> I18N.getString("param.category.default"),
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<String> DESCRIPTION =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.description.name"),
-                    I18N.getString("param.description.description"),
-                    BundleParams.PARAM_DESCRIPTION,
-                    String.class,
-                    params -> params.containsKey(APP_NAME.getID())
-                            ? APP_NAME.fetchFrom(params)
-                            : I18N.getString("param.description.default"),
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<String> COPYRIGHT =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.copyright.name"),
-                    I18N.getString("param.copyright.description"),
-                    BundleParams.PARAM_COPYRIGHT,
-                    String.class,
-                    params -> MessageFormat.format(I18N.getString("param.copyright.default"), new Date()),
-                    (s, p) -> s
-            );
-
-    // note that each bundler is likely to replace this one with their own converter
-    public static final StandardBundlerParam<RelativeFileSet> MAIN_JAR =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.main-jar.name"),
-                    I18N.getString("param.main-jar.description"),
-                    "mainJar",
-                    RelativeFileSet.class,
-                    params -> {
-                        extractMainClassInfoFromAppResources(params);
-                        return (RelativeFileSet) params.get("mainJar");
-                    },
-                    (s, p) -> {
-                        File appResourcesRoot = APP_RESOURCES.fetchFrom(p).getBaseDirectory();
-                        File f = new File(appResourcesRoot, s);
-                        return new RelativeFileSet(appResourcesRoot, new LinkedHashSet<>(Arrays.asList(f)));
-                    }
-            );
-
-    public static final StandardBundlerParam<String> MAIN_JAR_CLASSPATH =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.main-jar-classpath.name"),
-                    I18N.getString("param.main-jar-classpath.description"),
-                    "classpath",
-                    String.class,
-                    params -> {
-                        extractMainClassInfoFromAppResources(params);
-                        String cp = (String) params.get("classpath");
-                        return cp == null ? "" : cp;
-                    },
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<Boolean> USE_FX_PACKAGING =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.use-javafx-packaging.name"),
-                    I18N.getString("param.use-javafx-packaging.description"),
-                    "fxPackaging",
-                    Boolean.class,
-                    params -> {
-                        extractMainClassInfoFromAppResources(params);
-                        Boolean result = (Boolean) params.get("fxPackaging");
-                        return (result == null) ? Boolean.FALSE : result;
-                    },
-                    (s, p) -> Boolean.valueOf(s)
-            );
-
-    @SuppressWarnings("unchecked")
-    public static final StandardBundlerParam<List<String>> JVM_OPTIONS =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.jvm-options.name"),
-                    I18N.getString("param.jvm-options.description"),
-                    "jvmOptions",
-                    (Class<List<String>>) (Object) List.class,
-                    params -> Collections.emptyList(),
-                    (s, p) -> Arrays.asList(s.split("\\s+"))
-            );
-
-    @SuppressWarnings("unchecked")
-    public static final StandardBundlerParam<Map<String, String>> JVM_PROPERTIES =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.jvm-system-properties.name"),
-                    I18N.getString("param.jvm-system-properties.description"),
-                    "jvmProperties",
-                    (Class<Map<String, String>>) (Object) Map.class,
-                    params -> Collections.emptyMap(),
-                    (s, params) -> {
-                        Map<String, String> map = new HashMap<>();
-                        try {
-                            Properties p = new Properties();
-                            p.load(new StringReader(s));
-                            for (Map.Entry<Object, Object> entry : p.entrySet()) {
-                                map.put((String)entry.getKey(), (String)entry.getValue());
-                            }
-                        } catch (IOException e) {
-                            e.printStackTrace();
-                        }
-                        return map;
-                    }
-            );
-
-    @SuppressWarnings("unchecked")
-    public static final StandardBundlerParam<Map<String, String>> USER_JVM_OPTIONS =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.user-jvm-options.name"),
-                    I18N.getString("param.user-jvm-options.description"),
-                    "userJvmOptions",
-                    (Class<Map<String, String>>) (Object) Map.class,
-                    params -> Collections.emptyMap(),
-                    (s, params) -> {
-                        Map<String, String> map = new HashMap<>();
-                        try {
-                            Properties p = new Properties();
-                            p.load(new StringReader(s));
-                            for (Map.Entry<Object, Object> entry : p.entrySet()) {
-                                map.put((String)entry.getKey(), (String)entry.getValue());
-                            }
-                        } catch (IOException e) {
-                            e.printStackTrace();
-                        }
-                        return map;
-                    }
-            );
-
-    public static final StandardBundlerParam<String> TITLE =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.title.name"),
-                    I18N.getString("param.title.description"), //?? but what does it do?
-                    BundleParams.PARAM_TITLE,
-                    String.class,
-                    APP_NAME::fetchFrom,
-                    (s, p) -> s
-            );
-
-
-    // note that each bundler is likely to replace this one with their own converter
-    public static final StandardBundlerParam<String> VERSION =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.version.name"),
-                    I18N.getString("param.version.description"),
-                    BundleParams.PARAM_VERSION,
-                    String.class,
-                    params -> I18N.getString("param.version.default"),
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<Boolean> SYSTEM_WIDE =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.system-wide.name"),
-                    I18N.getString("param.system-wide.description"),
-                    BundleParams.PARAM_SYSTEM_WIDE,
-                    Boolean.class,
-                    params -> null,
-                    // valueOf(null) is false, and we actually do want null in some cases
-                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? null : Boolean.valueOf(s)
-            );
-
-    public static final StandardBundlerParam<Boolean> SERVICE_HINT  =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.service-hint.name"),
-                    I18N.getString("param.service-hint.description"),
-                    BundleParams.PARAM_SERVICE_HINT,
-                    Boolean.class,
-                    params -> false,
-                    // valueOf(null) is false, and we actually do want null in some cases
-                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
-            );
-
-    public static final StandardBundlerParam<Boolean> START_ON_INSTALL  =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.start-on-install.name"),
-                    I18N.getString("param.start-on-install.description"),
-                    "startOnInstall",
-                    Boolean.class,
-                    params -> false,
-                    // valueOf(null) is false, and we actually do want null in some cases
-                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
-            );
-
-    public static final StandardBundlerParam<Boolean> STOP_ON_UNINSTALL  =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.stop-on-uninstall.name"),
-                    I18N.getString("param.stop-on-uninstall.description"),
-                    "stopOnUninstall",
-                    Boolean.class,
-                    params -> true,
-                    // valueOf(null) is false, and we actually do want null in some cases
-                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
-            );
-
-    public static final StandardBundlerParam<Boolean> RUN_AT_STARTUP  =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.run-at-startup.name"),
-                    I18N.getString("param.run-at-startup.description"),
-                    "runAtStartup",
-                    Boolean.class,
-                    params -> false,
-                    // valueOf(null) is false, and we actually do want null in some cases
-                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
-            );
-
-    public static final StandardBundlerParam<Boolean> SHORTCUT_HINT =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.desktop-shortcut-hint.name"),
-                    I18N.getString("param.desktop-shortcut-hint.description"),
-                    BundleParams.PARAM_SHORTCUT,
-                    Boolean.class,
-                    params -> false,
-                    // valueOf(null) is false, and we actually do want null in some cases
-                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? false : Boolean.valueOf(s)
-            );
-
-    public static final StandardBundlerParam<Boolean> MENU_HINT =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.menu-shortcut-hint.name"),
-                    I18N.getString("param.menu-shortcut-hint.description"),
-                    BundleParams.PARAM_MENU,
-                    Boolean.class,
-                    params -> true,
-                    // valueOf(null) is false, and we actually do want null in some cases
-                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
-            );
-
-    @SuppressWarnings("unchecked")
-    public static final StandardBundlerParam<List<String>> LICENSE_FILE =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.license-file.name"),
-                    I18N.getString("param.license-file.description"),
-                    BundleParams.PARAM_LICENSE_FILE,
-                    (Class<List<String>>)(Object)List.class,
-                    params -> Collections.<String>emptyList(),
-                    (s, p) -> Arrays.asList(s.split(","))
-            );
-
-    public static final BundlerParamInfo<String> LICENSE_TYPE =
-            new StandardBundlerParam<> (
-                    I18N.getString("param.license-type.name"),
-                    I18N.getString("param.license-type.description"),
-                    BundleParams.PARAM_LICENSE_TYPE,
-                    String.class,
-                    params -> I18N.getString("param.license-type.default"),
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<File> BUILD_ROOT =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.build-root.name"),
-                    I18N.getString("param.build-root.description"),
-                    "buildRoot",
-                    File.class,
-                    params -> {
-                        try {
-                            return Files.createTempDirectory("fxbundler").toFile();
-                        } catch (IOException ioe) {
-                            return null;
-                        }
-                    },
-                    (s, p) -> new File(s)
-            );
-
-    public static final StandardBundlerParam<String> IDENTIFIER =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.identifier.name"),
-                    I18N.getString("param.identifier.description"),
-                    BundleParams.PARAM_IDENTIFIER,
-                    String.class,
-                    params -> {
-                        String s = MAIN_CLASS.fetchFrom(params);
-                        if (s == null) return null;
-
-                        int idx = s.lastIndexOf(".");
-                        if (idx >= 1) {
-                            return s.substring(0, idx);
-                        }
-                        return s;
-                    },
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<String> PREFERENCES_ID =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.preferences-id.name"),
-                    I18N.getString("param.preferences-id.description"),
-                    "preferencesID",
-                    String.class,
-                    p -> IDENTIFIER.fetchFrom(p).replace('.', '/'),
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<Boolean> VERBOSE  =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.verbose.name"),
-                    I18N.getString("param.verbose.description"),
-                    "verbose",
-                    Boolean.class,
-                    params -> false,
-                    // valueOf(null) is false, and we actually do want null in some cases
-                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
-            );
-
-    public static void extractMainClassInfoFromAppResources(Map<String, ? super Object> params) {
-        boolean hasMainClass = params.containsKey(MAIN_CLASS.getID());
-        boolean hasMainJar = params.containsKey(MAIN_JAR.getID());
-        boolean hasMainJarClassPath = params.containsKey(MAIN_JAR_CLASSPATH.getID());
-
-        if (hasMainClass && hasMainJar && hasMainJarClassPath) {
-            return;
-        }
-        Iterable<String> files;
-        File srcdir;
-
-        if (hasMainJar) {
-            RelativeFileSet rfs = MAIN_JAR.fetchFrom(params);
-            files = rfs.getIncludedFiles();
-            srcdir = rfs.getBaseDirectory();
-        } else if (hasMainJarClassPath) {
-            files = Arrays.asList(MAIN_JAR_CLASSPATH.fetchFrom(params).split(File.pathSeparator));
-            srcdir = APP_RESOURCES.fetchFrom(params).getBaseDirectory();
-        } else {
-            RelativeFileSet rfs = APP_RESOURCES.fetchFrom(params);
-            if (rfs == null) {
-                return;
-            }
-            files = rfs.getIncludedFiles();
-            srcdir = rfs.getBaseDirectory();
-        }
-
-
-        String declaredMainClass = (String) params.get(MAIN_CLASS.getID());
-
-        // presume the set iterates in-order
-        for (String fname : files) {
-            try {
-                // only sniff jars
-                if (!fname.toLowerCase().endsWith(".jar")) continue;
-
-                File file = new File(srcdir, fname);
-                // that actually exist
-                if (!file.exists()) continue;
-
-                JarFile jf = new JarFile(file);
-                Manifest m = jf.getManifest();
-                Attributes attrs = (m != null) ? m.getMainAttributes() : null;
-
-                if (attrs != null) {
-                    String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
-                    String fxMain = attrs.getValue(PackagerLib.MANIFEST_JAVAFX_MAIN);
-                    if (hasMainClass) {
-                        if (declaredMainClass.equals(fxMain)) {
-                            params.put(USE_FX_PACKAGING.getID(), true);
-                        } else if (declaredMainClass.equals(mainClass)) {
-                            params.put(USE_FX_PACKAGING.getID(), false);
-                        } else {
-                            if (fxMain != null) {
-                                Log.info(MessageFormat.format(I18N.getString("message.fx-app-does-not-match-specified-main"), fname, fxMain, declaredMainClass));
-                            }
-                            if (mainClass != null) {
-                                Log.info(MessageFormat.format(I18N.getString("message.main-class-does-not-match-specified-main"), fname, mainClass, declaredMainClass));
-                            }
-                            continue;
-                        }
-                    } else {
-                        if (fxMain != null) {
-                            params.put(USE_FX_PACKAGING.getID(), true);
-                            params.put(MAIN_CLASS.getID(), fxMain);
-                        } else if (mainClass != null) {
-                            params.put(USE_FX_PACKAGING.getID(), false);
-                            params.put(MAIN_CLASS.getID(), mainClass);
-                        } else {
-                            continue;
-                        }
-                    }
-                    if (!hasMainJar) {
-                        if (srcdir == null) {
-                            srcdir = file.getParentFile();
-                        }
-                        params.put(MAIN_JAR.getID(), new RelativeFileSet(srcdir, new LinkedHashSet<>(Arrays.asList(file))));
-                    }
-                    if (!hasMainJarClassPath) {
-                        String cp = attrs.getValue(Attributes.Name.CLASS_PATH);
-                        params.put(MAIN_JAR_CLASSPATH.getID(), cp == null ? "" : cp);
-                    }
-                    break;
-                }
-            } catch (IOException ignore) {
-                ignore.printStackTrace();
-            }
-        }
-    }
-
-    public static void validateMainClassInfoFromAppResources(Map<String, ? super Object> params) throws ConfigException {
-        boolean hasMainClass = params.containsKey(MAIN_CLASS.getID());
-        boolean hasMainJar = params.containsKey(MAIN_JAR.getID());
-        boolean hasMainJarClassPath = params.containsKey(MAIN_JAR_CLASSPATH.getID());
-
-        if (hasMainClass && hasMainJar && hasMainJarClassPath) {
-            return;
-        }
-
-        extractMainClassInfoFromAppResources(params);
-        if (!params.containsKey(MAIN_CLASS.getID())) {
-            if (hasMainJar) {
-                throw new ConfigException(
-                        MessageFormat.format(I18N.getString("error.no-main-class-with-main-jar"),
-                                MAIN_JAR.fetchFrom(params)),
-                        MessageFormat.format(I18N.getString("error.no-main-class-with-main-jar.advice"),
-                                MAIN_JAR.fetchFrom(params)));
-            } else if (hasMainJarClassPath) {
-                throw new ConfigException(
-                        I18N.getString("error.no-main-class-with-classpath"),
-                        I18N.getString("error.no-main-class-with-classpath.advice"));
-            } else {
-                throw new ConfigException(
-                        I18N.getString("error.no-main-class"),
-                        I18N.getString("error.no-main-class.advice"));
-            }
-        }
-    }
-}
\ No newline at end of file
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/mac/MacAppStoreBundler.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers.mac;
-
-import com.oracle.bundlers.BundlerParamInfo;
-import com.oracle.bundlers.JreUtils;
-import com.oracle.bundlers.StandardBundlerParam;
-import com.sun.javafx.tools.packager.Log;
-import com.sun.javafx.tools.packager.bundlers.ConfigException;
-import com.sun.javafx.tools.packager.bundlers.IOUtils;
-import com.sun.javafx.tools.packager.bundlers.MacAppBundler;
-import com.sun.javafx.tools.packager.bundlers.UnsupportedPlatformException;
-import com.sun.javafx.tools.resource.mac.MacResources;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-import static com.oracle.bundlers.JreUtils.Rule.suffix;
-import static com.oracle.bundlers.JreUtils.Rule.suffixNeg;
-import static com.oracle.bundlers.StandardBundlerParam.*;
-
-public class MacAppStoreBundler extends MacBaseInstallerBundler {
-
-    private static final ResourceBundle I18N =
-            ResourceBundle.getBundle("com.oracle.bundlers.mac.MacAppStoreBundler");
-
-    private static final String TEMPLATE_BUNDLE_ICON_HIDPI = "GenericAppHiDPI.icns";
-    private final static String DEFAULT_ENTITLEMENTS = "MacAppStore.entitlements";
-    private final static String DEFAULT_INHERIT_ENTITLEMENTS = "MacAppStore_Inherit.entitlements";
-
-    //Subsetting of JRE is restricted.
-    //JRE README defines what is allowed to strip:
-    //   http://www.oracle.com/technetwork/java/javase/jre-7-readme-430162.html //TODO update when 8 goes GA
-    //
-    public static final JreUtils.Rule[] MAC_APP_STORE_JDK_RULES =  new JreUtils.Rule[]{
-            suffixNeg("macos/libjli.dylib"),
-            suffixNeg("resources"),
-            suffixNeg("home/bin"),
-            suffixNeg("home/db"),
-            suffixNeg("home/demo"),
-            suffixNeg("home/include"),
-            suffixNeg("home/lib"),
-            suffixNeg("home/man"),
-            suffixNeg("home/release"),
-            suffixNeg("home/sample"),
-            suffixNeg("home/src.zip"),
-            //"home/rt" is not part of the official builds
-            // but we may be creating this symlink to make older NB projects
-            // happy. Make sure to not include it into final artifact
-            suffixNeg("home/rt"),
-            suffixNeg("jre/bin"),
-            suffixNeg("bin/rmiregistry"),
-            suffixNeg("bin/tnameserv"),
-            suffixNeg("bin/keytool"),
-            suffixNeg("bin/klist"),
-            suffixNeg("bin/ktab"),
-            suffixNeg("bin/policytool"),
-            suffixNeg("bin/orbd"),
-            suffixNeg("bin/servertool"),
-            suffixNeg("bin/javaws"),
-            suffixNeg("bin/java"),
-            //Rule.suffixNeg("jre/lib/ext"), //need some of jars there for https to work
-            suffixNeg("jre/lib/nibs"),
-            //keep core deploy APIs but strip plugin dll
-            //Rule.suffixNeg("jre/lib/deploy"),
-            //Rule.suffixNeg("jre/lib/deploy.jar"),
-            //Rule.suffixNeg("jre/lib/javaws.jar"),
-            //Rule.suffixNeg("jre/lib/libdeploy.dylib"),
-            //Rule.suffixNeg("jre/lib/plugin.jar"),
-            suffixNeg("lib/libnpjp2.dylib"),
-            suffixNeg("lib/security/javaws.policy"),
-
-            // jfxmedia uses QuickTime, which is not allowed as of OSX 10.9
-            suffixNeg("lib/libjfxmedia.dylib"),
-
-            // the plist is needed for signing
-            suffix("Info.plist"),
-
-    };
-
-    public static final BundlerParamInfo<String> MAC_APP_STORE_APP_SIGNING_KEY = new StandardBundlerParam<>(
-            I18N.getString("param.signing-key-app.name"),
-            I18N.getString("param.signing-key-app.description"),
-            "mac.signing-key-app",
-            String.class,
-            params -> {
-                String key = "3rd Party Mac Developer Application: " + SIGNING_KEY_USER.fetchFrom(params);
-                try {
-                    IOUtils.exec(new ProcessBuilder("security", "find-certificate", "-c", key), VERBOSE.fetchFrom(params));
-                    return key;
-                } catch (IOException ioe) {
-                    return null;
-                }
-            },
-            (s, p) -> s);
-
-    public static final BundlerParamInfo<String> MAC_APP_STORE_PKG_SIGNING_KEY = new StandardBundlerParam<>(
-            I18N.getString("param.signing-key-pkg.name"),
-            I18N.getString("param.signing-key-pkg.description"),
-            "mac.signing-key-pkg",
-            String.class,
-            params -> {
-                String key = "3rd Party Mac Developer Installer: " + SIGNING_KEY_USER.fetchFrom(params);
-                try {
-                    IOUtils.exec(new ProcessBuilder("security", "find-certificate", "-c", key), VERBOSE.fetchFrom(params));
-                    return key;
-                } catch (IOException ioe) {
-                    return null;
-                }
-            },
-            (s, p) -> s);
-
-    public static final StandardBundlerParam<File> MAC_APP_STORE_ENTITLEMENTS  = new StandardBundlerParam<>(
-            I18N.getString("param.mac-app-store-entitlements.name"),
-            I18N.getString("param.mac-app-store-entitlements.description"),
-            "mac.app-store-entitlements",
-            File.class,
-            params -> null,
-            (s, p) -> new File(s));
-
-    public MacAppStoreBundler() {
-        super();
-        baseResourceLoader = MacResources.class;
-    }
-
-    //@Override
-    public File bundle(Map<String, ? super Object> p, File outdir) {
-        Log.info(MessageFormat.format(I18N.getString("message.building-bundle"), APP_NAME.fetchFrom(p)));
-        if (!outdir.isDirectory() && !outdir.mkdirs()) {
-            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outdir.getAbsolutePath()));
-        }
-        if (!outdir.canWrite()) {
-            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outdir.getAbsolutePath()));
-        }
-
-        // first, load in some overrides
-        // icns needs @2 versions, so load in the @2 default
-        p.put(MacAppBundler.DEFAULT_ICNS_ICON.getID(), TEMPLATE_BUNDLE_ICON_HIDPI);
-
-        // next we need to change the jdk/jre stripping to strip gstreamer
-        p.put(MacAppBundler.MAC_JDK_RULES.getID(), MAC_APP_STORE_JDK_RULES);
-
-        // now we create the app
-        File appImageDir = APP_IMAGE_BUILD_ROOT.fetchFrom(p);
-        try {
-            appImageDir.mkdirs();
-
-            // first, make sure we don't use the local signing key
-            p.put(MacAppBundler.DEVELOPER_ID_APP_SIGNING_KEY.getID(), null);
-            File appLocation = prepareAppBundle(p);
-
-            prepareEntitlements(p);
-
-            String signingIdentity = MAC_APP_STORE_APP_SIGNING_KEY.fetchFrom(p);
-            String identifierPrefix = IDENTIFIER.fetchFrom(p) + ".";
-            String entitlementsFile = getConfig_Entitlements(p).toString();
-            String inheritEntitlements = getConfig_Inherit_Entitlements(p).toString();
-
-            signAppBundle(p, appLocation, signingIdentity, identifierPrefix, entitlementsFile, inheritEntitlements);
-            ProcessBuilder pb;
-
-            // create the final pkg file
-            File finalPKG = new File(outdir, APP_NAME.fetchFrom(p)+".pkg");
-            outdir.mkdirs();
-
-            pb = new ProcessBuilder("productbuild",
-                    "--component", appLocation.toString(), "/Applications",
-                    "--sign", MAC_APP_STORE_PKG_SIGNING_KEY.fetchFrom(p),
-                    "--product", appLocation + "/Contents/Info.plist",
-                    finalPKG.getAbsolutePath());
-            IOUtils.exec(pb, VERBOSE.fetchFrom(p));
-            return finalPKG;
-        } catch (Exception ex) {
-            Log.info("App Store Ready Bundle failed : " + ex.getMessage());
-            ex.printStackTrace();
-            Log.debug(ex);
-            return null;
-        } finally {
-            try {
-                if (appImageDir != null && !Log.isDebug()) {
-                    IOUtils.deleteRecursive(appImageDir);
-                } else if (appImageDir != null) {
-                    Log.info(MessageFormat.format(I18N.getString("mesasge.intermediate-bundle-location"), appImageDir.getAbsolutePath()));
-                }
-                if (!VERBOSE.fetchFrom(p)) {
-                    //cleanup
-                    cleanupConfigFiles(p);
-                } else {
-                    Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), CONFIG_ROOT.fetchFrom(p).getAbsolutePath()));
-                }
-            } catch (FileNotFoundException ex) {
-                //noinspection ReturnInsideFinallyBlock
-                return null;
-            }
-        }
-    }
-
-    protected void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (getConfig_Entitlements(params) != null) {
-            getConfig_Entitlements(params).delete();
-        }
-        if (getConfig_Inherit_Entitlements(params) != null) {
-            getConfig_Inherit_Entitlements(params).delete();
-        }
-        APP_BUNDLER.fetchFrom(params).cleanupConfigFiles(params);
-    }
-
-    private File getConfig_Entitlements(Map<String, ? super Object> params) {
-        return new File(CONFIG_ROOT.fetchFrom(params), APP_NAME.fetchFrom(params) + ".entitlements");
-    }
-
-    private File getConfig_Inherit_Entitlements(Map<String, ? super Object> params) {
-        return new File(CONFIG_ROOT.fetchFrom(params), APP_NAME.fetchFrom(params) + "_Inherit.entitlements");
-    }
-
-    private void prepareEntitlements(Map<String, ? super Object> params) throws IOException {
-        File entitlements = MAC_APP_STORE_ENTITLEMENTS.fetchFrom(params);
-        if (entitlements == null || !entitlements.exists()) {
-            fetchResource(getEntitlementsFileName(params),
-                    I18N.getString("resource.mac-app-store-entitlements"),
-                    DEFAULT_ENTITLEMENTS,
-                    getConfig_Entitlements(params),
-                    VERBOSE.fetchFrom(params));
-        } else {
-            fetchResource(getEntitlementsFileName(params),
-                    I18N.getString("resource.mac-app-store-entitlements"),
-                    entitlements,
-                    getConfig_Entitlements(params),
-                    VERBOSE.fetchFrom(params));
-        }
-        fetchResource(getInheritEntitlementsFileName(params),
-                I18N.getString("resource.mac-app-store-inherit-entitlements"),
-                DEFAULT_INHERIT_ENTITLEMENTS,
-                getConfig_Inherit_Entitlements(params),
-                VERBOSE.fetchFrom(params));
-    }
-
-    private String getEntitlementsFileName(Map<String, ? super Object> params) {
-        return MacAppBundler.MAC_BUNDLER_PREFIX+ APP_NAME.fetchFrom(params) +".entitlements";
-    }
-
-    private String getInheritEntitlementsFileName(Map<String, ? super Object> params) {
-        return MacAppBundler.MAC_BUNDLER_PREFIX+ APP_NAME.fetchFrom(params) +"_Inherit.entitlements";
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    // Implement Bundler
-    //////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public String getName() {
-        return I18N.getString("bundler.name");
-    }
-
-    @Override
-    public String getDescription() {
-        return I18N.getString("bundler.description");
-    }
-
-    @Override
-    public String getID() {
-        return "mac.appStore";
-    }
-
-    @Override
-    public Collection<BundlerParamInfo<?>> getBundleParameters() {
-        Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
-        results.addAll(MacAppBundler.getAppBundleParameters());
-        results.addAll(getPKGBundleParameters());
-        return results;
-    }
-
-    public Collection<BundlerParamInfo<?>> getPKGBundleParameters() {
-        Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
-
-        results.addAll(MacAppBundler.getAppBundleParameters());
-        results.addAll(Arrays.asList(
-                APP_BUNDLER,
-                APP_IMAGE_BUILD_ROOT,
-                APP_NAME,
-                APP_RESOURCES,
-                CONFIG_ROOT,
-                MAC_APP_IMAGE,
-                MAC_APP_STORE_APP_SIGNING_KEY,
-                MAC_APP_STORE_ENTITLEMENTS,
-                MAC_APP_STORE_PKG_SIGNING_KEY,
-                SIGNING_KEY_USER
-        ));
-
-        return results;
-    }
-
-    @Override
-    public boolean validate(Map<String, ? super Object> params) throws UnsupportedPlatformException, ConfigException {
-        try {
-            if (params == null) throw new ConfigException(
-                    I18N.getString("error.parameters-null"),
-                    I18N.getString("error.parameters-null.advice"));
-
-            // hdiutil is always available so there's no need to test for availability.
-            //run basic validation to ensure requirements are met
-
-            //run basic validation to ensure requirements are met
-            //we are not interested in return code, only possible exception
-            APP_BUNDLER.fetchFrom(params).doValidate(params);
-
-            // make sure we have settings for signatures
-            if (MAC_APP_STORE_APP_SIGNING_KEY.fetchFrom(params) == null) {
-                throw new ConfigException(
-                        I18N.getString("error.no-app-signing-key"),
-                        I18N.getString("error.no-app-signing-key.advice"));
-            }
-            if (MAC_APP_STORE_PKG_SIGNING_KEY.fetchFrom(params) == null) {
-                throw new ConfigException(
-                        I18N.getString("error.no-pkg-signing-key"),
-                        I18N.getString("error.no-pkg-signing-key.advice"));
-            }
-
-            // things we could check...
-            // check the icons, make sure it has hidpi icons
-            // check the category, make sure it fits in the list apple has provided
-            // validate bundle identifier is reverse dns
-            //  check for \a+\.\a+\..
-
-            return true;
-        } catch (RuntimeException re) {
-            throw new ConfigException(re);
-        }
-    }
-
-    @Override
-    public File execute(Map<String, ? super Object> params, File outputParentDir) {
-        return bundle(params, outputParentDir);
-    }
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/mac/MacBaseInstallerBundler.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,379 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers.mac;
-
-import com.oracle.bundlers.AbstractBundler;
-import com.oracle.bundlers.BundlerParamInfo;
-import com.oracle.bundlers.StandardBundlerParam;
-import com.sun.javafx.tools.packager.Log;
-import com.sun.javafx.tools.packager.bundlers.ConfigException;
-import com.sun.javafx.tools.packager.bundlers.IOUtils;
-import com.sun.javafx.tools.packager.bundlers.MacAppBundler;
-import com.sun.javafx.tools.packager.bundlers.UnsupportedPlatformException;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.attribute.PosixFilePermission;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.ResourceBundle;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static com.oracle.bundlers.StandardBundlerParam.*;
-
-public abstract class MacBaseInstallerBundler extends AbstractBundler {
-
-    private static final ResourceBundle I18N =
-            ResourceBundle.getBundle("com.oracle.bundlers.mac.MacBaseInstallerBundler");
-
-    //This could be generalized more to be for any type of Image Bundler
-    public static final BundlerParamInfo<MacAppBundler> APP_BUNDLER = new StandardBundlerParam<>(
-            I18N.getString("param.app-bundler.name"),
-            I18N.getString("param.app-bundle.description"),
-            "mac.app.bundler",
-            MacAppBundler.class,
-            params -> new MacAppBundler(),
-            (s, p) -> null);
-
-    public final BundlerParamInfo<File> APP_IMAGE_BUILD_ROOT = new StandardBundlerParam<>(
-            I18N.getString("param.app-image-build-root.name"),
-            I18N.getString("param.app-image-build-root.description"),
-            "mac.app.imageRoot",
-            File.class,
-            params -> {
-                File imageDir = IMAGES_ROOT.fetchFrom(params);
-                if (!imageDir.exists()) imageDir.mkdirs();
-                return new File(imageDir, getID()+ ".image");
-            },
-            (s, p) -> new File(s));
-
-    public static final StandardBundlerParam<File> MAC_APP_IMAGE = new StandardBundlerParam<>(
-            I18N.getString("param.app-image.name"),
-            I18N.getString("param.app-image.description"),
-            "mac.app.image",
-            File.class,
-            params -> null,
-            (s, p) -> new File(s));
-
-
-    public static final BundlerParamInfo<MacDaemonBundler> DAEMON_BUNDLER = new StandardBundlerParam<>(
-            I18N.getString("param.daemon-bundler.name"),
-            I18N.getString("param.daemon-bundler.description"),
-            "mac.daemon.bundler",
-            MacDaemonBundler.class,
-            params -> new MacDaemonBundler(),
-            (s, p) -> null);
-
-
-    public final BundlerParamInfo<File> DAEMON_IMAGE_BUILD_ROOT = new StandardBundlerParam<>(
-            I18N.getString("param.daemon-image-build-root.name"),
-            I18N.getString("param.daemon-image-build-root.description"),
-            "mac.daemon.image",
-            File.class,
-            params -> {
-                File imageDir = IMAGES_ROOT.fetchFrom(params);
-                if (!imageDir.exists()) imageDir.mkdirs();
-                return new File(imageDir, getID()+ ".daemon");
-            },
-            (s, p) -> new File(s));
-
-
-    public static final BundlerParamInfo<File> CONFIG_ROOT = new StandardBundlerParam<>(
-            I18N.getString("param.config-root.name"),
-            I18N.getString("param.config-root.description"),
-            "configRoot",
-            File.class,
-            params -> {
-                File imagesRoot = new File(BUILD_ROOT.fetchFrom(params), "macosx");
-                imagesRoot.mkdirs();
-                return imagesRoot;
-            },
-            (s, p) -> null);
-
-    public static final BundlerParamInfo<String> SIGNING_KEY_USER = new StandardBundlerParam<>(
-            I18N.getString("param.signing-key-name.name"),
-            I18N.getString("param.signing-key-name.description"),
-            "mac.signing-key-user-name",
-            String.class,
-            params -> {
-                try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) {
-                    ProcessBuilder pb = new ProcessBuilder(
-                            "dscacheutil",
-                            "-q", "user", "-a", "name", System.getProperty("user.name"));
-
-                    IOUtils.exec(pb, Log.isDebug(), false, ps);
-
-                    String commandOutput = baos.toString();
-
-                    Pattern pattern = Pattern.compile(".*gecos: (.*)");
-                    Matcher matcher = pattern.matcher(commandOutput);
-                    if (matcher.matches()) {
-                        return (matcher.group(1));
-                    }
-                } catch (IOException ioe) {
-                    Log.info(I18N.getString("message.could-not-retrieve-name"));
-                    Log.debug(ioe);
-                }
-                return null;
-            },
-            null);
-
-
-
-    public static File getPredefinedImage(Map<String, ? super Object> p) {
-        File applicationImage = null;
-        if (MAC_APP_IMAGE.fetchFrom(p) != null) {
-            applicationImage = MAC_APP_IMAGE.fetchFrom(p);
-            if (!applicationImage.exists()) {
-                throw new RuntimeException(
-                        MessageFormat.format(I18N.getString("message.app-image-dir-does-not-exist"), MAC_APP_IMAGE.getID(), applicationImage.toString()));
-            }
-        }
-        return applicationImage;
-    }
-
-    protected void validateAppImageAndBundeler(Map<String, ? super Object> params) throws ConfigException, UnsupportedPlatformException {
-        if (MAC_APP_IMAGE.fetchFrom(params) != null) {
-            File applicationImage = MAC_APP_IMAGE.fetchFrom(params);
-            if (!applicationImage.exists()) {
-                throw new ConfigException(
-                        MessageFormat.format(I18N.getString("message.app-image-dir-does-not-exist"), MAC_APP_IMAGE.getID(), applicationImage.toString()),
-                        MessageFormat.format(I18N.getString("message.app-image-dir-does-not-exist.advice"), MAC_APP_IMAGE.getID()));
-            }
-        } else {
-            APP_BUNDLER.fetchFrom(params).doValidate(params);
-        }
-    }
-
-    protected File prepareAppBundle(Map<String, ? super Object> p) {
-        if (getPredefinedImage(p) != null) {
-            return null;
-        }
-
-        File appImageRoot = APP_IMAGE_BUILD_ROOT.fetchFrom(p);
-        return APP_BUNDLER.fetchFrom(p).doBundle(p, appImageRoot, true);
-    }
-
-    protected File prepareDaemonBundle(Map<String, ? super Object> p) throws ConfigException {
-        File daemonImageRoot = DAEMON_IMAGE_BUILD_ROOT.fetchFrom(p);
-        return DAEMON_BUNDLER.fetchFrom(p).doBundle(p, daemonImageRoot, true);
-    }
-
-    public static void signAppBundle(Map<String, ? super Object> params, File appLocation, String signingIdentity, String identifierPrefix) throws IOException {
-        signAppBundle(params, appLocation, signingIdentity, identifierPrefix, null, null);
-    }
-
-    public static void signAppBundle(Map<String, ? super Object> params, File appLocation, String signingIdentity, String identifierPrefix, String entitlementsFile, String inheritedEntitlements) throws IOException {
-
-        AtomicReference<IOException> toThrow = new AtomicReference<>();
-
-        // sign all dylibs and jars
-        Files.walk(appLocation.toPath())
-                .filter(p -> (p.toString().endsWith(".jar")
-                                || p.toString().endsWith(".dylib"))
-                ).forEach(p -> {
-                    //noinspection ThrowableResultOfMethodCallIgnored
-                    if (toThrow.get() != null) return;
-
-                    List<String> args = new ArrayList<>();
-                    args.addAll(Arrays.asList(
-                            "codesign",
-                            "-f")); // replace all existing signatures
-                    if (signingIdentity != null) {
-                        args.add("-s");
-                        args.add(signingIdentity); // sign with this key
-                    }
-                    if (entitlementsFile != null) {
-                        args.add("--entitlements");
-                        args.add(entitlementsFile); // entitlements
-                    }
-                    args.add("-vvvv"); // super verbose output
-                    args.add(p.toString());
-
-
-                    try {
-                        Set<PosixFilePermission> oldPermissions = Files.getPosixFilePermissions(p);
-                        File f = p.toFile();
-                        f.setWritable(true, true);
-
-                        ProcessBuilder pb = new ProcessBuilder(args);
-                        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-
-                        Files.setPosixFilePermissions(p, oldPermissions);
-                    } catch (IOException ioe) {
-                        toThrow.set(ioe);
-                    }
-                });
-
-        IOException ioe = toThrow.get();
-        if (ioe != null) {
-            throw ioe;
-        }
-
-        // sign all contained executables with an inherit entitlement
-        Files.find(appLocation.toPath().resolve("Contents"), Integer.MAX_VALUE,
-                (path, attr) -> (Files.isExecutable(path) && Files.isRegularFile(path)))
-                .filter(path -> (!path.toString().endsWith(".dylib") && !path.toString().contains("/Contents/MacOS/")))
-                .forEachOrdered(path -> {
-                    //noinspection ThrowableResultOfMethodCallIgnored
-                    if (toThrow.get() != null) return;
-
-                    List<String> args = new ArrayList<>();
-                    args.addAll(Arrays.asList("codesign",
-                            "--deep",
-//                            "--prefix", identifierPrefix, // use the identifier as a prefix
-                            "-f")); // replace all existing signatures
-                    if (signingIdentity != null) {
-                        args.add("-s");
-                        args.add(signingIdentity); // sign with this key
-                    }
-                    if (inheritedEntitlements != null) {
-                        args.add("--entitlements");
-                        args.add(inheritedEntitlements); // entitlements
-                    }
-                    args.add("-vvvv"); // super verbose output
-                    args.add(path.toString()); // this is what we are signing
-
-                    try {
-                        Set<PosixFilePermission> oldPermissions = Files.getPosixFilePermissions(path);
-                        File f = path.toFile();
-                        f.setWritable(true, true);
-
-                        ProcessBuilder pb = new ProcessBuilder(args);
-                        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-
-                        Files.setPosixFilePermissions(path, oldPermissions);
-                    } catch (IOException e) {
-                        toThrow.set(e);
-                    }
-                });
-
-        ioe = toThrow.get();
-        if (ioe != null) {
-            throw ioe;
-        }
-
-        // sign all plugins and frameworks
-        Consumer<? super Path> signIdentifiedByPList = path -> {
-            //noinspection ThrowableResultOfMethodCallIgnored
-            if (toThrow.get() != null) return;
-
-            try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) {
-                ProcessBuilder pb = new ProcessBuilder("/usr/libexec/PlistBuddy",
-                        "-c", "Print :CFBundleIdentifier", path.resolve("Contents/Info.plist").toString());
-                IOUtils.exec(pb, VERBOSE.fetchFrom(params), false, ps);
-                String bundleID = baos.toString();
-
-                List<String> args = new ArrayList<>();
-                args.addAll(Arrays.asList("codesign",
-                        "-s", signingIdentity, // sign with this key
-                        "-f", // replace all existing signatures
-                        "--prefix", identifierPrefix, // use the identifier as a prefix
-                        //"-i", bundleID, // sign the bundle's CFBundleIdentifier
-                        "-vvvv"));
-                if (signingIdentity != null) {
-                    args.add("-s");
-                    args.add(signingIdentity); // sign with this key
-                }
-                args.add(path.toString());
-                pb = new ProcessBuilder(args);
-                IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-            } catch (IOException e) {
-                toThrow.set(e);
-            }
-        };
-
-        Path pluginsPath = appLocation.toPath().resolve("Contents/PlugIns");
-        if (Files.isDirectory(pluginsPath)) {
-            Files.list(pluginsPath)
-                    .forEach(signIdentifiedByPList);
-
-            ioe = toThrow.get();
-            if (ioe != null) {
-                throw ioe;
-            }
-        }
-        Path frameworkPath = appLocation.toPath().resolve("Contents/Frameworks");
-        if (Files.isDirectory(frameworkPath)) {
-            Files.list(frameworkPath)
-                    .forEach(signIdentifiedByPList);
-
-            ioe = toThrow.get();
-            if (ioe != null) {
-                throw ioe;
-            }
-        }
-
-        // sign the app itself
-        List<String> args = new ArrayList<>();
-        args.addAll(Arrays.asList("codesign",
-                "-s", signingIdentity, // sign with this key
-                "--deep", // sign deeply, including plugins
-                "-f")); // replace all existing signatures
-        if (entitlementsFile != null) {
-            args.add("--entitlements");
-            args.add(entitlementsFile); // entitlements
-        }
-        args.add("-vvvv"); // super verbose output
-        args.add(appLocation.toString());
-
-        ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[args.size()]));
-        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-    }
-
-    @Override
-    public Collection<BundlerParamInfo<?>> getBundleParameters() {
-        Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
-
-        results.addAll(MacAppBundler.getAppBundleParameters());
-        results.addAll(Arrays.asList(
-                APP_BUNDLER,
-                CONFIG_ROOT,
-                APP_IMAGE_BUILD_ROOT,
-                MAC_APP_IMAGE
-        ));
-
-        return results;
-    }
-
-    @Override
-    public String getBundleType() {
-        return "INSTALLER";
-    }
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/mac/MacDaemonBundler.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.bundlers.mac;
-
-import static com.oracle.bundlers.StandardBundlerParam.*;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.text.MessageFormat;import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-import com.oracle.bundlers.AbstractBundler;
-import com.oracle.bundlers.BundlerParamInfo;
-import com.oracle.bundlers.StandardBundlerParam;
-
-import com.sun.javafx.tools.packager.Log;
-import com.sun.javafx.tools.packager.bundlers.ConfigException;
-import com.sun.javafx.tools.packager.bundlers.IOUtils;
-import com.sun.javafx.tools.packager.bundlers.UnsupportedPlatformException;
-import com.sun.javafx.tools.resource.mac.MacResources;
-
-public class MacDaemonBundler extends AbstractBundler {
-
-    private static final ResourceBundle I18N =
-            ResourceBundle.getBundle("com.oracle.bundlers.mac.MacDaemonBundler");
-
-    private static final String TEMPLATE_LAUNCHD_PLIST  = "launchd.plist.template";
-
-    public final static String MAC_BUNDLER_PREFIX =
-            BUNDLER_PREFIX + "macosx" + File.separator;
-
-    public static final BundlerParamInfo<File> CONFIG_ROOT = new StandardBundlerParam<>(
-            I18N.getString("param.config-root.name"),
-            I18N.getString("param.config-root.description"),
-            "configRoot",
-            File.class,
-            params -> {
-                File configRoot = new File(BUILD_ROOT.fetchFrom(params), "macosx");
-                configRoot.mkdirs();
-                return configRoot;
-            },
-            (s, p) -> new File(s));
-
-    public MacDaemonBundler() {
-        super();
-        baseResourceLoader = MacResources.class;
-    }
-
-    private File getConfig_LaunchdPlist(Map<String, ? super Object> params) {
-        return new File(CONFIG_ROOT.fetchFrom(params), "launchd.plist");
-    }
-
-    private void prepareConfigFiles(Map<String, ? super Object> params) throws IOException {
-        File launchdPlistFile = getConfig_LaunchdPlist(params);
-        launchdPlistFile.createNewFile();
-        writeLaunchdPlist(launchdPlistFile, params);
-    }
-
-    private String getDaemonIdentifier(Map<String, ? super Object> params) {
-        return IDENTIFIER.fetchFrom(params).toLowerCase() + ".daemon";
-    }
-
-    public String getAppName(Map<String, ? super Object> params) {
-        return APP_NAME.fetchFrom(params) + ".app";
-    }
-
-    private String getLauncherName(Map<String, ? super Object> params) {
-        if (APP_NAME.fetchFrom(params) != null) {
-            return APP_NAME.fetchFrom(params);
-        } else {
-            return MAIN_CLASS.fetchFrom(params);
-        }
-    }
-
-    private String getDaemonLauncherPath(Map<String, ? super Object> params) {
-        return "/Applications/" + getAppName(params) +
-                "/Contents/MacOS/" + getLauncherName(params);
-    }
-
-    private void writeLaunchdPlist(File file, Map<String, ? super Object> params)
-            throws IOException
-    {
-        Log.verbose(MessageFormat.format(I18N.getString("message.preparing-launchd-plist"), file.getAbsolutePath()));
-
-        Map<String, String> data = new HashMap<>();
-
-        data.put("DEPLOY_DAEMON_IDENTIFIER", getDaemonIdentifier(params));
-        data.put("DEPLOY_DAEMON_LAUNCHER_PATH", getDaemonLauncherPath(params));
-        data.put("DEPLOY_RUN_AT_LOAD", String.valueOf((START_ON_INSTALL.fetchFrom(params))));
-        data.put("DEPLOY_KEEP_ALIVE", String.valueOf((RUN_AT_STARTUP.fetchFrom(params))));
-
-        Writer w = new BufferedWriter(new FileWriter(file));
-        w.write(preprocessTextResource(
-                MAC_BUNDLER_PREFIX + getConfig_LaunchdPlist(params).getName(),
-                I18N.getString("resource.launchd-config"), TEMPLATE_LAUNCHD_PLIST, data,
-                VERBOSE.fetchFrom(params)));
-        w.close();
-    }
-
-    protected void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (CONFIG_ROOT.fetchFrom(params) != null) {
-            if (getConfig_LaunchdPlist(params) != null) {
-                getConfig_LaunchdPlist(params).delete();
-            }
-        }
-    }
-
-    /*
-     * Creates the following structure
-     * 
-     *  <package-name>
-     *      Library
-     *          LaunchDaemons
-     *              plist file
-     */
-    public File doBundle(Map<String, ? super Object> params, File outputDirectory, boolean dependentTask) {
-        if (!outputDirectory.isDirectory() && !outputDirectory.mkdirs()) {
-            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outputDirectory.getAbsolutePath()));
-        }
-        if (!outputDirectory.canWrite()) {
-            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outputDirectory.getAbsolutePath()));
-        }
-
-        File rootDirectory = null;
-
-        try {
-            File file = BUILD_ROOT.fetchFrom(params);
-
-            //prepare config resources (we will copy them to the bundle later)
-            // NB: explicitly saving them to simplify customization
-            prepareConfigFiles(params);
-
-            // Create directory structure
-            rootDirectory = new File(outputDirectory, APP_NAME.fetchFrom(params) + ".daemon");
-            IOUtils.deleteRecursive(rootDirectory);
-            rootDirectory.mkdirs();
-
-            if (!dependentTask) {
-                Log.info(MessageFormat.format(I18N.getString("message.creating-daemon-component"), rootDirectory.getAbsolutePath()));
-            }
-
-            File libraryDirectory = new File(rootDirectory, "Library");
-            libraryDirectory.mkdirs();
-
-            File launchDaemonsDirectory = new File(libraryDirectory, "LaunchDaemons");
-            launchDaemonsDirectory.mkdirs();
-
-            // Generate launchd.plist
-            IOUtils.copyFile(getConfig_LaunchdPlist(params),
-                    new File(launchDaemonsDirectory,
-                            IDENTIFIER.fetchFrom(params).toLowerCase() + ".launchd.plist"));
-
-        } catch(IOException ex) {
-            Log.verbose(ex);
-            return null;
-        } finally {
-            if (!VERBOSE.fetchFrom(params)) {
-                //cleanup
-                cleanupConfigFiles(params);
-            } else {
-                Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), CONFIG_ROOT.fetchFrom(params).getAbsolutePath()));
-            }
-        }
-
-        return rootDirectory;
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    // Implement Bundler
-    //////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public String getName() {
-        return I18N.getString("bundle.name");
-    }
-
-    @Override
-    public String getDescription() {
-        return I18N.getString("bundle.description");
-    }
-
-    @Override
-    public String getID() {
-        return "mac.daemon";
-    }
-
-    @Override
-    public String getBundleType() {
-        return "INSTALLER";
-    }
-
-    @Override
-    public Collection<BundlerParamInfo<?>> getBundleParameters() {
-        return getDaemonBundleParameters();
-    }
-
-    public static Collection<BundlerParamInfo<?>> getDaemonBundleParameters() {
-        return Arrays.asList(
-                APP_NAME,
-                BUILD_ROOT,
-                IDENTIFIER,
-                START_ON_INSTALL,
-                RUN_AT_STARTUP
-        );
-    }
-
-    @Override
-    public boolean validate(Map<String, ? super Object> params)
-            throws UnsupportedPlatformException, ConfigException
-    {
-        try {
-            return doValidate(params);
-        } catch (RuntimeException re) {
-            throw new ConfigException(re);
-        }
-
-    }
-
-    public boolean doValidate(Map<String, ? super Object> p)
-            throws UnsupportedPlatformException, ConfigException
-    {
-        if (!System.getProperty("os.name").toLowerCase().contains("os x")) {
-            throw new UnsupportedPlatformException();
-        }
-
-        return true;
-    }
-
-    @Override
-    public File execute(Map<String, ? super Object> params, File outputParentDir) {
-        return doBundle(params, outputParentDir, false);
-    }
-
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/mac/MacPKGBundler.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,464 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers.mac;
-
-import com.oracle.bundlers.BundlerParamInfo;
-import com.oracle.bundlers.StandardBundlerParam;
-import com.sun.javafx.tools.packager.Log;
-import com.sun.javafx.tools.packager.bundlers.ConfigException;
-import com.sun.javafx.tools.packager.bundlers.IOUtils;
-import com.sun.javafx.tools.packager.bundlers.RelativeFileSet;
-import com.sun.javafx.tools.packager.bundlers.UnsupportedPlatformException;
-import com.sun.javafx.tools.resource.mac.MacResources;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.Writer;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-import static com.oracle.bundlers.StandardBundlerParam.*;
-
-public class MacPKGBundler extends MacBaseInstallerBundler {
-
-    private static final ResourceBundle I18N =
-            ResourceBundle.getBundle("com.oracle.bundlers.mac.MacPKGBundler");
-
-    public final static String MAC_BUNDLER_PREFIX =
-            BUNDLER_PREFIX + "macosx" + File.separator;
-
-    private static final String DEFAULT_BACKGROUND_IMAGE = "background_pkg.png";
-
-    private static final String TEMPLATE_PREINSTALL_SCRIPT = "preinstall.template";
-    private static final String TEMPLATE_POSTINSTALL_SCRIPT = "postinstall.template";
-
-    private static final String TEMPLATE_DISTRIBUTION_XML  = "distribution.dist.template";
-
-    private static final BundlerParamInfo<File> PACKAGES_ROOT = new StandardBundlerParam<>(
-            I18N.getString("param.packages-root.name"),
-            I18N.getString("param.packages-root.description"),
-            "mac.pkg.packagesRoot",
-            File.class,
-            params -> {
-                File packagesRoot = new File(BUILD_ROOT.fetchFrom(params), "packages");
-                packagesRoot.mkdirs();
-                return packagesRoot;
-            },
-            (s, p) -> new File(s));
-
-
-    protected final BundlerParamInfo<File> SCRIPTS_DIR = new StandardBundlerParam<>(
-            I18N.getString("param.scripts-dir.name"),
-            I18N.getString("param.scripts-dir.description"),
-            "mac.pkg.scriptsDir",
-            File.class,
-            params -> {
-                File scriptsDir = new File(CONFIG_ROOT.fetchFrom(params), "scripts");
-                scriptsDir.mkdirs();
-                return scriptsDir;
-            },
-            (s, p) -> new File(s));
-
-    public static final BundlerParamInfo<String> DEVELOPER_ID_INSTALLER_SIGNING_KEY = new StandardBundlerParam<>(
-            I18N.getString("param.signing-key-developer-id-installer.name"),
-            I18N.getString("param.signing-key-developer-id-installer.description"),
-            "mac.signing-key-developer-id-installer",
-            String.class,
-            params -> {
-                String key = "Developer ID Installer: " + SIGNING_KEY_USER.fetchFrom(params);
-                try {
-                    IOUtils.exec(new ProcessBuilder("security", "find-certificate", "-c", key), VERBOSE.fetchFrom(params));
-                    return key;
-                } catch (IOException ioe) {
-                    return null;
-                }
-            },
-            (s, p) -> s);
-
-    public MacPKGBundler() {
-        super();
-        baseResourceLoader = MacResources.class;
-    }
-
-    //@Override
-    public File bundle(Map<String, ? super Object> p, File outdir) {
-        Log.info(MessageFormat.format(I18N.getString("message.building-pkg"), APP_NAME.fetchFrom(p)));
-        if (!outdir.isDirectory() && !outdir.mkdirs()) {
-            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outdir.getAbsolutePath()));
-        }
-        if (!outdir.canWrite()) {
-            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outdir.getAbsolutePath()));
-        }
-
-        File appImageDir = APP_IMAGE_BUILD_ROOT.fetchFrom(p);
-        File daemonImageDir = DAEMON_IMAGE_BUILD_ROOT.fetchFrom(p);
-
-        try {
-            appImageDir.mkdirs();
-            prepareAppBundle(p);
-
-            if (SERVICE_HINT.fetchFrom(p)) {
-                daemonImageDir.mkdirs();
-                prepareDaemonBundle(p);
-            }
-
-            return createPKG(p, outdir);
-        } catch (Exception ex) {
-            return null;
-        }
-    }
-
-    private File getPackages_AppPackage(Map<String, ? super Object> params) {
-        return new File(PACKAGES_ROOT.fetchFrom(params), APP_NAME.fetchFrom(params) + "-app.pkg");
-    }
-
-    private File getPackages_DaemonPackage(Map<String, ? super Object> params) {
-        return new File(PACKAGES_ROOT.fetchFrom(params), APP_NAME.fetchFrom(params) + "-daemon.pkg");
-    }
-
-    private void cleanupPackagesFiles(Map<String, ? super Object> params) {
-        if (getPackages_AppPackage(params) != null) {
-            getPackages_AppPackage(params).delete();
-        }
-        if (getPackages_DaemonPackage(params) != null) {
-            getPackages_DaemonPackage(params).delete();
-        }
-    }
-
-    private File getConfig_DistributionXMLFile(Map<String, ? super Object> params) {
-        return new File(CONFIG_ROOT.fetchFrom(params), "distribution.dist");
-    }
-
-    private File getConfig_BackgroundImage(Map<String, ? super Object> params) {
-        return new File(CONFIG_ROOT.fetchFrom(params), APP_NAME.fetchFrom(params) + "-background.png");
-    }
-
-    private File getScripts_PreinstallFile(Map<String, ? super Object> params) {
-        return new File(SCRIPTS_DIR.fetchFrom(params), "preinstall");
-    }
-
-    private File getScripts_PostinstallFile(Map<String, ? super Object> params) {
-        return new File(SCRIPTS_DIR.fetchFrom(params), "postinstall");
-    }
-
-    private void cleanupPackageScripts(Map<String, ? super Object> params) {
-        if (getScripts_PreinstallFile(params) != null) {
-            getScripts_PreinstallFile(params).delete();
-        }
-        if (getScripts_PostinstallFile(params) != null) {
-            getScripts_PostinstallFile(params).delete();
-        }
-    }
-
-    private void cleanupConfigFiles(Map<String, ? super Object> params) {
-        if (getConfig_DistributionXMLFile(params) != null) {
-            getConfig_DistributionXMLFile(params).delete();
-        }
-        if (getConfig_BackgroundImage(params) != null) {
-            getConfig_BackgroundImage(params).delete();
-        }
-    }
-
-    private String getAppIdentifier(Map<String, ? super Object> params) {
-        return IDENTIFIER.fetchFrom(params);
-    }
-
-    private String getDaemonIdentifier(Map<String, ? super Object> params) {
-        return IDENTIFIER.fetchFrom(params) + ".daemon";
-    }
-
-    private void preparePackageScripts(Map<String, ? super Object> params) throws IOException
-    {
-        Log.verbose(I18N.getString("message.preparing-scripts"));
-
-        Map<String, String> data = new HashMap<>();
-
-        data.put("DEPLOY_DAEMON_IDENTIFIER", getDaemonIdentifier(params));
-        data.put("DEPLOY_LAUNCHD_PLIST_FILE",
-                IDENTIFIER.fetchFrom(params).toLowerCase() + ".launchd.plist");
-
-        Writer w = new BufferedWriter(new FileWriter(getScripts_PreinstallFile(params)));
-        String content = preprocessTextResource(
-                MAC_BUNDLER_PREFIX + getScripts_PreinstallFile(params).getName(),
-                I18N.getString("resource.pkg-preinstall-script"),
-                TEMPLATE_PREINSTALL_SCRIPT,
-                data,
-                VERBOSE.fetchFrom(params));
-        w.write(content);
-        w.close();
-        getScripts_PreinstallFile(params).setExecutable(true, false);
-
-        w = new BufferedWriter(new FileWriter(getScripts_PostinstallFile(params)));
-        content = preprocessTextResource(
-                MAC_BUNDLER_PREFIX + getScripts_PostinstallFile(params).getName(),
-                I18N.getString("resource.pkg-postinstall-script"),
-                TEMPLATE_POSTINSTALL_SCRIPT,
-                data,
-                VERBOSE.fetchFrom(params));
-        w.write(content);
-        w.close();
-        getScripts_PostinstallFile(params).setExecutable(true, false);
-    }
-
-    private void prepareDistributionXMLFile(Map<String, ? super Object> params)
-            throws IOException
-    {
-        File f = getConfig_DistributionXMLFile(params);
-
-        Log.verbose(MessageFormat.format(I18N.getString("message.preparing-distribution-dist"), f.getAbsolutePath()));
-
-        PrintStream out = new PrintStream(f);
-
-        out.println("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>");
-        out.println("<installer-gui-script minSpecVersion=\"1\">");
-
-        out.println("<title>" + APP_NAME.fetchFrom(params) + "</title>");
-        out.println("<background" +
-                " file=\"" + getConfig_BackgroundImage(params).getName() + "\"" +
-                " mime-type=\"image/png\"" +
-                " alignment=\"bottomleft\" " +
-                " scaling=\"none\""+
-                "/>");
-
-        if (!LICENSE_FILE.fetchFrom(params).isEmpty()) {
-            File licFile = new File(APP_RESOURCES.fetchFrom(params).getBaseDirectory(),
-                    LICENSE_FILE.fetchFrom(params).get(0));
-            out.println("<license" +
-                    " file=\"" + licFile.getAbsolutePath() + "\"" +
-                    " mime-type=\"text/rtf\"" +
-                    "/>");
-        }
-
-        /*
-         * Note that the content of the distribution file
-         * below is generated by productbuild --synthesize
-         */
-
-        String appId = getAppIdentifier(params);
-        String daemonId = getDaemonIdentifier(params);
-
-        out.println("<pkg-ref id=\"" + appId + "\"/>");
-        if (SERVICE_HINT.fetchFrom(params)) {
-            out.println("<pkg-ref id=\"" + daemonId + "\"/>");
-        }
-
-        out.println("<options customize=\"never\" require-scripts=\"false\"/>");
-        out.println("<choices-outline>");
-        out.println("    <line choice=\"default\">");
-        out.println("        <line choice=\"" + appId + "\"/>");
-        if (SERVICE_HINT.fetchFrom(params)) {
-            out.println("        <line choice=\"" + daemonId + "\"/>");
-        }
-        out.println("    </line>");
-        out.println("</choices-outline>");
-        out.println("<choice id=\"default\"/>");
-        out.println("<choice id=\"" + appId + "\" visible=\"false\">");
-        out.println("    <pkg-ref id=\"" + appId + "\"/>");
-        out.println("</choice>");
-        out.println("<pkg-ref id=\"" + appId + "\" version=\"" + VERSION.fetchFrom(params) +
-                "\" onConclusion=\"none\">" +
-                getPackages_AppPackage(params).getName() + "</pkg-ref>");
-
-        if (SERVICE_HINT.fetchFrom(params)) {
-            out.println("<choice id=\"" + daemonId + "\" visible=\"false\">");
-            out.println("    <pkg-ref id=\"" + daemonId + "\"/>");
-            out.println("</choice>");
-            out.println("<pkg-ref id=\"" + daemonId + "\" version=\"" + VERSION.fetchFrom(params) +
-                    "\" onConclusion=\"none\">" +
-                    getPackages_DaemonPackage(params).getName() + "</pkg-ref>");
-        }
-
-        out.println("</installer-gui-script>");
-
-        out.close();
-    }
-
-    private void prepareConfigFiles(Map<String, ? super Object> params) throws IOException {
-        File imageTarget = getConfig_BackgroundImage(params);
-        fetchResource(com.sun.javafx.tools.packager.bundlers.MacAppBundler.MAC_BUNDLER_PREFIX + imageTarget.getName(),
-                I18N.getString("resource.pkg-background-image"),
-                DEFAULT_BACKGROUND_IMAGE,
-                imageTarget,
-                VERBOSE.fetchFrom(params));
-
-        prepareDistributionXMLFile(params);
-    }
-
-    private File createPKG(Map<String, ? super Object> params, File outdir) {
-        //generic find attempt
-        try {
-            String appLocation =
-                    APP_IMAGE_BUILD_ROOT.fetchFrom(params) + "/" + APP_NAME.fetchFrom(params) + ".app";
-            File predefinedImage = getPredefinedImage(params);
-            if (predefinedImage != null) {
-                appLocation = predefinedImage.getAbsolutePath();
-            }
-
-            String daemonLocation = DAEMON_IMAGE_BUILD_ROOT.fetchFrom(params) + "/" + APP_NAME.fetchFrom(params) + ".daemon";
-
-            File appPKG = getPackages_AppPackage(params);
-            File daemonPKG = getPackages_DaemonPackage(params);
-
-            // build application package
-            ProcessBuilder pb = new ProcessBuilder("pkgbuild",
-                    "--component",
-                    appLocation,
-                    "--install-location",
-                    "/Applications",
-                    appPKG.getAbsolutePath());
-            IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-
-            prepareConfigFiles(params);
-
-            // build daemon package if requested
-            if (SERVICE_HINT.fetchFrom(params)) {
-                preparePackageScripts(params);
-
-                pb = new ProcessBuilder("pkgbuild",
-                        "--identifier",
-                        APP_NAME.fetchFrom(params) + ".daemon",
-                        "--root",
-                        daemonLocation,
-                        "--scripts",
-                        SCRIPTS_DIR.fetchFrom(params).getAbsolutePath(),
-                        daemonPKG.getAbsolutePath());
-                IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-            }
-
-            // build final package
-            File finalPKG = new File(outdir, APP_NAME.fetchFrom(params)+".pkg");
-            outdir.mkdirs();
-
-            List<String> commandLine = new ArrayList<>();
-            commandLine.add("productbuild");
-
-            commandLine.add("--resources");
-            commandLine.add(CONFIG_ROOT.fetchFrom(params).getAbsolutePath());
-
-            // maybe sign
-            String signingIdentity = DEVELOPER_ID_INSTALLER_SIGNING_KEY.fetchFrom(params);
-            if (signingIdentity != null) {
-                commandLine.add("--sign");
-                commandLine.add(signingIdentity);
-            }
-
-            commandLine.add("--distribution");
-            commandLine.add(getConfig_DistributionXMLFile(params).getAbsolutePath());
-            commandLine.add("--package-path");
-            commandLine.add(PACKAGES_ROOT.fetchFrom(params).getAbsolutePath());
-
-            commandLine.add(finalPKG.getAbsolutePath());
-
-            pb = new ProcessBuilder(commandLine);
-            IOUtils.exec(pb, VERBOSE.fetchFrom(params));
-
-            return finalPKG;
-        } catch (Exception ignored) {
-            Log.verbose(ignored);
-            return null;
-        } finally {
-            if (!VERBOSE.fetchFrom(params)) {
-                cleanupPackagesFiles(params);
-                cleanupConfigFiles(params);
-
-                if (SERVICE_HINT.fetchFrom(params)) {
-                    cleanupPackageScripts(params);
-                }
-            }
-        }
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    // Implement Bundler
-    //////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public String getName() {
-        return I18N.getString("bundler.name");
-    }
-
-    @Override
-    public String getDescription() {
-        return I18N.getString("bundler.description");
-    }
-
-    @Override
-    public String getID() {
-        return "pkg";
-    }
-
-    @Override
-    public Collection<BundlerParamInfo<?>> getBundleParameters() {
-        //Add PKG Specific parameters as required
-        return super.getBundleParameters();
-    }
-
-    @Override
-    public boolean validate(Map<String, ? super Object> params) throws UnsupportedPlatformException, ConfigException {
-        try {
-            if (params == null) throw new ConfigException(
-                    I18N.getString("error.parameters-null"),
-                    I18N.getString("error.parameters-null.advice"));
-
-            //run basic validation to ensure requirements are met
-            //we are not interested in return code, only possible exception
-            APP_BUNDLER.fetchFrom(params).doValidate(params);
-
-            // validate license file, if used, exists in the proper place
-            if (params.containsKey(LICENSE_FILE.getID())) {
-                RelativeFileSet appResources = APP_RESOURCES.fetchFrom(params);
-                for (String license : LICENSE_FILE.fetchFrom(params)) {
-                    if (!appResources.contains(license)) {
-                        throw new ConfigException(
-                                I18N.getString("error.license-missing"),
-                                MessageFormat.format(I18N.getString("error.license-missing.advice"),
-                                        license, appResources.getBaseDirectory().toString()));
-                    }
-                }
-            }
-
-            // hdiutil is always available so there's no need to test for availability.
-
-            return true;
-        } catch (RuntimeException re) {
-            throw new ConfigException(re);
-        }
-    }
-
-    @Override
-    public File execute(Map<String, ? super Object> params, File outputParentDir) {
-        return bundle(params, outputParentDir);
-    }
-
-}
--- a/modules/fxpackager/src/main/java/com/oracle/bundlers/windows/WindowsBundlerParam.java	Thu May 01 11:16:36 2014 +1200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.bundlers.windows;
-
-import com.oracle.bundlers.StandardBundlerParam;
-import com.sun.javafx.tools.packager.Log;
-import com.sun.javafx.tools.packager.bundlers.IOUtils;
-import com.sun.javafx.tools.packager.bundlers.RelativeFileSet;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Map;
-import java.util.ResourceBundle;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-public class WindowsBundlerParam<T> extends StandardBundlerParam<T> {
-    
-    private static final ResourceBundle I18N = ResourceBundle.getBundle("com.oracle.bundlers.windows.WindowsBundlerParam");
-    
-    public WindowsBundlerParam(String name, String description, String id, Class<T> valueType, Function<Map<String, ? super Object>, T> defaultValueFunction, BiFunction<String, Map<String, ? super Object>, T> stringConverter) {
-        super(name, description, id, valueType, defaultValueFunction, stringConverter);
-    }
-
-    public static final StandardBundlerParam<String> MENU_GROUP =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.menu-group.name"),
-                    I18N.getString("param.menu-group.description"),
-                    "win.menuGroup",
-                    String.class,
-                    params -> params.containsKey(VENDOR.getID())
-                            ? VENDOR.fetchFrom(params)
-                            : params.containsKey(CATEGORY.getID())
-                            ? CATEGORY.fetchFrom(params)
-                            : I18N.getString("param.menu-group.default"),
-                    (s, p) -> s
-            );
-
-    public static final StandardBundlerParam<Boolean> BIT_ARCH_64 =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.64-bit.name"),
-                    I18N.getString("param.64-bit.description"),
-                    "win.64Bit",
-                    Boolean.class,
-                    params -> System.getProperty("os.arch").contains("64"),
-                    (s, p) -> Boolean.valueOf(s)
-            );
-
-    public static final StandardBundlerParam<Boolean> BIT_ARCH_64_RUNTIME =
-            new StandardBundlerParam<>(
-                    I18N.getString("param.runtime-64-bit.name"),
-                    I18N.getString("param.runtime-64-bit.description"),
-                    "win.64BitJreRuntime",
-                    Boolean.class,
-                    params -> {extractFlagsFromRuntime(params); return "64".equals(params.get(".runtime.bit-arch"));},
-                    (s, p) -> Boolean.valueOf(s)
-            );
-       
-    public static void extractFlagsFromRuntime(Map<String, ? super Object> params) {
-        if (params.containsKey(".runtime.autodetect")) return;
-        
-        params.put(".runtime.autodetect", "attempted");
-        RelativeFileSet runtime = RUNTIME.fetchFrom(params);
-        String commandline;
-        if (runtime == null) {
-            //its ok, request to use system JRE
-            //TODO extract from system properties
-            commandline = "java version \"" + System.getProperty("java.version") + "\"\n"
-                    + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.version") + ", " + System.getProperty("java.vm.info") + ")\n";  
-        } else {
-            File runtimePath = runtime.getBaseDirectory();
-            File launcherPath = new File(runtimePath, "bin\\java");
-    
-            ProcessBuilder pb = new ProcessBuilder(launcherPath.getAbsolutePath(), "-version");
-            try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
-                try (PrintStream pout = new PrintStream(baos)) {
-                    IOUtils.exec(pb, Log.isDebug(), true, pout);                    
-                }
-                
-                commandline = baos.toString();
-            } catch (IOException e) {
-                e.printStackTrace();
-                params.put(".runtime.autodetect", "failed");
-                return;
-            }
-        }
-        extractFlagsFromVersion(params, commandline);
-        params.put(".runtime.autodetect", "succeeded");
-    }
-
-    public static void extractFlagsFromVersion(Map<String, ? super Object> params, String versionOutput) {
-        Pattern bitArchPattern = Pattern.compile("(\\d*)[- ]?[bB]it");
-        Matcher matcher = bitArchPattern.matcher(versionOutput);
-        if (matcher.find()) {
-            params.put(".runtime.bit-arch", matcher.group(1));
-        } else {
-            // presume 32 bit on no match
-            params.put(".runtime.bit-arch", "32");
-        }
-
-        Pattern versionMatcher = Pattern.compile("java version \"((\\d+.\\d+.\\d+)_(\\d+))(-(.*))?\"");
-        matcher = versionMatcher.matcher(versionOutput);
-        if (matcher.find()) {
-            params.put(".runtime.version", matcher.group(1));
-            params.put(".runtime.version.release", matcher.group(2));
-            params.put(".runtime.version.update", matcher.group(3));
-            params.put(".runtime.version.modifiers", matcher.group(5));
-        } else {
-            params.put(".runtime.version", "");
-            params.put(".runtime.version.release", "");
-            params.put(".runtime.version.update", "");
-            params.put(".runtime.version.modifiers", "");
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/AbstractBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import com.oracle.tools.packager.windows.WindowsBundlerParam;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.*;
+
+public abstract class AbstractBundler implements Bundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(AbstractBundler.class.getName());
+
+    public static final BundlerParamInfo<File> IMAGES_ROOT = new WindowsBundlerParam<>(
+            I18N.getString("param.images-root.name"),
+            I18N.getString("param.images-root.description"),
+            "imagesRoot",
+            File.class,
+            params -> new File(StandardBundlerParam.BUILD_ROOT.fetchFrom(params), "images"),
+            (s, p) -> null);
+
+    //do not use file separator -
+    // we use it for classpath lookup and there / are not platform specific
+    public final static String BUNDLER_PREFIX = "package/";
+
+    protected static final String JAVAFX_LAUNCHER_CLASS = "com.javafx.main.Main";
+
+    protected Class baseResourceLoader = null;
+    
+    //helper method to test if required files are present in the runtime
+    public void testRuntime(Map<String, ? super Object> p, String[] file) throws ConfigException {
+        RelativeFileSet runtime = StandardBundlerParam.RUNTIME.fetchFrom(p);
+        if (runtime == null) {
+            return; //null runtime is ok (request to use system)
+        }
+        Set<String> rfiles = runtime.getIncludedFiles();
+        for (String aFile : file) {
+            if (rfiles.contains(aFile)) {
+                return;
+            }
+        }
+        throw new ConfigException(
+                MessageFormat.format(I18N.getString("error.jre-missing-file"), Arrays.toString(file)),
+                I18N.getString("error.jre-missing-file.advice"));
+    }
+
+    protected void fetchResource(
+            String publicName, String category,
+            String defaultName, File result, boolean verbose)
+            throws IOException {
+        URL u = locateResource(publicName, category, defaultName, verbose);
+        if (u != null) {
+            IOUtils.copyFromURL(u, result);
+        } else {
+            if (verbose) {
+                Log.info(MessageFormat.format(I18N.getString("message.using-default-resource"), category == null ? "" : "[" + category + "] ", publicName));
+            }
+        }
+    }
+
+    protected void fetchResource(
+            String publicName, String category,
+            File defaultFile, File result, boolean verbose)
+            throws IOException {
+        URL u = locateResource(publicName, category, null, verbose);
+        if (u != null) {
+            IOUtils.copyFromURL(u, result);
+        } else {
+            IOUtils.copyFile(defaultFile, result);
+            if (verbose) {
+                Log.info(MessageFormat.format(I18N.getString("message.using-default-resource-from-file"), category == null ? "" : "[" + category + "] ", defaultFile.getAbsoluteFile()));
+            }
+        }
+    }
+
+    private URL locateResource(String publicName, String category,
+                               String defaultName, boolean verbose) throws IOException {
+        URL u = null;
+        boolean custom = false;
+        if (publicName != null) {
+            u = baseResourceLoader.getClassLoader().getResource(publicName);
+            custom = (u != null);
+        }
+        if (u == null && defaultName != null) {
+            u = baseResourceLoader.getResource(defaultName);
+        }
+        String msg = null;
+        if (custom) {
+            msg = MessageFormat.format(I18N.getString("message.using-custom-resource-from-classpath"), category == null ? "" : "[" + category + "] ", publicName);
+        } else if (u != null) {
+            msg = MessageFormat.format(I18N.getString("message.using-default-resource-from-classpath"), category == null ? "" : "[" + category + "] ", publicName);
+        }
+        if (verbose && u != null) {
+            Log.info(msg);
+        }
+        return u;
+    }
+
+    protected String preprocessTextResource(String publicName, String category,
+                                            String defaultName, Map<String, String> pairs,
+                                            boolean verbose) throws IOException {
+        URL u = locateResource(publicName, category, defaultName, verbose);
+        InputStream inp = u.openStream();
+        if (inp == null) {
+            throw new RuntimeException("Jar corrupt? No "+defaultName+" resource!");
+        }
+
+        //read fully into memory
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int length;
+        while ((length = inp.read(buffer)) != -1) {
+            baos.write(buffer, 0, length);
+        }
+
+        //substitute
+        String result = new String(baos.toByteArray());
+        for (Map.Entry<String, String> e : pairs.entrySet()) {
+            if (e.getValue() != null) {
+                result = result.replace(e.getKey(), e.getValue());
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/BasicBundlers.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import com.oracle.tools.packager.linux.LinuxRpmBundler;
+import com.oracle.tools.packager.mac.MacAppStoreBundler;
+import com.oracle.tools.packager.mac.MacDmgBundler;
+import com.oracle.tools.packager.mac.MacPkgBundler;
+import com.oracle.tools.packager.linux.LinuxAppBundler;
+import com.oracle.tools.packager.linux.LinuxDebBundler;
+import com.oracle.tools.packager.mac.MacAppBundler;
+import com.oracle.tools.packager.windows.WinAppBundler;
+import com.oracle.tools.packager.windows.WinExeBundler;
+import com.oracle.tools.packager.windows.WinMsiBundler;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.ServiceLoader;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * A basic bundlers collection that loads the OpenJFX default bundlers.
+ * Loads the bundlers common to OpenJFX.
+ * <UL>
+ *     <LI>Windows file image</LI>
+ *     <LI>Mac .app</LI>
+ *     <LI>Linux file image</LI>
+ *     <LI>Windows MSI</LI>
+ *     <LI>Windows EXE</LI>
+ *     <LI>Mac DMG</LI>
+ *     <LI>Mac PKG</LI>
+ *     <LI>Linux DEB</LI>
+ *     <LI>Linux RPM</LI>
+ *
+ * </UL>
+ */
+public class BasicBundlers implements Bundlers {
+
+    boolean defaultsLoaded = false;
+
+    private Collection<Bundler> bundlers = new CopyOnWriteArrayList<>();
+
+    public Collection<Bundler> getBundlers() {
+        return Collections.unmodifiableCollection(bundlers);
+    }
+
+    public Collection<Bundler> getBundlers(String type) {
+        if (type == null) return Collections.emptySet();
+        switch (type) {
+            case "NONE":
+                return Collections.emptySet();
+            case "ALL":
+                return getBundlers();
+            default:
+                return Arrays.asList(getBundlers().stream()
+                        .filter(b -> type.equals(b.getBundleType()))
+                        .toArray(Bundler[]::new));
+        }
+    }
+
+    /**
+     * A list of the "standard" parameters that bundlers should support
+     * or fall back to when their specific parameters are not used.
+     * @return an unmodifieable collection of the standard parameters.
+     */
+    public Collection<BundlerParamInfo> getStandardParameters() {
+        //TODO enumerate the stuff in BundleParams
+        return null;
+    }
+
+    /**
+     * Loads the bundlers common to OpenJFX.
+     * <UL>
+     *     <LI>Windows file image</LI>
+     *     <LI>Mac .app</LI>
+     *     <LI>Linux file image</LI>
+     *     <LI>Windows MSI</LI>
+     *     <LI>Windows EXE</LI>
+     *     <LI>Mac DMG</LI>
+     *     <LI>Mac PKG</LI>
+     *     <LI>Linux DEB</LI>
+     *     <LI>Linux RPM</LI>
+     *
+     * </UL>
+     */
+    public void loadDefaultBundlers() {
+        if (defaultsLoaded) return;
+
+        bundlers.add(new WinAppBundler());
+        bundlers.add(new WinExeBundler());
+        bundlers.add(new WinMsiBundler());
+
+        bundlers.add(new LinuxAppBundler());
+        bundlers.add(new LinuxDebBundler());
+        bundlers.add(new LinuxRpmBundler());
+
+        bundlers.add(new MacAppBundler());
+        bundlers.add(new MacDmgBundler());
+        bundlers.add(new MacPkgBundler());
+        bundlers.add(new MacAppStoreBundler());
+
+        //bundlers.add(new JNLPBundler());
+
+        defaultsLoaded = true;
+    }
+
+    /**
+     * Loads bundlers from the META-INF/services direct
+     */
+    public void loadBundlersFromServices(ClassLoader cl) {
+        ServiceLoader<Bundler> loader = ServiceLoader.load(Bundler.class, cl);
+        for (Bundler aLoader : loader) {
+            bundlers.add(aLoader);
+        }
+    }
+
+    public void loadBundler(Bundler bundler) {
+        bundlers.add(bundler);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/Bundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Map;
+
+public interface Bundler {
+
+
+    /**
+     * @return User Friendly name of this bundler.
+     */
+    String getName();
+
+    /**
+     * @return A more verbose description of the bundler.
+     */
+    String getDescription();
+
+    /**
+     * @return Command line identifier of the bundler.  Should be unique.
+     */
+    String getID();
+
+    /**
+     * @return The bundle type of the bundle that is created by this bundler.
+     */
+    String getBundleType();
+
+    /**
+     * The parameters that this bundler uses to generate it's bundle.
+     * @return immutable collection
+     */
+    Collection<BundlerParamInfo<?>> getBundleParameters();
+
+    /**
+     * Determines if this bundler will execute with the given parameters.
+     *
+     * @param params The parameters to be validate.  Validation may modify
+     *               the map, so if you are going to be using the same map
+     *               across multiple bundlers you should pass in a deep copy.
+     * @return true if valid
+     * @throws UnsupportedPlatformException If the bundler cannot run on this
+     *         platform (i.e. creating mac apps on windows)
+     * @throws ConfigException If the configuration params are incorrect.  The
+     *         exception may contain advice on how to modify the params map
+     *         to make it valid.
+     */
+    boolean validate(Map<String, ? super Object> params) throws UnsupportedPlatformException, ConfigException;
+
+    /**
+     * Creates a bundle from existing content.
+     *
+     * If a call to {@link #validate(java.util.Map)} date} returns true with the
+     * parameters map, then you can expect a valid output.  However if an exception
+     * was thrown out of validate or it returned false then you should not
+     * expect sensible results from this call.  It may or may not return a value,
+     * and it may or may not throw an exception.  But any output should not
+     * be considered valid or sane.
+     *
+     * @param params The parameters as specified by getBundleParameters.
+     *               Keyed by the id from the ParamInfo.  Execution may
+     *               modify the map, so if you are going to be using the
+     *               same map across multiple bundlers you should pass
+     *               in a deep copy.
+     * @param outputParentDir
+     *   The parent dir that the returned bundle will be placed in.
+     * @return The resulting bundled file
+     *
+     * For a bundler that produces a single artifact file this will be the
+     * location of that artifact (.exe file, .deb file, etc)
+     *
+     * For a bundler that produces a specific directory format output this will
+     * be the location of that specific directory (.app file, etc).
+     *
+     * For a bundler that produce multiple files, this will be a parent
+     * directory of those files (linux and windows images), whose name is not
+     * relevant to the result.
+     *
+     * @throws java.lang.IllegalArgumentException for any of the following
+     * reasons:
+     *  <ul>
+     *      <li>A required parameter is not found in the params list, for
+     *      example missing the main class.</li>
+     *      <li>A parameter has the wrong type of an object, for example a
+     *      String where a File is required</li>
+     *      <li>Bundler specific incompatibilities with the parameters, for
+     *      example a bad version number format or an application id with
+     *      forward slashes.</li>
+     *  </ul>
+     */
+    public File execute(Map<String, ? super Object> params, File outputParentDir);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/BundlerParamInfo.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+public class BundlerParamInfo<T> {
+
+    /**
+     * The user friendly name of the parameter
+     */
+    String name;
+
+    /**
+     * A more verbose description of the parameter
+     */
+    String description;
+
+    /**
+     * The command line and hashmap name of the parameter
+     */
+    String id;
+
+    /**
+     * Type of the parameter.  Typically String.class
+     */
+    Class<T> valueType;
+
+    /**
+     * If the value is not set, and no fallback value is found, the parameter uses the value returned by the producer.
+     */
+    Function<Map<String, ? super Object>, T> defaultValueFunction;
+
+    /**
+     * An optional string converter for command line arguments.
+     */
+    BiFunction<String, Map<String, ? super Object>, T> stringConverter;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getID() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Class<T> getValueType() {
+        return valueType;
+    }
+
+    public void setValueType(Class<T> valueType) {
+        this.valueType = valueType;
+    }
+
+    public Function<Map<String, ? super Object>, T> getDefaultValueFunction() {
+        return defaultValueFunction;
+    }
+
+    public void setDefaultValueFunction(Function<Map<String, ? super Object>, T> defaultValueFunction) {
+        this.defaultValueFunction = defaultValueFunction;
+    }
+
+    public BiFunction<String, Map<String, ? super Object>,T> getStringConverter() {
+        return stringConverter;
+    }
+
+    public void setStringConverter(BiFunction<String, Map<String, ? super Object>, T> stringConverter) {
+        this.stringConverter = stringConverter;
+    }
+
+    @SuppressWarnings("unchecked")
+    public final T fetchFrom(Map<String, ? super Object> params) {
+        Object o = params.get(getID());
+        if (o instanceof String && getStringConverter() != null) {
+            return getStringConverter().apply((String)o, params);
+        }
+
+        Class klass = getValueType();
+        if (klass.isInstance(o)) {
+            return (T) o;
+        }
+        if (o != null) {
+            throw new IllegalArgumentException("Param " + getID() + " should be of type " + getValueType() + " but is a " + o.getClass());
+        }
+        if (params.containsKey(getID())) {
+            // explicit nulls are allowed
+            return null;
+        }
+
+        if (getDefaultValueFunction() != null) {
+            T result =  getDefaultValueFunction().apply(params);
+            if (result != null) {
+                params.put(getID(), result);
+            }
+            return result;
+        }
+
+        // ultimate fallback
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/Bundlers.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+
+public interface Bundlers {
+
+    /**
+     * This convenience method will call {@link #createBundlersInstance(ClassLoader)}
+     * with the classloader that this Bundlers is loaded from.
+     *
+     * @return an instance of Bundlers loaded and configured from the current ClassLoader.
+     */
+    public static Bundlers createBundlersInstance() {
+        return createBundlersInstance(Bundlers.class.getClassLoader());
+    }
+
+    /**
+     * This convenience method will automatically load a Bundlers instance
+     * from either META-INF/services or the default
+     * {@link BasicBundlers} if none are found in
+     * the services meta-inf.
+     *
+     * After instantiating the bundlers instance it will load the default
+     * bundlers via {@link #loadDefaultBundlers()} as well as requesting
+     * the services loader to load any other bundelrs via
+     * {@link #loadBundlersFromServices(ClassLoader)}.
+
+     *
+     * @param servicesClassLoader the classloader to search for
+     *                            META-INF/service registered bundlers
+     * @return an instance of Bundlers loaded and configured from the specified ClassLoader
+     */
+    public static Bundlers createBundlersInstance(ClassLoader servicesClassLoader) {
+        ServiceLoader<Bundlers> bundlersLoader = ServiceLoader.load(Bundlers.class, servicesClassLoader);
+        Bundlers bundlers = null;
+        Iterator<Bundlers> iter = bundlersLoader.iterator();
+        if (iter.hasNext()) {
+            bundlers = iter.next();
+        }
+        if (bundlers == null) {
+            bundlers = new BasicBundlers();
+        }
+
+        bundlers.loadDefaultBundlers();
+        bundlers.loadBundlersFromServices(servicesClassLoader);
+        return bundlers;
+    }
+
+    /**
+     * Returns all of the preconfigured, requested, and manually
+     * configured bundlers loaded with this instance.
+     *
+     * @return  a read-only collection of the requested bundlers
+     */
+    Collection<Bundler> getBundlers();
+
+    /**
+     * Returns all of the preconfigured, requested, and manually
+     * configured bundlers loaded with this instance that are of
+     * a specific BundleType, such as disk images, installers, or
+     * remote installers.
+     *
+     * @return a read-only collection of the requested bundlers
+     */
+    Collection<Bundler> getBundlers(String type);
+
+    /**
+     * A list of the "standard" parameters that bundlers should support
+     * or fall back to when their specific parameters are not used.
+     *
+     * @return an unmodifiable collection of the standard parameters.
+     */
+    Collection<BundlerParamInfo> getStandardParameters();
+
+    /**
+     * Loads the bundlers common to the JDK.  A typical implementation
+     * would load:
+     * <UL>
+     *     <LI>Windows file image</LI>
+     *     <LI>Mac .app</LI>
+     *     <LI>Linux file image</LI>
+
+     *     <LI>Windows MSI</LI>
+     *     <LI>Windows EXE</LI>
+     *     <LI>Mac DMG</LI>
+     *     <LI>Linux DEB</LI>
+     *     <LI>Linux RPM</LI>
+     *
+     * </UL>
+     *
+     * This method is called from the {@link #createBundlersInstance(ClassLoader)}
+     * and {@link #createBundlersInstance()} methods.
+     */
+    void loadDefaultBundlers();
+
+    /**
+     * Loads bundlers from the META-INF/services directly.
+     *
+     * This method is called from the {@link #createBundlersInstance(ClassLoader)}
+     * and {@link #createBundlersInstance()} methods.
+     */
+    void loadBundlersFromServices(ClassLoader cl);
+
+    /**
+     * Loads a specific bundler into the set of bundlers.
+     * Useful for a manually configured bundler.
+     *
+     * @param bundler the specific bundler to add
+     */
+    void loadBundler(Bundler bundler);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/ConfigException.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+public class ConfigException extends Exception {
+    final String advice;
+
+    public ConfigException(String msg, String advice) {
+        super(msg);
+        this.advice = advice;
+    }
+
+    public ConfigException(Exception cause) {
+        super(cause);
+        this.advice = null;
+    }
+
+    public String getAdvice() {
+        return advice;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/EnumeratedBundlerParam.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * 
+ * The idea for this Param is that is contains a list of possible values which the IDE
+ * can display and then choose the appropriate value for. For instance the Mac has a
+ * predefined set of categories which can be applied to LSApplicationCategoryType which
+ * is required for the mac app store.
+ */
+public class EnumeratedBundlerParam<T> extends BundlerParamInfo<T> {
+    //Not sure if this is the correct order, my idea is that from and IDE's perspective
+    //the string to display to the user is the key and then the value is some type of
+    //object (although probably a String in most cases)
+    private Map<String, T> possibleValues;
+    private boolean strict;
+
+    public EnumeratedBundlerParam(String name,
+                                  String description,
+                                  String id,
+                                  Class<T> valueType,
+                                  Function<Map<String, ? super Object>, T> defaultValueFunction,
+                                  BiFunction<String, Map<String, ? super Object>, T> stringConverter,
+                                  Map<String, T> possibleValues,
+                                  boolean strict) {
+        this.name = name;
+        this.description = description;
+        this.id = id;
+        this.valueType = valueType;
+        this.defaultValueFunction = defaultValueFunction;
+        this.stringConverter = stringConverter;
+        this.possibleValues = possibleValues;
+        this.strict = strict;
+    }
+
+    public boolean isInPossibleValues(T value) {
+        return possibleValues.values().contains(value);
+    }
+
+    //Having the displayable values as the keys seems a bit wacky
+    public Set<String> getDisplayableKeys() {
+        return Collections.unmodifiableSet(possibleValues.keySet());
+    }
+
+    public boolean isStrict() {
+        return strict;
+    }
+
+    public boolean isLoose() {
+        return !isStrict();
+    }
+
+    public T validatedFetchFrom(Map<String, ? super Object> params)
+            throws InvalidBundlerParamException {
+        if (isStrict()) {
+            T value = fetchFrom(params);
+            if (!isInPossibleValues(value)) {
+                throw new InvalidBundlerParamException("Parameter " + value.toString() + " not in valid set of values for BundlerParam " + name);
+            }
+            return value;
+        }
+        return fetchFrom(params);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/IOUtils.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import com.oracle.tools.packager.Log;
+import java.io.*;
+import java.net.URL;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+
+public class IOUtils {
+
+    public static boolean deleteRecursive(File path) throws FileNotFoundException {
+        boolean ret = true;
+        if (!path.exists()) { //nothing to do
+            return true;
+        }
+        if (path.isDirectory()) {
+            File[] children = path.listFiles();
+            if (children != null) {
+                for (File f : children) {
+                    ret = ret && deleteRecursive(f);
+                }
+            }
+        }
+        return ret && path.delete();
+    }
+
+    public static void copyFromURL(URL location, File file) throws IOException {
+        if (location == null) {
+            throw new IOException("Missing input resource!");
+        }
+        if (file.exists()) {
+           file.delete();
+        }
+        InputStream in = location.openStream();
+        FileOutputStream out = new FileOutputStream(file);
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = in.read(buffer)) != -1) {
+            out.write(buffer, 0, len);
+        }
+        out.close();
+        in.close();
+        file.setReadOnly();
+        file.setReadable(true, false);
+    }
+
+    public static void copyFile(File sourceFile, File destFile)
+            throws IOException {
+        destFile.getParentFile().mkdirs();
+
+        //recreate the file as existing copy may have weird permissions
+        destFile.delete();
+        destFile.createNewFile();
+
+        FileChannel source = null;
+        FileChannel destination = null;
+        source = new FileInputStream(sourceFile).getChannel();
+        destination = new FileOutputStream(destFile).getChannel();
+        if (destination != null && source != null) {
+            destination.transferFrom(source, 0, source.size());
+        }
+        if (source != null) {
+            source.close();
+        }
+        if (destination != null) {
+            destination.close();
+        }
+
+        //preserve executable bit!
+        if (sourceFile.canExecute()) {
+            destFile.setExecutable(true, false);
+        }
+        if (!sourceFile.canWrite()) {
+            destFile.setReadOnly();
+        }
+        destFile.setReadable(true, false);
+    }
+
+    public static long getFolderSize(File folder) {
+        long foldersize = 0;
+
+        File[] children = folder.listFiles();
+        if (children != null) {
+            for (File f : children) {
+                if (f.isDirectory()) {
+                    foldersize += getFolderSize(f);
+                } else {
+                    foldersize += f.length();
+                }
+            }
+        }
+
+        return foldersize;
+    }
+
+    //run "launcher paramfile" in the directory where paramfile is kept
+    public static void run(String launcher, File paramFile, boolean verbose)
+            throws IOException {
+        if (paramFile != null && paramFile.exists()) {
+            ProcessBuilder pb = new ProcessBuilder(launcher, paramFile.getName());
+            pb = pb.directory(paramFile.getParentFile());
+            exec(pb, verbose);
+        }
+    }
+
+    public static void exec(ProcessBuilder pb, boolean verbose) throws IOException {
+        exec(pb, verbose, false);
+    }
+
+
+    public static void exec(ProcessBuilder pb, boolean verbose,
+            boolean testForPresenseOnly) throws IOException {
+        exec(pb, verbose, testForPresenseOnly, null);
+    }
+
+    public static void exec(ProcessBuilder pb, boolean verbose,
+            boolean testForPresenseOnly, PrintStream consumer) throws IOException {
+        pb.redirectErrorStream(true);
+        Log.verbose("Running " + Arrays.toString(pb.command().toArray(new String[0]))
+                                + (pb.directory() != null ? (" in " + pb.directory()) : ""));
+        Process p = pb.start();
+        InputStreamReader isr = new InputStreamReader(p.getInputStream());
+        BufferedReader br = new BufferedReader(isr);
+        String lineRead;
+        while ((lineRead = br.readLine()) != null) {
+            if (consumer != null) {
+                consumer.print(lineRead);
+            } else if (verbose) {
+               Log.info(lineRead);
+            } else {
+               Log.debug(lineRead);
+            }
+        }
+        try {
+            int ret = p.waitFor();
+            if (ret != 0 && !(testForPresenseOnly && ret != 127)) {
+                throw new IOException("Exec failed with code " + ret +
+                        " command [" + Arrays.toString(pb.command().toArray(new String[0])) +
+                        " in " + (pb.directory() != null ?
+                           pb.directory().getAbsolutePath() : "unspecified directory"));
+            }
+        } catch (InterruptedException ex) {
+        }
+    }
+
+    //no good test if we are running pre-JRE7
+    //use heuristic approach
+    // "false positive" is better than wrong answer
+    public static boolean isNotSymbolicLink(File file) {
+        //no symlinks on windows
+        if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
+            return true;
+        }
+        try {
+            if (file == null || file.getParent() == null) {
+                return false;
+            }
+            File file_canonical = new File(
+                    file.getParentFile().getCanonicalFile(), file.getName());
+            if (file_canonical.getCanonicalFile().equals(
+                       file_canonical.getAbsoluteFile())) {
+                return true;
+            }
+        } catch (IOException ioe) {}
+        return false;
+    }
+
+    public static byte[] readFully(File f) throws IOException {
+        InputStream inp = new FileInputStream(f);
+        //read fully into memory
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int length = 0;
+        while ((length = inp.read(buffer)) != -1) {
+            baos.write(buffer, 0, length);
+        }
+        baos.close();
+        return baos.toByteArray();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/InvalidBundlerParamException.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+public class InvalidBundlerParamException extends RuntimeException {
+    public InvalidBundlerParamException(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/JreUtils.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+public class JreUtils {
+
+    public static class Rule {
+        String regex;
+        boolean includeRule;
+        Type type;
+        enum Type {SUFFIX, PREFIX, SUBSTR, REGEX}
+
+        private Rule(String regex, boolean includeRule, Type type) {
+            this.regex = regex;
+            this.type = type;
+            this.includeRule = includeRule;
+        }
+
+        boolean match(String str) {
+            if (type == Type.SUFFIX) {
+                return str.endsWith(regex);
+            }
+            if (type == Type.PREFIX) {
+                return str.startsWith(regex);
+            }
+            if (type == Type.SUBSTR) {
+                return str.contains(regex);
+            }
+            return str.matches(regex);
+        }
+
+        boolean treatAsAccept() {return includeRule;}
+
+        public static Rule suffix(String s) {
+            return new Rule(s, true, Type.SUFFIX);
+        }
+        public static Rule suffixNeg(String s) {
+            return new Rule(s, false, Type.SUFFIX);
+        }
+        static Rule prefix(String s) {
+            return new Rule(s, true, Type.PREFIX);
+        }
+        public static Rule prefixNeg(String s) {
+            return new Rule(s, false, Type.PREFIX);
+        }
+        static Rule substr(String s) {
+            return new Rule(s, true, Type.SUBSTR);
+        }
+        public static Rule substrNeg(String s) {
+            return new Rule(s, false, Type.SUBSTR);
+        }
+    }
+
+    public static boolean shouldExclude(File baseDir, File f, Rule ruleset[]) {
+        if (ruleset == null) {
+            return false;
+        }
+
+        String fname = f.getAbsolutePath().toLowerCase().substring(
+                baseDir.getAbsolutePath().length());
+        //first rule match defines the answer
+        for (Rule r: ruleset) {
+            if (r.match(fname)) {
+                return !r.treatAsAccept();
+            }
+        }
+        //default is include
+        return false;
+    }
+
+    public static void walk(File base, File root, Rule ruleset[], Set<File> files) {
+        if (!root.isDirectory()) {
+            if (root.isFile()) {
+                files.add(root);
+            }
+            return;
+        }
+
+        File[] lst = root.listFiles();
+        if (lst != null) {
+            for (File f : lst) {
+                //ignore symbolic links!
+                if (IOUtils.isNotSymbolicLink(f) && !shouldExclude(base, f, ruleset)) {
+                    if (f.isDirectory()) {
+                        walk(base, f, ruleset, files);
+                    } else if (f.isFile()) {
+                        //add to list
+                        files.add(f);
+                    }
+                }
+            }
+        }
+    }
+
+    public static RelativeFileSet extractJreAsRelativeFileSet(String root, JreUtils.Rule[] ruleset) {
+        File baseDir = new File(root);
+
+        Set<File> lst = new HashSet<>();
+
+        walk(baseDir, baseDir, ruleset, lst);
+
+        return new RelativeFileSet(baseDir, lst);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/Log.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+public class Log {
+    public static class Logger {
+        private boolean verbose = false;
+
+        public Logger(boolean v) {
+            verbose = v;
+        }
+
+        public void info(String msg) {
+            System.out.println(msg);
+        }
+
+        public void verbose(Throwable t) {
+            if (Log.debug || verbose) {
+                t.printStackTrace(System.out);
+            }
+        }
+
+        public void verbose(String msg) {
+            if (Log.debug || verbose) {
+                System.out.println(msg);
+            }
+        }
+
+        public void debug(String msg) {
+            if (Log.debug) {
+                System.out.println(msg);
+            }
+        }
+    }
+
+    private static Logger delegate = null;
+    private static boolean debug =
+            "true".equals(System.getenv("JAVAFX_ANT_DEBUG"));
+
+    public static void setLogger(Logger l) {
+        delegate = l;
+        if (l == null) {
+            delegate = new Logger(false);
+        }
+    }
+
+
+    public static void info(String msg) {
+        if (delegate != null) {
+           delegate.info(msg);
+        }
+    }
+
+    public static void verbose(String msg) {
+        if (delegate != null) {
+           delegate.verbose(msg);
+        }
+    }
+
+    public static void verbose(Throwable t) {
+        if (delegate != null) {
+           delegate.verbose(t);
+        }
+    }
+
+    public static void debug(String msg) {
+        if (delegate != null) {
+           delegate.debug(msg);
+        }
+    }
+
+    public static void debug(RuntimeException re) {
+        debug((Throwable) re);
+    }
+
+    public static void debug(Throwable t) {
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+            try (PrintStream ps = new PrintStream(baos)) {
+                t.printStackTrace(ps);
+            }
+            debug(baos.toString());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static boolean isDebug() {
+        return debug;
+    }
+
+    public static void setDebug(boolean debug) {
+        Log.debug = debug;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/RelativeFileSet.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import com.oracle.tools.packager.Log;
+import java.io.File;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+public class RelativeFileSet {
+    private File basedir;
+    Set<String> files = new LinkedHashSet<>();
+
+    public RelativeFileSet(File base, Set<File> files) {
+        basedir = base;
+        String baseAbsolute = basedir.getAbsolutePath();
+        for (File f: files) {
+            String absolute = f.getAbsolutePath();
+            if (!absolute.startsWith(baseAbsolute)) {
+                throw new RuntimeException("File " + f.getAbsolutePath() +
+                        " does not belong to "+baseAbsolute);
+            }
+            if (!absolute.equals(baseAbsolute)) { //possible in javafxpackager case
+               this.files.add(absolute.substring(baseAbsolute.length()+1));
+            }
+        }
+    }
+
+    public boolean contains(String[] requiredFiles) {
+        boolean result = true;
+
+        for(String fname: requiredFiles) {
+            if (!files.contains(fname)) {
+                Log.debug("  Runtime does not contain [" + fname + "]");
+                result = false;
+            }
+        }
+
+        return result;
+    }
+
+    public boolean contains(String requiredFile) {
+        if (files.contains(requiredFile)) {
+            return true;
+        } else {
+            Log.debug("  Runtime does not contain [" + requiredFile + "]");
+            return false;
+        }
+    }
+
+    public File getBaseDirectory() {
+        return basedir;
+    }
+
+    public Set<String> getIncludedFiles() {
+        return files;
+    }
+
+    public void dump() {
+        Log.verbose("\n=========\nBasedir: " + basedir + "\n");
+        for (String fname : files) {
+            Log.verbose("  " + fname);
+        }
+        Log.verbose("\n========");
+    }
+    
+    @Override
+    public String toString() {
+        return "RelativeFileSet{basedir:" + basedir + ", files:" + files + "}";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/StandardBundlerParam.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,562 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+import com.sun.javafx.tools.packager.bundlers.BundleParams;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.file.Files;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+public class StandardBundlerParam<T> extends BundlerParamInfo<T> {
+
+    public static final String MANIFEST_JAVAFX_MAIN ="JavaFX-Application-Class";
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(StandardBundlerParam.class.getName());
+
+    public StandardBundlerParam(String name, String description, String id,
+                                Class<T> valueType,
+                                Function<Map<String, ? super Object>, T> defaultValueFunction,
+                                BiFunction<String, Map<String, ? super Object>, T> stringConverter) {
+        this.name = name;
+        this.description = description;
+        this.id = id;
+        this.valueType = valueType;
+        this.defaultValueFunction = defaultValueFunction;
+        this.stringConverter = stringConverter;
+    }
+
+    public static final StandardBundlerParam<RelativeFileSet> RUNTIME =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.runtime.name"),
+                    I18N.getString("param.runtime.description"),
+                    BundleParams.PARAM_RUNTIME,
+                    RelativeFileSet.class,
+                    params -> null,
+                    (s, p) -> null
+            );
+
+    public static final StandardBundlerParam<RelativeFileSet> APP_RESOURCES =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.app-resources.name"),
+                    I18N.getString("param.app-resource.description"),
+                    BundleParams.PARAM_APP_RESOURCES,
+                    RelativeFileSet.class,
+                    null, // no default.  Required parameter
+                    null // no string translation, tool must provide complex type
+            );
+
+    public static final StandardBundlerParam<File> ICON =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.icon-file.name"),
+                    I18N.getString("param.icon-file.description"),
+                    BundleParams.PARAM_ICON,
+                    File.class,
+                    params -> null,
+                    (s, p) -> new File(s)
+            );
+
+
+    public static final StandardBundlerParam<String> MAIN_CLASS =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.main-class.name"),
+                    I18N.getString("param.main-class.description"),
+                    BundleParams.PARAM_APPLICATION_CLASS,
+                    String.class,
+                    params -> {
+                        extractMainClassInfoFromAppResources(params);
+                        return (String) params.get(BundleParams.PARAM_APPLICATION_CLASS);
+                    },
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<String> APP_NAME =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.app-name.name"),
+                    I18N.getString("param.app-name.description"),
+                    BundleParams.PARAM_NAME,
+                    String.class,
+                    params -> {
+                        String s = MAIN_CLASS.fetchFrom(params);
+                        if (s == null) return null;
+
+                        int idx = s.lastIndexOf(".");
+                        if (idx >= 0) {
+                            return s.substring(idx+1);
+                        }
+                        return s;
+                    },
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<String> VENDOR =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.vendor.name"),
+                    I18N.getString("param.vendor.description"),
+                    BundleParams.PARAM_VENDOR,
+                    String.class,
+                    params -> I18N.getString("param.vendor.default"),
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<String> CATEGORY =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.category.name"),
+                    I18N.getString("param.category.description"),
+                    BundleParams.PARAM_CATEGORY,
+                    String.class,
+                    params -> I18N.getString("param.category.default"),
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<String> DESCRIPTION =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.description.name"),
+                    I18N.getString("param.description.description"),
+                    BundleParams.PARAM_DESCRIPTION,
+                    String.class,
+                    params -> params.containsKey(APP_NAME.getID())
+                            ? APP_NAME.fetchFrom(params)
+                            : I18N.getString("param.description.default"),
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<String> COPYRIGHT =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.copyright.name"),
+                    I18N.getString("param.copyright.description"),
+                    BundleParams.PARAM_COPYRIGHT,
+                    String.class,
+                    params -> MessageFormat.format(I18N.getString("param.copyright.default"), new Date()),
+                    (s, p) -> s
+            );
+
+    // note that each bundler is likely to replace this one with their own converter
+    public static final StandardBundlerParam<RelativeFileSet> MAIN_JAR =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.main-jar.name"),
+                    I18N.getString("param.main-jar.description"),
+                    "mainJar",
+                    RelativeFileSet.class,
+                    params -> {
+                        extractMainClassInfoFromAppResources(params);
+                        return (RelativeFileSet) params.get("mainJar");
+                    },
+                    (s, p) -> {
+                        File appResourcesRoot = APP_RESOURCES.fetchFrom(p).getBaseDirectory();
+                        File f = new File(appResourcesRoot, s);
+                        return new RelativeFileSet(appResourcesRoot, new LinkedHashSet<>(Arrays.asList(f)));
+                    }
+            );
+
+    public static final StandardBundlerParam<String> MAIN_JAR_CLASSPATH =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.main-jar-classpath.name"),
+                    I18N.getString("param.main-jar-classpath.description"),
+                    "classpath",
+                    String.class,
+                    params -> {
+                        extractMainClassInfoFromAppResources(params);
+                        String cp = (String) params.get("classpath");
+                        return cp == null ? "" : cp;
+                    },
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<Boolean> USE_FX_PACKAGING =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.use-javafx-packaging.name"),
+                    I18N.getString("param.use-javafx-packaging.description"),
+                    "fxPackaging",
+                    Boolean.class,
+                    params -> {
+                        extractMainClassInfoFromAppResources(params);
+                        Boolean result = (Boolean) params.get("fxPackaging");
+                        return (result == null) ? Boolean.FALSE : result;
+                    },
+                    (s, p) -> Boolean.valueOf(s)
+            );
+
+    @SuppressWarnings("unchecked")
+    public static final StandardBundlerParam<List<String>> JVM_OPTIONS =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.jvm-options.name"),
+                    I18N.getString("param.jvm-options.description"),
+                    "jvmOptions",
+                    (Class<List<String>>) (Object) List.class,
+                    params -> Collections.emptyList(),
+                    (s, p) -> Arrays.asList(s.split("\\s+"))
+            );
+
+    @SuppressWarnings("unchecked")
+    public static final StandardBundlerParam<Map<String, String>> JVM_PROPERTIES =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.jvm-system-properties.name"),
+                    I18N.getString("param.jvm-system-properties.description"),
+                    "jvmProperties",
+                    (Class<Map<String, String>>) (Object) Map.class,
+                    params -> Collections.emptyMap(),
+                    (s, params) -> {
+                        Map<String, String> map = new HashMap<>();
+                        try {
+                            Properties p = new Properties();
+                            p.load(new StringReader(s));
+                            for (Map.Entry<Object, Object> entry : p.entrySet()) {
+                                map.put((String)entry.getKey(), (String)entry.getValue());
+                            }
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                        }
+                        return map;
+                    }
+            );
+
+    @SuppressWarnings("unchecked")
+    public static final StandardBundlerParam<Map<String, String>> USER_JVM_OPTIONS =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.user-jvm-options.name"),
+                    I18N.getString("param.user-jvm-options.description"),
+                    "userJvmOptions",
+                    (Class<Map<String, String>>) (Object) Map.class,
+                    params -> Collections.emptyMap(),
+                    (s, params) -> {
+                        Map<String, String> map = new HashMap<>();
+                        try {
+                            Properties p = new Properties();
+                            p.load(new StringReader(s));
+                            for (Map.Entry<Object, Object> entry : p.entrySet()) {
+                                map.put((String)entry.getKey(), (String)entry.getValue());
+                            }
+                        } catch (IOException e) {
+                            e.printStackTrace();
+                        }
+                        return map;
+                    }
+            );
+
+    public static final StandardBundlerParam<String> TITLE =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.title.name"),
+                    I18N.getString("param.title.description"), //?? but what does it do?
+                    BundleParams.PARAM_TITLE,
+                    String.class,
+                    APP_NAME::fetchFrom,
+                    (s, p) -> s
+            );
+
+
+    // note that each bundler is likely to replace this one with their own converter
+    public static final StandardBundlerParam<String> VERSION =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.version.name"),
+                    I18N.getString("param.version.description"),
+                    BundleParams.PARAM_VERSION,
+                    String.class,
+                    params -> I18N.getString("param.version.default"),
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<Boolean> SYSTEM_WIDE =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.system-wide.name"),
+                    I18N.getString("param.system-wide.description"),
+                    BundleParams.PARAM_SYSTEM_WIDE,
+                    Boolean.class,
+                    params -> null,
+                    // valueOf(null) is false, and we actually do want null in some cases
+                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? null : Boolean.valueOf(s)
+            );
+
+    public static final StandardBundlerParam<Boolean> SERVICE_HINT  =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.service-hint.name"),
+                    I18N.getString("param.service-hint.description"),
+                    BundleParams.PARAM_SERVICE_HINT,
+                    Boolean.class,
+                    params -> false,
+                    // valueOf(null) is false, and we actually do want null in some cases
+                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
+            );
+
+    public static final StandardBundlerParam<Boolean> START_ON_INSTALL  =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.start-on-install.name"),
+                    I18N.getString("param.start-on-install.description"),
+                    "startOnInstall",
+                    Boolean.class,
+                    params -> false,
+                    // valueOf(null) is false, and we actually do want null in some cases
+                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
+            );
+
+    public static final StandardBundlerParam<Boolean> STOP_ON_UNINSTALL  =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.stop-on-uninstall.name"),
+                    I18N.getString("param.stop-on-uninstall.description"),
+                    "stopOnUninstall",
+                    Boolean.class,
+                    params -> true,
+                    // valueOf(null) is false, and we actually do want null in some cases
+                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
+            );
+
+    public static final StandardBundlerParam<Boolean> RUN_AT_STARTUP  =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.run-at-startup.name"),
+                    I18N.getString("param.run-at-startup.description"),
+                    "runAtStartup",
+                    Boolean.class,
+                    params -> false,
+                    // valueOf(null) is false, and we actually do want null in some cases
+                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
+            );
+
+    public static final StandardBundlerParam<Boolean> SHORTCUT_HINT =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.desktop-shortcut-hint.name"),
+                    I18N.getString("param.desktop-shortcut-hint.description"),
+                    BundleParams.PARAM_SHORTCUT,
+                    Boolean.class,
+                    params -> false,
+                    // valueOf(null) is false, and we actually do want null in some cases
+                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? false : Boolean.valueOf(s)
+            );
+
+    public static final StandardBundlerParam<Boolean> MENU_HINT =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.menu-shortcut-hint.name"),
+                    I18N.getString("param.menu-shortcut-hint.description"),
+                    BundleParams.PARAM_MENU,
+                    Boolean.class,
+                    params -> true,
+                    // valueOf(null) is false, and we actually do want null in some cases
+                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
+            );
+
+    @SuppressWarnings("unchecked")
+    public static final StandardBundlerParam<List<String>> LICENSE_FILE =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.license-file.name"),
+                    I18N.getString("param.license-file.description"),
+                    BundleParams.PARAM_LICENSE_FILE,
+                    (Class<List<String>>)(Object)List.class,
+                    params -> Collections.<String>emptyList(),
+                    (s, p) -> Arrays.asList(s.split(","))
+            );
+
+    public static final BundlerParamInfo<String> LICENSE_TYPE =
+            new StandardBundlerParam<> (
+                    I18N.getString("param.license-type.name"),
+                    I18N.getString("param.license-type.description"),
+                    BundleParams.PARAM_LICENSE_TYPE,
+                    String.class,
+                    params -> I18N.getString("param.license-type.default"),
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<File> BUILD_ROOT =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.build-root.name"),
+                    I18N.getString("param.build-root.description"),
+                    "buildRoot",
+                    File.class,
+                    params -> {
+                        try {
+                            return Files.createTempDirectory("fxbundler").toFile();
+                        } catch (IOException ioe) {
+                            return null;
+                        }
+                    },
+                    (s, p) -> new File(s)
+            );
+
+    public static final StandardBundlerParam<String> IDENTIFIER =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.identifier.name"),
+                    I18N.getString("param.identifier.description"),
+                    BundleParams.PARAM_IDENTIFIER,
+                    String.class,
+                    params -> {
+                        String s = MAIN_CLASS.fetchFrom(params);
+                        if (s == null) return null;
+
+                        int idx = s.lastIndexOf(".");
+                        if (idx >= 1) {
+                            return s.substring(0, idx);
+                        }
+                        return s;
+                    },
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<String> PREFERENCES_ID =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.preferences-id.name"),
+                    I18N.getString("param.preferences-id.description"),
+                    "preferencesID",
+                    String.class,
+                    p -> IDENTIFIER.fetchFrom(p).replace('.', '/'),
+                    (s, p) -> s
+            );
+
+    public static final StandardBundlerParam<Boolean> VERBOSE  =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.verbose.name"),
+                    I18N.getString("param.verbose.description"),
+                    "verbose",
+                    Boolean.class,
+                    params -> false,
+                    // valueOf(null) is false, and we actually do want null in some cases
+                    (s, p) -> (s == null || "null".equalsIgnoreCase(s))? true : Boolean.valueOf(s)
+            );
+
+    public static void extractMainClassInfoFromAppResources(Map<String, ? super Object> params) {
+        boolean hasMainClass = params.containsKey(MAIN_CLASS.getID());
+        boolean hasMainJar = params.containsKey(MAIN_JAR.getID());
+        boolean hasMainJarClassPath = params.containsKey(MAIN_JAR_CLASSPATH.getID());
+
+        if (hasMainClass && hasMainJar && hasMainJarClassPath) {
+            return;
+        }
+        Iterable<String> files;
+        File srcdir;
+
+        if (hasMainJar) {
+            RelativeFileSet rfs = MAIN_JAR.fetchFrom(params);
+            files = rfs.getIncludedFiles();
+            srcdir = rfs.getBaseDirectory();
+        } else if (hasMainJarClassPath) {
+            files = Arrays.asList(MAIN_JAR_CLASSPATH.fetchFrom(params).split(File.pathSeparator));
+            srcdir = APP_RESOURCES.fetchFrom(params).getBaseDirectory();
+        } else {
+            RelativeFileSet rfs = APP_RESOURCES.fetchFrom(params);
+            if (rfs == null) {
+                return;
+            }
+            files = rfs.getIncludedFiles();
+            srcdir = rfs.getBaseDirectory();
+        }
+
+
+        String declaredMainClass = (String) params.get(MAIN_CLASS.getID());
+
+        // presume the set iterates in-order
+        for (String fname : files) {
+            try {
+                // only sniff jars
+                if (!fname.toLowerCase().endsWith(".jar")) continue;
+
+                File file = new File(srcdir, fname);
+                // that actually exist
+                if (!file.exists()) continue;
+
+                JarFile jf = new JarFile(file);
+                Manifest m = jf.getManifest();
+                Attributes attrs = (m != null) ? m.getMainAttributes() : null;
+
+                if (attrs != null) {
+                    String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
+                    String fxMain = attrs.getValue(MANIFEST_JAVAFX_MAIN);
+                    if (hasMainClass) {
+                        if (declaredMainClass.equals(fxMain)) {
+                            params.put(USE_FX_PACKAGING.getID(), true);
+                        } else if (declaredMainClass.equals(mainClass)) {
+                            params.put(USE_FX_PACKAGING.getID(), false);
+                        } else {
+                            if (fxMain != null) {
+                                Log.info(MessageFormat.format(I18N.getString("message.fx-app-does-not-match-specified-main"), fname, fxMain, declaredMainClass));
+                            }
+                            if (mainClass != null) {
+                                Log.info(MessageFormat.format(I18N.getString("message.main-class-does-not-match-specified-main"), fname, mainClass, declaredMainClass));
+                            }
+                            continue;
+                        }
+                    } else {
+                        if (fxMain != null) {
+                            params.put(USE_FX_PACKAGING.getID(), true);
+                            params.put(MAIN_CLASS.getID(), fxMain);
+                        } else if (mainClass != null) {
+                            params.put(USE_FX_PACKAGING.getID(), false);
+                            params.put(MAIN_CLASS.getID(), mainClass);
+                        } else {
+                            continue;
+                        }
+                    }
+                    if (!hasMainJar) {
+                        if (srcdir == null) {
+                            srcdir = file.getParentFile();
+                        }
+                        params.put(MAIN_JAR.getID(), new RelativeFileSet(srcdir, new LinkedHashSet<>(Arrays.asList(file))));
+                    }
+                    if (!hasMainJarClassPath) {
+                        String cp = attrs.getValue(Attributes.Name.CLASS_PATH);
+                        params.put(MAIN_JAR_CLASSPATH.getID(), cp == null ? "" : cp);
+                    }
+                    break;
+                }
+            } catch (IOException ignore) {
+                ignore.printStackTrace();
+            }
+        }
+    }
+
+    public static void validateMainClassInfoFromAppResources(Map<String, ? super Object> params) throws ConfigException {
+        boolean hasMainClass = params.containsKey(MAIN_CLASS.getID());
+        boolean hasMainJar = params.containsKey(MAIN_JAR.getID());
+        boolean hasMainJarClassPath = params.containsKey(MAIN_JAR_CLASSPATH.getID());
+
+        if (hasMainClass && hasMainJar && hasMainJarClassPath) {
+            return;
+        }
+
+        extractMainClassInfoFromAppResources(params);
+        if (!params.containsKey(MAIN_CLASS.getID())) {
+            if (hasMainJar) {
+                throw new ConfigException(
+                        MessageFormat.format(I18N.getString("error.no-main-class-with-main-jar"),
+                                MAIN_JAR.fetchFrom(params)),
+                        MessageFormat.format(I18N.getString("error.no-main-class-with-main-jar.advice"),
+                                MAIN_JAR.fetchFrom(params)));
+            } else if (hasMainJarClassPath) {
+                throw new ConfigException(
+                        I18N.getString("error.no-main-class-with-classpath"),
+                        I18N.getString("error.no-main-class-with-classpath.advice"));
+            } else {
+                throw new ConfigException(
+                        I18N.getString("error.no-main-class"),
+                        I18N.getString("error.no-main-class.advice"));
+            }
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/UnsupportedPlatformException.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager;
+
+public class UnsupportedPlatformException extends Exception {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/linux/LinuxAppBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager.linux;
+
+import com.oracle.tools.packager.AbstractBundler;
+import com.oracle.tools.packager.BundlerParamInfo;
+import com.oracle.tools.packager.JreUtils;
+import com.oracle.tools.packager.JreUtils.Rule;
+import com.oracle.tools.packager.StandardBundlerParam;
+import com.oracle.tools.packager.Log;
+import com.oracle.tools.packager.ConfigException;
+import com.oracle.tools.packager.IOUtils;
+import com.oracle.tools.packager.RelativeFileSet;
+import com.oracle.tools.packager.UnsupportedPlatformException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.*;
+
+import static com.oracle.tools.packager.StandardBundlerParam.*;
+
+public class LinuxAppBundler extends AbstractBundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(LinuxAppBundler.class.getName());
+    
+    protected static final String LINUX_BUNDLER_PREFIX =
+            BUNDLER_PREFIX + "linux" + File.separator;
+    private static final String EXECUTABLE_NAME = "JavaAppLauncher";
+
+    public static final BundlerParamInfo<File> ICON_PNG = new StandardBundlerParam<>(
+            I18N.getString("param.icon-png.name"),
+            I18N.getString("param.icon-png.description"),
+            "icon.png",
+            File.class,
+            params -> {
+                File f = ICON.fetchFrom(params);
+                if (f != null && !f.getName().toLowerCase().endsWith(".png")) {
+                    Log.info(MessageFormat.format(I18N.getString("message.icon-not-png"), f));
+                    return null;
+                }
+                return f;
+            },
+            (s, p) -> new File(s));
+
+    public static final BundlerParamInfo<URL> RAW_EXECUTABLE_URL = new StandardBundlerParam<>(
+            I18N.getString("param.raw-executable-url.name"),
+            I18N.getString("param.raw-executable-url.description"),
+            "linux.launcher.url",
+            URL.class,
+            params -> LinuxResources.class.getResource(EXECUTABLE_NAME),
+            (s, p) -> {
+                try {
+                    return new URL(s);
+                } catch (MalformedURLException e) {
+                    Log.info(e.toString());
+                    return null;
+                }
+            });
+
+    //Subsetting of JRE is restricted.
+    //JRE README defines what is allowed to strip:
+    //   http://www.oracle.com/technetwork/java/javase/jre-7-readme-430162.html //TODO update when 8 goes GA
+    //
+    public static final BundlerParamInfo<Rule[]> LINUX_JRE_RULES = new StandardBundlerParam<>(
+            "",
+            "",
+            ".linux.runtime.rules",
+            Rule[].class,
+            params -> new Rule[]{
+                    Rule.prefixNeg("/bin"),
+                    Rule.prefixNeg("/plugin"),
+                    //Rule.prefixNeg("/lib/ext"), //need some of jars there for https to work
+                    Rule.suffix("deploy.jar"), //take deploy.jar
+                    Rule.prefixNeg("/lib/deploy"),
+                    Rule.prefixNeg("/lib/desktop"),
+                    Rule.substrNeg("libnpjp2.so")
+            },
+            (s, p) ->  null
+    );
+
+    public static final BundlerParamInfo<RelativeFileSet> LINUX_RUNTIME = new StandardBundlerParam<>(
+            RUNTIME.getName(),
+            RUNTIME.getDescription(),
+            RUNTIME.getID(),
+            RelativeFileSet.class,
+            params -> JreUtils.extractJreAsRelativeFileSet(System.getProperty("java.home"),
+                    LINUX_JRE_RULES.fetchFrom(params)),
+            (s, p) -> JreUtils.extractJreAsRelativeFileSet(s, LINUX_JRE_RULES.fetchFrom(p))
+    );
+
+    @Override
+    public boolean validate(Map<String, ? super Object> p) throws UnsupportedPlatformException, ConfigException {
+        try {
+            if (p == null) throw new ConfigException(
+                    I18N.getString("error.parameters-null"),
+                    I18N.getString("error.parameters-null.advice"));
+
+            return doValidate(p);
+        } catch (RuntimeException re) {
+            throw new ConfigException(re);
+        }
+    }
+
+    //used by chained bundlers to reuse validation logic
+    boolean doValidate(Map<String, ? super Object> p) throws UnsupportedPlatformException, ConfigException {
+        if (!System.getProperty("os.name").toLowerCase().startsWith("linux")) {
+            throw new UnsupportedPlatformException();
+        }
+
+        StandardBundlerParam.validateMainClassInfoFromAppResources(p);
+
+        if (RAW_EXECUTABLE_URL.fetchFrom(p) == null) {
+            throw new ConfigException(
+                    I18N.getString("error.no-linux-resources"),
+                    I18N.getString("error.no-linux-resources.advice"));
+        }
+
+        if (MAIN_JAR.fetchFrom(p) == null) {
+            throw new ConfigException(
+                    I18N.getString("error.no-application-jar"),
+                    I18N.getString("error.no-application-jar.advice"));
+        }
+
+        //validate required inputs
+        if (USE_FX_PACKAGING.fetchFrom(p)) {
+            testRuntime(p, new String[] {"lib/ext/jfxrt.jar", "lib/jfxrt.jar"});
+        }
+        testRuntime(p, new String[] { "lib/rt.jar" });
+
+        return true;
+    }
+
+    //it is static for the sake of sharing with "installer" bundlers
+    // that may skip calls to validate/bundle in this class!
+    private static File getRootDir(File outDir, Map<String, ? super Object> p) {
+        return new File(outDir, APP_NAME.fetchFrom(p));
+    }
+
+    public static File getLauncher(File outDir, Map<String, ? super Object> p) {
+        return new File(getRootDir(outDir, p), APP_NAME.fetchFrom(p));
+    }
+
+    File doBundle(Map<String, ? super Object> p, File outputDirectory, boolean dependentTask) {
+        try {
+            if (!outputDirectory.isDirectory() && !outputDirectory.mkdirs()) {
+                throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outputDirectory.getAbsolutePath()));
+            }
+            if (!outputDirectory.canWrite()) {
+                throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outputDirectory.getAbsolutePath()));
+            }
+
+            // Create directory structure
+            File rootDirectory = new File(outputDirectory, APP_NAME.fetchFrom(p));
+            IOUtils.deleteRecursive(rootDirectory);
+            rootDirectory.mkdirs();
+
+            if (!dependentTask) {
+                Log.info(MessageFormat.format(I18N.getString("message.creating-bundle-location"), rootDirectory.getAbsolutePath()));
+            }
+
+            File runtimeDirectory = new File(rootDirectory, "runtime");
+
+            File appDirectory = new File(rootDirectory, "app");
+            appDirectory.mkdirs();
+
+            // Copy executable to Linux folder
+            File executableFile = getLauncher(outputDirectory, p);
+            IOUtils.copyFromURL(
+                    RAW_EXECUTABLE_URL.fetchFrom(p),
+                    executableFile);
+
+            executableFile.setExecutable(true, false);
+            executableFile.setWritable(true, true); //for str
+
+            // Generate PkgInfo
+            File pkgInfoFile = new File(appDirectory, "package.cfg");
+            pkgInfoFile.createNewFile();
+            writePkgInfo(p, pkgInfoFile);
+
+            // Copy runtime to PlugIns folder
+            copyRuntime(p, runtimeDirectory);
+
+            // Copy class path entries to Java folder
+            copyApplication(p, appDirectory);
+
+            // Copy icon to Resources folder
+//FIXME            copyIcon(resourcesDirectory);
+
+            return rootDirectory;
+        } catch (IOException ex) {
+            Log.info("Exception: "+ex);
+            Log.debug(ex);
+            return null;
+        }
+    }
+
+    private void copyApplication(Map<String, ? super Object> params, File appDirectory) throws IOException {
+        RelativeFileSet appResources = APP_RESOURCES.fetchFrom(params);
+        if (appResources == null) {
+            throw new RuntimeException("Null app resources?");
+        }
+        File srcdir = appResources.getBaseDirectory();
+        for (String fname : appResources.getIncludedFiles()) {
+            IOUtils.copyFile(
+                    new File(srcdir, fname), new File(appDirectory, fname));
+        }
+    }
+
+    private void writePkgInfo(Map<String, ? super Object> params, File pkgInfoFile) throws FileNotFoundException {
+        pkgInfoFile.delete();
+        PrintStream out = new PrintStream(pkgInfoFile);
+        out.println("app.mainjar=" + MAIN_JAR.fetchFrom(params).getIncludedFiles().iterator().next());
+        out.println("app.version=" + VERSION.fetchFrom(params));
+
+        //use '/' in the clas name (instead of '.' to simplify native code
+        if (USE_FX_PACKAGING.fetchFrom(params)) {
+            out.println("app.mainclass=" +
+                    JAVAFX_LAUNCHER_CLASS.replaceAll("\\.", "/"));
+        } else {
+            out.println("app.mainclass=" +
+                    MAIN_CLASS.fetchFrom(params).replaceAll("\\.", "/"));
+        }
+        //This will be emtry string for correctly packaged JavaFX apps
+        out.println("app.classpath=" + MAIN_JAR_CLASSPATH.fetchFrom(params));
+
+        List<String> jvmargs = JVM_OPTIONS.fetchFrom(params);
+        int idx = 1;
+        for (String a : jvmargs) {
+            out.println("jvmarg."+idx+"="+a);
+            idx++;
+        }
+
+        //app.id required for setting user preferences (Java Preferences API)
+        out.println("app.preferences.id=" + PREFERENCES_ID.fetchFrom(params));
+
+        Map<String, String> overridableJVMOptions = USER_JVM_OPTIONS.fetchFrom(params);
+        idx = 1;
+        for (Map.Entry<String, String> arg: overridableJVMOptions.entrySet()) {
+            if (arg.getKey() == null || arg.getValue() == null) {
+                Log.info(I18N.getString("message.jvm-user-arg-is-null"));
+            }
+            else {
+                out.println("jvmuserarg."+idx+".name="+arg.getKey());
+                out.println("jvmuserarg."+idx+".value="+arg.getValue());
+            }
+            idx++;
+        }
+        out.close();
+    }
+
+    private void copyRuntime(Map<String, ? super Object> params, File runtimeDirectory) throws IOException {
+        RelativeFileSet runtime = LINUX_RUNTIME.fetchFrom(params);
+        if (runtime == null) {
+            //request to use system runtime
+            return;
+        }
+        runtimeDirectory.mkdirs();
+
+        File srcdir = runtime.getBaseDirectory();
+        File destDir = new File(runtimeDirectory, srcdir.getName());
+        Set<String> filesToCopy = runtime.getIncludedFiles();
+        for (String fname : filesToCopy) {
+            IOUtils.copyFile(
+                    new File(srcdir, fname), new File(destDir, fname));
+        }
+    }
+
+    @Override
+    public String getName() {
+        return I18N.getString("bundler.name");
+    }
+
+    @Override
+    public String getDescription() {
+        return I18N.getString("bundler.description");
+    }
+
+    @Override
+    public String getID() {
+        return "linux.app";
+    }
+
+    @Override
+    public String getBundleType() {
+        return "IMAGE";
+    }
+
+    @Override
+    public Collection<BundlerParamInfo<?>> getBundleParameters() {
+        return getAppBundleParameters();
+    }
+
+    public static Collection<BundlerParamInfo<?>> getAppBundleParameters() {
+        return Arrays.asList(
+                APP_NAME,
+                APP_RESOURCES,
+                BUILD_ROOT,
+                JVM_OPTIONS,
+                MAIN_CLASS,
+                MAIN_JAR,
+                MAIN_JAR_CLASSPATH,
+                PREFERENCES_ID,
+                RAW_EXECUTABLE_URL,
+                LINUX_RUNTIME,
+                USER_JVM_OPTIONS,
+                VERSION
+        );
+    }
+
+    @Override
+    public File execute(Map<String, ? super Object> params, File outputParentDir) {
+        return doBundle(params, outputParentDir, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/linux/LinuxDebBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,633 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager.linux;
+
+import com.oracle.tools.packager.*;
+import com.oracle.tools.packager.IOUtils;
+import com.sun.javafx.tools.packager.bundlers.BundleParams;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static com.oracle.tools.packager.StandardBundlerParam.*;
+
+public class LinuxDebBundler extends AbstractBundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(LinuxDebBundler.class.getName());
+
+    public static final BundlerParamInfo<LinuxAppBundler> APP_BUNDLER = new StandardBundlerParam<>(
+            I18N.getString("param.app-bundler.name"),
+            I18N.getString("param.app-bundler.description"),
+            "linux.app.bundler",
+            LinuxAppBundler.class,
+            params -> new LinuxAppBundler(),
+            (s, p) -> null);
+
+    public static final BundlerParamInfo<String> BUNDLE_NAME = new StandardBundlerParam<> (
+            I18N.getString("param.bundle-name.name"),
+            I18N.getString("param.bundle-name.description"),
+            "linux.bundleName",
+            String.class,
+            params -> {
+                String nm = APP_NAME.fetchFrom(params);
+                if (nm == null) return null;
+
+                // only lower-alphanumeric and -+. are allowed
+                // so to lower case,
+                // spaces and underscores become dashes
+                // and drop all other bad characters
+                nm = nm.toLowerCase()
+                       .replaceAll("[ _]", "-")
+                       .replaceAll("[^-+.a-z0-9]", "");
+                return nm;
+            },
+            (s, p) -> s);
+
+    public static final BundlerParamInfo<String> FULL_PACKAGE_NAME = new StandardBundlerParam<> (
+            I18N.getString("param.full-package-name.name"),
+            I18N.getString("param.full-package-name.description"),
+            "linux.deb.fullPackageName",
+            String.class,
+            params -> BUNDLE_NAME.fetchFrom(params) + "-" + VERSION.fetchFrom(params),
+            (s, p) -> s);
+
+    public static final BundlerParamInfo<File> CONFIG_ROOT = new StandardBundlerParam<>(
+            I18N.getString("param.config-root.name"),
+            I18N.getString("param.config-root.description"),
+            "configRoot",
+            File.class,
+            params ->  new File(BUILD_ROOT.fetchFrom(params), "linux"),
+            (s, p) -> new File(s));
+
+    public static final BundlerParamInfo<File> DEB_IMAGE_DIR = new StandardBundlerParam<>(
+            I18N.getString("param.image-dir.name"),
+            I18N.getString("param.image-dir.description"),
+            "linux.deb.imageDir",
+            File.class,
+            params -> {
+                File imagesRoot = IMAGES_ROOT.fetchFrom(params);
+                if (!imagesRoot.exists()) imagesRoot.mkdirs();
+                return new File(new File(imagesRoot, "linux-deb.image"), FULL_PACKAGE_NAME.fetchFrom(params));
+            },
+            (s, p) -> new File(s));
+
+    public static final BundlerParamInfo<File> APP_IMAGE_ROOT = new StandardBundlerParam<>(
+            I18N.getString("param.app-image-root.name"),
+            I18N.getString("param.app-image-root.description"),
+            "linux.deb.imageRoot",
+            File.class,
+            params -> {
+                File imageDir = DEB_IMAGE_DIR.fetchFrom(params);
+                return new File(imageDir, "opt");
+            },
+            (s, p) -> new File(s));
+
+    public static final BundlerParamInfo<File> CONFIG_DIR = new StandardBundlerParam<>(
+            I18N.getString("param.config-dir.name"),
+            I18N.getString("param.config-dir.description"),
+            "linux.deb.configDir",
+            File.class,
+            params ->  new File(DEB_IMAGE_DIR.fetchFrom(params), "DEBIAN"),
+            (s, p) -> new File(s));
+
+    public static final BundlerParamInfo<String> EMAIL = new StandardBundlerParam<> (
+            I18N.getString("param.maintainer-email.name"),
+            I18N.getString("param.maintainer-email.description"),
+            BundleParams.PARAM_EMAIL,
+            String.class,
+            params -> "Unknown",
+            (s, p) -> s);
+
+    public static final BundlerParamInfo<String> MAINTAINER = new StandardBundlerParam<> (
+            I18N.getString("param.maintainer-name.name"),
+            I18N.getString("param.maintainer-name.description"),
+            "linux.deb.maintainer",
+            String.class,
+            params -> VENDOR.fetchFrom(params) + " <" + EMAIL.fetchFrom(params) + ">",
+            (s, p) -> s);
+
+    public static final BundlerParamInfo<String> LICENSE_TEXT = new StandardBundlerParam<> (
+            I18N.getString("param.license-text.name"),
+            I18N.getString("param.license-text.description"),
+            "linux.deb.licenseText",
+            String.class,
+            params -> {
+                try {
+                    List<String> licenseFiles = LICENSE_FILE.fetchFrom(params);
+                    com.oracle.tools.packager.RelativeFileSet appRoot = APP_RESOURCES.fetchFrom(params);
+                    //need to copy license file to the root of linux-app.image
+                    if (licenseFiles.size() > 0) {
+                        return new String(IOUtils.readFully(new File(appRoot.getBaseDirectory(), licenseFiles.get(0))));
+                    }
+                } catch (Exception e) {
+                    if (Log.isDebug()) {
+                        e.printStackTrace();
+                    }
+                }
+                return LICENSE_TYPE.fetchFrom(params);
+            },
+            (s, p) -> s);
+
+    private final static String DEFAULT_ICON = "javalogo_white_32.png";
+    private final static String DEFAULT_CONTROL_TEMPLATE = "template.control";
+    private final static String DEFAULT_PRERM_TEMPLATE = "template.prerm";
+    private final static String DEFAULT_PREINSTALL_TEMPLATE = "template.preinst";
+    private final static String DEFAULT_POSTRM_TEMPLATE = "template.postrm";
+    private final static String DEFAULT_POSTINSTALL_TEMPLATE = "template.postinst";
+    private final static String DEFAULT_COPYRIGHT_TEMPLATE = "template.copyright";
+    private final static String DEFAULT_DESKTOP_FILE_TEMPLATE = "template.desktop";
+    private final static String DEFAULT_INIT_SCRIPT_TEMPLATE = "template.deb.init.script";
+
+    private final static String TOOL_DPKG = "dpkg-deb";
+
+    public LinuxDebBundler() {
+        super();
+        baseResourceLoader = LinuxResources.class;
+    }
+
+    private boolean testTool(String toolName, String minVersion) {
+        try {
+            ProcessBuilder pb = new ProcessBuilder(
+                    toolName,
+                    "--version");
+            IOUtils.exec(pb, Log.isDebug(), true); //FIXME not interested in the output
+        } catch (Exception e) {
+            Log.verbose(MessageFormat.format(I18N.getString("message.test-for-tool"), toolName, e.getMessage()));
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean validate(Map<String, ? super Object> p) throws UnsupportedPlatformException, ConfigException {
+        try {
+            if (p == null) throw new ConfigException(
+                    I18N.getString("error.parameters-null"),
+                    I18N.getString("error.parameters-null.advice"));
+
+            //run basic validation to ensure requirements are met
+            //we are not interested in return code, only possible exception
+            APP_BUNDLER.fetchFrom(p).doValidate(p);
+
+            //NOTE: Can we validate that the required tools are available before we start?
+            if (!testTool(TOOL_DPKG, "1")){
+                throw new ConfigException(
+                        MessageFormat.format(I18N.getString("error.tool-not-found"), TOOL_DPKG),
+                        I18N.getString("error.tool-not-found.advice"));
+            }
+
+            // validate license file, if used, exists in the proper place
+            if (p.containsKey(LICENSE_FILE.getID())) {
+                com.oracle.tools.packager.RelativeFileSet appResources = APP_RESOURCES.fetchFrom(p);
+                for (String license : LICENSE_FILE.fetchFrom(p)) {
+                    if (!appResources.contains(license)) {
+                        throw new ConfigException(
+                                I18N.getString("error.license-missing"),
+                                MessageFormat.format(I18N.getString("error.license-missing.advice"),
+                                        license, appResources.getBaseDirectory().toString()));
+                    }
+                }
+            } else {
+                Log.info(I18N.getString("message.debs-like-licenses"));
+            }
+
+            return true;
+        } catch (RuntimeException re) {
+            throw new ConfigException(re);
+        }
+    }
+
+    private boolean prepareProto(Map<String, ? super Object> p) {
+        File appImageRoot = APP_IMAGE_ROOT.fetchFrom(p);
+        File appDir = APP_BUNDLER.fetchFrom(p).doBundle(p, appImageRoot, true);
+        return appDir != null;
+    }
+
+    //@Override
+    public File bundle(Map<String, ? super Object> p, File outdir) {
+        if (!outdir.isDirectory() && !outdir.mkdirs()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outdir.getAbsolutePath()));
+        }
+        if (!outdir.canWrite()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outdir.getAbsolutePath()));
+        }
+
+        //we want to create following structure
+        //   <package-name>
+        //        DEBIAN
+        //          control   (file with main package details)
+        //          menu      (request to create menu)
+        //          ... other control files if needed ....
+        //        opt
+        //          AppFolder (this is where app image goes)
+        //             launcher executable
+        //             app
+        //             runtime
+
+        File imageDir = DEB_IMAGE_DIR.fetchFrom(p);
+        File configDir = CONFIG_DIR.fetchFrom(p);
+
+        try {
+
+            imageDir.mkdirs();
+            configDir.mkdirs();
+
+            if (prepareProto(p) && prepareProjectConfig(p)) {
+                return buildDeb(p, outdir);
+            }
+            return null;
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            return null;
+        } finally {
+            try {
+                if (VERBOSE.fetchFrom(p)) {
+                    saveConfigFiles(p);
+                }
+                if (imageDir != null && !Log.isDebug()) {
+                    IOUtils.deleteRecursive(imageDir);
+                } else if (imageDir != null) {
+                    Log.info(MessageFormat.format(I18N.getString("message.debug-working-directory"), imageDir.getAbsolutePath()));
+                }
+            } catch (FileNotFoundException ex) {
+                //noinspection ReturnInsideFinallyBlock
+                return null;
+            }
+        }
+    }
+
+    /*
+     * set permissions with a string like "rwxr-xr-x"
+     * 
+     * This cannot be directly backport to 22u which is unfortunately built with 1.6
+     */
+    private void setPermissions(File file, String permissions) {
+        Set<PosixFilePermission> filePermissions = PosixFilePermissions.fromString(permissions);
+        try {
+            if (file.exists()) {
+                Files.setPosixFilePermissions(file.toPath(), filePermissions);
+            }
+        } catch (IOException ex) {
+            Logger.getLogger(LinuxDebBundler.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+    }
+
+    protected void saveConfigFiles(Map<String, ? super Object> params) {
+        try {
+            File configRoot = CONFIG_ROOT.fetchFrom(params);
+
+            if (getConfig_ControlFile(params).exists()) {
+                IOUtils.copyFile(getConfig_ControlFile(params),
+                        new File(configRoot, getConfig_ControlFile(params).getName()));
+            }
+            if (getConfig_CopyrightFile(params).exists()) {
+                IOUtils.copyFile(getConfig_CopyrightFile(params),
+                        new File(configRoot, getConfig_CopyrightFile(params).getName()));
+            }
+            if (getConfig_PreinstallFile(params).exists()) {
+                IOUtils.copyFile(getConfig_PreinstallFile(params),
+                        new File(configRoot, getConfig_PreinstallFile(params).getName()));
+            }
+            if (getConfig_PrermFile(params).exists()) {
+                IOUtils.copyFile(getConfig_PrermFile(params),
+                        new File(configRoot, getConfig_PrermFile(params).getName()));
+            }
+            if (getConfig_PostinstallFile(params).exists()) {
+                IOUtils.copyFile(getConfig_PostinstallFile(params),
+                        new File(configRoot, getConfig_PostinstallFile(params).getName()));
+            }
+            if (getConfig_PostrmFile(params).exists()) {
+                IOUtils.copyFile(getConfig_PostrmFile(params),
+                        new File(configRoot, getConfig_PostrmFile(params).getName()));
+            }
+            if (getConfig_DesktopShortcutFile(params).exists()) {
+                IOUtils.copyFile(getConfig_DesktopShortcutFile(params),
+                        new File(configRoot, getConfig_DesktopShortcutFile(params).getName()));
+            }
+            if (getConfig_IconFile(params).exists()) {
+                IOUtils.copyFile(getConfig_IconFile(params),
+                        new File(configRoot, getConfig_IconFile(params).getName()));
+            }
+            if (SERVICE_HINT.fetchFrom(params)) {
+                if (getConfig_InitScriptFile(params).exists()) {
+                    IOUtils.copyFile(getConfig_InitScriptFile(params),
+                            new File(configRoot, getConfig_InitScriptFile(params).getName()));
+                }
+            }
+            Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), configRoot.getAbsolutePath()));
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+
+    private String getArch() {
+        String arch = System.getProperty("os.arch");
+        if ("i386".equals(arch))
+            return "i386";
+        else
+            return "amd64";
+    }
+
+    private long getInstalledSizeKB(Map<String, ? super Object> params) {
+        return getInstalledSizeKB(APP_IMAGE_ROOT.fetchFrom(params)) >> 10;
+    }
+
+    private long getInstalledSizeKB(File dir) {
+        long count = 0;
+        File[] children = dir.listFiles();
+        if (children != null) {
+            for (File file : children) {
+                if (file.isFile()) {
+                    count += file.length();
+                }
+                else if (file.isDirectory()) {
+                    count += getInstalledSizeKB(file);
+                }
+            }
+        }
+        return count;
+    }
+
+    private boolean prepareProjectConfig(Map<String, ? super Object> params) throws IOException {
+        Map<String, String> data = new HashMap<>();
+
+        data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params));
+        data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params));
+        data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params));
+        data.put("APPLICATION_MAINTAINER", MAINTAINER.fetchFrom(params));
+        data.put("APPLICATION_VERSION", VERSION.fetchFrom(params));
+        data.put("APPLICATION_LAUNCHER_FILENAME",
+                LinuxAppBundler.getLauncher(APP_IMAGE_ROOT.fetchFrom(params), params).getName());
+        data.put("DEPLOY_BUNDLE_CATEGORY", CATEGORY.fetchFrom(params));
+        data.put("APPLICATION_DESCRIPTION", DESCRIPTION.fetchFrom(params));
+        data.put("APPLICATION_SUMMARY", TITLE.fetchFrom(params));
+        data.put("APPLICATION_COPYRIGHT", COPYRIGHT.fetchFrom(params));
+        data.put("APPLICATION_LICENSE_TYPE", LICENSE_TYPE.fetchFrom(params));
+        data.put("APPLICATION_LICENSE_TEXT", LICENSE_TEXT.fetchFrom(params));
+        data.put("APPLICATION_ARCH", getArch());
+        data.put("APPLICATION_INSTALLED_SIZE", Long.toString(getInstalledSizeKB(params)));
+        data.put("SERVICE_HINT", String.valueOf(SERVICE_HINT.fetchFrom(params)));
+        data.put("START_ON_INSTALL", String.valueOf(START_ON_INSTALL.fetchFrom(params)));
+        data.put("STOP_ON_UNINSTALL", String.valueOf(STOP_ON_UNINSTALL.fetchFrom(params)));
+        data.put("RUN_AT_STARTUP", String.valueOf(RUN_AT_STARTUP.fetchFrom(params)));
+
+        //prepare control file
+        Writer w = new BufferedWriter(new FileWriter(getConfig_ControlFile(params)));
+        String content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_ControlFile(params).getName(),
+                I18N.getString("resource.deb-control-file"),
+                DEFAULT_CONTROL_TEMPLATE,
+                data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+
+        w = new BufferedWriter(new FileWriter(getConfig_PreinstallFile(params)));
+        content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_PreinstallFile(params).getName(),
+                I18N.getString("resource.deb-preinstall-script"),
+                DEFAULT_PREINSTALL_TEMPLATE,
+                data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+        setPermissions(getConfig_PreinstallFile(params), "rwxr-xr-x");
+
+        w = new BufferedWriter(new FileWriter(getConfig_PrermFile(params)));
+        content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_PrermFile(params).getName(),
+                I18N.getString("resource.deb-prerm-script"),
+                DEFAULT_PRERM_TEMPLATE,
+                data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+        setPermissions(getConfig_PrermFile(params), "rwxr-xr-x");
+
+        w = new BufferedWriter(new FileWriter(getConfig_PostinstallFile(params)));
+        content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_PostinstallFile(params).getName(),
+                I18N.getString("resource.deb-postinstall-script"),
+                DEFAULT_POSTINSTALL_TEMPLATE,
+                data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+        setPermissions(getConfig_PostinstallFile(params), "rwxr-xr-x");
+
+        w = new BufferedWriter(new FileWriter(getConfig_PostrmFile(params)));
+        content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_PostrmFile(params).getName(),
+                I18N.getString("resource.deb-postrm-script"),
+                DEFAULT_POSTRM_TEMPLATE,
+                data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+        setPermissions(getConfig_PostrmFile(params), "rwxr-xr-x");
+
+        w = new BufferedWriter(new FileWriter(getConfig_CopyrightFile(params)));
+        content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_CopyrightFile(params).getName(),
+                I18N.getString("resource.deb-copyright-file"),
+                DEFAULT_COPYRIGHT_TEMPLATE,
+                data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+
+        //prepare desktop shortcut
+        w = new BufferedWriter(new FileWriter(getConfig_DesktopShortcutFile(params)));
+        content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_DesktopShortcutFile(params).getName(),
+                I18N.getString("resource.menu-shortcut-descriptor"),
+                DEFAULT_DESKTOP_FILE_TEMPLATE,
+                data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+
+        //prepare installer icon
+        File iconTarget = getConfig_IconFile(params);
+        File icon = LinuxAppBundler.ICON_PNG.fetchFrom(params);
+        if (icon == null || !icon.exists()) {
+            fetchResource(LinuxAppBundler.LINUX_BUNDLER_PREFIX + iconTarget.getName(),
+                    I18N.getString("resource.menu-icon"),
+                    DEFAULT_ICON,
+                    iconTarget,
+                    VERBOSE.fetchFrom(params));
+        } else {
+            fetchResource(LinuxAppBundler.LINUX_BUNDLER_PREFIX + iconTarget.getName(),
+                    I18N.getString("resource.menu-icon"),
+                    icon,
+                    iconTarget,
+                    VERBOSE.fetchFrom(params));
+        }
+
+        if (SERVICE_HINT.fetchFrom(params)) {
+            //prepare init script
+            w = new BufferedWriter(new FileWriter(getConfig_InitScriptFile(params)));
+            content = preprocessTextResource(
+                    LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_InitScriptFile(params).getName(),
+                    I18N.getString("resource.deb-init-script"),
+                    DEFAULT_INIT_SCRIPT_TEMPLATE,
+                    data,
+                    VERBOSE.fetchFrom(params));
+            w.write(content);
+            w.close();
+            setPermissions(getConfig_InitScriptFile(params), "rwxr-xr-x");
+        }
+
+        return true;
+    }
+
+    private File getConfig_DesktopShortcutFile(Map<String, ? super Object> params) {
+        return new File(
+                LinuxAppBundler.getLauncher(APP_IMAGE_ROOT.fetchFrom(params), params).getParentFile(),
+                APP_NAME.fetchFrom(params) + ".desktop");
+    }
+
+    private File getConfig_IconFile(Map<String, ? super Object> params) {
+        return new File(
+                LinuxAppBundler.getLauncher(APP_IMAGE_ROOT.fetchFrom(params), params).getParentFile(),
+                APP_NAME.fetchFrom(params) + ".png");
+    }
+
+    private File getConfig_InitScriptFile(Map<String, ? super Object> params) {
+        return new File(
+                LinuxAppBundler.getLauncher(APP_IMAGE_ROOT.fetchFrom(params), params).getParentFile(),
+                BUNDLE_NAME.fetchFrom(params) + ".init");
+    }
+
+    private File getConfig_ControlFile(Map<String, ? super Object> params) {
+        return new File(CONFIG_DIR.fetchFrom(params), "control");
+    }
+
+    private File getConfig_PreinstallFile(Map<String, ? super Object> params) {
+        return new File(CONFIG_DIR.fetchFrom(params), "preinst");
+    }
+
+    private File getConfig_PrermFile(Map<String, ? super Object> params) {
+        return new File(CONFIG_DIR.fetchFrom(params), "prerm");
+    }
+
+    private File getConfig_PostinstallFile(Map<String, ? super Object> params) {
+        return new File(CONFIG_DIR.fetchFrom(params), "postinst");
+    }
+
+    private File getConfig_PostrmFile(Map<String, ? super Object> params) {
+        return new File(CONFIG_DIR.fetchFrom(params), "postrm");
+    }
+
+    private File getConfig_CopyrightFile(Map<String, ? super Object> params) {
+        return new File(CONFIG_DIR.fetchFrom(params), "copyright");
+    }
+
+    private File buildDeb(Map<String, ? super Object> params, File outdir) throws IOException {
+        File outFile = new File(outdir, FULL_PACKAGE_NAME.fetchFrom(params)+".deb");
+        Log.verbose(MessageFormat.format(I18N.getString("message.outputting-to-location"), outFile.getAbsolutePath()));
+
+        outFile.getParentFile().mkdirs();
+
+        //run dpkg
+        ProcessBuilder pb = new ProcessBuilder(
+                "fakeroot", TOOL_DPKG, "-b",  FULL_PACKAGE_NAME.fetchFrom(params),
+                outFile.getAbsolutePath());
+        pb = pb.directory(DEB_IMAGE_DIR.fetchFrom(params).getParentFile());
+        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
+
+        Log.info(MessageFormat.format(I18N.getString("message.output-to-location"), outFile.getAbsolutePath()));
+
+        return outFile;
+    }
+
+    @Override
+    public String getName() {
+        return I18N.getString("bundler.name");
+    }
+
+    @Override
+    public String getDescription() {
+        return I18N.getString("bundler.description");
+    }
+
+    @Override
+    public String getID() {
+        return "deb";
+    }
+
+    @Override
+    public String getBundleType() {
+        return "INSTALLER";
+    }
+
+    @Override
+    public Collection<BundlerParamInfo<?>> getBundleParameters() {
+        Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
+        results.addAll(LinuxAppBundler.getAppBundleParameters());
+        results.addAll(getDebBundleParameters());
+        return results;
+    }
+
+    public static Collection<BundlerParamInfo<?>> getDebBundleParameters() {
+        return Arrays.asList(
+                APP_BUNDLER,
+                APP_IMAGE_ROOT,
+                APP_RESOURCES,
+                BUNDLE_NAME,
+                CONFIG_DIR,
+                COPYRIGHT,
+                CATEGORY,
+                DESCRIPTION,
+                EMAIL,
+                FULL_PACKAGE_NAME,
+                LinuxAppBundler.ICON_PNG,
+                DEB_IMAGE_DIR,
+                IMAGES_ROOT,
+                LICENSE_FILE,
+                LICENSE_TEXT,
+                LICENSE_TYPE,
+                MAINTAINER,
+                TITLE,
+                VENDOR,
+                VERSION
+        );
+    }
+
+    @Override
+    public File execute(Map<String, ? super Object> params, File outputParentDir) {
+        return bundle(params, outputParentDir);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/linux/LinuxResources.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager.linux;
+
+public class LinuxResources {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/linux/LinuxRpmBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager.linux;
+
+import com.oracle.tools.packager.*;
+import com.oracle.tools.packager.IOUtils;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.oracle.tools.packager.StandardBundlerParam.*;
+
+public class LinuxRpmBundler extends AbstractBundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(LinuxRpmBundler.class.getName());
+
+    public static final BundlerParamInfo<LinuxAppBundler> APP_BUNDLER = new StandardBundlerParam<>(
+            I18N.getString("param.app-bundler.name"), 
+            I18N.getString("param.app-bundler.description"),
+            "linux.app.bundler",
+            LinuxAppBundler.class,
+            params -> new LinuxAppBundler(),
+            null);
+
+    public static final BundlerParamInfo<File> RPM_IMAGE_DIR = new StandardBundlerParam<>(
+            I18N.getString("param.image-dir.name"), 
+            I18N.getString("param.image-dir.description"),
+            "linux.rpm.imageDir",
+            File.class,
+            params -> {
+                File imagesRoot = IMAGES_ROOT.fetchFrom(params);
+                if (!imagesRoot.exists()) imagesRoot.mkdirs();
+                return new File(imagesRoot, "linux-rpm.image");
+            },
+            (s, p) -> new File(s));
+
+    public static final BundlerParamInfo<File> CONFIG_ROOT = new StandardBundlerParam<>(
+            I18N.getString("param.config-root.name"), 
+            I18N.getString("param.config-root.description"),
+            "configRoot",
+            File.class,
+            params ->  new File(BUILD_ROOT.fetchFrom(params), "linux"),
+            (s, p) -> new File(s));
+
+    public static final BundlerParamInfo<String> BUNDLE_NAME = new StandardBundlerParam<> (
+            I18N.getString("param.bundle-name.name"), 
+            I18N.getString("param.bundle-name.description"),
+            "linux.bundleName",
+            String.class,
+            params -> {
+                String nm = APP_NAME.fetchFrom(params);
+                if (nm == null) return null;
+
+                // Fedora rules are used here
+                // https://fedoraproject.org/wiki/Packaging:NamingGuidelines?rd=Packaging/NamingGuidelines
+                // The net effect is to lowercase the app name,
+                // change spaces and underscores to dashes,
+                // and to remove all alphanum+dashes
+                nm = nm.toLowerCase()
+                        .replaceAll("[ _]", "-")
+                        .replaceAll("[^-abcdefghijklmnopqrstuvwxyz0123456789]", "");
+                return nm;
+            },
+            (s, p) -> s);
+
+    private final static String DEFAULT_ICON = "javalogo_white_32.png";
+    private final static String DEFAULT_SPEC_TEMPLATE = "template.spec";
+    private final static String DEFAULT_DESKTOP_FILE_TEMPLATE = "template.desktop";
+    private final static String DEFAULT_INIT_SCRIPT_TEMPLATE = "template.rpm.init.script";
+
+    public final static String TOOL_RPMBUILD = "rpmbuild";
+    public final static double TOOL_RPMBUILD_MIN_VERSION = 4.0d;
+
+    public LinuxRpmBundler() {
+        super();
+        baseResourceLoader = LinuxResources.class;
+    }
+
+    public static boolean testTool(String toolName, double minVersion) {
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) {
+            ProcessBuilder pb = new ProcessBuilder(
+                    toolName,
+                    "--version");
+
+            IOUtils.exec(pb, Log.isDebug(), false, ps); //not interested in the output
+
+            //TODO: Version is ignored; need to extract version string and compare!
+            String content = new String(baos.toByteArray());
+            Pattern pattern = Pattern.compile("RPM version (\\d+\\.\\d+)");
+            Matcher matcher = pattern.matcher(content);
+            if (matcher.find()) {
+                String v = matcher.group(1);
+                double version = new Double(v);
+                return minVersion <= version;
+            } else {
+               return false;
+            }
+        } catch (Exception e) {
+            Log.verbose(MessageFormat.format(I18N.getString("message.test-for-tool"), toolName, e.getMessage()));
+            return false;
+        }
+    }
+
+    @Override
+    public boolean validate(Map<String, ? super Object> p) throws UnsupportedPlatformException, ConfigException {
+        try {
+            if (p == null) throw new ConfigException(
+                    I18N.getString("error.parameters-null"),
+                    I18N.getString("error.parameters-null.advice"));
+
+            //run basic validation to ensure requirements are met
+            //we are not interested in return code, only possible exception
+            APP_BUNDLER.fetchFrom(p).doValidate(p);
+
+            // validate license file, if used, exists in the proper place
+            if (p.containsKey(LICENSE_FILE.getID())) {
+                RelativeFileSet appResources = APP_RESOURCES.fetchFrom(p);
+                for (String license : LICENSE_FILE.fetchFrom(p)) {
+                    if (!appResources.contains(license)) {
+                        throw new ConfigException(
+                                I18N.getString("error.license-missing"),
+                                MessageFormat.format(I18N.getString("error.license-missing.advice"),
+                                        license, appResources.getBaseDirectory().toString()));
+                    }
+                }
+            }
+
+            //validate presense of required tools
+            if (!testTool(TOOL_RPMBUILD, TOOL_RPMBUILD_MIN_VERSION)){
+                throw new ConfigException(
+                        I18N.getString(MessageFormat.format("error.cannot-find-rpmbuild", TOOL_RPMBUILD_MIN_VERSION)),
+                        I18N.getString(MessageFormat.format("error.cannot-find-rpmbuild.advice", TOOL_RPMBUILD_MIN_VERSION)));
+            }
+
+            return true;
+        } catch (RuntimeException re) {
+            throw new ConfigException(re);
+        }
+    }
+
+    private boolean prepareProto(Map<String, ? super Object> params) {
+        File imageDir = RPM_IMAGE_DIR.fetchFrom(params);
+        File appDir = APP_BUNDLER.fetchFrom(params).doBundle(params, imageDir, true);
+        return appDir != null;
+    }
+
+    public File bundle(Map<String, ? super Object> p, File outdir) {
+        if (!outdir.isDirectory() && !outdir.mkdirs()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outdir.getAbsolutePath()));
+        }
+        if (!outdir.canWrite()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outdir.getAbsolutePath()));
+        }
+
+        File imageDir = RPM_IMAGE_DIR.fetchFrom(p);
+        try {
+
+            imageDir.mkdirs();
+
+            boolean menuShortcut = MENU_HINT.fetchFrom(p);
+            boolean desktopShortcut = SHORTCUT_HINT.fetchFrom(p);
+            if (!menuShortcut && !desktopShortcut) {
+                //both can not be false - user will not find the app
+                Log.verbose(I18N.getString("message.one-shortcut-required"));
+                p.put(MENU_HINT.getID(), true);
+            }
+
+            if (prepareProto(p) && prepareProjectConfig(p)) {
+                return buildRPM(p, outdir);
+            }
+            return null;
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            return null;
+        } finally {
+            try {
+                if (VERBOSE.fetchFrom(p)) {
+                    saveConfigFiles(p);
+                }
+                if (imageDir != null && !Log.isDebug()) {
+                    IOUtils.deleteRecursive(imageDir);
+                } else if (imageDir != null) {
+                    Log.info(MessageFormat.format(I18N.getString("message.debug-working-directory"), imageDir.getAbsolutePath()));
+                }
+            } catch (FileNotFoundException ex) {
+                //noinspection ReturnInsideFinallyBlock
+                return null;
+            }
+        }
+    }
+
+    /*
+     * set permissions with a string like "rwxr-xr-x"
+     * 
+     * This cannot be directly backport to 22u which is unfortunately built with 1.6
+     */
+    private void setPermissions(File file, String permissions) {
+        Set<PosixFilePermission> filePermissions = PosixFilePermissions.fromString(permissions);
+        try {
+            if (file.exists()) {
+                Files.setPosixFilePermissions(file.toPath(), filePermissions);
+            }
+        } catch (IOException ex) {
+            Logger.getLogger(LinuxDebBundler.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+    
+    protected void saveConfigFiles(Map<String, ? super Object> params) {
+        try {
+            File configRoot = CONFIG_ROOT.fetchFrom(params);
+            if (getConfig_SpecFile(params).exists()) {
+                IOUtils.copyFile(getConfig_SpecFile(params),
+                        new File(configRoot, getConfig_SpecFile(params).getName()));
+            }
+            if (getConfig_DesktopShortcutFile(params).exists()) {
+                IOUtils.copyFile(getConfig_DesktopShortcutFile(params),
+                        new File(configRoot, getConfig_DesktopShortcutFile(params).getName()));
+            }
+            if (getConfig_IconFile(params).exists()) {
+                IOUtils.copyFile(getConfig_IconFile(params),
+                        new File(configRoot, getConfig_IconFile(params).getName()));
+            }
+            if (SERVICE_HINT.fetchFrom(params)) {
+                if (getConfig_InitScriptFile(params).exists()) {
+                    IOUtils.copyFile(getConfig_InitScriptFile(params),
+                            new File(configRoot, getConfig_InitScriptFile(params).getName()));
+                }
+            }
+            Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), configRoot.getAbsolutePath()));
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+
+    private String getLicenseFileString(Map<String, ? super Object> params) {
+        StringBuilder sb = new StringBuilder();
+        for (String f: LICENSE_FILE.fetchFrom(params)) {
+            if (sb.length() != 0) {
+                sb.append("\n");
+            }
+            sb.append("%doc /opt/");
+            sb.append(APP_NAME.fetchFrom(params));
+            sb.append("/app/");
+            sb.append(f);
+        }
+        return sb.toString();
+    }
+
+    private boolean prepareProjectConfig(Map<String, ? super Object> params) throws IOException {
+        Map<String, String> data = new HashMap<>();
+
+        data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params));
+        data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params));
+        data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params));
+        data.put("APPLICATION_VERSION", VERSION.fetchFrom(params));
+        data.put("APPLICATION_LAUNCHER_FILENAME",
+                LinuxAppBundler.getLauncher(RPM_IMAGE_DIR.fetchFrom(params), params).getName());
+        data.put("DEPLOY_BUNDLE_CATEGORY", CATEGORY.fetchFrom(params)); //TODO rpm categories
+        data.put("APPLICATION_DESCRIPTION", DESCRIPTION.fetchFrom(params));
+        data.put("APPLICATION_SUMMARY", TITLE.fetchFrom(params));
+        data.put("APPLICATION_LICENSE_TYPE", LICENSE_TYPE.fetchFrom(params));
+        data.put("APPLICATION_LICENSE_FILE", getLicenseFileString(params));
+        data.put("SERVICE_HINT", String.valueOf(SERVICE_HINT.fetchFrom(params)));
+        data.put("START_ON_INSTALL", String.valueOf(START_ON_INSTALL.fetchFrom(params)));
+        data.put("STOP_ON_UNINSTALL", String.valueOf(STOP_ON_UNINSTALL.fetchFrom(params)));
+        data.put("RUN_AT_STARTUP", String.valueOf(RUN_AT_STARTUP.fetchFrom(params)));
+
+        //prepare spec file
+        Writer w = new BufferedWriter(new FileWriter(getConfig_SpecFile(params)));
+        String content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_SpecFile(params).getName(),
+                I18N.getString("resource.rpm-spec-file"), DEFAULT_SPEC_TEMPLATE, data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+
+        //prepare desktop shortcut
+        w = new BufferedWriter(new FileWriter(getConfig_DesktopShortcutFile(params)));
+        content = preprocessTextResource(
+                LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_DesktopShortcutFile(params).getName(),
+                I18N.getString("resource.menu-shortcut-descriptor"), DEFAULT_DESKTOP_FILE_TEMPLATE, data,
+                VERBOSE.fetchFrom(params));
+        w.write(content);
+        w.close();
+
+        //prepare installer icon
+        File iconTarget = getConfig_IconFile(params);
+        File icon = LinuxAppBundler.ICON_PNG.fetchFrom(params);
+        if (icon == null || !icon.exists()) {
+            fetchResource(LinuxAppBundler.LINUX_BUNDLER_PREFIX + iconTarget.getName(),
+                    I18N.getString("resource.menu-icon"),
+                    DEFAULT_ICON,
+                    iconTarget,
+                    VERBOSE.fetchFrom(params));
+        } else {
+            fetchResource(LinuxAppBundler.LINUX_BUNDLER_PREFIX + iconTarget.getName(),
+                    I18N.getString("resource.menu-icon"),
+                    icon,
+                    iconTarget,
+                    VERBOSE.fetchFrom(params));
+        }
+
+        if (SERVICE_HINT.fetchFrom(params)) {
+            //prepare init script
+            w = new BufferedWriter(new FileWriter(getConfig_InitScriptFile(params)));
+            content = preprocessTextResource(
+                    LinuxAppBundler.LINUX_BUNDLER_PREFIX + getConfig_InitScriptFile(params).getName(),
+                    I18N.getString("resource.rpm-init-script"), 
+                    DEFAULT_INIT_SCRIPT_TEMPLATE, 
+                    data,
+                    VERBOSE.fetchFrom(params));
+            w.write(content);
+            w.close();
+            setPermissions(getConfig_InitScriptFile(params), "rwxr-xr-x");
+        }
+
+        return true;
+    }
+
+    private File getConfig_DesktopShortcutFile(Map<String, ? super Object> params) {
+        return new File(LinuxAppBundler.getLauncher(RPM_IMAGE_DIR.fetchFrom(params), params).getParentFile(),
+                BUNDLE_NAME.fetchFrom(params) + ".desktop");
+    }
+
+    private File getConfig_IconFile(Map<String, ? super Object> params) {
+        return new File(LinuxAppBundler.getLauncher(RPM_IMAGE_DIR.fetchFrom(params), params).getParentFile(),
+                BUNDLE_NAME.fetchFrom(params) + ".png");
+    }
+
+    private File getConfig_InitScriptFile(Map<String, ? super Object> params) {
+        return new File(LinuxAppBundler.getLauncher(RPM_IMAGE_DIR.fetchFrom(params), params).getParentFile(),
+                BUNDLE_NAME.fetchFrom(params) + ".init");
+    }
+
+    private File getConfig_SpecFile(Map<String, ? super Object> params) {
+        return new File(RPM_IMAGE_DIR.fetchFrom(params),
+                BUNDLE_NAME.fetchFrom(params) + ".spec");
+    }
+
+    private File buildRPM(Map<String, ? super Object> params, File outdir) throws IOException {
+        Log.verbose(MessageFormat.format(I18N.getString("message.outputting-bundle-location"), outdir.getAbsolutePath()));
+
+        File broot = new File(BUILD_ROOT.fetchFrom(params), "rmpbuildroot");
+
+        outdir.mkdirs();
+
+        //run rpmbuild
+        ProcessBuilder pb = new ProcessBuilder(
+                TOOL_RPMBUILD,
+                "-bb", getConfig_SpecFile(params).getAbsolutePath(),
+//                "--define", "%__jar_repack %{nil}",  //debug: improves build time (but will require unpack to install?)
+                "--define", "%_sourcedir "+ RPM_IMAGE_DIR.fetchFrom(params).getAbsolutePath(),
+                "--define", "%_rpmdir " + outdir.getAbsolutePath(), //save result to output dir
+                "--define", "%_topdir " + broot.getAbsolutePath() //do not use other system directories to build as current user
+        );
+        pb = pb.directory(RPM_IMAGE_DIR.fetchFrom(params));
+        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
+
+        if (!Log.isDebug()) {
+            IOUtils.deleteRecursive(broot);
+        }
+
+        Log.info(MessageFormat.format(I18N.getString("message.output-bundle-location"), outdir.getAbsolutePath()));
+
+        // presume the result is the ".rpm" file with the newest modified time
+        // not the best solution, but it is the most reliable
+        File result = null;
+        long lastModified = 0;
+        File[] list = outdir.listFiles();
+        if (list != null) {
+            for (File f : list) {
+                if (f.getName().endsWith(".rpm") && f.lastModified() > lastModified) {
+                    result = f;
+                    lastModified = f.lastModified();
+                }
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public String getName() {
+        return I18N.getString("bundler.name");
+    }
+
+    @Override
+    public String getDescription() {
+        return I18N.getString("bundler.description");
+    }
+
+    @Override
+    public String getID() {
+        return "rpm";
+    }
+
+    @Override
+    public String getBundleType() {
+        return "INSTALLER";
+    }
+
+    @Override
+    public Collection<BundlerParamInfo<?>> getBundleParameters() {
+        Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
+        results.addAll(LinuxAppBundler.getAppBundleParameters());
+        results.addAll(getRpmBundleParameters());
+        return results;
+    }
+
+    public static Collection<BundlerParamInfo<?>> getRpmBundleParameters() {
+        return Arrays.asList(
+                APP_BUNDLER,
+                APP_NAME,
+                BUILD_ROOT,
+                BUNDLE_NAME,
+                CONFIG_ROOT,
+                CATEGORY,
+                DESCRIPTION,
+                LinuxAppBundler.ICON_PNG,
+                RPM_IMAGE_DIR,
+                IMAGES_ROOT,
+                LICENSE_FILE,
+                LICENSE_TYPE,
+                TITLE,
+                VENDOR,
+                VERSION
+        );
+    }
+
+    @Override
+    public File execute(Map<String, ? super Object> params, File outputParentDir) {
+        return bundle(params, outputParentDir);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacAppBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.tools.packager.mac;
+
+import com.oracle.tools.packager.AbstractBundler;
+import com.oracle.tools.packager.BundlerParamInfo;
+import com.oracle.tools.packager.EnumeratedBundlerParam;
+import com.oracle.tools.packager.JreUtils;
+import com.oracle.tools.packager.JreUtils.Rule;
+import com.oracle.tools.packager.StandardBundlerParam;
+import com.oracle.tools.packager.Log;
+import com.sun.javafx.tools.packager.bundlers.BundleParams;
+import com.oracle.tools.packager.ConfigException;
+import com.oracle.tools.packager.IOUtils;
+import com.oracle.tools.packager.RelativeFileSet;
+import com.oracle.tools.packager.UnsupportedPlatformException;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.*;
+
+import static com.oracle.tools.packager.StandardBundlerParam.*;
+import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.SIGNING_KEY_USER;
+import static com.oracle.tools.packager.mac.MacBaseInstallerBundler.getPredefinedImage;
+
+public class MacAppBundler extends AbstractBundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(MacAppBundler.class.getName());
+
+    public final static String MAC_BUNDLER_PREFIX =
+            BUNDLER_PREFIX + "macosx" + File.separator;
+
+    private static final String EXECUTABLE_NAME      = "JavaAppLauncher";
+    private static final String TEMPLATE_BUNDLE_ICON = "GenericApp.icns";
+    private static final String OS_TYPE_CODE         = "APPL";
+    private static final String TEMPLATE_INFO_PLIST  = "Info.plist.template";
+
+    private static Map<String, String> getMacCategories() {
+        Map<String, String> map = new HashMap<>();
+        map.put("Business", "public.app-category.business");
+        map.put("Developer Tools", "public.app-category.developer-tools");
+        map.put("Education", "public.app-category.education");
+        map.put("Entertainment", "public.app-category.entertainment");
+        map.put("Finance", "public.app-category.finance");
+        map.put("Games", "public.app-category.games");
+        map.put("Graphics & Design", "public.app-category.graphics-design");
+        map.put("Healthcare & Fitness", "public.app-category.healthcare-fitness");
+        map.put("Lifestyle", "public.app-category.lifestyle");
+        map.put("Medical", "public.app-category.medical");
+        map.put("Music", "public.app-category.music");
+        map.put("News", "public.app-category.news");
+        map.put("Photography", "public.app-category.photography");
+        map.put("Productivity", "public.app-category.productivity");
+        map.put("Reference", "public.app-category.reference");
+        map.put("Social Networking", "public.app-category.social-networking");
+        map.put("Sports", "public.app-category.sports");
+        map.put("Travel", "public.app-category.travel");
+        map.put("Utilities", "public.app-category.utilities");
+        map.put("Video", "public.app-category.video");
+        map.put("Weather", "public.app-category.weather");
+
+        map.put("Action Games", "public.app-category.action-games");
+        map.put("Adventure Games", "public.app-category.adventure-games");
+        map.put("Arcade Games", "public.app-category.arcade-games");
+        map.put("Board Games", "public.app-category.board-games");
+        map.put("Card Games", "public.app-category.card-games");
+        map.put("Casino Games", "public.app-category.casino-games");
+        map.put("Dice Games", "public.app-category.dice-games");
+        map.put("Educational Games", "public.app-category.educational-games");
+        map.put("Family Games", "public.app-category.family-games");
+        map.put("Kids Games", "public.app-category.kids-games");
+        map.put("Music Games", "public.app-category.music-games");
+        map.put("Puzzle Games", "public.app-category.puzzle-games");
+        map.put("Racing Games", "public.app-category.racing-games");
+        map.put("Role Playing Games", "public.app-category.role-playing-games");
+        map.put("Simulation Games", "public.app-category.simulation-games");
+        map.put("Sports Games", "public.app-category.sports-games");
+        map.put("Strategy Games", "public.app-category.strategy-games");
+        map.put("Trivia Games", "public.app-category.trivia-games");
+        map.put("Word Games", "public.app-category.word-games");
+
+        return map;
+    }
+
+    public static final EnumeratedBundlerParam<String> MAC_CATEGORY =
+            new EnumeratedBundlerParam<>(
+                    I18N.getString("param.category-name"),
+                    I18N.getString("param.category-name.description"),
+                    "mac.category",
+                    String.class,
+                    params -> params.containsKey(CATEGORY.getID())
+                            ? CATEGORY.fetchFrom(params)
+                            : "Unknown",
+                    (s, p) -> s,
+                    getMacCategories(),
+                    false //strict - for MacStoreBundler this should be strict
+            );
+
+    public static final BundlerParamInfo<String> MAC_CF_BUNDLE_NAME =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.cfbundle-name"),
+                    I18N.getString("param.cfbundle-name.description"),
+                    "mac.CFBundleName",
+                    String.class,
+                    params -> null,
+                    (s, p) -> s);
+
+    public static final BundlerParamInfo<File> CONFIG_ROOT = new StandardBundlerParam<>(
+            I18N.getString("param.config-root.name"),
+            I18N.getString("param.config-root.description"),
+            "configRoot",
+            File.class,
+            params -> {
+                File configRoot = new File(BUILD_ROOT.fetchFrom(params), "macosx");
+                configRoot.mkdirs();
+                return configRoot;
+            },
+            (s, p) -> new File(s));
+
+    public static final BundlerParamInfo<URL> RAW_EXECUTABLE_URL = new StandardBundlerParam<>(
+            I18N.getString("param.raw-executable-url.name"),
+            I18N.getString("param.raw-executable-url.description"),
+            "mac.launcher.url",
+            URL.class,
+            params -> MacResources.class.getResource(EXECUTABLE_NAME),
+            (s, p) -> {
+                try {
+                    return new URL(s);
+                } catch (MalformedURLException e) {
+                    Log.info(e.toString());
+                    return null;
+                }
+            });
+
+    public static final BundlerParamInfo<String> DEFAULT_ICNS_ICON = new StandardBundlerParam<>(
+            I18N.getString("param.default-icon-icns"),
+            I18N.getString("param.default-icon-icns.description"),
+            ".mac.default.icns",
+            String.class,
+            params -> TEMPLATE_BUNDLE_ICON,
+            (s, p) -> s);
+
+    //Subsetting of JRE is restricted.
+    //JRE README defines what is allowed to strip:
+    //   http://www.oracle.com/technetwork/java/javase/jre-7-readme-430162.html //TODO update when 8 goes GA
+    //
+    public static final BundlerParamInfo<Rule[]> MAC_JDK_RULES = new StandardBundlerParam<>(
+            "",
+            "",
+            ".mac-jdk.runtime.rules",
+            Rule[].class,
+            params -> new Rule[]{
+                    Rule.suffixNeg("macos/libjli.dylib"),
+                    Rule.suffixNeg("resources"),
+                    Rule.suffixNeg("home/bin"),
+                    Rule.suffixNeg("home/db"),
+                    Rule.suffixNeg("home/demo"),
+                    Rule.suffixNeg("home/include"),
+                    Rule.suffixNeg("home/lib"),
+                    Rule.suffixNeg("home/man"),
+                    Rule.suffixNeg("home/release"),
+                    Rule.suffixNeg("home/sample"),
+                    Rule.suffixNeg("home/src.zip"),
+                    //"home/rt" is not part of the official builds
+                    // but we may be creating this symlink to make older NB projects
+                    // happy. Make sure to not include it into final artifact
+                    Rule.suffixNeg("home/rt"),
+                    Rule.suffixNeg("jre/bin"),
+                    Rule.suffixNeg("jre/bin/rmiregistry"),
+                    Rule.suffixNeg("jre/bin/tnameserv"),
+                    Rule.suffixNeg("jre/bin/keytool"),
+                    Rule.suffixNeg("jre/bin/klist"),
+                    Rule.suffixNeg("jre/bin/ktab"),
+                    Rule.suffixNeg("jre/bin/policytool"),
+                    Rule.suffixNeg("jre/bin/orbd"),
+                    Rule.suffixNeg("jre/bin/servertool"),
+                    Rule.suffixNeg("jre/bin/javaws"),
+                    Rule.suffixNeg("jre/bin/java"),
+                    //Rule.suffixNeg("jre/lib/ext"), //need some of jars there for https to work
+                    Rule.suffixNeg("jre/lib/nibs"),
+                    //keep core deploy APIs but strip plugin dll
+                    //Rule.suffixNeg("jre/lib/deploy"),
+                    //Rule.suffixNeg("jre/lib/deploy.jar"),
+                    //Rule.suffixNeg("jre/lib/javaws.jar"),
+                    //Rule.suffixNeg("jre/lib/libdeploy.dylib"),
+                    //Rule.suffixNeg("jre/lib/plugin.jar"),
+                    Rule.suffixNeg("jre/lib/libnpjp2.dylib"),
+                    Rule.suffixNeg("jre/lib/security/javaws.policy"),
+                    Rule.substrNeg("Contents/Info.plist")
+            },
+            (s, p) -> null
+    );
+
+    public static final BundlerParamInfo<RelativeFileSet> MAC_RUNTIME = new StandardBundlerParam<>(
+            RUNTIME.getName(),
+            RUNTIME.getDescription(),
+            RUNTIME.getID(),
+            RelativeFileSet.class,
+            params -> extractMacRuntime(System.getProperty("java.home"), params),
+            MacAppBundler::extractMacRuntime
+    );
+
+    public static final BundlerParamInfo<String> DEVELOPER_ID_APP_SIGNING_KEY = new StandardBundlerParam<>(
+            I18N.getString("param.signing-key-developer-id-app.name"),
+            I18N.getString("param.signing-key-developer-id-app.description"),
+            "mac.signing-key-developer-id-app",
+            String.class,
+            params -> {
+                String key = "Developer ID Application: " + SIGNING_KEY_USER.fetchFrom(params);
+                try {
+                    IOUtils.exec(new ProcessBuilder("security", "find-certificate", "-c", key), VERBOSE.fetchFrom(params));
+                    return key;
+                } catch (IOException ioe) {
+                    return null;
+                }
+            },
+            (s, p) -> s);
+
+    public static final BundlerParamInfo<File> ICON_ICNS = new StandardBundlerParam<>(
+            I18N.getString("param.icon-icns.name"),
+            I18N.getString("param.icon-icns.description"),
+            "icon.icns",
+            File.class,
+            params -> {
+                File f = ICON.fetchFrom(params);
+                if (f != null && !f.getName().toLowerCase().endsWith(".icns")) {
+                    Log.info(MessageFormat.format(I18N.getString("message.icon-not-icns"), f));
+                    return null;
+                }
+                return f;
+            },
+            (s, p) -> new File(s));
+
+    public static RelativeFileSet extractMacRuntime(String base, Map<String, ? super Object> params) {
+        if (base.endsWith("/Home")) {
+            throw new IllegalArgumentException(I18N.getString("message.no-mac-jre-support"));
+        } else if (base.endsWith("/Home/jre")) {
+            File baseDir = new File(base).getParentFile().getParentFile().getParentFile();
+            return JreUtils.extractJreAsRelativeFileSet(baseDir.toString(),
+                    MAC_JDK_RULES.fetchFrom(params));
+        } else {
+            // for now presume we are pointed to the top of a JDK
+            return JreUtils.extractJreAsRelativeFileSet(base,
+                    MAC_JDK_RULES.fetchFrom(params));
+        }
+    }
+
+    public MacAppBundler() {
+        super();
+        baseResourceLoader = MacResources.class;
+    }
+
+    @Override
+    public boolean validate(Map<String, ? super Object> params) throws UnsupportedPlatformException, ConfigException {
+        try {
+            return doValidate(params);
+        } catch (RuntimeException re) {
+            throw new ConfigException(re);
+        }
+    }
+
+    //to be used by chained bundlers, e.g. by EXE bundler to avoid
+    // skipping validation if p.type does not include "image"
+    public boolean doValidate(Map<String, ? super Object> p) throws UnsupportedPlatformException, ConfigException {
+        if (!System.getProperty("os.name").toLowerCase().contains("os x")) {
+            throw new UnsupportedPlatformException();
+        }
+
+        StandardBundlerParam.validateMainClassInfoFromAppResources(p);
+
+        if (getPredefinedImage(p) != null) {
+            return true;
+        }
+
+        if (MAIN_JAR.fetchFrom(p) == null) {
+            throw new ConfigException(
+                    I18N.getString("error.no-application-jar"),
+                    I18N.getString("error.no-application-jar.advice"));
+        }
+
+        //validate required inputs
+        if (USE_FX_PACKAGING.fetchFrom(p)) {
+            testRuntime(p, new String[] {"Contents/Home/jre/lib/ext/jfxrt.jar", "Contents/Home/jre/lib/jfxrt.jar"});
+        }
+
+        return true;
+    }
+
+
+    private File getConfig_InfoPlist(Map<String, ? super Object> params) {
+        return new File(CONFIG_ROOT.fetchFrom(params), "Info.plist");
+    }
+
+    private File getConfig_Icon(Map<String, ? super Object> params) {
+        return new File(CONFIG_ROOT.fetchFrom(params), APP_NAME.fetchFrom(params) + ".icns");
+    }
+
+    private void prepareConfigFiles(Map<String, ? super Object> params) throws IOException {
+        File infoPlistFile = getConfig_InfoPlist(params);
+        infoPlistFile.createNewFile();
+        writeInfoPlist(infoPlistFile, params);
+
+        // Copy icon to Resources folder
+        prepareIcon(params);
+    }
+
+    public File doBundle(Map<String, ? super Object> p, File outputDirectory, boolean dependentTask) {
+        File rootDirectory = null;
+        if (!outputDirectory.isDirectory() && !outputDirectory.mkdirs()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outputDirectory.getAbsolutePath()));
+        }
+        if (!outputDirectory.canWrite()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outputDirectory.getAbsolutePath()));
+        }
+
+        try {
+            final File predefinedImage = getPredefinedImage(p);
+            if (predefinedImage != null) {
+                return predefinedImage;
+            }
+
+            // side effect is temp dir is created if not specified
+            BUILD_ROOT.fetchFrom(p);
+
+            //prepare config resources (we will copy them to the bundle later)
+            // NB: explicitly saving them to simplify customization
+            prepareConfigFiles(p);
+
+            // Create directory structure
+            rootDirectory = new File(outputDirectory, APP_NAME.fetchFrom(p) + ".app");
+            IOUtils.deleteRecursive(rootDirectory);
+            rootDirectory.mkdirs();
+
+            if (!dependentTask) {
+                Log.info(MessageFormat.format(I18N.getString("message.creating-app-bundle"), rootDirectory.getAbsolutePath()));
+            }
+
+            File contentsDirectory = new File(rootDirectory, "Contents");
+            contentsDirectory.mkdirs();
+
+            File macOSDirectory = new File(contentsDirectory, "MacOS");
+            macOSDirectory.mkdirs();
+
+            File javaDirectory = new File(contentsDirectory, "Java");
+            javaDirectory.mkdirs();
+
+            File plugInsDirectory = new File(contentsDirectory, "PlugIns");
+
+            File resourcesDirectory = new File(contentsDirectory, "Resources");
+            resourcesDirectory.mkdirs();
+
+            // Generate PkgInfo
+            File pkgInfoFile = new File(contentsDirectory, "PkgInfo");
+            pkgInfoFile.createNewFile();
+            writePkgInfo(pkgInfoFile);
+
+            // Copy executable to MacOS folder
+            File executableFile = new File(macOSDirectory, getLauncherName(p));
+            IOUtils.copyFromURL(
+                    RAW_EXECUTABLE_URL.fetchFrom(p),
+                    executableFile);
+
+            executableFile.setExecutable(true, false);
+
+            // Copy runtime to PlugIns folder
+            copyRuntime(plugInsDirectory, p);
+
+            // Copy class path entries to Java folder
+            copyClassPathEntries(javaDirectory, p);
+
+//TODO: Need to support adding native libraries.
+            // Copy library path entries to MacOS folder
+            //copyLibraryPathEntries(macOSDirectory);
+
+            /*********** Take care of "config" files *******/
+            // Copy icon to Resources folder
+            IOUtils.copyFile(getConfig_Icon(p),
+                    new File(resourcesDirectory, getConfig_Icon(p).getName()));
+            // Generate Info.plist
+            IOUtils.copyFile(getConfig_InfoPlist(p),
+                    new File(contentsDirectory, "Info.plist"));
+
+            // maybe sign
+            String signingIdentity = DEVELOPER_ID_APP_SIGNING_KEY.fetchFrom(p);
+            if (signingIdentity != null) {
+                MacBaseInstallerBundler.signAppBundle(p, rootDirectory, signingIdentity, IDENTIFIER.fetchFrom(p) + ".");
+            }
+        } catch (IOException ex) {
+            Log.info(ex.toString());
+            Log.verbose(ex);
+            return null;
+        } finally {
+            if (!VERBOSE.fetchFrom(p)) {
+                //cleanup
+                cleanupConfigFiles(p);
+            } else {
+                Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), CONFIG_ROOT.fetchFrom(p).getAbsolutePath()));
+            }
+        }
+        return rootDirectory;
+    }
+
+    public String getAppName(Map<String, ? super Object> params) {
+        return APP_NAME.fetchFrom(params) + ".app";
+    }
+
+    public void cleanupConfigFiles(Map<String, ? super Object> params) {
+        //Since building the app can be bypassed, make sure configRoot was set
+        if (CONFIG_ROOT.fetchFrom(params) != null) {
+            if (getConfig_Icon(params) != null) {
+                getConfig_Icon(params).delete();
+            }
+            if (getConfig_InfoPlist(params) != null) {
+                getConfig_InfoPlist(params).delete();
+            }
+        }
+    }
+
+
+    private void copyClassPathEntries(File javaDirectory, Map<String, ? super Object> params) throws IOException {
+        RelativeFileSet classPath = APP_RESOURCES.fetchFrom(params);
+        if (classPath == null) {
+            throw new RuntimeException(I18N.getString("message.null-classpath"));
+        }
+        File srcdir = classPath.getBaseDirectory();
+        for (String fname : classPath.getIncludedFiles()) {
+            IOUtils.copyFile(
+                    new File(srcdir, fname), new File(javaDirectory, fname));
+        }
+    }
+
+    private void copyRuntime(File plugInsDirectory, Map<String, ? super Object> params) throws IOException {
+        RelativeFileSet runTime = MAC_RUNTIME.fetchFrom(params);
+        if (runTime == null) {
+            //request to use system runtime => do not bundle
+            return;
+        }
+        plugInsDirectory.mkdirs();
+
+        File srcdir = runTime.getBaseDirectory();
+        File destDir = new File(plugInsDirectory, srcdir.getName());
+        Set<String> filesToCopy = runTime.getIncludedFiles();
+
+        for (String fname : filesToCopy) {
+            IOUtils.copyFile(
+                    new File(srcdir, fname), new File(destDir, fname));
+        }
+    }
+
+    private void prepareIcon(Map<String, ? super Object> params) throws IOException {
+        File icon = ICON_ICNS.fetchFrom(params);
+        if (icon == null || !icon.exists()) {
+            fetchResource(MAC_BUNDLER_PREFIX+ APP_NAME.fetchFrom(params) +".icns",
+                    "icon",
+                    DEFAULT_ICNS_ICON.fetchFrom(params),
+                    getConfig_Icon(params),
+                    VERBOSE.fetchFrom(params));
+        } else {
+            fetchResource(MAC_BUNDLER_PREFIX+ APP_NAME.fetchFrom(params) +".icns",
+                    "icon",
+                    icon,
+                    getConfig_Icon(params),
+                    VERBOSE.fetchFrom(params));
+        }
+    }
+
+    private String getLauncherName(Map<String, ? super Object> params) {
+        if (APP_NAME.fetchFrom(params) != null) {
+            return APP_NAME.fetchFrom(params);
+        } else {
+            return MAIN_CLASS.fetchFrom(params);
+        }
+    }
+
+    private String getBundleName(Map<String, ? super Object> params) {
+        //TODO: Check to see what rules/limits are in place for CFBundleName
+        if (MAC_CF_BUNDLE_NAME.fetchFrom(params) != null) {
+            String bn = MAC_CF_BUNDLE_NAME.fetchFrom(params);
+            if (bn.length() > 16) {
+                Log.info(MessageFormat.format(I18N.getString("message.bundle-name-too-long-warning"), MAC_CF_BUNDLE_NAME.getID(), bn));
+            }
+            return MAC_CF_BUNDLE_NAME.fetchFrom(params);
+        } else if (APP_NAME.fetchFrom(params) != null) {
+            return APP_NAME.fetchFrom(params);
+        } else {
+            String nm = MAIN_CLASS.fetchFrom(params);
+            if (nm.length() > 16) {
+                nm = nm.substring(0, 16);
+            }
+            return nm;
+        }
+    }
+
+    private String getBundleIdentifier(Map<String, ? super Object> params) {
+        //TODO: Check to see what rules/limits are in place for CFBundleIdentifier
+        return  IDENTIFIER.fetchFrom(params);
+    }
+
+    private void writeInfoPlist(File file, Map<String, ? super Object> params) throws IOException {
+        Log.verbose(MessageFormat.format(I18N.getString("message.preparing-info-plist"), file.getAbsolutePath()));
+
+        //prepare config for exe
+        //Note: do not need CFBundleDisplayName if we do not support localization
+        Map<String, String> data = new HashMap<>();
+        data.put("DEPLOY_ICON_FILE", getConfig_Icon(params).getName());
+        data.put("DEPLOY_BUNDLE_IDENTIFIER",
+                getBundleIdentifier(params));
+        data.put("DEPLOY_BUNDLE_NAME",
+                getBundleName(params));
+        data.put("DEPLOY_BUNDLE_COPYRIGHT",
+                COPYRIGHT.fetchFrom(params) != null ? COPYRIGHT.fetchFrom(params) : "Unknown");
+        data.put("DEPLOY_LAUNCHER_NAME", getLauncherName(params));
+        if (MAC_RUNTIME.fetchFrom(params) != null) {
+            data.put("DEPLOY_JAVA_RUNTIME_NAME",
+                    MAC_RUNTIME.fetchFrom(params).getBaseDirectory().getName());
+        } else {
+            data.put("DEPLOY_JAVA_RUNTIME_NAME", "");
+        }
+        data.put("DEPLOY_BUNDLE_SHORT_VERSION",
+                VERSION.fetchFrom(params) != null ? VERSION.fetchFrom(params) : "1.0.0");
+        data.put("DEPLOY_BUNDLE_CATEGORY",
+                //TODO parameters should provide set of values for IDEs
+                MAC_CATEGORY.validatedFetchFrom(params));
+
+        //TODO NOT THE WAY TODO THIS but good enough for first pass
+        data.put("DEPLOY_MAIN_JAR_NAME", new BundleParams(params).getMainApplicationJar());
+//        data.put("DEPLOY_MAIN_JAR_NAME", MAIN_JAR.fetchFrom(params).toString());
+
+        data.put("DEPLOY_PREFERENCES_ID", PREFERENCES_ID.fetchFrom(params).toLowerCase());
+
+        StringBuilder sb = new StringBuilder();
+        List<String> jvmOptions = JVM_OPTIONS.fetchFrom(params);
+
+        String newline = ""; //So we don't add unneccessary extra line after last append
+        for (String o : jvmOptions) {
+            sb.append(newline).append("    <string>").append(o).append("</string>");
+            newline = "\n";
+        }
+        data.put("DEPLOY_JVM_OPTIONS", sb.toString());
+
+        newline = "";
+        sb = new StringBuilder();
+        Map<String, String> overridableJVMOptions = USER_JVM_OPTIONS.fetchFrom(params);
+        for (Map.Entry<String, String> arg: overridableJVMOptions.entrySet()) {
+            sb.append(newline);
+            sb.append("      <key>").append(arg.getKey()).append("</key>\n");
+            sb.append("      <string>").append(arg.getValue()).append("</string>");
+            newline = "\n";
+        }
+        data.put("DEPLOY_JVM_USER_OPTIONS", sb.toString());
+
+
+        //TODO UNLESS we are supporting building for jre7, this is unnecessary
+//        if (params.useJavaFXPackaging()) {
+//            data.put("DEPLOY_LAUNCHER_CLASS", JAVAFX_LAUNCHER_CLASS);
+//        } else {
+        data.put("DEPLOY_LAUNCHER_CLASS", MAIN_CLASS.fetchFrom(params));
+//        }
+        // This will be an empty string for correctly packaged JavaFX apps
+        data.put("DEPLOY_APP_CLASSPATH", MAIN_JAR_CLASSPATH.fetchFrom(params).replace(":", " "));
+
+        //TODO: Add remainder of the classpath
+
+        Writer w = new BufferedWriter(new FileWriter(file));
+        w.write(preprocessTextResource(
+                MAC_BUNDLER_PREFIX + getConfig_InfoPlist(params).getName(),
+                I18N.getString("resource.bundle-config-file"), TEMPLATE_INFO_PLIST, data,
+                VERBOSE.fetchFrom(params)));
+        w.close();
+
+    }
+
+    private void writePkgInfo(File file) throws IOException {
+
+        //hardcoded as it does not seem we need to change it ever
+        String signature = "????";
+
+        try (Writer out = new BufferedWriter(new FileWriter(file))) {
+            out.write(OS_TYPE_CODE + signature);
+            out.flush();
+        }
+    }
+
+    //////////////////////////////////////////////////////////////////////////////////
+    // Implement Bundler
+    //////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public String getName() {
+        return I18N.getString("bundler.name");
+    }
+
+    @Override
+    public String getDescription() {
+        return I18N.getString("bundler.description");
+    }
+
+    @Override
+    public String getID() {
+        return "mac.app";
+    }
+
+    @Override
+    public String getBundleType() {
+        return "IMAGE";
+    }
+
+    @Override
+    public Collection<BundlerParamInfo<?>> getBundleParameters() {
+        return getAppBundleParameters();
+    }
+
+    public static Collection<BundlerParamInfo<?>> getAppBundleParameters() {
+        return Arrays.asList(
+                APP_NAME,
+                APP_RESOURCES,
+                BUILD_ROOT,
+                JVM_OPTIONS,
+                MAIN_CLASS,
+                MAIN_JAR,
+                MAIN_JAR_CLASSPATH,
+                PREFERENCES_ID,
+                RAW_EXECUTABLE_URL,
+                MAC_RUNTIME,
+                USER_JVM_OPTIONS,
+                VERSION,
+                ICON,
+                MAC_CATEGORY
+        );
+    }
+
+
+    @Override
+    public File execute(Map<String, ? super Object> params, File outputParentDir) {
+        return doBundle(params, outputParentDir, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacAppStoreBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager.mac;
+
+import com.oracle.tools.packager.BundlerParamInfo;
+import com.oracle.tools.packager.JreUtils;
+import com.oracle.tools.packager.StandardBundlerParam;
+import com.oracle.tools.packager.Log;
+import com.oracle.tools.packager.ConfigException;
+import com.oracle.tools.packager.IOUtils;
+import com.oracle.tools.packager.UnsupportedPlatformException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import static com.oracle.tools.packager.JreUtils.Rule.suffix;
+import static com.oracle.tools.packager.JreUtils.Rule.suffixNeg;
+import static com.oracle.tools.packager.StandardBundlerParam.*;
+
+public class MacAppStoreBundler extends MacBaseInstallerBundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(MacAppStoreBundler.class.getName());
+
+    private static final String TEMPLATE_BUNDLE_ICON_HIDPI = "GenericAppHiDPI.icns";
+    private final static String DEFAULT_ENTITLEMENTS = "MacAppStore.entitlements";
+    private final static String DEFAULT_INHERIT_ENTITLEMENTS = "MacAppStore_Inherit.entitlements";
+
+    //Subsetting of JRE is restricted.
+    //JRE README defines what is allowed to strip:
+    //   http://www.oracle.com/technetwork/java/javase/jre-7-readme-430162.html //TODO update when 8 goes GA
+    //
+    public static final JreUtils.Rule[] MAC_APP_STORE_JDK_RULES =  new JreUtils.Rule[]{
+            suffixNeg("macos/libjli.dylib"),
+            suffixNeg("resources"),
+            suffixNeg("home/bin"),
+            suffixNeg("home/db"),
+            suffixNeg("home/demo"),
+            suffixNeg("home/include"),
+            suffixNeg("home/lib"),
+            suffixNeg("home/man"),
+            suffixNeg("home/release"),
+            suffixNeg("home/sample"),
+            suffixNeg("home/src.zip"),
+            //"home/rt" is not part of the official builds
+            // but we may be creating this symlink to make older NB projects
+            // happy. Make sure to not include it into final artifact
+            suffixNeg("home/rt"),
+            suffixNeg("jre/bin"),
+            suffixNeg("bin/rmiregistry"),
+            suffixNeg("bin/tnameserv"),
+            suffixNeg("bin/keytool"),
+            suffixNeg("bin/klist"),
+            suffixNeg("bin/ktab"),
+            suffixNeg("bin/policytool"),
+            suffixNeg("bin/orbd"),
+            suffixNeg("bin/servertool"),
+            suffixNeg("bin/javaws"),
+            suffixNeg("bin/java"),
+            //Rule.suffixNeg("jre/lib/ext"), //need some of jars there for https to work
+            suffixNeg("jre/lib/nibs"),
+            //keep core deploy APIs but strip plugin dll
+            //Rule.suffixNeg("jre/lib/deploy"),
+            //Rule.suffixNeg("jre/lib/deploy.jar"),
+            //Rule.suffixNeg("jre/lib/javaws.jar"),
+            //Rule.suffixNeg("jre/lib/libdeploy.dylib"),
+            //Rule.suffixNeg("jre/lib/plugin.jar"),
+            suffixNeg("lib/libnpjp2.dylib"),
+            suffixNeg("lib/security/javaws.policy"),
+
+            // jfxmedia uses QuickTime, which is not allowed as of OSX 10.9
+            suffixNeg("lib/libjfxmedia.dylib"),
+
+            // the plist is needed for signing
+            suffix("Info.plist"),
+
+    };
+
+    public static final BundlerParamInfo<String> MAC_APP_STORE_APP_SIGNING_KEY = new StandardBundlerParam<>(
+            I18N.getString("param.signing-key-app.name"),
+            I18N.getString("param.signing-key-app.description"),
+            "mac.signing-key-app",
+            String.class,
+            params -> {
+                String key = "3rd Party Mac Developer Application: " + SIGNING_KEY_USER.fetchFrom(params);
+                try {
+                    IOUtils.exec(new ProcessBuilder("security", "find-certificate", "-c", key), VERBOSE.fetchFrom(params));
+                    return key;
+                } catch (IOException ioe) {
+                    return null;
+                }
+            },
+            (s, p) -> s);
+
+    public static final BundlerParamInfo<String> MAC_APP_STORE_PKG_SIGNING_KEY = new StandardBundlerParam<>(
+            I18N.getString("param.signing-key-pkg.name"),
+            I18N.getString("param.signing-key-pkg.description"),
+            "mac.signing-key-pkg",
+            String.class,
+            params -> {
+                String key = "3rd Party Mac Developer Installer: " + SIGNING_KEY_USER.fetchFrom(params);
+                try {
+                    IOUtils.exec(new ProcessBuilder("security", "find-certificate", "-c", key), VERBOSE.fetchFrom(params));
+                    return key;
+                } catch (IOException ioe) {
+                    return null;
+                }
+            },
+            (s, p) -> s);
+
+    public static final StandardBundlerParam<File> MAC_APP_STORE_ENTITLEMENTS  = new StandardBundlerParam<>(
+            I18N.getString("param.mac-app-store-entitlements.name"),
+            I18N.getString("param.mac-app-store-entitlements.description"),
+            "mac.app-store-entitlements",
+            File.class,
+            params -> null,
+            (s, p) -> new File(s));
+
+    public MacAppStoreBundler() {
+        super();
+        baseResourceLoader = MacResources.class;
+    }
+
+    //@Override
+    public File bundle(Map<String, ? super Object> p, File outdir) {
+        Log.info(MessageFormat.format(I18N.getString("message.building-bundle"), APP_NAME.fetchFrom(p)));
+        if (!outdir.isDirectory() && !outdir.mkdirs()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outdir.getAbsolutePath()));
+        }
+        if (!outdir.canWrite()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outdir.getAbsolutePath()));
+        }
+
+        // first, load in some overrides
+        // icns needs @2 versions, so load in the @2 default
+        p.put(MacAppBundler.DEFAULT_ICNS_ICON.getID(), TEMPLATE_BUNDLE_ICON_HIDPI);
+
+        // next we need to change the jdk/jre stripping to strip gstreamer
+        p.put(MacAppBundler.MAC_JDK_RULES.getID(), MAC_APP_STORE_JDK_RULES);
+
+        // now we create the app
+        File appImageDir = APP_IMAGE_BUILD_ROOT.fetchFrom(p);
+        try {
+            appImageDir.mkdirs();
+
+            // first, make sure we don't use the local signing key
+            p.put(MacAppBundler.DEVELOPER_ID_APP_SIGNING_KEY.getID(), null);
+            File appLocation = prepareAppBundle(p);
+
+            prepareEntitlements(p);
+
+            String signingIdentity = MAC_APP_STORE_APP_SIGNING_KEY.fetchFrom(p);
+            String identifierPrefix = IDENTIFIER.fetchFrom(p) + ".";
+            String entitlementsFile = getConfig_Entitlements(p).toString();
+            String inheritEntitlements = getConfig_Inherit_Entitlements(p).toString();
+
+            signAppBundle(p, appLocation, signingIdentity, identifierPrefix, entitlementsFile, inheritEntitlements);
+            ProcessBuilder pb;
+
+            // create the final pkg file
+            File finalPKG = new File(outdir, APP_NAME.fetchFrom(p)+".pkg");
+            outdir.mkdirs();
+
+            pb = new ProcessBuilder("productbuild",
+                    "--component", appLocation.toString(), "/Applications",
+                    "--sign", MAC_APP_STORE_PKG_SIGNING_KEY.fetchFrom(p),
+                    "--product", appLocation + "/Contents/Info.plist",
+                    finalPKG.getAbsolutePath());
+            IOUtils.exec(pb, VERBOSE.fetchFrom(p));
+            return finalPKG;
+        } catch (Exception ex) {
+            Log.info("App Store Ready Bundle failed : " + ex.getMessage());
+            ex.printStackTrace();
+            Log.debug(ex);
+            return null;
+        } finally {
+            try {
+                if (appImageDir != null && !Log.isDebug()) {
+                    IOUtils.deleteRecursive(appImageDir);
+                } else if (appImageDir != null) {
+                    Log.info(MessageFormat.format(I18N.getString("mesasge.intermediate-bundle-location"), appImageDir.getAbsolutePath()));
+                }
+                if (!VERBOSE.fetchFrom(p)) {
+                    //cleanup
+                    cleanupConfigFiles(p);
+                } else {
+                    Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), CONFIG_ROOT.fetchFrom(p).getAbsolutePath()));
+                }
+            } catch (FileNotFoundException ex) {
+                //noinspection ReturnInsideFinallyBlock
+                return null;
+            }
+        }
+    }
+
+    protected void cleanupConfigFiles(Map<String, ? super Object> params) {
+        if (getConfig_Entitlements(params) != null) {
+            getConfig_Entitlements(params).delete();
+        }
+        if (getConfig_Inherit_Entitlements(params) != null) {
+            getConfig_Inherit_Entitlements(params).delete();
+        }
+        APP_BUNDLER.fetchFrom(params).cleanupConfigFiles(params);
+    }
+
+    private File getConfig_Entitlements(Map<String, ? super Object> params) {
+        return new File(CONFIG_ROOT.fetchFrom(params), APP_NAME.fetchFrom(params) + ".entitlements");
+    }
+
+    private File getConfig_Inherit_Entitlements(Map<String, ? super Object> params) {
+        return new File(CONFIG_ROOT.fetchFrom(params), APP_NAME.fetchFrom(params) + "_Inherit.entitlements");
+    }
+
+    private void prepareEntitlements(Map<String, ? super Object> params) throws IOException {
+        File entitlements = MAC_APP_STORE_ENTITLEMENTS.fetchFrom(params);
+        if (entitlements == null || !entitlements.exists()) {
+            fetchResource(getEntitlementsFileName(params),
+                    I18N.getString("resource.mac-app-store-entitlements"),
+                    DEFAULT_ENTITLEMENTS,
+                    getConfig_Entitlements(params),
+                    VERBOSE.fetchFrom(params));
+        } else {
+            fetchResource(getEntitlementsFileName(params),
+                    I18N.getString("resource.mac-app-store-entitlements"),
+                    entitlements,
+                    getConfig_Entitlements(params),
+                    VERBOSE.fetchFrom(params));
+        }
+        fetchResource(getInheritEntitlementsFileName(params),
+                I18N.getString("resource.mac-app-store-inherit-entitlements"),
+                DEFAULT_INHERIT_ENTITLEMENTS,
+                getConfig_Inherit_Entitlements(params),
+                VERBOSE.fetchFrom(params));
+    }
+
+    private String getEntitlementsFileName(Map<String, ? super Object> params) {
+        return MacAppBundler.MAC_BUNDLER_PREFIX+ APP_NAME.fetchFrom(params) +".entitlements";
+    }
+
+    private String getInheritEntitlementsFileName(Map<String, ? super Object> params) {
+        return MacAppBundler.MAC_BUNDLER_PREFIX+ APP_NAME.fetchFrom(params) +"_Inherit.entitlements";
+    }
+
+    //////////////////////////////////////////////////////////////////////////////////
+    // Implement Bundler
+    //////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public String getName() {
+        return I18N.getString("bundler.name");
+    }
+
+    @Override
+    public String getDescription() {
+        return I18N.getString("bundler.description");
+    }
+
+    @Override
+    public String getID() {
+        return "mac.appStore";
+    }
+
+    @Override
+    public Collection<BundlerParamInfo<?>> getBundleParameters() {
+        Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
+        results.addAll(MacAppBundler.getAppBundleParameters());
+        results.addAll(getPKGBundleParameters());
+        return results;
+    }
+
+    public Collection<BundlerParamInfo<?>> getPKGBundleParameters() {
+        Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
+
+        results.addAll(MacAppBundler.getAppBundleParameters());
+        results.addAll(Arrays.asList(
+                APP_BUNDLER,
+                APP_IMAGE_BUILD_ROOT,
+                APP_NAME,
+                APP_RESOURCES,
+                CONFIG_ROOT,
+                MAC_APP_IMAGE,
+                MAC_APP_STORE_APP_SIGNING_KEY,
+                MAC_APP_STORE_ENTITLEMENTS,
+                MAC_APP_STORE_PKG_SIGNING_KEY,
+                SIGNING_KEY_USER
+        ));
+
+        return results;
+    }
+
+    @Override
+    public boolean validate(Map<String, ? super Object> params) throws UnsupportedPlatformException, ConfigException {
+        try {
+            if (params == null) throw new ConfigException(
+                    I18N.getString("error.parameters-null"),
+                    I18N.getString("error.parameters-null.advice"));
+
+            // hdiutil is always available so there's no need to test for availability.
+            //run basic validation to ensure requirements are met
+
+            //run basic validation to ensure requirements are met
+            //we are not interested in return code, only possible exception
+            APP_BUNDLER.fetchFrom(params).doValidate(params);
+
+            // make sure we have settings for signatures
+            if (MAC_APP_STORE_APP_SIGNING_KEY.fetchFrom(params) == null) {
+                throw new ConfigException(
+                        I18N.getString("error.no-app-signing-key"),
+                        I18N.getString("error.no-app-signing-key.advice"));
+            }
+            if (MAC_APP_STORE_PKG_SIGNING_KEY.fetchFrom(params) == null) {
+                throw new ConfigException(
+                        I18N.getString("error.no-pkg-signing-key"),
+                        I18N.getString("error.no-pkg-signing-key.advice"));
+            }
+
+            // things we could check...
+            // check the icons, make sure it has hidpi icons
+            // check the category, make sure it fits in the list apple has provided
+            // validate bundle identifier is reverse dns
+            //  check for \a+\.\a+\..
+
+            return true;
+        } catch (RuntimeException re) {
+            throw new ConfigException(re);
+        }
+    }
+
+    @Override
+    public File execute(Map<String, ? super Object> params, File outputParentDir) {
+        return bundle(params, outputParentDir);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacBaseInstallerBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.tools.packager.mac;
+
+import com.oracle.tools.packager.AbstractBundler;
+import com.oracle.tools.packager.BundlerParamInfo;
+import com.oracle.tools.packager.StandardBundlerParam;
+import com.oracle.tools.packager.Log;
+import com.oracle.tools.packager.ConfigException;
+import com.oracle.tools.packager.IOUtils;
+import com.oracle.tools.packager.UnsupportedPlatformException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.PosixFilePermission;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static com.oracle.tools.packager.StandardBundlerParam.*;
+
+public abstract class MacBaseInstallerBundler extends AbstractBundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(MacBaseInstallerBundler.class.getName());
+
+    //This could be generalized more to be for any type of Image Bundler
+    public static final BundlerParamInfo<MacAppBundler> APP_BUNDLER = new StandardBundlerParam<>(
+            I18N.getString("param.app-bundler.name"),
+            I18N.getString("param.app-bundle.description"),
+            "mac.app.bundler",
+            MacAppBundler.class,
+            params -> new MacAppBundler(),
+            (s, p) -> null);
+
+    public final BundlerParamInfo<File> APP_IMAGE_BUILD_ROOT = new StandardBundlerParam<>(
+            I18N.getString("param.app-image-build-root.name"),
+            I18N.getString("param.app-image-build-root.description"),
+            "mac.app.imageRoot",
+            File.class,
+            params -> {
+                File imageDir = IMAGES_ROOT.fetchFrom(params);
+                if (!imageDir.exists()) imageDir.mkdirs();
+                return new File(imageDir, getID()+ ".image");
+            },
+            (s, p) -> new File(s));
+
+    public static final StandardBundlerParam<File> MAC_APP_IMAGE = new StandardBundlerParam<>(
+            I18N.getString("param.app-image.name"),
+            I18N.getString("param.app-image.description"),
+            "mac.app.image",
+            File.class,
+            params -> null,
+            (s, p) -> new File(s));
+
+
+    public static final BundlerParamInfo<MacDaemonBundler> DAEMON_BUNDLER = new StandardBundlerParam<>(
+            I18N.getString("param.daemon-bundler.name"),
+            I18N.getString("param.daemon-bundler.description"),
+            "mac.daemon.bundler",
+            MacDaemonBundler.class,
+            params -> new MacDaemonBundler(),
+            (s, p) -> null);
+
+
+    public final BundlerParamInfo<File> DAEMON_IMAGE_BUILD_ROOT = new StandardBundlerParam<>(
+            I18N.getString("param.daemon-image-build-root.name"),
+            I18N.getString("param.daemon-image-build-root.description"),
+            "mac.daemon.image",
+            File.class,
+            params -> {
+                File imageDir = IMAGES_ROOT.fetchFrom(params);
+                if (!imageDir.exists()) imageDir.mkdirs();
+                return new File(imageDir, getID()+ ".daemon");
+            },
+            (s, p) -> new File(s));
+
+
+    public static final BundlerParamInfo<File> CONFIG_ROOT = new StandardBundlerParam<>(
+            I18N.getString("param.config-root.name"),
+            I18N.getString("param.config-root.description"),
+            "configRoot",
+            File.class,
+            params -> {
+                File imagesRoot = new File(BUILD_ROOT.fetchFrom(params), "macosx");
+                imagesRoot.mkdirs();
+                return imagesRoot;
+            },
+            (s, p) -> null);
+
+    public static final BundlerParamInfo<String> SIGNING_KEY_USER = new StandardBundlerParam<>(
+            I18N.getString("param.signing-key-name.name"),
+            I18N.getString("param.signing-key-name.description"),
+            "mac.signing-key-user-name",
+            String.class,
+            params -> {
+                try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) {
+                    ProcessBuilder pb = new ProcessBuilder(
+                            "dscacheutil",
+                            "-q", "user", "-a", "name", System.getProperty("user.name"));
+
+                    IOUtils.exec(pb, Log.isDebug(), false, ps);
+
+                    String commandOutput = baos.toString();
+
+                    Pattern pattern = Pattern.compile(".*gecos: (.*)");
+                    Matcher matcher = pattern.matcher(commandOutput);
+                    if (matcher.matches()) {
+                        return (matcher.group(1));
+                    }
+                } catch (IOException ioe) {
+                    Log.info(I18N.getString("message.could-not-retrieve-name"));
+                    Log.debug(ioe);
+                }
+                return null;
+            },
+            null);
+
+
+
+    public static File getPredefinedImage(Map<String, ? super Object> p) {
+        File applicationImage = null;
+        if (MAC_APP_IMAGE.fetchFrom(p) != null) {
+            applicationImage = MAC_APP_IMAGE.fetchFrom(p);
+            if (!applicationImage.exists()) {
+                throw new RuntimeException(
+                        MessageFormat.format(I18N.getString("message.app-image-dir-does-not-exist"), MAC_APP_IMAGE.getID(), applicationImage.toString()));
+            }
+        }
+        return applicationImage;
+    }
+
+    protected void validateAppImageAndBundeler(Map<String, ? super Object> params) throws ConfigException, UnsupportedPlatformException {
+        if (MAC_APP_IMAGE.fetchFrom(params) != null) {
+            File applicationImage = MAC_APP_IMAGE.fetchFrom(params);
+            if (!applicationImage.exists()) {
+                throw new ConfigException(
+                        MessageFormat.format(I18N.getString("message.app-image-dir-does-not-exist"), MAC_APP_IMAGE.getID(), applicationImage.toString()),
+                        MessageFormat.format(I18N.getString("message.app-image-dir-does-not-exist.advice"), MAC_APP_IMAGE.getID()));
+            }
+        } else {
+            APP_BUNDLER.fetchFrom(params).doValidate(params);
+        }
+    }
+
+    protected File prepareAppBundle(Map<String, ? super Object> p) {
+        if (getPredefinedImage(p) != null) {
+            return null;
+        }
+
+        File appImageRoot = APP_IMAGE_BUILD_ROOT.fetchFrom(p);
+        return APP_BUNDLER.fetchFrom(p).doBundle(p, appImageRoot, true);
+    }
+
+    protected File prepareDaemonBundle(Map<String, ? super Object> p) throws ConfigException {
+        File daemonImageRoot = DAEMON_IMAGE_BUILD_ROOT.fetchFrom(p);
+        return DAEMON_BUNDLER.fetchFrom(p).doBundle(p, daemonImageRoot, true);
+    }
+
+    public static void signAppBundle(Map<String, ? super Object> params, File appLocation, String signingIdentity, String identifierPrefix) throws IOException {
+        signAppBundle(params, appLocation, signingIdentity, identifierPrefix, null, null);
+    }
+
+    public static void signAppBundle(Map<String, ? super Object> params, File appLocation, String signingIdentity, String identifierPrefix, String entitlementsFile, String inheritedEntitlements) throws IOException {
+
+        AtomicReference<IOException> toThrow = new AtomicReference<>();
+
+        // sign all dylibs and jars
+        Files.walk(appLocation.toPath())
+                .filter(p -> (p.toString().endsWith(".jar")
+                                || p.toString().endsWith(".dylib"))
+                ).forEach(p -> {
+                    //noinspection ThrowableResultOfMethodCallIgnored
+                    if (toThrow.get() != null) return;
+
+                    List<String> args = new ArrayList<>();
+                    args.addAll(Arrays.asList(
+                            "codesign",
+                            "-f")); // replace all existing signatures
+                    if (signingIdentity != null) {
+                        args.add("-s");
+                        args.add(signingIdentity); // sign with this key
+                    }
+                    if (entitlementsFile != null) {
+                        args.add("--entitlements");
+                        args.add(entitlementsFile); // entitlements
+                    }
+                    args.add("-vvvv"); // super verbose output
+                    args.add(p.toString());
+
+
+                    try {
+                        Set<PosixFilePermission> oldPermissions = Files.getPosixFilePermissions(p);
+                        File f = p.toFile();
+                        f.setWritable(true, true);
+
+                        ProcessBuilder pb = new ProcessBuilder(args);
+                        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
+
+                        Files.setPosixFilePermissions(p, oldPermissions);
+                    } catch (IOException ioe) {
+                        toThrow.set(ioe);
+                    }
+                });
+
+        IOException ioe = toThrow.get();
+        if (ioe != null) {
+            throw ioe;
+        }
+
+        // sign all contained executables with an inherit entitlement
+        Files.find(appLocation.toPath().resolve("Contents"), Integer.MAX_VALUE,
+                (path, attr) -> (Files.isExecutable(path) && Files.isRegularFile(path)))
+                .filter(path -> (!path.toString().endsWith(".dylib") && !path.toString().contains("/Contents/MacOS/")))
+                .forEachOrdered(path -> {
+                    //noinspection ThrowableResultOfMethodCallIgnored
+                    if (toThrow.get() != null) return;
+
+                    List<String> args = new ArrayList<>();
+                    args.addAll(Arrays.asList("codesign",
+                            "--deep",
+//                            "--prefix", identifierPrefix, // use the identifier as a prefix
+                            "-f")); // replace all existing signatures
+                    if (signingIdentity != null) {
+                        args.add("-s");
+                        args.add(signingIdentity); // sign with this key
+                    }
+                    if (inheritedEntitlements != null) {
+                        args.add("--entitlements");
+                        args.add(inheritedEntitlements); // entitlements
+                    }
+                    args.add("-vvvv"); // super verbose output
+                    args.add(path.toString()); // this is what we are signing
+
+                    try {
+                        Set<PosixFilePermission> oldPermissions = Files.getPosixFilePermissions(path);
+                        File f = path.toFile();
+                        f.setWritable(true, true);
+
+                        ProcessBuilder pb = new ProcessBuilder(args);
+                        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
+
+                        Files.setPosixFilePermissions(path, oldPermissions);
+                    } catch (IOException e) {
+                        toThrow.set(e);
+                    }
+                });
+
+        ioe = toThrow.get();
+        if (ioe != null) {
+            throw ioe;
+        }
+
+        // sign all plugins and frameworks
+        Consumer<? super Path> signIdentifiedByPList = path -> {
+            //noinspection ThrowableResultOfMethodCallIgnored
+            if (toThrow.get() != null) return;
+
+            try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos)) {
+                ProcessBuilder pb = new ProcessBuilder("/usr/libexec/PlistBuddy",
+                        "-c", "Print :CFBundleIdentifier", path.resolve("Contents/Info.plist").toString());
+                IOUtils.exec(pb, VERBOSE.fetchFrom(params), false, ps);
+                String bundleID = baos.toString();
+
+                List<String> args = new ArrayList<>();
+                args.addAll(Arrays.asList("codesign",
+                        "-s", signingIdentity, // sign with this key
+                        "-f", // replace all existing signatures
+                        "--prefix", identifierPrefix, // use the identifier as a prefix
+                        //"-i", bundleID, // sign the bundle's CFBundleIdentifier
+                        "-vvvv"));
+                if (signingIdentity != null) {
+                    args.add("-s");
+                    args.add(signingIdentity); // sign with this key
+                }
+                args.add(path.toString());
+                pb = new ProcessBuilder(args);
+                IOUtils.exec(pb, VERBOSE.fetchFrom(params));
+            } catch (IOException e) {
+                toThrow.set(e);
+            }
+        };
+
+        Path pluginsPath = appLocation.toPath().resolve("Contents/PlugIns");
+        if (Files.isDirectory(pluginsPath)) {
+            Files.list(pluginsPath)
+                    .forEach(signIdentifiedByPList);
+
+            ioe = toThrow.get();
+            if (ioe != null) {
+                throw ioe;
+            }
+        }
+        Path frameworkPath = appLocation.toPath().resolve("Contents/Frameworks");
+        if (Files.isDirectory(frameworkPath)) {
+            Files.list(frameworkPath)
+                    .forEach(signIdentifiedByPList);
+
+            ioe = toThrow.get();
+            if (ioe != null) {
+                throw ioe;
+            }
+        }
+
+        // sign the app itself
+        List<String> args = new ArrayList<>();
+        args.addAll(Arrays.asList("codesign",
+                "-s", signingIdentity, // sign with this key
+                "--deep", // sign deeply, including plugins
+                "-f")); // replace all existing signatures
+        if (entitlementsFile != null) {
+            args.add("--entitlements");
+            args.add(entitlementsFile); // entitlements
+        }
+        args.add("-vvvv"); // super verbose output
+        args.add(appLocation.toString());
+
+        ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[args.size()]));
+        IOUtils.exec(pb, VERBOSE.fetchFrom(params));
+    }
+
+    @Override
+    public Collection<BundlerParamInfo<?>> getBundleParameters() {
+        Collection<BundlerParamInfo<?>> results = new LinkedHashSet<>();
+
+        results.addAll(MacAppBundler.getAppBundleParameters());
+        results.addAll(Arrays.asList(
+                APP_BUNDLER,
+                CONFIG_ROOT,
+                APP_IMAGE_BUILD_ROOT,
+                MAC_APP_IMAGE
+        ));
+
+        return results;
+    }
+
+    @Override
+    public String getBundleType() {
+        return "INSTALLER";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacDaemonBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.tools.packager.mac;
+
+import static com.oracle.tools.packager.StandardBundlerParam.*;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.text.MessageFormat;import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import com.oracle.tools.packager.AbstractBundler;
+import com.oracle.tools.packager.BundlerParamInfo;
+import com.oracle.tools.packager.StandardBundlerParam;
+
+import com.oracle.tools.packager.Log;
+import com.oracle.tools.packager.ConfigException;
+import com.oracle.tools.packager.IOUtils;
+import com.oracle.tools.packager.UnsupportedPlatformException;
+
+public class MacDaemonBundler extends AbstractBundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(MacDaemonBundler.class.getName());
+
+    private static final String TEMPLATE_LAUNCHD_PLIST  = "launchd.plist.template";
+
+    public final static String MAC_BUNDLER_PREFIX =
+            BUNDLER_PREFIX + "macosx" + File.separator;
+
+    public static final BundlerParamInfo<File> CONFIG_ROOT = new StandardBundlerParam<>(
+            I18N.getString("param.config-root.name"),
+            I18N.getString("param.config-root.description"),
+            "configRoot",
+            File.class,
+            params -> {
+                File configRoot = new File(BUILD_ROOT.fetchFrom(params), "macosx");
+                configRoot.mkdirs();
+                return configRoot;
+            },
+            (s, p) -> new File(s));
+
+    public MacDaemonBundler() {
+        super();
+        baseResourceLoader = MacResources.class;
+    }
+
+    private File getConfig_LaunchdPlist(Map<String, ? super Object> params) {
+        return new File(CONFIG_ROOT.fetchFrom(params), "launchd.plist");
+    }
+
+    private void prepareConfigFiles(Map<String, ? super Object> params) throws IOException {
+        File launchdPlistFile = getConfig_LaunchdPlist(params);
+        launchdPlistFile.createNewFile();
+        writeLaunchdPlist(launchdPlistFile, params);
+    }
+
+    private String getDaemonIdentifier(Map<String, ? super Object> params) {
+        return IDENTIFIER.fetchFrom(params).toLowerCase() + ".daemon";
+    }
+
+    public String getAppName(Map<String, ? super Object> params) {
+        return APP_NAME.fetchFrom(params) + ".app";
+    }
+
+    private String getLauncherName(Map<String, ? super Object> params) {
+        if (APP_NAME.fetchFrom(params) != null) {
+            return APP_NAME.fetchFrom(params);
+        } else {
+            return MAIN_CLASS.fetchFrom(params);
+        }
+    }
+
+    private String getDaemonLauncherPath(Map<String, ? super Object> params) {
+        return "/Applications/" + getAppName(params) +
+                "/Contents/MacOS/" + getLauncherName(params);
+    }
+
+    private void writeLaunchdPlist(File file, Map<String, ? super Object> params)
+            throws IOException
+    {
+        Log.verbose(MessageFormat.format(I18N.getString("message.preparing-launchd-plist"), file.getAbsolutePath()));
+
+        Map<String, String> data = new HashMap<>();
+
+        data.put("DEPLOY_DAEMON_IDENTIFIER", getDaemonIdentifier(params));
+        data.put("DEPLOY_DAEMON_LAUNCHER_PATH", getDaemonLauncherPath(params));
+        data.put("DEPLOY_RUN_AT_LOAD", String.valueOf((START_ON_INSTALL.fetchFrom(params))));
+        data.put("DEPLOY_KEEP_ALIVE", String.valueOf((RUN_AT_STARTUP.fetchFrom(params))));
+
+        Writer w = new BufferedWriter(new FileWriter(file));
+        w.write(preprocessTextResource(
+                MAC_BUNDLER_PREFIX + getConfig_LaunchdPlist(params).getName(),
+                I18N.getString("resource.launchd-config"), TEMPLATE_LAUNCHD_PLIST, data,
+                VERBOSE.fetchFrom(params)));
+        w.close();
+    }
+
+    protected void cleanupConfigFiles(Map<String, ? super Object> params) {
+        if (CONFIG_ROOT.fetchFrom(params) != null) {
+            if (getConfig_LaunchdPlist(params) != null) {
+                getConfig_LaunchdPlist(params).delete();
+            }
+        }
+    }
+
+    /*
+     * Creates the following structure
+     * 
+     *  <package-name>
+     *      Library
+     *          LaunchDaemons
+     *              plist file
+     */
+    public File doBundle(Map<String, ? super Object> params, File outputDirectory, boolean dependentTask) {
+        if (!outputDirectory.isDirectory() && !outputDirectory.mkdirs()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outputDirectory.getAbsolutePath()));
+        }
+        if (!outputDirectory.canWrite()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outputDirectory.getAbsolutePath()));
+        }
+
+        File rootDirectory = null;
+
+        try {
+            File file = BUILD_ROOT.fetchFrom(params);
+
+            //prepare config resources (we will copy them to the bundle later)
+            // NB: explicitly saving them to simplify customization
+            prepareConfigFiles(params);
+
+            // Create directory structure
+            rootDirectory = new File(outputDirectory, APP_NAME.fetchFrom(params) + ".daemon");
+            IOUtils.deleteRecursive(rootDirectory);
+            rootDirectory.mkdirs();
+
+            if (!dependentTask) {
+                Log.info(MessageFormat.format(I18N.getString("message.creating-daemon-component"), rootDirectory.getAbsolutePath()));
+            }
+
+            File libraryDirectory = new File(rootDirectory, "Library");
+            libraryDirectory.mkdirs();
+
+            File launchDaemonsDirectory = new File(libraryDirectory, "LaunchDaemons");
+            launchDaemonsDirectory.mkdirs();
+
+            // Generate launchd.plist
+            IOUtils.copyFile(getConfig_LaunchdPlist(params),
+                    new File(launchDaemonsDirectory,
+                            IDENTIFIER.fetchFrom(params).toLowerCase() + ".launchd.plist"));
+
+        } catch(IOException ex) {
+            Log.verbose(ex);
+            return null;
+        } finally {
+            if (!VERBOSE.fetchFrom(params)) {
+                //cleanup
+                cleanupConfigFiles(params);
+            } else {
+                Log.info(MessageFormat.format(I18N.getString("message.config-save-location"), CONFIG_ROOT.fetchFrom(params).getAbsolutePath()));
+            }
+        }
+
+        return rootDirectory;
+    }
+
+    //////////////////////////////////////////////////////////////////////////////////
+    // Implement Bundler
+    //////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public String getName() {
+        return I18N.getString("bundle.name");
+    }
+
+    @Override
+    public String getDescription() {
+        return I18N.getString("bundle.description");
+    }
+
+    @Override
+    public String getID() {
+        return "mac.daemon";
+    }
+
+    @Override
+    public String getBundleType() {
+        return "INSTALLER";
+    }
+
+    @Override
+    public Collection<BundlerParamInfo<?>> getBundleParameters() {
+        return getDaemonBundleParameters();
+    }
+
+    public static Collection<BundlerParamInfo<?>> getDaemonBundleParameters() {
+        return Arrays.asList(
+                APP_NAME,
+                BUILD_ROOT,
+                IDENTIFIER,
+                START_ON_INSTALL,
+                RUN_AT_STARTUP
+        );
+    }
+
+    @Override
+    public boolean validate(Map<String, ? super Object> params)
+            throws UnsupportedPlatformException, ConfigException
+    {
+        try {
+            return doValidate(params);
+        } catch (RuntimeException re) {
+            throw new ConfigException(re);
+        }
+
+    }
+
+    public boolean doValidate(Map<String, ? super Object> p)
+            throws UnsupportedPlatformException, ConfigException
+    {
+        if (!System.getProperty("os.name").toLowerCase().contains("os x")) {
+            throw new UnsupportedPlatformException();
+        }
+
+        return true;
+    }
+
+    @Override
+    public File execute(Map<String, ? super Object> params, File outputParentDir) {
+        return doBundle(params, outputParentDir, false);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/fxpackager/src/main/java/com/oracle/tools/packager/mac/MacDmgBundler.java	Mon Apr 28 21:28:19 2014 -0600
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.tools.packager.mac;
+
+import com.oracle.tools.packager.*;
+import com.oracle.tools.packager.IOUtils;
+import sun.misc.BASE64Encoder;
+
+import java.io.*;
+import java.text.MessageFormat;
+import java.util.*;
+
+import static com.oracle.tools.packager.StandardBundlerParam.*;
+
+public class MacDmgBundler extends MacBaseInstallerBundler {
+
+    private static final ResourceBundle I18N =
+            ResourceBundle.getBundle(MacDmgBundler.class.getName());
+
+    static final String DEFAULT_BACKGROUND_IMAGE="background_dmg.png";
+    static final String DEFAULT_DMG_SETUP_SCRIPT="DMGsetup.scpt";
+    static final String TEMPLATE_BUNDLE_ICON = "GenericApp.icns";
+
+    //existing SQE tests look for "license" string in the filenames
+    // when they look for unathorized license files in the build artifacts
+    // Use different name to make them happy
+    static final String DEFAULT_LICENSE_PLIST="lic_template.plist";
+
+    public MacDmgBundler() {
+        super();
+        baseResourceLoader = MacResources.class;
+    }
+
+    //@Override
+    public File bundle(Map<String, ? super Object> params, File outdir) {
+        Log.info(MessageFormat.format(I18N.getString("message.building-dmg"), APP_NAME.fetchFrom(params)));
+        if (!outdir.isDirectory() && !outdir.mkdirs()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-create-output-dir"), outdir.getAbsolutePath()));
+        }
+        if (!outdir.canWrite()) {
+            throw new RuntimeException(MessageFormat.format(I18N.getString("error.cannot-write-to-output-dir"), outdir.getAbsolutePath()));
+        }
+
+        File appImageDir = APP_IMAGE_BUILD_ROOT.fetchFrom(params);
+        try {
+            appImageDir.mkdirs();
+
+            if (prepareAppBundle(params) != null && p