changeset 9992:0f32ff067545 jdk-9+132

Merge
author kcr
date Fri, 12 Aug 2016 13:41:28 -0700
parents 1f37dfbe7019 aec2986a8c3a
children 5cdc7635e67c 449481906320
files
diffstat 54 files changed, 1340 insertions(+), 569 deletions(-) [+]
line wrap: on
line diff
--- a/apps/samples/Ensemble8/build.xml	Thu Aug 11 11:48:13 2016 +0000
+++ b/apps/samples/Ensemble8/build.xml	Fri Aug 12 13:41:28 2016 -0700
@@ -106,7 +106,7 @@
     	</copy>
     	<replaceregexp
     		file="${build.cssref.dir}/cssref.html"
-    		match="https://docs.oracle.com/javase/8/docs/legal/cpyr.html"
+    		match="http://download.java.net/java/jdk9/docs/legal/cpyr.html"
     		replace="http://www.oracle.com/technetwork/java/javase/terms/license/oraclebsd-1603217.txt"
     		byline="true"/>
     </target>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/Hello/src/main/java/hello/HelloDirectoryChooser.java	Fri Aug 12 13:41:28 2016 -0700
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2016 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 hello;
+
+import java.io.File;
+import javafx.application.Application;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.VBox;
+import javafx.stage.DirectoryChooser;
+import javafx.stage.Stage;
+
+public final class HelloDirectoryChooser extends Application {
+
+    final CheckBox useTitle = new CheckBox("Use dialog title");
+
+    DirectoryChooser directoryChooser;
+
+    final TextField directory = new TextField("");
+
+    final TextArea text = new TextArea();
+
+    Scene scene;
+
+    @Override
+    public void start(final Stage stage) {
+        stage.setTitle("Directory Chooser Sample");
+
+        VBox fcTypeBox = new VBox();
+        fcTypeBox.setSpacing(10);
+
+        HBox dirBox = new HBox();
+        dirBox.getChildren().addAll(
+                new Label("Starting Directory:"),
+                directory
+        );
+        directory.setPrefColumnCount(50);
+
+        HBox nameBox = new HBox();
+
+        VBox fcOptionsBox = new VBox();
+        fcOptionsBox.getChildren().addAll(
+                new Label("Dialog Options:"),
+                useTitle,
+                dirBox,
+                nameBox
+        );
+
+        final Button openButton = new Button("Make it so...");
+
+        text.setPrefColumnCount(60);
+        text.setPrefRowCount(10);
+
+        openButton.setOnAction(
+                new EventHandler<ActionEvent>() {
+                    @Override
+                    public void handle(final ActionEvent e) {
+                        directoryChooser = new DirectoryChooser();
+
+                        if (useTitle.isSelected()) {
+                            System.out.println("Adding title");
+                            directoryChooser.setTitle("Alternate Title - Open Directory");
+                        }
+
+                        String dir = directory.getText();
+                        if (!dir.equals("")) {
+                            System.out.println("Directory:" + dir);
+                            directoryChooser.setInitialDirectory(new File(dir));
+                        }
+
+                        File selectedDir = directoryChooser.showDialog(scene.getWindow());
+
+                        System.out.println("selectedDir = "+selectedDir);
+
+                        StringBuilder sb = new StringBuilder();
+                        sb.append("DirectoryChooser dialog returns:\n");
+                        sb.append(selectedDir == null ? "null" : selectedDir);
+                        text.setText(sb.toString());}
+                });
+
+        final Pane rootGroup = new VBox(12);
+        rootGroup.getChildren().addAll(
+                fcTypeBox,
+                fcOptionsBox,
+                openButton,
+                text);
+        rootGroup.setPadding(new Insets(12, 12, 12, 12));
+
+        scene = new Scene(rootGroup);
+
+        stage.setScene(scene);
+        stage.show();
+    }
+
+    public static void main(String[] args) {
+        Application.launch(args);
+    }
+
+}
--- a/build.gradle	Thu Aug 11 11:48:13 2016 +0000
+++ b/build.gradle	Fri Aug 12 13:41:28 2016 -0700
@@ -320,7 +320,7 @@
 defineProperty("JAVAH", cygpath("$JDK_HOME/bin/javah${IS_WINDOWS ? '.exe' : ''}"))
 defineProperty("JAVADOC", cygpath("$JDK_HOME/bin/javadoc${IS_WINDOWS ? '.exe' : ''}"))
 defineProperty("JDK_DOCS", "https://docs.oracle.com/javase/8/docs/api/")
-defineProperty("JIGSAW_MODULES", cygpath(System.getenv("JIGSAW_MODULES")) ?: "")
+defineProperty("JIGSAW_MODULES", cygpath(System.getenv("JIGSAW_MODULES")) ?: cygpath(System.getenv("JIGSAW_HOME") + "/jmods"))
 
 defineProperty("javaRuntimeVersion", System.getProperty("java.runtime.version"))
 def javaVersionInfo = parseJavaVersion(javaRuntimeVersion)
@@ -1937,6 +1937,11 @@
     project.ext.buildModule = COMPILE_FXPACKAGER
     project.ext.moduleRuntime = false
     project.ext.moduleName = "jdk.packager"
+    manifest {
+        attributes(
+                "Main-Class": "com.sun.javafx.tools.packager.Main"
+        )
+    }
     tasks.all {
         if (!COMPILE_FXPACKAGER) it.enabled = false
     }
@@ -1963,7 +1968,7 @@
     jar {
         includeEmptyDirs = false
         archiveName = "ant-javafx.jar"
-        includes = ["com/sun/javafx/tools/ant/**", "com/javafx/main/**"]
+        includes = ["com/sun/javafx/tools/ant/**", "com/javafx/main/**", "resources/web-files/**"]
         eachFile { FileCopyDetails details ->
             if (details.path.startsWith("com/javafx/main")) {
                 details.path = "resources/classes/$details.path"
@@ -1983,7 +1988,7 @@
     }
     processResources.dependsOn man
 
-    // Compile the native launchers. These are included in ant-javafx.jar.
+    // Compile the native launchers. These are included in jdk.packager.jmod.
     if (IS_WINDOWS && COMPILE_FXPACKAGER) {
         task buildWinLauncher(type: CCTask, group: "Build") {
             description = "Compiles native sources for the application co-bundle launcher";
@@ -2258,7 +2263,6 @@
                 from "$projectDir/src/test/resources/hello/test.icns"
                 from "$projectDir/src/test/resources/hello/LICENSE-RTF.rtf"
                 from "$projectDir/../../LICENSE"
-                from "$projectDir/build/libs/packager.jar"
                 into project.file("$projectDir/build/tmp/tests/appResources")
             }
             copy {
@@ -2323,6 +2327,64 @@
                 packagerDevOpts
         ].flatten()
     }
+
+    task buildRedistributableFiles() {
+        def projectDir = "tools/java/redistributable-files"
+        def sourceDir = "src/$projectDir"
+        def buildDir = "build/$projectDir"
+
+        doLast {
+            exec {
+                commandLine(JIGSAW_JAVAC)
+                args("-d")
+                args("$buildDir")
+                args("$sourceDir/RedistributableFiles.java")
+            }
+        }
+    }
+
+    task runRedistributableFiles() {
+        def projectDir = "tools/java/redistributable-files"
+        def sourceDir = "src/$projectDir"
+        def buildDir = "build/$projectDir"
+        def resourceDir = "build/resources/main/jdk/packager/internal/resources/tools/redistributable-files"
+
+        doLast {
+            def fxmodules = ""
+
+            if (!file("$JIGSAW_MODULES/jdk.packager.jmod").exists()) {
+                moduleProjList.each { project ->
+                    if (fxmodules.isEmpty()) {
+                        fxmodules = project.ext.moduleName
+                    }
+                    else {
+                        fxmodules += "," + project.ext.moduleName
+                    }
+                }
+            }
+
+            exec {
+                commandLine(JIGSAW_JAVA)
+                args("-classpath")
+                args("$buildDir")
+                args("RedistributableFiles")
+                args("--module-path")
+                args("$JIGSAW_MODULES")
+                args("--exclude-filelist")
+                args("$sourceDir/exclude_modules.list")
+                args("--out-file")
+                args("$resourceDir/redistributable.list")
+
+                if (!fxmodules.isEmpty()) {
+                    args("--add-modules")
+                    args("$fxmodules")
+                }
+            }
+        }
+    }
+
+    runRedistributableFiles.dependsOn buildRedistributableFiles
+    processResources.dependsOn runRedistributableFiles
 }
 
 project(":media") {
@@ -2944,8 +3006,16 @@
         compile.options.compilerArgs = [
                 "-XaddExports:java.base/sun.security.pkcs=ALL-UNNAMED,"
                         + "java.base/sun.security.timestamp=ALL-UNNAMED,"
-                        + "java.base/sun.security.x509=ALL-UNNAMED,"
-                        + "jdk.jdeps/com.sun.tools.jdeps=ALL-UNNAMED",
+                        + "java.base/sun.security.x509=ALL-UNNAMED",
+                "-encoding", "UTF-8"]
+    }
+}
+
+// fxpackagerservices requires JDK 9 to compile
+project(":fxpackagerservices") {
+    tasks.withType(JavaCompile) { compile ->
+        compile.options.forkOptions.executable = JIGSAW_JAVAC
+        compile.options.compilerArgs = [
                 "-encoding", "UTF-8"]
     }
 }
--- a/build.properties	Thu Aug 11 11:48:13 2016 +0000
+++ b/build.properties	Fri Aug 12 13:41:28 2016 -0700
@@ -48,7 +48,8 @@
 #
 ##############################################################################
 
-javadoc.bottom=<small><a href="https://docs.oracle.com/javase/8/docs/legal/cpyr.html">Copyright</a> (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.</small>
+javadoc.bottom=<font size="-1"><a href="http://bugreport.java.com/bugreport/" target="_blank">Submit a bug or feature</a><br>For further API reference and developer documentation, see <a href="http://download.java.net/java/jdk9/docs/index.html" target="_blank">Java SE Documentation</a>. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.<br> <a href="http://download.java.net/java/jdk9/docs/legal/cpyr.html" target="_blank">Copyright</a> &copy; 2008, 2016, Oracle and/or its affiliates. All rights reserved.<br><b>DRAFT 9-ea</b></font>
+
 javadoc.title=JavaFX 9
 javadoc.header=JavaFX&nbsp;9
 
--- a/buildSrc/src/main/java/workaround/GradleJUnitWorker.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/buildSrc/src/main/java/workaround/GradleJUnitWorker.java	Fri Aug 12 13:41:28 2016 -0700
@@ -65,6 +65,8 @@
 
     private static final String ENCODERCLASS
             = "jarjar.org.gradle.process.internal.child.EncodedStream$EncodedInput";
+    private static final String ENCODERCLASS_2
+            = "worker.org.gradle.process.internal.streams.EncodedStream$EncodedInput";
 
     private static URL fileToURL(File file) throws IOException {
         return file.getCanonicalFile().toURI().toURL();
@@ -233,13 +235,22 @@
                     }
                 }
             }
+            if (encoderClass == null) {
+                try {
+                    encoderClass = Class.forName(ENCODERCLASS_2, true, cloader);
+                } catch (ClassNotFoundException e) {
+                    if (debug) {
+                        System.err.println("did not find " + ENCODERCLASS_2);
+                    }
+                }
+            }
 
             if (encoderClass != null) {
                 if (debug) {
                     System.err.println("Found EncoderClass " + encoderClass.getName());
                 }
             } else {
-                throw new RuntimeException("Encoder not found");
+                throw new RuntimeException("Gradle Encoder Class not found");
             }
 
             Constructor constructor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/buildSrc/src/main/java/worker/org/gradle/process/internal/worker/child/BootstrapSecurityManager.java	Fri Aug 12 13:41:28 2016 -0700
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 2016, 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 worker.org.gradle.process.internal.worker.child;
+
+import java.security.Permission;
+
+/**
+ * override Gradle bootstrap loader hack for JDK 9
+ */
+public class BootstrapSecurityManager extends SecurityManager {
+
+    private boolean initialised;
+    private final ClassLoader target;
+
+    public BootstrapSecurityManager() {
+        this(null);
+    }
+
+    BootstrapSecurityManager(ClassLoader target) {
+        //System.err.println("STARTING OVERRIDE  BootstrapSecurityManager");
+        this.target = target;
+    }
+
+    @Override
+    public void checkPermission(Permission permission) {
+        synchronized (this) {
+            if (initialised) {
+                return;
+            }
+            if (System.in == null) {
+                // Still starting up
+                return;
+            }
+
+            initialised = true;
+        }
+
+        try {
+            System.clearProperty("java.security.manager");
+            System.setSecurityManager(null);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
--- a/modules/javafx.controls/src/main/java/com/sun/javafx/charts/Legend.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/com/sun/javafx/charts/Legend.java	Fri Aug 12 13:41:28 2016 -0700
@@ -25,6 +25,8 @@
 
 package com.sun.javafx.charts;
 
+import java.util.List;
+import java.util.stream.Collectors;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.BooleanPropertyBase;
 import javafx.beans.property.ObjectProperty;
@@ -52,8 +54,10 @@
     // -------------- PRIVATE FIELDS ------------------------------------------
 
     private ListChangeListener<LegendItem> itemsListener = c -> {
-        getChildren().clear();
-        for (LegendItem item : getItems()) getChildren().add(item.label);
+        List<Label> labels = getItems().stream()
+                                       .map(i -> i.label)
+                                       .collect(Collectors.toList());
+        getChildren().setAll(labels);
         if(isVisible()) requestLayout();
     };
 
@@ -83,28 +87,31 @@
      /** The legend items to display in this legend */
     private ObjectProperty<ObservableList<LegendItem>> items = new ObjectPropertyBase<ObservableList<LegendItem>>() {
         ObservableList<LegendItem> oldItems = null;
-         @Override protected void invalidated() {
-             if(oldItems!=null) oldItems.removeListener(itemsListener);
-             getChildren().clear();
-             ObservableList<LegendItem> newItems = get();
-             if(newItems != null) {
-                 newItems.addListener(itemsListener);
-                 for(LegendItem item: newItems) getChildren().add(item.label);
-             }
-             oldItems = get();
-             requestLayout();
-         }
+        @Override protected void invalidated() {
+            if (oldItems != null) oldItems.removeListener(itemsListener);
+            getChildren().clear();
+            ObservableList<LegendItem> newItems = get();
+            if (newItems != null) {
+                newItems.addListener(itemsListener);
+                List<Label> labels = newItems.stream()
+                        .map(i -> i.label)
+                        .collect(Collectors.toList());
+                getChildren().addAll(labels);
+            }
+            oldItems = newItems;
+            requestLayout();
+        }
 
-         @Override
-         public Object getBean() {
-             return Legend.this;
-         }
+        @Override
+        public Object getBean() {
+            return Legend.this;
+        }
 
-         @Override
-         public String getName() {
-             return "items";
-         }
-     };
+        @Override
+        public String getName() {
+            return "items";
+        }
+    };
     public final void setItems(ObservableList<LegendItem> value) {itemsProperty().set(value);}
     public final ObservableList<LegendItem> getItems() { return items.get();}
     public final ObjectProperty<ObservableList<LegendItem>> itemsProperty() {return items;}
@@ -198,4 +205,3 @@
         }
     }
 }
-
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/AreaChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/AreaChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -51,7 +51,6 @@
 import javafx.scene.shape.StrokeLineJoin;
 import javafx.util.Duration;
 
-import com.sun.javafx.charts.Legend;
 import com.sun.javafx.charts.Legend.LegendItem;
 import javafx.css.converter.BooleanConverter;
 import javafx.beans.property.BooleanProperty;
@@ -71,7 +70,6 @@
 
     /** A multiplier for teh Y values that we store for each series, it is used to animate in a new series */
     private Map<Series<X,Y>, DoubleProperty> seriesYMultiplierMap = new HashMap<>();
-    private Legend legend = new Legend();
 
     // -------------- PUBLIC PROPERTIES ----------------------------------------
 
@@ -146,7 +144,6 @@
      */
     public AreaChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) {
         super(xAxis,yAxis);
-        setLegend(legend);
         setData(data);
     }
 
@@ -493,27 +490,12 @@
         return symbol;
     }
 
-    /**
-     * This is called whenever a series is added or removed and the legend needs to be updated
-     */
-    @Override protected void updateLegend() {
-        legend.getItems().clear();
-        if (getData() != null) {
-            for (int seriesIndex=0; seriesIndex < getData().size(); seriesIndex++) {
-                Series<X,Y> series = getData().get(seriesIndex);
-                LegendItem legenditem = new LegendItem(series.getName());
-                legenditem.getSymbol().getStyleClass().addAll("chart-area-symbol","series"+seriesIndex,
-                        "area-legend-symbol", series.defaultColorStyleClass);
-                legend.getItems().add(legenditem);
-            }
-        }
-        if (legend.getItems().size() > 0) {
-            if (getLegend() == null) {
-                setLegend(legend);
-            }
-        } else {
-            setLegend(null);
-        }
+    @Override
+    LegendItem createLegendItemForSeries(Series<X, Y> series, int seriesIndex) {
+        LegendItem legendItem = new LegendItem(series.getName());
+        legendItem.getSymbol().getStyleClass().addAll("chart-area-symbol", "series" + seriesIndex,
+                "area-legend-symbol", series.defaultColorStyleClass);
+        return legendItem;
     }
 
     // -------------- STYLESHEET HANDLING --------------------------------------
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/BarChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/BarChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -46,7 +46,6 @@
 import javafx.scene.layout.StackPane;
 import javafx.util.Duration;
 
-import com.sun.javafx.charts.Legend;
 import com.sun.javafx.charts.Legend.LegendItem;
 
 import javafx.css.StyleableDoubleProperty;
@@ -69,7 +68,6 @@
     // -------------- PRIVATE FIELDS -------------------------------------------
 
     private Map<Series<X,Y>, Map<String, Data<X,Y>>> seriesCategoryMap = new HashMap<>();
-    private Legend legend = new Legend();
     private final Orientation orientation;
     private CategoryAxis categoryAxis;
     private ValueAxis valueAxis;
@@ -154,7 +152,6 @@
     public BarChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) {
         super(xAxis, yAxis);
         getStyleClass().add("bar-chart");
-        setLegend(legend);
         if (!((xAxis instanceof ValueAxis && yAxis instanceof CategoryAxis) ||
              (yAxis instanceof ValueAxis && xAxis instanceof CategoryAxis))) {
             throw new IllegalArgumentException("Axis type incorrect, one of X,Y should be CategoryAxis and the other NumberAxis");
@@ -318,14 +315,13 @@
                 removeSeriesFromDisplay(series);
             });
 
-            boolean lastSeries = (getSeriesSize() > 1) ? false : true;
             XYValueMap.clear();
             for (final Data<X,Y> d : series.getData()) {
                 final Node bar = d.getNode();
                 // Animate series deletion
-                if (!lastSeries) {
-                        Timeline t = createDataRemoveTimeline(d, bar, series);
-                        pt.getChildren().add(t);
+                if (getSeriesSize() > 1) {
+                    Timeline t = createDataRemoveTimeline(d, bar, series);
+                    pt.getChildren().add(t);
                 } else {
                     // fade out last series
                     FadeTransition ft = new FadeTransition(Duration.millis(700),bar);
@@ -398,27 +394,12 @@
         }
     }
 
-    /**
-     * This is called whenever a series is added or removed and the legend needs to be updated
-     */
-    @Override protected void updateLegend() {
-        legend.getItems().clear();
-        if (getData() != null) {
-            for (int seriesIndex = 0; seriesIndex < getData().size(); seriesIndex++) {
-                Series<X,Y> series = getData().get(seriesIndex);
-                LegendItem legenditem = new LegendItem(series.getName());
-                legenditem.getSymbol().getStyleClass().addAll("chart-bar", "series" + seriesIndex, "bar-legend-symbol",
-                        series.defaultColorStyleClass);
-                legend.getItems().add(legenditem);
-            }
-        }
-        if (legend.getItems().size() > 0) {
-            if (getLegend() == null) {
-                setLegend(legend);
-            }
-        } else {
-            setLegend(null);
-        }
+    @Override
+    LegendItem createLegendItemForSeries(Series<X, Y> series, int seriesIndex) {
+        LegendItem legendItem = new LegendItem(series.getName());
+        legendItem.getSymbol().getStyleClass().addAll("chart-bar", "series" + seriesIndex,
+                "bar-legend-symbol", series.defaultColorStyleClass);
+        return legendItem;
     }
 
     // -------------- PRIVATE METHODS ------------------------------------------
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/BubbleChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/BubbleChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -39,7 +39,6 @@
 import javafx.scene.shape.Ellipse;
 import javafx.util.Duration;
 
-import com.sun.javafx.charts.Legend;
 import com.sun.javafx.charts.Legend.LegendItem;
 
 /**
@@ -49,10 +48,6 @@
  */
 public class BubbleChart<X,Y> extends XYChart<X,Y> {
 
-    // -------------- PRIVATE FIELDS ------------------------------------------
-
-    private Legend legend = new Legend();
-
     // -------------- CONSTRUCTORS ----------------------------------------------
 
     /**
@@ -76,7 +71,6 @@
      */
     public BubbleChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) {
         super(xAxis, yAxis);
-        setLegend(legend);
         if (!(xAxis instanceof ValueAxis && yAxis instanceof ValueAxis)) {
             throw new IllegalArgumentException("Axis type incorrect, X and Y should both be NumberAxis");
         }
@@ -289,26 +283,11 @@
         }
     }
 
-    /**
-     * This is called whenever a series is added or removed and the legend needs to be updated
-     */
-    @Override protected void updateLegend() {
-        legend.getItems().clear();
-        if (getData() != null) {
-            for (int seriesIndex=0; seriesIndex< getData().size(); seriesIndex++) {
-                Series<X,Y> series = getData().get(seriesIndex);
-                LegendItem legenditem = new LegendItem(series.getName());
-                legenditem.getSymbol().getStyleClass().addAll("series"+seriesIndex,"chart-bubble",
-                        "bubble-legend-symbol", series.defaultColorStyleClass);
-                legend.getItems().add(legenditem);
-            }
-        }
-        if (legend.getItems().size() > 0) {
-            if (getLegend() == null) {
-                setLegend(legend);
-            }
-        } else {
-            setLegend(null);
-        }
+    @Override
+    LegendItem createLegendItemForSeries(Series<X, Y> series, int seriesIndex) {
+        LegendItem legendItem = new LegendItem(series.getName());
+        legendItem.getSymbol().getStyleClass().addAll("series" + seriesIndex, "chart-bubble",
+                "bubble-legend-symbol", series.defaultColorStyleClass);
+        return legendItem;
     }
 }
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/LineChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/LineChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -57,7 +57,6 @@
 import javafx.scene.shape.StrokeLineJoin;
 import javafx.util.Duration;
 
-import com.sun.javafx.charts.Legend;
 import com.sun.javafx.charts.Legend.LegendItem;
 
 import javafx.css.StyleableBooleanProperty;
@@ -82,7 +81,6 @@
 
     /** A multiplier for the Y values that we store for each series, it is used to animate in a new series */
     private Map<Series<X,Y>, DoubleProperty> seriesYMultiplierMap = new HashMap<>();
-    private Legend legend = new Legend();
     private Timeline dataRemoveTimeline;
     private Series<X,Y> seriesOfDataRemoved = null;
     private Data<X,Y> dataItemBeingRemoved = null;
@@ -184,7 +182,6 @@
      */
     public LineChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) {
         super(xAxis,yAxis);
-        setLegend(legend);
         setData(data);
     }
 
@@ -566,26 +563,12 @@
         return symbol;
     }
 
-    /**
-     * This is called whenever a series is added or removed and the legend needs to be updated
-     */
-     @Override protected void updateLegend() {
-        legend.getItems().clear();
-        if (getData() != null) {
-            for (int seriesIndex=0; seriesIndex < getData().size(); seriesIndex++) {
-                Series<X,Y> series = getData().get(seriesIndex);
-                LegendItem legenditem = new LegendItem(series.getName());
-                legenditem.getSymbol().getStyleClass().addAll("chart-line-symbol", "series"+seriesIndex, series.defaultColorStyleClass);
-                legend.getItems().add(legenditem);
-            }
-        }
-        if (legend.getItems().size() > 0) {
-            if (getLegend() == null) {
-                setLegend(legend);
-            }
-        } else {
-            setLegend(null);
-        }
+    @Override
+    LegendItem createLegendItemForSeries(Series<X, Y> series, int seriesIndex) {
+        LegendItem legendItem = new LegendItem(series.getName());
+        legendItem.getSymbol().getStyleClass().addAll("chart-line-symbol", "series" + seriesIndex,
+                series.defaultColorStyleClass);
+        return legendItem;
     }
 
     // -------------- STYLESHEET HANDLING --------------------------------------
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/PieChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/PieChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -130,10 +130,7 @@
                         ptr = item;
                     }
                 }
-                // update legend style classes
-                if (isLegendVisible()) {
-                    updateLegend();
-                }
+                updateLegend();
                 requestChartLayout();
                 return;
             }
@@ -175,10 +172,7 @@
                     Data item = getData().get(i);
                     updateDataItemStyleClass(item, i);
                 }
-                // update legend if any data has changed
-                if (isLegendVisible()) {
-                    updateLegend();
-                }
+                updateLegend();
             }
         }
         // re-layout everything
@@ -747,18 +741,19 @@
      */
     private void updateLegend() {
         Node legendNode = getLegend();
-        if (legendNode != null && legendNode != legend) return; // RT-23569 dont update when user has set legend.
+        if (legendNode != null && legendNode != legend) return; // RT-23596 dont update when user has set legend.
         legend.setVertical(getLegendSide().equals(Side.LEFT) || getLegendSide().equals(Side.RIGHT));
-        legend.getItems().clear();
+        List<Legend.LegendItem> legendList = new ArrayList<>();
         if (getData() != null) {
             for (Data item : getData()) {
                 LegendItem legenditem = new LegendItem(item.getName());
                 legenditem.getSymbol().getStyleClass().addAll(item.getNode().getStyleClass());
                 legenditem.getSymbol().getStyleClass().add("pie-legend-symbol");
-                legend.getItems().add(legenditem);
+                legendList.add(legenditem);
             }
         }
-        if (legend.getItems().size() > 0) {
+        legend.getItems().setAll(legendList);
+        if (legendList.size() > 0) {
             if (legendNode == null) {
                 setLegend(legend);
             }
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/ScatterChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/ScatterChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -36,7 +36,6 @@
 import javafx.scene.layout.StackPane;
 import javafx.util.Duration;
 
-import com.sun.javafx.charts.Legend;
 import com.sun.javafx.charts.Legend.LegendItem;
 
 import java.util.Iterator;
@@ -47,10 +46,6 @@
  */
 public class ScatterChart<X,Y> extends XYChart<X,Y> {
 
-    // -------------- PRIVATE FIELDS ------------------------------------------
-
-    private Legend legend = new Legend();
-
     // -------------- CONSTRUCTORS ----------------------------------------------
 
     /**
@@ -72,7 +67,6 @@
      */
     public ScatterChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) {
         super(xAxis,yAxis);
-        setLegend(legend);
         setData(data);
     }
 
@@ -191,27 +185,13 @@
         }
     }
 
-    /**
-     * This is called whenever a series is added or removed and the legend needs to be updated
-     */
-    @Override protected void updateLegend() {
-        legend.getItems().clear();
-        if (getData() != null) {
-            for (int seriesIndex=0; seriesIndex< getData().size(); seriesIndex++) {
-                Series<X,Y> series = getData().get(seriesIndex);
-                LegendItem legenditem = new LegendItem(series.getName());
-                if (!series.getData().isEmpty() && series.getData().get(0).getNode() != null) {
-                    legenditem.getSymbol().getStyleClass().addAll(series.getData().get(0).getNode().getStyleClass());
-                }
-                legend.getItems().add(legenditem);
-            }
+    @Override
+    LegendItem createLegendItemForSeries(Series<X, Y> series, int seriesIndex) {
+        LegendItem legendItem = new LegendItem(series.getName());
+        Node node = series.getData().isEmpty() ? null : series.getData().get(0).getNode();
+        if (node != null) {
+            legendItem.getSymbol().getStyleClass().addAll(node.getStyleClass());
         }
-        if (legend.getItems().size() > 0) {
-            if (getLegend() == null) {
-                setLegend(legend);
-            }
-        } else {
-            setLegend(null);
-        }
+        return legendItem;
     }
 }
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/StackedAreaChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/StackedAreaChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -43,7 +43,6 @@
 import javafx.scene.shape.*;
 import javafx.util.Duration;
 
-import com.sun.javafx.charts.Legend;
 import com.sun.javafx.charts.Legend.LegendItem;
 import javafx.css.converter.BooleanConverter;
 
@@ -74,7 +73,6 @@
 
     /** A multiplier for teh Y values that we store for each series, it is used to animate in a new series */
     private Map<Series<X,Y>, DoubleProperty> seriesYMultiplierMap = new HashMap<>();
-    private Legend legend = new Legend();
 
     // -------------- PUBLIC PROPERTIES ----------------------------------------
     /**
@@ -156,7 +154,6 @@
         if (!(yAxis instanceof ValueAxis)) {
             throw new IllegalArgumentException("Axis type incorrect, yAxis must be of ValueAxis type.");
         }
-        setLegend(legend);
         setData(data);
     }
 
@@ -794,27 +791,12 @@
         return symbol;
     }
 
-    /**
-     * This is called whenever a series is added or removed and the legend needs to be updated
-     */
-    @Override protected void updateLegend() {
-        legend.getItems().clear();
-        if (getData() != null) {
-            for (int seriesIndex=0; seriesIndex < getData().size(); seriesIndex++) {
-                Series<X,Y> series = getData().get(seriesIndex);
-                LegendItem legenditem = new LegendItem(series.getName());
-                legenditem.getSymbol().getStyleClass().addAll("chart-area-symbol","series"+seriesIndex,
-                        "area-legend-symbol", series.defaultColorStyleClass);
-                legend.getItems().add(legenditem);
-            }
-        }
-        if (legend.getItems().size() > 0) {
-            if (getLegend() == null) {
-                setLegend(legend);
-            }
-        } else {
-            setLegend(null);
-        }
+    @Override
+    LegendItem createLegendItemForSeries(Series<X, Y> series, int seriesIndex) {
+        LegendItem legendItem = new LegendItem(series.getName());
+        legendItem.getSymbol().getStyleClass().addAll("chart-area-symbol", "series" + seriesIndex,
+                "area-legend-symbol", series.defaultColorStyleClass);
+        return legendItem;
     }
 
     // -------------- INNER CLASSES --------------------------------------------
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/StackedBarChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/StackedBarChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -41,7 +41,7 @@
 import javafx.scene.layout.StackPane;
 import javafx.util.Duration;
 
-import com.sun.javafx.charts.Legend;
+import com.sun.javafx.charts.Legend.LegendItem;
 
 import javafx.css.StyleableDoubleProperty;
 import javafx.css.CssMetaData;
@@ -66,7 +66,6 @@
     // -------------- PRIVATE FIELDS -------------------------------------------
     private Map<Series<X, Y>, Map<String, List<Data<X, Y>>>> seriesCategoryMap =
             new HashMap<>();
-    private Legend legend = new Legend();
     private final Orientation orientation;
     private CategoryAxis categoryAxis;
     private ValueAxis valueAxis;
@@ -150,7 +149,6 @@
     public StackedBarChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X, Y>> data) {
         super(xAxis, yAxis);
         getStyleClass().add("stacked-bar-chart");
-        setLegend(legend);
         if (!((xAxis instanceof ValueAxis && yAxis instanceof CategoryAxis)
                 || (yAxis instanceof ValueAxis && xAxis instanceof CategoryAxis))) {
             throw new IllegalArgumentException("Axis type incorrect, one of X,Y should be CategoryAxis and the other NumberAxis");
@@ -314,11 +312,8 @@
                 final Node bar = d.getNode();
                 // Animate series deletion
                 if (getSeriesSize() > 1) {
-                    for (int j = 0; j < series.getData().size(); j++) {
-                        Data<X, Y> item = series.getData().get(j);
-                        Timeline t = createDataRemoveTimeline(item, bar, series);
-                        pt.getChildren().add(t);
-                    }
+                    Timeline t = createDataRemoveTimeline(d, bar, series);
+                    pt.getChildren().add(t);
                 } else {
                     // fade out last series
                     FadeTransition ft = new FadeTransition(Duration.millis(700), bar);
@@ -437,41 +432,12 @@
         }
     }
 
-    /**
-     * Computes the size of series linked list
-     * @return size of series linked list
-     */
-    @Override int getSeriesSize() {
-        int count = 0;
-        Iterator<Series<X, Y>> seriesIterator = getDisplayedSeriesIterator();
-        while (seriesIterator.hasNext()) {
-            seriesIterator.next();
-            count++;
-        }
-        return count;
-    }
-
-    /**
-     * This is called whenever a series is added or removed and the legend needs to be updated
-     */
-    @Override protected void updateLegend() {
-        legend.getItems().clear();
-        if (getData() != null) {
-            for (int seriesIndex = 0; seriesIndex < getData().size(); seriesIndex++) {
-                Series<X,Y> series = getData().get(seriesIndex);
-                Legend.LegendItem legenditem = new Legend.LegendItem(series.getName());
-                legenditem.getSymbol().getStyleClass().addAll("chart-bar", "series" + seriesIndex, "bar-legend-symbol",
-                        series.defaultColorStyleClass);
-                legend.getItems().add(legenditem);
-            }
-        }
-        if (legend.getItems().size() > 0) {
-            if (getLegend() == null) {
-                setLegend(legend);
-            }
-        } else {
-            setLegend(null);
-        }
+    @Override
+    LegendItem createLegendItemForSeries(Series<X, Y> series, int seriesIndex) {
+        LegendItem legendItem = new LegendItem(series.getName());
+        legendItem.getSymbol().getStyleClass().addAll("chart-bar", "series" + seriesIndex,
+                "bar-legend-symbol", series.defaultColorStyleClass);
+        return legendItem;
     }
 
     private void updateMap(Series<X,Y> series, Data<X,Y> item) {
--- a/modules/javafx.controls/src/main/java/javafx/scene/chart/XYChart.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/chart/XYChart.java	Fri Aug 12 13:41:28 2016 -0700
@@ -26,6 +26,7 @@
 package javafx.scene.chart;
 
 
+import com.sun.javafx.charts.Legend;
 import java.util.ArrayList;
 import java.util.BitSet;
 import java.util.Collections;
@@ -113,6 +114,7 @@
     private final Rectangle plotAreaClip = new Rectangle();
 
     private final List<Series<X, Y>> displayedSeries = new ArrayList<>();
+    private Legend legend = new Legend();
 
     /** This is called when a series is added or removed from the chart */
     private final ListChangeListener<Series<X,Y>> seriesChanged = c -> {
@@ -470,6 +472,7 @@
             if(getXAxis() != null) getXAxis().setAnimated(newValue);
             if(getYAxis() != null) getYAxis().setAnimated(newValue);
         });
+        setLegend(legend);
     }
 
     // -------------- METHODS ------------------------------------------------------------------------------------------
@@ -520,7 +523,34 @@
     /**
      * This is called whenever a series is added or removed and the legend needs to be updated
      */
-    protected void updateLegend(){}
+    protected void updateLegend() {
+        List<Legend.LegendItem> legendList = new ArrayList<>();
+        if (getData() != null) {
+            for (int seriesIndex = 0; seriesIndex < getData().size(); seriesIndex++) {
+                Series<X, Y> series = getData().get(seriesIndex);
+                legendList.add(createLegendItemForSeries(series, seriesIndex));
+            }
+        }
+        legend.getItems().setAll(legendList);
+        if (legendList.size() > 0) {
+            if (getLegend() == null) {
+                setLegend(legend);
+            }
+        } else {
+            setLegend(null);
+        }
+    }
+
+    /**
+     * Called by the updateLegend for each series in the chart in order to
+     * create new legend item
+     * @param series the series for this legend item
+     * @param seriesIndex the index of the series
+     * @return new legend item for this series
+     */
+    Legend.LegendItem createLegendItemForSeries(Series<X, Y> series, int seriesIndex) {
+        return new Legend.LegendItem(series.getName());
+    }
 
     /**
      * This method is called when there is an attempt to add series that was
--- a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/MenuButtonSkin.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/MenuButtonSkin.java	Fri Aug 12 13:41:28 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -26,6 +26,7 @@
 package javafx.scene.control.skin;
 
 import com.sun.javafx.scene.control.ContextMenuContent;
+import javafx.scene.AccessibleAttribute;
 import javafx.scene.control.Control;
 import javafx.scene.control.MenuButton;
 
@@ -139,4 +140,20 @@
     @Override MenuButtonBehavior getBehavior() {
         return behavior;
     }
+
+
+
+    /***************************************************************************
+     *                                                                         *
+     * Accessibility handling                                                  *
+     *                                                                         *
+     **************************************************************************/
+
+    @Override
+    public Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) {
+        switch (attribute) {
+            case MNEMONIC: return label.queryAccessibleAttribute(AccessibleAttribute.MNEMONIC);
+            default: return super.queryAccessibleAttribute(attribute, parameters);
+        }
+    }
 }
--- a/modules/javafx.controls/src/test/java/test/javafx/scene/chart/PieChartTest.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.controls/src/test/java/test/javafx/scene/chart/PieChartTest.java	Fri Aug 12 13:41:28 2016 -0700
@@ -27,15 +27,12 @@
 
 import com.sun.javafx.charts.Legend;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 import javafx.scene.Node;
 import javafx.scene.chart.Chart;
 import javafx.scene.chart.ChartShim;
 import javafx.scene.chart.PieChart;
-import javafx.scene.text.Text;
 import org.junit.Test;
 import static org.junit.Assert.*;
 
@@ -55,49 +52,36 @@
         return pc;
     }
 
-    @Test
-    public void testLabelsVisibleFalse_RT24106() {
+    private void addTestData() {
         data.add(new PieChart.Data("Sun", 20));
         data.add(new PieChart.Data("IBM", 12));
         data.add(new PieChart.Data("HP", 25));
         data.add(new PieChart.Data("Dell", 22));
         data.add(new PieChart.Data("Apple", 30));
+    }
+
+    @Test
+    public void testLabelsVisibleFalse_RT24106() {
+        addTestData();
         pc.setLabelsVisible(false);
         assertEquals(false, pc.getLabelsVisible());
     }
 
     @Test
     public void testLegendUpdateAfterPieNameChange_RT26854() {
-        startApp();
         data.add(new PieChart.Data("Sun", 20));
-        for(Node n : ChartShim.getChartChildren(pc)) {
-            if (n instanceof Text) {
-                assertEquals("Sun", pc.getData().get(0).getName());
-            }
-        }
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException ex) {
-            Logger.getLogger(PieChartTest.class.getName()).log(Level.SEVERE, null, ex);
-        }
+        Legend.LegendItem legendItem = ((Legend)ChartShim.getLegend(pc)).getItems().get(0);
+        assertEquals("Sun", legendItem.getText());
         // change name of data item.
         pc.getData().get(0).setName("Oracle");
-        for(Node n : ChartShim.getChartChildren(pc)) {
-            if (n instanceof Text) {
-                assertEquals("Oracle", pc.getData().get(0).getName());
-            }
-        }
+        legendItem = ((Legend)ChartShim.getLegend(pc)).getItems().get(0);
+        assertEquals("Oracle", legendItem.getText());
     }
 
     @Test
     public void testDataItemRemovedWithAnimation() {
-        startApp();
         pc.setAnimated(true);
-        data.add(new PieChart.Data("Sun", 20));
-        data.add(new PieChart.Data("IBM", 12));
-        data.add(new PieChart.Data("HP", 25));
-        data.add(new PieChart.Data("Dell", 22));
-        data.add(new PieChart.Data("Apple", 30));
+        addTestData();
         pc.getData().remove(0);
         assertEquals(4, pc.getData().size());
     }
@@ -166,4 +150,14 @@
         checkStyleClass(6, "default-color7");
         checkStyleClass(7, "default-color2");
     }
+
+    @Test
+    public void testLegendUpdateWhileNotVisible_8163454() {
+        addTestData();
+        assertEquals(5, ((Legend)ChartShim.getLegend(pc)).getItems().size());
+        pc.setLegendVisible(false);
+        data.remove(0);
+        pc.setLegendVisible(true);
+        assertEquals(4, ((Legend)ChartShim.getLegend(pc)).getItems().size());
+    }
 }
--- a/modules/javafx.fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.fxml/src/main/docs/javafx/fxml/doc-files/introduction_to_fxml.html	Fri Aug 12 13:41:28 2016 -0700
@@ -4,9 +4,9 @@
 <head>
 <link href="fxml.css" rel="stylesheet"/>    
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
-<title>Introduction to FXML | JavaFX 8</title>
-<meta name="description" content="The document introduces FXML, an XML-based declarative markup language for defining user interfaces in JavaFX 8 applications."/>
-<meta name="keywords" content="JavaFX 8, FXML, JavaFX GUI development, web development, Java application development, GUI applications, rich internet applications, RIA, expressive content"/>
+<title>Introduction to FXML | JavaFX 9</title>
+<meta name="description" content="The document introduces FXML, an XML-based declarative markup language for defining user interfaces in JavaFX 9 applications."/>
+<meta name="keywords" content="JavaFX 9, FXML, JavaFX GUI development, web development, Java application development, GUI applications, rich internet applications, RIA, expressive content"/>
 </head>
 <body>
 
@@ -1035,7 +1035,7 @@
 
 <hr>
 <p>
-<small><a href="https://docs.oracle.com/javase/8/docs/legal/cpyr.html">Copyright</a> (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.</small>
+<font size="-1"><a href="http://bugreport.java.com/bugreport/" target="_blank">Submit a bug or feature</a><br>For further API reference and developer documentation, see <a href="http://download.java.net/java/jdk9/docs/index.html" target="_blank">Java SE Documentation</a>. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.<br> <a href="http://download.java.net/java/jdk9/docs/legal/cpyr.html" target="_blank">Copyright</a> &copy; 2008, 2016, Oracle and/or its affiliates. All rights reserved.<br><b>DRAFT 9-ea</b></font>
 </p>
 </body>
 </html>
--- a/modules/javafx.graphics/src/main/docs/javafx/scene/doc-files/cssref.html	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/docs/javafx/scene/doc-files/cssref.html	Fri Aug 12 13:41:28 2016 -0700
@@ -2,7 +2,7 @@
 <html lang="en-US">
   <head>
     <meta name="description" content="This document describes the JavaFX
-              Cascading Style Sheets (CSS) for JavaFX 8 and explains the
+              Cascading Style Sheets (CSS) for JavaFX 9 and explains the
               styles, values, properties and associated grammar.">
     <meta name="keywords" content="JavaFX, JavaFX CSS, JavaFX CSS reference,
               JavaFX CSS guide, JavaFX styling, CSS styles, CSS, cascading style sheets,
@@ -179,7 +179,7 @@
   <body>
     <div class="fx-code-header">
       <div class="version"><br>
-        Release: JavaFX 8</div>
+        Release: JavaFX 9</div>
     </div>
     <h1>JavaFX CSS Reference Guide</h1>
     <h2>Contents</h2>
@@ -559,7 +559,7 @@
         blendMode variable would have a corresponding CSS property name of
         "-fx-blend-mode". </p>
     <h3><a name="intropublicapi" id="intropublicapi">CSS Public API</a></h3>
-    Beginning with JavaFX 8.0, public API is available for developers to create styleable properties and manage
+    Beginning with JavaFX 8, public API is available for developers to create styleable properties and manage
     pseudo-class state. Refer to <a href="../../../javafx/css/package-summary.html">javafx.css</a> for details.
     <h3><a name="introinheritance" id="introinheritance">Inheritance</a></h3>
     <p>CSS also provides for certain properties to be inherited by default, or
@@ -6220,7 +6220,7 @@
     <p>[5] Uniform Resource Identifier (URI): Generic Syntax <a href="http://www.ietf.org/rfc/rfc3986">RFC-3986</a></p>
     <hr>
     <p>
-<span style="font-size: small;"><a href="https://docs.oracle.com/javase/8/docs/legal/cpyr.html">Copyright</a> (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.</span>
+<font size="-1"><a href="http://bugreport.java.com/bugreport/" target="_blank">Submit a bug or feature</a><br>For further API reference and developer documentation, see <a href="http://download.java.net/java/jdk9/docs/index.html" target="_blank">Java SE Documentation</a>. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.<br> <a href="http://download.java.net/java/jdk9/docs/legal/cpyr.html" target="_blank">Copyright</a> &copy; 2008, 2016, Oracle and/or its affiliates. All rights reserved.<br><b>DRAFT 9-ea</b></font>
     </p>
     <br>
   </body>
--- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/CommonDialogs.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/CommonDialogs.java	Fri Aug 12 13:41:28 2016 -0700
@@ -252,7 +252,9 @@
     {
         List<File> list = new ArrayList<File>();
         for (String s : files) {
-            list.add(new File(s));
+            if (s != null) {
+                list.add(new File(s));
+            }
         }
         return new FileChooserResult(list,
                 extensionFilters == null || index < 0 || index >= extensionFilters.length ?
--- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/Robot.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/Robot.java	Fri Aug 12 13:41:28 2016 -0700
@@ -25,6 +25,7 @@
 package com.sun.glass.ui;
 
 import static com.sun.javafx.FXPermissions.CREATE_ROBOT_PERMISSION;
+import java.nio.IntBuffer;
 
 public abstract class Robot {
 
@@ -140,7 +141,59 @@
         return _getPixelColor(x, y);
     }
 
-    protected abstract Pixels _getScreenCapture(int x, int y, int width, int height, boolean isHiDPI);
+    // Subclasses must override and implement at least one of the following two
+    // _getScreenCapture methods
+
+    protected void _getScreenCapture(int x, int y, int width, int height, int[] data) {
+        throw new UnsupportedOperationException("Not implementated in the base class");
+    }
+
+    protected Pixels _getScreenCapture(int x, int y, int width, int height, boolean isHiDPI) {
+        Screen mainScreen = Screen.getMainScreen();
+        float uiScaleX = mainScreen.getPlatformScaleX();
+        float uiScaleY = mainScreen.getPlatformScaleY();
+        int data[];
+        int dw, dh;
+        if (uiScaleX == 1.0f && uiScaleY == 1.0f) {
+            data = new int[width * height];
+            _getScreenCapture(x, y, width, height, data);
+            dw = width;
+            dh = height;
+        } else {
+            int pminx = (int) Math.floor(x * uiScaleX);
+            int pminy = (int) Math.floor(y * uiScaleY);
+            int pmaxx = (int) Math.ceil((x + width) * uiScaleX);
+            int pmaxy = (int) Math.ceil((y + height) * uiScaleY);
+            int pwidth = pmaxx - pminx;
+            int pheight = pmaxy - pminy;
+            int tmpdata[] = new int[pwidth * pheight];
+            _getScreenCapture(pminx, pminy, pwidth, pheight, tmpdata);
+            if (isHiDPI) {
+                data = tmpdata;
+                dw = pwidth;
+                dh = pheight;
+            } else {
+                data = new int[width * height];
+                int index = 0;
+                for (int iy = 0; iy < height; iy++) {
+                    float rely = ((y + iy + 0.5f) * uiScaleY) - (pminy + 0.5f);
+                    int irely = (int) Math.floor(rely);
+                    int fracty = (int) ((rely - irely) * 256);
+                    for (int ix = 0; ix < width; ix++) {
+                        float relx = ((x + ix + 0.5f) * uiScaleX) - (pminx + 0.5f);
+                        int irelx = (int) Math.floor(relx);
+                        int fractx = (int) ((relx - irelx) * 256);
+                        data[index++] =
+                            interp(tmpdata, irelx, irely, pwidth, pheight, fractx, fracty);
+                    }
+                }
+                dw = width;
+                dh = height;
+            }
+        }
+        return Application.GetApplication().createPixels(dw, dh, IntBuffer.wrap(data));
+    }
+
     /**
      * Returns a capture of the specified rectangular area of the screen.
      *
@@ -170,4 +223,48 @@
     public Pixels getScreenCapture(int x, int y, int width, int height) {
         return getScreenCapture(x, y, width, height, false);
     }
+
+    private static int interp(int pixels[], int x, int y, int w, int h, int fractx1, int fracty1) {
+        int fractx0 = 256 - fractx1;
+        int fracty0 = 256 - fracty1;
+        int i = y * w + x;
+        int rgb00 = (x < 0 || y < 0 || x >= w || y >= h) ? 0 : pixels[i];
+        if (fracty1 == 0) {
+            // No interplation with pixels[y+1]
+            if (fractx1 == 0) {
+                // No interpolation with any neighbors
+                return rgb00;
+            }
+            int rgb10 = (y < 0 || x+1 >= w || y >= h) ? 0 : pixels[i+1];
+            return interp(rgb00, rgb10, fractx0, fractx1);
+        } else if (fractx1 == 0) {
+            // No interpolation with pixels[x+1]
+            int rgb01 = (x < 0 || x >= w || y+1 >= h) ? 0 : pixels[i+w];
+            return interp(rgb00, rgb01, fracty0, fracty1);
+        } else {
+            // All 4 neighbors must be interpolated
+            int rgb10 = (y < 0 || x+1 >= w || y >= h) ? 0 : pixels[i+1];
+            int rgb01 = (x < 0 || x >= w || y+1 >= h) ? 0 : pixels[i+w];
+            int rgb11 = (x+1 >= w || y+1 >= h) ? 0 : pixels[i+w+1];
+            return interp(interp(rgb00, rgb10, fractx0, fractx1),
+                          interp(rgb01, rgb11, fractx0, fractx1),
+                          fracty0, fracty1);
+        }
+    }
+
+    private static int interp(int rgb0, int rgb1, int fract0, int fract1) {
+        int a0 = (rgb0 >> 24) & 0xff;
+        int r0 = (rgb0 >> 16) & 0xff;
+        int g0 = (rgb0 >>  8) & 0xff;
+        int b0 = (rgb0      ) & 0xff;
+        int a1 = (rgb1 >> 24) & 0xff;
+        int r1 = (rgb1 >> 16) & 0xff;
+        int g1 = (rgb1 >>  8) & 0xff;
+        int b1 = (rgb1      ) & 0xff;
+        int a = (a0 * fract0 + a1 * fract1) >> 8;
+        int r = (r0 * fract0 + r1 * fract1) >> 8;
+        int g = (g0 * fract0 + g1 * fract1) >> 8;
+        int b = (b0 * fract0 + b1 * fract1) >> 8;
+        return (a << 24) | (r << 16) | (g << 8) | b;
+    }
 }
--- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/gtk/GtkRobot.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/gtk/GtkRobot.java	Fri Aug 12 13:41:28 2016 -0700
@@ -73,94 +73,5 @@
         return result[0];
     }
 
-    native private void _getScreenCapture(int x, int y, int width, int height, int[] data);
-    @Override protected Pixels _getScreenCapture(int x, int y, int width, int height, boolean isHiDPI) {
-        Screen mainScreen = Screen.getMainScreen();
-        float uiScaleX = mainScreen.getPlatformScaleX();
-        float uiScaleY = mainScreen.getPlatformScaleY();
-        int data[];
-        int dw, dh;
-        if (uiScaleX == 1.0f && uiScaleY == 1.0f) {
-            data = new int[width * height];
-            _getScreenCapture(x, y, width, height, data);
-            dw = width;
-            dh = height;
-        } else {
-            int pminx = (int) Math.floor(x * uiScaleX);
-            int pminy = (int) Math.floor(y * uiScaleY);
-            int pmaxx = (int) Math.ceil((x + width) * uiScaleX);
-            int pmaxy = (int) Math.ceil((y + height) * uiScaleY);
-            int pwidth = pmaxx - pminx;
-            int pheight = pmaxy - pminy;
-            int tmpdata[] = new int[pwidth * pheight];
-            _getScreenCapture(pminx, pminy, pwidth, pheight, tmpdata);
-            if (isHiDPI) {
-                data = tmpdata;
-                dw = pwidth;
-                dh = pheight;
-            } else {
-                data = new int[width * height];
-                int index = 0;
-                for (int iy = 0; iy < height; iy++) {
-                    float rely = ((y + iy + 0.5f) * uiScaleY) - (pminy + 0.5f);
-                    int irely = (int) Math.floor(rely);
-                    int fracty = (int) ((rely - irely) * 256);
-                    for (int ix = 0; ix < width; ix++) {
-                        float relx = ((x + ix + 0.5f) * uiScaleX) - (pminx + 0.5f);
-                        int irelx = (int) Math.floor(relx);
-                        int fractx = (int) ((relx - irelx) * 256);
-                        data[index++] =
-                            interp(tmpdata, irelx, irely, pwidth, pheight, fractx, fracty);
-                    }
-                }
-                dw = width;
-                dh = height;
-            }
-        }
-        return Application.GetApplication().createPixels(dw, dh, IntBuffer.wrap(data));
-    }
-
-    static int interp(int pixels[], int x, int y, int w, int h, int fractx1, int fracty1) {
-        int fractx0 = 256 - fractx1;
-        int fracty0 = 256 - fracty1;
-        int i = y * w + x;
-        int rgb00 = (x < 0 || y < 0 || x >= w || y >= h) ? 0 : pixels[i];
-        if (fracty1 == 0) {
-            // No interplation with pixels[y+1]
-            if (fractx1 == 0) {
-                // No interpolation with any neighbors
-                return rgb00;
-            }
-            int rgb10 = (y < 0 || x+1 >= w || y >= h) ? 0 : pixels[i+1];
-            return interp(rgb00, rgb10, fractx0, fractx1);
-        } else if (fractx1 == 0) {
-            // No interpolation with pixels[x+1]
-            int rgb01 = (x < 0 || x >= w || y+1 >= h) ? 0 : pixels[i+w];
-            return interp(rgb00, rgb01, fracty0, fracty1);
-        } else {
-            // All 4 neighbors must be interpolated
-            int rgb10 = (y < 0 || x+1 >= w || y >= h) ? 0 : pixels[i+1];
-            int rgb01 = (x < 0 || x >= w || y+1 >= h) ? 0 : pixels[i+w];
-            int rgb11 = (x+1 >= w || y+1 >= h) ? 0 : pixels[i+w+1];
-            return interp(interp(rgb00, rgb10, fractx0, fractx1),
-                          interp(rgb01, rgb11, fractx0, fractx1),
-                          fracty0, fracty1);
-        }
-    }
-
-    static int interp(int rgb0, int rgb1, int fract0, int fract1) {
-        int a0 = (rgb0 >> 24) & 0xff;
-        int r0 = (rgb0 >> 16) & 0xff;
-        int g0 = (rgb0 >>  8) & 0xff;
-        int b0 = (rgb0      ) & 0xff;
-        int a1 = (rgb1 >> 24) & 0xff;
-        int r1 = (rgb1 >> 16) & 0xff;
-        int g1 = (rgb1 >>  8) & 0xff;
-        int b1 = (rgb1      ) & 0xff;
-        int a = (a0 * fract0 + a1 * fract1) >> 8;
-        int r = (r0 * fract0 + r1 * fract1) >> 8;
-        int g = (g0 * fract0 + g1 * fract1) >> 8;
-        int b = (b0 * fract0 + b1 * fract1) >> 8;
-        return (a << 24) | (r << 16) | (g << 8) | b;
-    }
+    @Override native protected void _getScreenCapture(int x, int y, int width, int height, int[] data);
 }
--- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/lens/LensRobot.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/lens/LensRobot.java	Fri Aug 12 13:41:28 2016 -0700
@@ -105,7 +105,7 @@
 
     @Override native protected int _getPixelColor(int x, int y);
 
-    native private void _getScreenCapture(int x, int y, int width, int height, int[] data);
+    @Override native protected void _getScreenCapture(int x, int y, int width, int height, int[] data);
     @Override protected Pixels _getScreenCapture(int x, int y, int width, int height, boolean isHiDPI) {
         int data[] = new int[width * height];
         _getScreenCapture(x, y, width, height, data);
--- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/win/WinAccessible.java	Fri Aug 12 13:41:28 2016 -0700
@@ -690,7 +690,7 @@
                 if (mnemonic != null) {
                     variant = new WinVariant();
                     variant.vt = WinVariant.VT_BSTR;
-                    variant.bstrVal = "Alt " + mnemonic.toLowerCase();
+                    variant.bstrVal = "Alt+" + mnemonic.toLowerCase();
                 }
                 break;
             }
--- a/modules/javafx.graphics/src/main/java/com/sun/glass/ui/win/WinRobot.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/java/com/sun/glass/ui/win/WinRobot.java	Fri Aug 12 13:41:28 2016 -0700
@@ -51,12 +51,5 @@
     @Override native protected int _getMouseY();
 
     @Override native protected int _getPixelColor(int x, int y);
-    native private void _getScreenCapture(int x, int y, int width, int height, int[] data);
-    @Override protected Pixels _getScreenCapture(int x, int y, int width, int height, boolean isHiDPI) {
-        int data[] = new int[width * height];
-        _getScreenCapture(x, y, width, height, data);
-        return Application.GetApplication().createPixels(width, height, IntBuffer.wrap(data));
-    }
-
+    @Override native protected void _getScreenCapture(int x, int y, int width, int height, int[] data);
 }
-
--- a/modules/javafx.graphics/src/main/native-glass/gtk/GlassApplication.cpp	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/native-glass/gtk/GlassApplication.cpp	Fri Aug 12 13:41:28 2016 -0700
@@ -137,6 +137,7 @@
     process_events_prev = (GdkEventFunc) handler;
     disableGrab = (gboolean) _disableGrab;
 
+    glass_gdk_x11_display_set_window_scale(gdk_display_get_default(), 1);
     gdk_event_handler_set(process_events, NULL, NULL);
 
     GdkScreen *default_gdk_screen = gdk_screen_get_default();
--- a/modules/javafx.graphics/src/main/native-glass/gtk/glass_wrapper.h	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/native-glass/gtk/glass_wrapper.h	Fri Aug 12 13:41:28 2016 -0700
@@ -119,6 +119,9 @@
 void
 glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y);
 
+void
+glass_gdk_x11_display_set_window_scale(GdkDisplay *display, gint scale);
+
 gboolean
 glass_configure_window_transparency(GtkWidget *window, gboolean transparent);
 
--- a/modules/javafx.graphics/src/main/native-glass/gtk/wrapper_gdk.c	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/native-glass/gtk/wrapper_gdk.c	Fri Aug 12 13:41:28 2016 -0700
@@ -267,6 +267,8 @@
                       GdkWMFunction functions);
 static void (*_gdk_window_show) (GdkWindow * window);
 static Display *(*_gdk_x11_display_get_xdisplay) (GdkDisplay * display);
+static void (*_gdk_x11_display_set_window_scale) (GdkDisplay *display,
+                                  gint scale);
 static XID (*_gdk_x11_drawable_get_xid) (GdkDrawable * drawable);
 static gint (*_gdk_x11_get_default_screen) (void);
 static Display *(*_gdk_x11_get_default_xdisplay) (void);
@@ -359,8 +361,16 @@
         fprintf(stderr,"failed loading %s\n", #x); \
     }
 
+#define PRELOAD_SYMBOL_GDK_OPT(x) \
+    _##x = dlsym(libgdk, #x); \
+    if (wrapper_debug && _##x == NULL) { \
+        symbol_load_missing++; \
+        fprintf(stderr, "missing optional %s\n", #x); \
+    }
+
 int wrapper_load_symbols_gdk (int version, void * libgdk)
 {
+    int symbol_load_missing = 0;
     int symbol_load_errors = 0;
 
     PRELOAD_SYMBOL_GDK (gdk_atom_intern);
@@ -492,10 +502,15 @@
         PRELOAD_SYMBOL_GDK (gdk_cairo_region_create_from_surface);
         PRELOAD_SYMBOL_GDK (gdk_window_shape_combine_region);
         PRELOAD_SYMBOL_GDK (gdk_window_input_shape_combine_region);
+        PRELOAD_SYMBOL_GDK_OPT (gdk_x11_display_set_window_scale);
     }
 
     if (symbol_load_errors && wrapper_debug) {
-        fprintf (stderr, "failed to load %d gdk symbols", symbol_load_errors);
+        fprintf (stderr, "failed to load %d required gdk symbols\n", symbol_load_errors);
+    }
+
+    if (symbol_load_missing && wrapper_debug) {
+        fprintf (stderr, "missing %d optional gdk symbols\n", symbol_load_missing);
     }
 
     return symbol_load_errors;
@@ -515,6 +530,19 @@
         } \
     }
 
+#define CHECK_LOAD_SYMBOL_GDK_OPT(x) \
+    { \
+        if (!_##x) { \
+            if (wrapper_debug) fprintf(stderr,"missing optional %s\n", #x); \
+            return; \
+        } else { \
+            if (wrapper_debug) { \
+               fprintf(stderr,"using %s\n", #x); \
+               fflush(stderr); \
+            } \
+        } \
+    }
+
 
 GdkAtom gdk_atom_intern (const gchar * atom_name, gboolean only_if_exists)
 {
@@ -1157,6 +1185,19 @@
     return (*_gdk_x11_display_get_xdisplay) (display);
 }
 
+void glass_gdk_x11_display_set_window_scale (GdkDisplay *display,
+                          gint scale)
+{
+    if (wrapper_gtk_version >= 3) {
+        // Optional call, if it does not exist then GTK3 is not yet
+        // doing automatic scaling of coordinates so we do not need
+        // to override it.  CHECK_LOAD_SYMBOL_GDK_OPT will simply
+        // return if the symbol was not found.
+        CHECK_LOAD_SYMBOL_GDK_OPT (gdk_x11_display_set_window_scale);
+        (*_gdk_x11_display_set_window_scale) (display, scale);
+    }
+}
+
 XID gdk_x11_drawable_get_xid (GdkDrawable * drawable)
 {
     if (wrapper_gtk_version == 2) {
--- a/modules/javafx.graphics/src/main/native-glass/gtk/wrapper_gio.c	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/native-glass/gtk/wrapper_gio.c	Fri Aug 12 13:41:28 2016 -0700
@@ -76,15 +76,12 @@
     PRELOAD_SYMBOL_GIO_OPT (g_settings_new);
     PRELOAD_SYMBOL_GIO_OPT (g_settings_get_uint);
 
-    if (symbol_load_errors && wrapper_debug)
-    {
-      fprintf (stderr, "failed to load %d required gio symbols\n",
-           symbol_load_errors);
+    if (symbol_load_errors && wrapper_debug) {
+        fprintf (stderr, "failed to load %d required gio symbols\n", symbol_load_errors);
     }
-    if (symbol_load_missing && wrapper_debug)
-    {
-      fprintf (stderr, "missing %d optional gio symbols\n",
-           symbol_load_missing);
+
+    if (symbol_load_missing && wrapper_debug) {
+        fprintf (stderr, "missing %d optional gio symbols\n", symbol_load_missing);
     }
 
     return symbol_load_errors;
@@ -106,7 +103,7 @@
 #define CHECK_LOAD_SYMBOL_GIO_OPT(x, retval) \
     { \
         if (!_##x) { \
-            if (wrapper_debug) fprintf(stderr, "missing %s\n", #x); \
+            if (wrapper_debug) fprintf(stderr, "missing optional %s\n", #x); \
             return retval; \
         } else { \
             if (wrapper_debug) { \
--- a/modules/javafx.graphics/src/main/native-glass/mac/GlassScreen.m	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/native-glass/mac/GlassScreen.m	Fri Aug 12 13:41:28 2016 -0700
@@ -39,6 +39,8 @@
 
 #define MAX_DISPLAY_COUNT 1024
 
+NSSize maxScreenDimensions;
+
 CGFloat GetScreenScaleFactor(NSScreen *screen)
 {
     if ([screen respondsToSelector:@selector(backingScaleFactor)]) {
@@ -132,7 +134,17 @@
                                                       jScreenClass,
                                                       NULL);
     GLASS_CHECK_EXCEPTION(env);
+    maxScreenDimensions = NSMakeSize(0.f,0.f);
     for (NSUInteger index = 0; index < [screens count]; index++) {
+        NSRect screenRect = [[screens objectAtIndex:index] frame];
+
+        if (screenRect.size.width > maxScreenDimensions.width) {
+            maxScreenDimensions.width = screenRect.size.width;
+        }
+        if (screenRect.size.height > maxScreenDimensions.height) {
+            maxScreenDimensions.height = screenRect.size.height;
+        }
+
         jobject javaScreen = createJavaScreen(env, [screens objectAtIndex:index]);
         (*env)->SetObjectArrayElement(env, screenArray, index, javaScreen);
         GLASS_CHECK_EXCEPTION(env);
--- a/modules/javafx.graphics/src/main/native-glass/mac/GlassWindow+Java.m	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/native-glass/mac/GlassWindow+Java.m	Fri Aug 12 13:41:28 2016 -0700
@@ -42,6 +42,7 @@
 #endif
 
 static NSWindow *s_grabWindow = nil;
+extern NSSize maxScreenDimensions;
 
 @interface NSWindow (External)
 
@@ -359,6 +360,14 @@
     frameRect.origin.y = screenFrame.size.height - frameRect.size.height - frameRect.origin.y;
     //NSLog(@"            set to frameRect:%.2f,%.2f %.2fx%.2f", frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height);
 
+    if (frameRect.size.width > maxScreenDimensions.width) {
+        frameRect.size.width = maxScreenDimensions.width;
+    }
+
+    if (frameRect.size.height > maxScreenDimensions.height) {
+        frameRect.size.height = maxScreenDimensions.height;
+    }
+
     [self->nsWindow setFrame:frameRect display:displayFlag animate:animateFlag];
 
     //frameRect = [self _flipFrame];
--- a/modules/javafx.graphics/src/main/native-glass/mac/GlassWindow+Overrides.m	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/native-glass/mac/GlassWindow+Overrides.m	Fri Aug 12 13:41:28 2016 -0700
@@ -180,6 +180,11 @@
 - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
 {
     GET_MAIN_JENV;
+
+    if ([window isZoomed]) {
+        return NO;
+    }
+
     (*env)->CallVoidMethod(env, jWindow, jWindowNotifyResize, com_sun_glass_events_WindowEvent_MAXIMIZE, (int)newFrame.size.width, (int)newFrame.size.height);
 
     return YES;
--- a/modules/javafx.graphics/src/main/native-glass/win/Robot.cpp	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.graphics/src/main/native-glass/win/Robot.cpp	Fri Aug 12 13:41:28 2016 -0700
@@ -300,17 +300,6 @@
 JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinRobot__1getScreenCapture
     (JNIEnv *env, jobject jrobot, jint x, jint y, jint width, jint height, jintArray pixelArray)
 {
-    jfloat fx = (jfloat) x;
-    jfloat fy = (jfloat) y;
-    GlassScreen::FX2Win(&fx, &fy);
-    jint dx = (jint) ceil(fx - 0.5f);
-    jint dy = (jint) ceil(fy - 0.5f);
-    fx = (jfloat) (x + width);
-    fy = (jfloat) (y + height);
-    GlassScreen::FX2Win(&fx, &fy);
-    jint dw = ((jint) ceil(fx - 0.5f)) - dx;
-    jint dh = ((jint) ceil(fy - 0.5f)) - dy;
-
     int numPixels = width * height;
     int pixelDataSize = sizeof(jint) * numPixels;
     ASSERT(pixelDataSize > 0 && pixelDataSize % 4 == 0);
@@ -318,7 +307,7 @@
     jint * pixelData = (jint *)(new BYTE[pixelDataSize]);
 
     if (pixelData) {
-        GetScreenCapture(dx, dy, dw, dh, pixelData, width, height);
+        GetScreenCapture(x, y, width, height, pixelData, width, height);
 
         // copy pixels into Java array
         env->SetIntArrayRegion(pixelArray, 0, numPixels, pixelData);
--- a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PathTraversalState.cpp	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/PathTraversalState.cpp	Fri Aug 12 13:41:28 2016 -0700
@@ -26,8 +26,6 @@
 
 namespace WebCore {
 
-static const float kPathSegmentLengthTolerance = 0.00001f;
-
 static inline FloatPoint midPoint(const FloatPoint& first, const FloatPoint& second)
 {
     return FloatPoint((first.x() + second.x()) / 2.0f, (first.y() + second.y()) / 2.0f);
@@ -46,9 +44,15 @@
         : start(s)
         , control(c)
         , end(e)
+        , splitDepth(0)
     {
     }
 
+    double magnitudeSquared() const
+    {
+        return ((double)(start.dot(start)) + (double)(control.dot(control)) + (double)(end.dot(end))) / 9.0;
+    }
+
     float approximateDistance() const
     {
         return distanceLine(start, control) + distanceLine(control, end);
@@ -65,11 +69,14 @@
 
         left.start = start;
         right.end = end;
+
+        left.splitDepth = right.splitDepth = splitDepth + 1;
     }
 
     FloatPoint start;
     FloatPoint control;
     FloatPoint end;
+    unsigned short splitDepth;
 };
 
 struct CubicBezier {
@@ -79,9 +86,15 @@
         , control1(c1)
         , control2(c2)
         , end(e)
+        , splitDepth(0)
     {
     }
 
+    double magnitudeSquared() const
+    {
+        return ((double)(start.dot(start)) + (double)(control1.dot(control1)) + (double)(control2.dot(control2)) + (double)(end.dot(end))) / 16.0;
+    }
+
     float approximateDistance() const
     {
         return distanceLine(start, control1) + distanceLine(control1, control2) + distanceLine(control2, end);
@@ -102,20 +115,17 @@
         FloatPoint leftControl2ToRightControl1 = midPoint(left.control2, right.control1);
         left.end = leftControl2ToRightControl1;
         right.start = leftControl2ToRightControl1;
+
+        left.splitDepth = right.splitDepth = splitDepth + 1;
     }
 
     FloatPoint start;
     FloatPoint control1;
     FloatPoint control2;
     FloatPoint end;
+    unsigned short splitDepth;
 };
 
-// FIXME: This function is possibly very slow due to the ifs required for proper path measuring
-// A simple speed-up would be to use an additional boolean template parameter to control whether
-// to use the "fast" version of this function with no PathTraversalState updating, vs. the slow
-// version which does update the PathTraversalState.  We'll have to shark it to see if that's necessary.
-// Another check which is possible up-front (to send us down the fast path) would be to check if
-// approximateDistance() + current total distance > desired distance
 template<class CurveType>
 static float curveLength(const PathTraversalState& traversalState, const CurveType& originalCurve, FloatPoint& previous, FloatPoint& current)
 {
@@ -124,10 +134,17 @@
     Vector<CurveType, curveStackDepthLimit> curveStack;
     float totalLength = 0;
 
+    static const double pathSegmentLengthToleranceSquared = 1.e-16;
+
+    double curveScaleForToleranceSquared = originalCurve.magnitudeSquared();
+    if (curveScaleForToleranceSquared < pathSegmentLengthToleranceSquared)
+        return 0;
     while (true) {
         float length = curve.approximateDistance();
+        double lengthDiscrepancy = length - distanceLine(curve.start, curve.end);
 
-        if ((length - distanceLine(curve.start, curve.end)) > kPathSegmentLengthTolerance && curveStack.size() < curveStackDepthLimit) {
+        // Note : 8163582
+        if ((lengthDiscrepancy * lengthDiscrepancy) / curveScaleForToleranceSquared > pathSegmentLengthToleranceSquared && curve.splitDepth < curveStackDepthLimit) {
             CurveType leftCurve;
             CurveType rightCurve;
             curve.split(leftCurve, rightCurve);
@@ -263,4 +280,3 @@
 }
 
 }
-
--- a/modules/javafx.web/src/test/java/test/javafx/scene/web/LoadTest.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.web/src/test/java/test/javafx/scene/web/LoadTest.java	Fri Aug 12 13:41:28 2016 -0700
@@ -33,12 +33,14 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 import java.io.File;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import javafx.concurrent.Worker.State;
 import javafx.event.EventHandler;
 import javafx.scene.web.WebEngine;
+import netscape.javascript.JSObject;
 import org.junit.Test;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -273,27 +275,104 @@
         load("jar:" + new File(System.getProperties().get("WEB_ARCHIVE_JAR_TEST_DIR").toString()
                 + "/webArchiveJar.jar").toURI().toASCIIString() + "!/archive-root0.html");
         assertEquals("archive-root0.html failed to load src='archive-r0.js'",
-                executeScript("jsr0()").toString(), "loaded");
+                "loaded", executeScript("jsr0()").toString());
 
         assertEquals("archive-root0.html failed to load src='c/archive-c0.js'",
-                executeScript("jsc0()").toString(), "loaded");
+                "loaded", executeScript("jsc0()").toString());
 
         // archive-root1.html -- src ./archive-r0.js, ./c/archive-c0.js
         load("jar:" + new File(System.getProperties().get("WEB_ARCHIVE_JAR_TEST_DIR").toString()
                 + "/webArchiveJar.jar").toURI().toASCIIString() + "!/archive-root1.html");
         assertEquals("archive-root1.html failed to load src='./archive-r0.js'",
-                executeScript("jsr0()").toString(), "loaded");
+                "loaded", executeScript("jsr0()").toString());
 
         assertEquals("archive-root1.html failed to load src='./c/archive-c0.js'",
-                executeScript("jsc0()").toString(), "loaded");
+                "loaded", executeScript("jsc0()").toString());
 
         // archive-root2.html -- src ./c/../archive-r0.js, ./c/./././archive-c0.js
         load("jar:" + new File(System.getProperties().get("WEB_ARCHIVE_JAR_TEST_DIR").toString()
                 + "/webArchiveJar.jar").toURI().toASCIIString() + "!/archive-root2.html");
         assertEquals("archive-root2.html failed to load src='./c/../archive-r0.js'",
-                executeScript("jsr0()").toString(), "loaded");
+                "loaded", executeScript("jsr0()").toString());
 
         assertEquals("archive-root2.html failed to load src='./c/./././archive-c0.js'",
-                executeScript("jsc0()").toString(), "loaded");
+                "loaded", executeScript("jsc0()").toString());
+    }
+
+    /**
+     * 8153681 html "img" tag event listener
+     */
+    public final class ImageEvent {
+        public void onLoad() {
+            ++loaded;
+        }
+
+        public void onError() {
+            ++failed;
+        }
+
+        int loaded;
+        int failed;
+    }
+
+    /**
+     * @test
+     * @bug 8153681
+     * summary testing jrt url scheme support in WebView
+     */
+    @Test(timeout = 30000) public void loadJrtResource() throws Exception {
+        assumeTrue(isJigsawMode());
+
+        final String[] jrtResources = {
+                "jrt:/javafx.web/javafx/scene/web/AlignLeft_16x16_JFX.png",
+                "jrt:/javafx.web/./javafx/scene/web/Strikethrough_16x16_JFX.png",
+                "jrt:/javafx.web/./javafx/scene/../../javafx/scene/web/FontColor_16x16_JFX.png",
+                "jrt:/javafx.web/./javafx/./scene/./web/./DrawHorizontalLine_16x16_JFX.png",
+                "jrt:/javafx.web/javafx/scene/web/../../../javafx/scene/web/OrderedListNumbers_16x16_JFX-rtl.png"
+        };
+
+        // Load single resource and check for image is being rendered
+        // Check the natural width of rendered image
+        load(jrtResources[0]);
+        assertEquals("Failed to load " + jrtResources[0],
+                1, executeScript("document.getElementsByTagName('img').length"));
+
+        assertEquals("Failed to Render " + jrtResources[0],
+                16, executeScript("document.getElementsByTagName('img')[0].naturalWidth"));
+
+        // LoadContent with multiple jrt resource which needs to
+        // resolve path navigation i.e ./ or ../ in native url handler
+        final ImageEvent imageEvent = new ImageEvent();
+
+        // Wait till contents are loaded (SUCCEEDED)
+        final CountDownLatch latch = new CountDownLatch(1);
+        submit(() -> {
+            WebEngine webEngine = new WebEngine();
+            webEngine.getLoadWorker().stateProperty().addListener(((observable, oldValue, newValue) -> {
+                if (newValue == SUCCEEDED) {
+                    final String msg = String.format(
+                            "Failed to load : %d / %d resources",
+                            imageEvent.failed, jrtResources.length);
+                    assertTrue(msg, imageEvent.loaded == jrtResources.length);
+                    latch.countDown();
+                }
+            }));
+
+            StringBuffer jrtContent = new StringBuffer();
+            for (int i = 0; i < jrtResources.length; ++i) {
+                jrtContent.append("<img src=" +  jrtResources[i] +
+                        " onload='imageStatus.onLoad()'" +
+                        " onerror='imageStatus.onError()'/>");
+            }
+            final JSObject window = (JSObject) webEngine.executeScript("window");
+            window.setMember("imageStatus", imageEvent );
+            webEngine.loadContent(jrtContent.toString());
+        });
+
+        try {
+            latch.await();
+        } catch (InterruptedException ex) {
+            throw new AssertionError(ex);
+        }
     }
 }
--- a/modules/javafx.web/src/test/java/test/javafx/scene/web/MiscellaneousTest.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.web/src/test/java/test/javafx/scene/web/MiscellaneousTest.java	Fri Aug 12 13:41:28 2016 -0700
@@ -29,16 +29,20 @@
 import static java.lang.String.format;
 import java.net.HttpURLConnection;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Random;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
 import javafx.application.Platform;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.concurrent.Worker.State;
 import javafx.scene.web.WebEngine;
 import javafx.scene.web.WebView;
+import netscape.javascript.JSObject;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import org.junit.Test;
 import org.w3c.dom.Document;
@@ -144,6 +148,110 @@
            obj.resultObject.toString();
      }
 
+    // JDK-8162715
+    public class TimerCallback {
+        private static final int INTERVAL_COUNT = 20;
+        private final CountDownLatch latch = new CountDownLatch(INTERVAL_COUNT);
+        private class Stat {
+            private long firedTime;
+            private long createdTime;
+            private long interval;
+        }
+        private Stat[] stats = new Stat[INTERVAL_COUNT];
+
+        public void call(long createdTime, long interval, int index) {
+            Stat stat = new Stat();
+            stat.firedTime = System.currentTimeMillis();
+            stat.createdTime = createdTime;
+            stat.interval = interval;
+            stats[index] = stat;
+            latch.countDown();
+        }
+    }
+
+    @Test(timeout = 30000) public void testDOMTimer() {
+        final TimerCallback timer = new TimerCallback();
+        final WebEngine webEngine = createWebEngine();
+        submit(() -> {
+            final JSObject window = (JSObject) webEngine.executeScript("window");
+            assertNotNull(window);
+            window.setMember("timer", timer);
+            // Try various intervals
+            for (int i = 0; i < timer.INTERVAL_COUNT; i++) {
+                int timeout = i * (1000 / timer.INTERVAL_COUNT);
+                webEngine.executeScript("window.setTimeout("
+                                      + "timer.call.bind(timer, Date.now(),"
+                                      // pass 'i' to call to test time
+                                      + timeout +"," + i + "),"
+                                      // set 'i' as a timeout interval
+                                      + timeout + ")");
+            }
+
+        });
+
+        try {
+            timer.latch.await();
+        } catch (InterruptedException e) {
+            throw new AssertionError(e);
+        }
+        for (TimerCallback.Stat stat : timer.stats) {
+            assertNotNull(stat);
+            final String msg = String.format(
+                    "expected delta:%d, actual delta:%d",
+                    stat.interval,
+                    stat.firedTime - stat.createdTime);
+            // Timer should not fire too early. Added 20 ms offset to compensate
+            // the floating point approximation issues while dealing with timer.
+            assertTrue(msg,
+                    ((stat.firedTime + 20) - stat.createdTime) >= stat.interval);
+            // Timer should not be too late. Since it is not a real time system,
+            // we can't expect the timer to be fire at exactly on the requested
+            // time, give a 1000 ms extra time.
+            assertTrue(msg,
+                    (stat.firedTime - stat.createdTime) <= (stat.interval + 1000));
+        }
+    }
+
+    /**
+     * @test
+     * @bug 8163582
+     * summary svg.path.getTotalLength
+     * Load a simple SVG, Replace its path and get its path's totalLength using pat.getTotalLength
+     */
+    @Test(timeout = 30000) public void testSvgGetTotalLength() throws Exception {
+        final String svgStub = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'>" +
+                " <path id='pathId' d='M150 0 L75 200 L225 200 Z' /> <svg>";
+
+        // <Path, [Expected, Error Tolerance]>
+        final HashMap<String, Double[]> svgPaths = new HashMap<>();
+        svgPaths.put("'M 0 0 L 100 0 L 100 100 L 0 100 Z'",
+                new Double[] {400.0, 0.000001});
+        svgPaths.put("'M 0 0 l 100 0 l 0 100 l -100 0 Z'",
+                new Double[] {400.0, 0.000001});
+        svgPaths.put("'M 0 0 t 0 100'",
+                new Double[] {100.0, 0.1});
+        svgPaths.put("'M 0 0 Q 55 50 100 100'",
+                new Double[] {141.4803314, 0.000001});
+        svgPaths.put("'M 778.4191616766467 375.19086364081954 C 781.239563 " +
+                        "375.1908569 786.8525244750526 346.60170830052556 786.8802395209582 346.87991373394766'",
+                new Double[] {29.86020, 0.0001});
+        svgPaths.put("'M 0 0 C 0.00001 0.00001 0.00002 0.00001 0.00003 0'",
+                new Double[] {0.0000344338, 0.000000001});
+
+        loadContent(svgStub);
+
+        svgPaths.forEach((pathData, expected) -> {
+            executeScript("document.getElementById('pathId').setAttribute('d' , " + pathData + ");");
+            // Get svg path's total length
+            Double totalLength = ((Number) executeScript("document.getElementById('pathId').getTotalLength();")).doubleValue();
+            final String msg = String.format(
+                    "svg.path.getTotalLength() for %s, expected : %f, actual : %f",
+                    pathData, expected[0], totalLength);
+            assertEquals(msg,
+                    expected[0], totalLength, expected[1]);
+        });
+    }
+
     private WebEngine createWebEngine() {
         return submit(() -> new WebEngine());
     }
--- a/modules/javafx.web/src/test/java/test/javafx/scene/web/TestBase.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/javafx.web/src/test/java/test/javafx/scene/web/TestBase.java	Fri Aug 12 13:41:28 2016 -0700
@@ -288,4 +288,16 @@
     public void waitLoadFinished() {
         wait(LOCK, getLoadTimeOut());
     }
+
+    /**
+     * Check for Jigsaw Mode
+     */
+    public boolean isJigsawMode() {
+        Class clazz = null;
+        try {
+            clazz = Class.forName("java.lang.reflect.Module", false, TestBase.class.getClassLoader());
+        } catch (Exception e) { }
+
+        return clazz != null;
+    }
 }
--- a/modules/jdk.packager/src/main/java/com/oracle/tools/packager/StandardBundlerParam.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/com/oracle/tools/packager/StandardBundlerParam.java	Fri Aug 12 13:41:28 2016 -0700
@@ -96,6 +96,25 @@
                     StandardBundlerParam::createAppResourcesListFromString
             );
 
+    @SuppressWarnings("unchecked")
+    public static final StandardBundlerParam<String> SOURCE_DIR =
+            new StandardBundlerParam<>(
+                    I18N.getString("param.source-dir.name"),
+                    I18N.getString("param.source-dir.description"),
+                    "srcdir",
+                    String.class,
+                    p -> null,
+                    (s, p) -> {
+                        String value = String.valueOf(s);
+                        if (value.charAt(value.length() - 1) == File.separatorChar) {
+                            return value.substring(0, value.length() - 1);
+                        }
+                        else {
+                            return value;
+                        }
+                    }
+            );
+
     private static List<RelativeFileSet> createAppResourcesListFromString(String s, Map<String, ? super Object> objectObjectMap) {
         List<RelativeFileSet> result = new ArrayList<>();
         for (String path : s.split("[:;]")) {
@@ -239,7 +258,7 @@
                             }
                             else {
                                 List<Path> modulePath = JLinkBundlerHelper.MODULE_PATH.fetchFrom(p);
-                                Path modularJarPath = JLinkBundlerHelper.findModulePath(modulePath, s);
+                                Path modularJarPath = JLinkBundlerHelper.findPathOfModule(modulePath, s);
 
                                 if (modularJarPath != null && Files.exists(modularJarPath)) {
                                     return new RelativeFileSet(appResourcesRoot, new LinkedHashSet<>(Collections.singletonList(modularJarPath.toFile())));
--- a/modules/jdk.packager/src/main/java/com/sun/javafx/tools/ant/Application.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/com/sun/javafx/tools/ant/Application.java	Fri Aug 12 13:41:28 2016 -0700
@@ -31,7 +31,6 @@
 import java.util.Properties;
 import com.sun.javafx.tools.packager.HtmlParam;
 import com.sun.javafx.tools.packager.Param;
-//import java.nio.file.Path;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.types.DataType;
 import org.apache.tools.ant.types.Reference;
--- a/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/DeployParams.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/DeployParams.java	Fri Aug 12 13:41:28 2016 -0700
@@ -84,7 +84,7 @@
     String modulePath = null;
     String module = null;
     String debugPort = null;
-    File srcdir;
+    String srcdir;
 
     int width;
     int height;
@@ -277,7 +277,7 @@
         this.module = value;
     }
 
-    public void setDebugPort(String value) {
+    public void setDebug(String value) {
         this.debugPort = value;
     }
 
@@ -494,11 +494,14 @@
         if (outfile == null) {
             throw new PackagerException("ERR_MissingArgument", "-outfile");
         }
-        if (resources.isEmpty()) {
-            throw new PackagerException("ERR_MissingAppResources");
-        }
-        if (applicationClass == null && module == null) { //TODO better error here for mainmodule
-            throw new PackagerException("ERR_MissingArgument", "-appclass");
+
+        if (module == null) {
+            if (resources.isEmpty()) {
+                throw new PackagerException("ERR_MissingAppResources");
+            }
+            if (applicationClass == null) {
+                throw new PackagerException("ERR_MissingArgument", "-appclass");
+            }
         }
     }
 
@@ -716,7 +719,7 @@
         }
 
         if (debugPort != null && !debugPort.isEmpty()) {
-            bundleParams.setDebugPort(debugPort);
+            bundleParams.setDebug(debugPort);
         }
 
         if (detectmods != null) {
--- a/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/Main.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/Main.java	Fri Aug 12 13:41:28 2016 -0700
@@ -66,15 +66,27 @@
     private static boolean makeAll = false;
 
     private static void addResources(CommonParams commonParams,
-                                     File baseDir, String s) {
+                                     String baseDir, String s) {
         if (s == null || "".equals(s)) {
             return;
         }
 
-        String[] pathArray = s.split(File.pathSeparator);
+        String ls = ".";
+
+        if (s != null) {
+            ls = s;
+        }
+
+        String[] pathArray = ls.split(File.pathSeparator);
+
+        File lbaseDir = null;
+
+        if (baseDir != null) {
+            lbaseDir = new File(baseDir);
+        }
 
         for (final String path: pathArray) {
-            commonParams.addResource(baseDir, path);
+            commonParams.addResource(lbaseDir, path);
         }
     }
 
@@ -174,11 +186,11 @@
             CreateBSSParams createBssParams = new CreateBSSParams();
             SignJarParams signJarParams = new SignJarParams();
             MakeAllParams makeAllParams = new MakeAllParams();
+            String srcdir = null;
+            String srcfiles = null;
 
-            File srcdir = null;
             try {
                 if (args[0].equalsIgnoreCase("-createjar")) {
-                    boolean srcfilesSet = false;
                     for (int i = 1; i < args.length; i++) {
                         String arg = args[i];
                         if (arg.equalsIgnoreCase("-appclass")) {
@@ -203,11 +215,10 @@
                             createJarParams.setOutdir(new File(nextArg(args, i++)));
                         } else if (arg.equalsIgnoreCase("-outfile")) {
                             createJarParams.setOutfile(nextArg(args, i++));
-                        } else if (arg.equalsIgnoreCase("-srcdir")) {
-                            srcdir = new File(nextArg(args, i++));
+                        } else if (arg.equalsIgnoreCase("-" + StandardBundlerParam.SOURCE_DIR.getID())) {
+                            srcdir = nextArg(args, i++);
                         } else if (arg.equalsIgnoreCase("-srcfiles")) {
-                            addResources(createJarParams, srcdir, nextArg(args, i++));
-                            srcfilesSet = true;
+                            srcfiles = nextArg(args, i++);
                         } else if (arg.equalsIgnoreCase("-argument")) {
                             addArgument(createJarParams, nextArg(args, i++));
                         }  else if (arg.equalsIgnoreCase("-paramFile")) {
@@ -216,20 +227,10 @@
                             throw new PackagerException("ERR_UnknownArgument", arg);
                         }
                     }
-                    if (srcdir != null && !srcdir.isDirectory()) {
-                        throw new PackagerException("ERR_InvalidDirectory", srcdir.getAbsolutePath());
-                    }
-                    if (!srcfilesSet) {
-                        //using "." as default dir is confusing. Require explicit list of inputs
-                        if (srcdir == null) {
-                            throw new PackagerException("ERR_MissingArgument", "-srcfiles (-srcdir)");
-                        }
-                        addResources(createJarParams, srcdir, ".");
-                    }
+
+                    addResources(createJarParams, srcdir, srcfiles);
                     packageAsJar = true;
-
                 } else if (args[0].equalsIgnoreCase("-deploy")) {
-                    boolean srcfilesSet = false;
                     File templateInFile = null;
                     File templateOutFile = null;
                     deployParams.setBundleType(BundleType.JNLP);
@@ -334,12 +335,11 @@
                             deployParams.setOutdir(new File(nextArg(args, i++)));
                         } else if (arg.equalsIgnoreCase("-outfile")) {
                             deployParams.setOutfile(nextArg(args, i++));
-                        } else if (arg.equalsIgnoreCase("-srcdir")) {
-                            srcdir = new File(nextArg(args, i++));
+                        } else if (arg.equalsIgnoreCase("-" + StandardBundlerParam.SOURCE_DIR.getID())) {
+                            srcdir = nextArg(args, i++);
                             deployParams.srcdir = srcdir;
                         } else if (arg.equalsIgnoreCase("-srcfiles")) {
-                            addResources(deployParams, srcdir, nextArg(args, i++));
-                            srcfilesSet = true;
+                            srcfiles = nextArg(args, i++);
                         } else if (arg.equalsIgnoreCase("-argument")) {
                             addArgument(deployParams, nextArg(args, i++));
                         } else if (arg.equalsIgnoreCase("-nosign")) {
@@ -362,16 +362,12 @@
                             deployParams.modulePath = nextArg(args, i++);
                         } else if (arg.equals(MODULE_PATH + "=")) {
                             deployParams.modulePath = arg.replace(MODULE_PATH + "=", "");
-                        } else if (arg.equals(P + "=")) {
-                            deployParams.modulePath = arg.replace(P + "=", "");
                         } else if (arg.equals(MODULE) || arg.equals(M)) {
                             deployParams.setModule(nextArg(args, i++));
                         } else if (arg.equals(MODULE + "=")) {
                             deployParams.setModule(arg.replace(MODULE + "=", ""));
-                        } else if (arg.equals(M + "=")) {
-                            deployParams.setModule(arg.replace(M + "=", ""));
-                        } else if (arg.equals("-Xdebug")) {
-                            deployParams.setDebugPort(nextArg(args, i++));
+                        } else if (arg.startsWith(J_XDEBUG)) {
+                            deployParams.setDebug(arg.replace(J_XDEBUG, ""));
                         } else {
                             throw new PackagerException("ERR_UnknownArgument", arg);
                         }
@@ -388,11 +384,8 @@
                         genPackages = true;
                     }
 
-                    if (!srcfilesSet) {
-                        addResources(deployParams, srcdir, ".");
-                    }
+                    addResources(deployParams, srcdir, srcfiles);
                 } else if (args[0].equalsIgnoreCase("-createbss")) {
-                    boolean srcfilesSet = false;
                     for (int i = 1; i < args.length; i++) {
                         String arg = args[i];
                         if (arg.equalsIgnoreCase("-verbose") || arg.equalsIgnoreCase("-v")) {
@@ -401,28 +394,17 @@
                         } else if (arg.equalsIgnoreCase("-outdir")) {
                             createBssParams.setOutdir(new File(nextArg(args, i++)));
                         } else if (arg.equalsIgnoreCase("-srcdir")) {
-                            srcdir = new File(nextArg(args, i++));
+                            srcdir = nextArg(args, i++);
                         } else if (arg.equalsIgnoreCase("-srcfiles")) {
-                            addResources(createBssParams, srcdir, nextArg(args, i++));
-                            srcfilesSet = true;
+                            srcfiles = nextArg(args, i++);
                         } else {
                             throw new PackagerException("ERR_UnknownArgument", arg);
                         }
                     }
-                    if (srcdir != null && !srcdir.isDirectory()) {
-                        throw new PackagerException("ERR_InvalidDirectory", srcdir.getAbsolutePath());
-                    }
-                    if (!srcfilesSet) {
-                        //using "." as default dir is confusing. Require explicit list of inputs
-                        if (srcdir == null) {
-                            throw new PackagerException("ERR_MissingArgument", "-srcfiles (-srcdir)");
-                        }
-                        addResources(createBssParams, srcdir, ".");
-                    }
+
+                    addResources(createBssParams, srcdir, srcfiles);
                     css2Bin = true;
-
                 } else if (args[0].equalsIgnoreCase("-signJar")) {
-                    boolean srcfilesSet = false;
                     for (int i = 1; i < args.length; i++) {
                         String arg = args[i];
                         if (arg.equalsIgnoreCase("-keyStore")) {
@@ -441,24 +423,15 @@
                         } else if (arg.equalsIgnoreCase("-outdir")) {
                             signJarParams.setOutdir(new File(nextArg(args, i++)));
                         } else if (arg.equalsIgnoreCase("-srcdir")) {
-                            srcdir = new File(nextArg(args, i++));
+                            srcdir = nextArg(args, i++);
                         } else if (arg.equalsIgnoreCase("-srcfiles")) {
-                            addResources(signJarParams, srcdir, nextArg(args, i++));
-                            srcfilesSet = true;
+                            srcfiles = nextArg(args, i++);
                         } else {
                             throw new PackagerException("ERR_UnknownArgument", arg);
                         }
                     }
-                    if (srcdir != null && !srcdir.isDirectory()) {
-                        throw new PackagerException("ERR_InvalidDirectory", srcdir.getAbsolutePath());
-                    }
-                    if (!srcfilesSet) {
-                        //using "." as default dir is confusing. Require explicit list of inputs
-                        if (srcdir == null) {
-                            throw new PackagerException("ERR_MissingArgument", "-srcfiles (-srcdir)");
-                        }
-                        addResources(signJarParams, srcdir, ".");
-                    }
+
+                    addResources(signJarParams, srcdir, srcfiles);
                     signJar = true;
                 } else if (args[0].equalsIgnoreCase("-makeall")) {
                     for (int i = 1; i < args.length; i++) {
@@ -553,6 +526,7 @@
             }
         }
     }
+    private static final String J_XDEBUG = JLinkBundlerHelper.DEBUG.getID() + ":";
 
     private static final String MODULE = "--" + JLinkBundlerHelper.MODULE.getID();
     private static final String M = "-m";
--- a/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/bundlers/BundleParams.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/com/sun/javafx/tools/packager/bundlers/BundleParams.java	Fri Aug 12 13:41:28 2016 -0700
@@ -186,8 +186,8 @@
         putUnlessNull(JLinkBundlerHelper.DETECT_MODULES.getID(), value);
     }
 
-    public void setSrcDir(File value) {
-        //putUnlessNull(JDK_MODULE_PATH.getID(), appModulePath); //TODO remove?
+    public void setSrcDir(String value) {
+        putUnlessNull(SOURCE_DIR.getID(), value);
     }
 
     public void setModulePath(String value) {
@@ -198,8 +198,8 @@
         putUnlessNull(JLinkBundlerHelper.MODULE.getID(), value);
     }
 
-    public void setDebugPort(String value) {
-        putUnlessNull(JLinkBundlerHelper.DEBUG_PORT.getID(), value);
+    public void setDebug(String value) {
+        putUnlessNull(JLinkBundlerHelper.DEBUG.getID(), value);
     }
 
     public String getApplicationID() {
@@ -501,15 +501,6 @@
     private String mainJarClassPath = null;
     private boolean useFXPackaging = true;
 
-    //are we packaging JavaFX application or regular executable Jar?
-    public boolean useJavaFXPackaging() {
-        if (mainJar == null) {
-            //this will find out answer
-            getMainApplicationJar();
-        }
-        return useFXPackaging;
-    }
-
     //For regular executable Jars we need to take care of classpath
     //For JavaFX executable jars we do not need to pay attention to ClassPath entry in manifest
     public String getAppClassPath() {
--- a/modules/jdk.packager/src/main/java/jdk/packager/builders/AbstractAppImageBuilder.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/jdk/packager/builders/AbstractAppImageBuilder.java	Fri Aug 12 13:41:28 2016 -0700
@@ -208,9 +208,15 @@
             }
         }
 
+        String version = JLinkBundlerHelper.getJDKVersion(params);
+
+        if (!version.isEmpty()) {
+            out.println("app.java.version=" + version);
+        }
+
         out.println("packager.java.version=" + System.getProperty("java.version"));
 
-        Integer port = JLinkBundlerHelper.DEBUG_PORT.fetchFrom(params);
+        Integer port = JLinkBundlerHelper.DEBUG.fetchFrom(params);
 
         if (port != null) {
             out.println("app.debug=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:" + port);
--- a/modules/jdk.packager/src/main/java/jdk/packager/internal/JLinkBundlerHelper.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/jdk/packager/internal/JLinkBundlerHelper.java	Fri Aug 12 13:41:28 2016 -0700
@@ -174,11 +174,11 @@
                     (s, p) -> s);
 
     @SuppressWarnings("unchecked")
-    public static final BundlerParamInfo<Integer> DEBUG_PORT =
+    public static final BundlerParamInfo<Integer> DEBUG =
             new StandardBundlerParam<>(
                     I18N.getString("param.main.module.name"),
                     I18N.getString("param.main.module.description"),
-                    "-Xdebug",
+                    "-J-Xdebug",
                     Integer.class,
                     p -> null,
                     (s, p) -> {
@@ -215,10 +215,17 @@
 
     public static File getMainJar(Map<String, ? super Object> params) {
         File result = null;
+        String srcdir = StandardBundlerParam.SOURCE_DIR.fetchFrom(params);
         RelativeFileSet fileset = MAIN_JAR.fetchFrom(params);
 
         if (fileset != null) {
-            result = new File(fileset.getIncludedFiles().iterator().next());
+            String filename = fileset.getIncludedFiles().iterator().next();
+
+            if (srcdir != null) {
+                filename = srcdir + File.separator + filename;
+            }
+
+            result = new File(filename);
         }
 
         return result;
@@ -264,6 +271,21 @@
         return result;
     }
 
+    public static String getJDKVersion(Map<String, ? super Object> params) {
+        String result = "";
+        List<Path> modulePath = MODULE_PATH.fetchFrom(params);
+        Path jdkModulePath = setupDefaultModulePathIfNecessary(modulePath);
+        Path javaBasePath = jdkModulePath.resolve("java.base.jmod");
+
+        if (javaBasePath != null && javaBasePath.toFile().exists()) {
+            result = RedistributableModules.getModuleVersion(javaBasePath.toFile(),
+                        modulePath, ADD_MODULES.fetchFrom(params),
+                        LIMIT_MODULES.fetchFrom(params));
+        }
+
+        return result;
+    }
+
     public static void execute(Map<String, ? super Object> params, AbstractAppImageBuilder imageBuilder) throws IOException, Exception {
         List<Path> modulePath = MODULE_PATH.fetchFrom(params);
         Set<String> addModules = ADD_MODULES.fetchFrom(params);
@@ -335,7 +357,7 @@
     }
 
     // Returns the path to the JDK modules in the user defined module path.
-    public static Path findModulePath(List<Path> modulePath, String moduleName) {
+    public static Path findPathOfModule(List<Path> modulePath, String moduleName) {
         Path result = null;
 
         for (Path path : modulePath) {
@@ -352,7 +374,7 @@
 
     private static Path setupDefaultModulePathIfNecessary(List<Path> modulePath) {
         Path result = null;
-        Path userDefinedJdkModulePath = findModulePath(modulePath, "java.base.jmod");
+        Path userDefinedJdkModulePath = findPathOfModule(modulePath, "java.base.jmod");
 
         //TODO Fix JDK-8158977
 
@@ -379,10 +401,12 @@
     private static Set<String> getResourceFileJarList(Map<String, ? super Object> params, Module.JarType Query) {
         Set<String> files = new LinkedHashSet();
 
+        String srcdir = StandardBundlerParam.SOURCE_DIR.fetchFrom(params);
+
         for (RelativeFileSet appResources : StandardBundlerParam.APP_RESOURCES_LIST.fetchFrom(params)) {
             for (String resource : appResources.getIncludedFiles()) {
                 if (resource.endsWith(".jar")) {
-                    String filename = appResources.getBaseDirectory() + File.separator + resource;
+                    String filename = srcdir + File.separator + resource;
 
                     switch (Query) {
                         case All: {
@@ -413,57 +437,11 @@
         return files;
     }
 
-    /**
-     * This helper class
-     */
     private static class ModuleHelper {
-        private static final Set<String> REDISTRIBUTBLE_MODULES = Set.of(
-            "java.base",
-            "java.compiler",
-            "java.datatransfer",
-            "java.desktop",
-            "java.httpclient",
-            "java.instrument",
-            "java.logging",
-            "java.management",
-            "java.naming",
-            "java.prefs",
-            "java.rmi",
-            "java.scripting",
-            "java.security.jgss",
-            "java.security.sasl",
-            "java.sql",
-            "java.sql.rowset",
-            "java.xml",
-            "java.xml.crypto",
-            "javafx.base",
-            "javafx.controls",
-            "javafx.fxml",
-            "javafx.graphics",
-            "javafx.media",
-            "javafx.swing",
-            "javafx.web",
-            "jdk.accessibility",
-            "jdk.dynalink",
-            "jdk.httpserver",
-            "jdk.jfr",
-            "jdk.jsobject",
-            "jdk.management",
-            "jdk.management.cmm",
-            "jdk.management.jfr",
-            "jdk.management.resource",
-            "jdk.net",
-            "jdk.scripting.nashorn",
-            "jdk.sctp",
-            "jdk.security.auth",
-            "jdk.security.jgss",
-            "jdk.unsupported",
-            "jdk.vm.cds",
-            "jdk.xml.dom");
-
-        // The token for "all modules on the module path"
+        // The token for "all modules on the module path".
         private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
 
+        // The token for "all redistributable runtime modules".
         public static final String ALL_RUNTIME = "ALL-RUNTIME";
 
         private final Set<String> modules = new HashSet<>();
@@ -487,7 +465,12 @@
                         iterator.remove();
 
                         if (!found) {
-                            modules.addAll(REDISTRIBUTBLE_MODULES);
+                            Set<String> modules = RedistributableModules.getRedistributableModules(paths, roots, limitMods);
+
+                            if (modules != null) {
+                                this.modules.addAll(modules);
+                            }
+
                             found = true;
                         }
                         break;
--- a/modules/jdk.packager/src/main/java/jdk/packager/internal/Module.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/jdk/packager/internal/Module.java	Fri Aug 12 13:41:28 2016 -0700
@@ -22,6 +22,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package jdk.packager.internal;
 
 import java.io.File;
@@ -61,12 +62,6 @@
         return moduleType;
     }
 
-    public String getVersion() {
-        String result = "";
-        //TODO implement JDK-8149975
-        return result;
-    }
-
     private static ModuleType getModuleType(File AFile) {
         ModuleType result = ModuleType.Unknown;
         String filename = AFile.getAbsolutePath();
--- a/modules/jdk.packager/src/main/java/jdk/packager/internal/ModuleManager.java	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/java/jdk/packager/internal/ModuleManager.java	Fri Aug 12 13:41:28 2016 -0700
@@ -22,6 +22,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package jdk.packager.internal;
 
 import java.io.File;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/jdk.packager/src/main/java/jdk/packager/internal/RedistributableModules.java	Fri Aug 12 13:41:28 2016 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015, 2016, 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 jdk.packager.internal;
+
+
+import com.oracle.tools.packager.IOUtils;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Optional;
+
+import jdk.tools.jlink.internal.packager.AppRuntimeImageBuilder;
+
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.lang.module.ModuleReader;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+public final class RedistributableModules {
+    private static final String JDK_PACKAGER_MODULE = "jdk.packager";
+    private static final String REDISTRIBUTABLE_MODULES_FILENAME = "jdk/packager/internal/resources/tools/redistributable-files/redistributable.list";
+
+    private RedistributableModules() {}
+
+    public static Set<String> getRedistributableModules(List<Path> modulePath, Set<String> addModules, Set<String> limitModules) {
+        Set<String> result = null;
+        ModuleFinder finder = AppRuntimeImageBuilder.moduleFinder(modulePath, addModules, limitModules);
+        Optional<ModuleReference> mref = finder.find(JDK_PACKAGER_MODULE);
+
+        if (mref.isPresent()) {
+            ModuleReader reader = null;
+
+            try {
+                reader = mref.get().open();
+            } catch (IOException ex) {
+            }
+
+            if (reader != null) {
+                Optional<InputStream> stream = null;
+
+                try {
+                    stream = reader.open(REDISTRIBUTABLE_MODULES_FILENAME);
+                } catch (IOException ex) {
+                }
+
+                if (stream != null) {
+                    if (stream.isPresent()) {
+                        BufferedReader br = null;
+
+                        try {
+                            br = new BufferedReader(new InputStreamReader(stream.get(), "UTF-8"));
+                        } catch (UnsupportedEncodingException ex) {
+                        }
+
+                        if (br != null) {
+                            result = new LinkedHashSet();
+                            String line;
+
+                            try {
+                                while ((line = br.readLine()) != null) {
+                                    result.add(line);
+                                }
+                            } catch (IOException ex) {
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public static String getModuleVersion(File moduleFile, List<Path> modulePath, Set<String> addModules, Set<String> limitModules) {
+        String result = "";
+
+        Module module = new Module(moduleFile);
+        ModuleFinder finder = AppRuntimeImageBuilder.moduleFinder(modulePath, addModules, limitModules);
+        Optional<ModuleReference> mref = finder.find(module.getModuleName());
+
+        if (mref.isPresent()) {
+            ModuleDescriptor descriptor = mref.get().descriptor();
+
+            if (descriptor != null) {
+                Optional<ModuleDescriptor.Version> version = descriptor.version();
+
+                if (version.isPresent()) {
+                    result = version.get().toString();
+                }
+            }
+        }
+
+        return result;
+    }
+}
--- a/modules/jdk.packager/src/main/native/library/common/Package.cpp	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/native/library/common/Package.cpp	Fri Aug 12 13:41:28 2016 -0700
@@ -196,7 +196,6 @@
         FBootFields->FArgs.push_back(debug);
     }
 
-
     MergeJVMDefaultsWithOverrides();
 }
 
--- a/modules/jdk.packager/src/main/resources/com/oracle/tools/packager/StandardBundlerParam.properties	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/resources/com/oracle/tools/packager/StandardBundlerParam.properties	Fri Aug 12 13:41:28 2016 -0700
@@ -148,6 +148,9 @@
 param.com-app-cds-root.name=AppCDS Root Classes
 param.com-app-cds-root.description=List of "root classes" for AppCDS to generate class sharing data from.  Default is the main class.
 
+param.source-dir.name=Source Directory
+param.source-dir.description=Path to the directory containing the files to be bundled.
+
 error.required-parameter={0} is a required parameter.
 error.no-main-class-with-main-jar=An application class was not specified nor was one found in the jar {0}
 error.no-main-class-with-main-jar.advice=Please specify a applicationClass or ensure that the jar {0} specifies one in the manifest.
--- a/modules/jdk.packager/src/main/resources/com/sun/javafx/tools/packager/Bundle.properties	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/resources/com/sun/javafx/tools/packager/Bundle.properties	Fri Aug 12 13:41:28 2016 -0700
@@ -220,5 +220,5 @@
 MSG_BundlerConfigExceptionNoAdvice=Bundler {0} skipped because of a configuration problem\: {1}
 MSG_BundlerRuntimeException=Bundler {0} failed because of {1}
 MSG_JarNoSelfCopy=Skip jar copy to itself\: {0}
-MSG_EnterKeystorePassword=Enter Passphrase for keystore: 
-MSG_EnterKeyPassword=Enter key password for %s: 
+MSG_EnterKeystorePassword=Enter Passphrase for keystore:
+MSG_EnterKeyPassword=Enter key password for %s:
--- a/modules/jdk.packager/src/main/resources/jdk/packager/internal/JLinkBundlerHelper.properties	Thu Aug 11 11:48:13 2016 +0000
+++ b/modules/jdk.packager/src/main/resources/jdk/packager/internal/JLinkBundlerHelper.properties	Fri Aug 12 13:41:28 2016 -0700
@@ -30,6 +30,6 @@
 warning.no.jdk.modules.found=Warning: No JDK Modules found.
 
 message.detected.modules="Automatically adding detected modules: %s."
-message.modules="Adding modules: %s to jimage."
+message.modules="Adding modules: %s to runtime image."
 
 using.experimental.feature="Using experimental feature: %s."
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/jdk.packager/src/tools/java/redistributable-files/RedistributableFiles.java	Fri Aug 12 13:41:28 2016 -0700
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.module.ModuleReference;
+import java.lang.module.ResolvedModule;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * This program gets a list of all the modules in the current boot layer,
+ * and saves that list (removing the excluded modules) and saving it to disk
+ * to be included in the jdk.packager.jmod for use by the Java Packager.
+ */
+public final class RedistributableFiles {
+    private static final String JAVA_SE = "java.se";
+
+    private static final String ADD_MODULES = "--add-modules";
+    private static final String MODULE_PATH = "--module-path";
+    private static final String EXCLUDE_MODULES = "--exclude-modules";
+    private static final String EXCLUDE_FILELIST = "--exclude-filelist";
+    private static final String OUT_FILE = "--out-file";
+
+    private RedistributableFiles() {}
+
+    static private Set<String> defaultPlatformModules() {
+        return Layer.boot()
+                    .modules()
+                    .stream()
+                    .map(Module::getName)
+                    .sorted()
+                    .collect(Collectors.toSet());
+    }
+
+    private static String nextArg(String args[], int i) {
+        return (i == args.length - 1) ? "" : args[i + 1];
+    }
+
+    private static Set<String> loadFromFile(String filename) {
+        Set<String> result = null;
+        BufferedReader br = null;
+
+        File file = new File(filename);
+
+        if (file.exists()) {
+            FileInputStream stream = null;
+
+            try {
+                stream = new FileInputStream(file);
+            } catch (FileNotFoundException ex) {
+            }
+
+            if (stream != null) {
+                try {
+                    br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
+                } catch (UnsupportedEncodingException ex) {
+                }
+
+                if (br != null) {
+                    result = new LinkedHashSet<>();
+                    String line;
+
+                    try {
+                        while ((line = br.readLine()) != null) {
+                            result.add(line);
+                        }
+                    } catch (IOException ex) {
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+    private static void saveToFile(String filename, List<String> modules) throws Exception {
+        PrintWriter writer = null;
+
+        try {
+            File file = new File(filename);
+            file.getParentFile().mkdirs();
+            writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(filename), "UTF-8"));
+
+            for (String s : modules) {
+                writer.println(s);
+            }
+
+            writer.flush();
+        } finally {
+            if (writer != null) {
+                writer.close();
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Set<String> addModules = null;
+        List<Path> modulePath = null;
+        Set<String> excludeModules = null;
+        String outfile = null;
+
+        for (int i = 0; i < args.length; i++) {
+            String arg = args[i];
+            String next = nextArg(args, i++);
+
+            switch (arg) {
+                case ADD_MODULES:
+                    System.out.println(ADD_MODULES + "=" + next);
+                    addModules = new LinkedHashSet<String>(Arrays.asList(next.split(",")));
+                    break;
+                case MODULE_PATH:
+                    System.out.println(MODULE_PATH + "=" + next);
+                    modulePath = Arrays.asList(next.split("[;:]")).stream()
+                                       .map(ss -> new File(ss).toPath())
+                                       .collect(Collectors.toList());
+                    break;
+                case EXCLUDE_MODULES:
+                    System.out.println(EXCLUDE_MODULES + "=" + next);
+                    excludeModules = new LinkedHashSet<String>(Arrays.asList(next.split(",")));
+                    saveToFile("ExcludedModules.list", new ArrayList<>(excludeModules));
+                    break;
+                case EXCLUDE_FILELIST:
+                    excludeModules = loadFromFile(next);
+                    break;
+                case OUT_FILE:
+                    System.out.println(OUT_FILE + "=" + next);
+                    outfile = next;
+                    break;
+            }
+        }
+
+        if (addModules == null) {
+            addModules = new LinkedHashSet<>();
+        }
+
+        if (modulePath != null && outfile != null) {
+            Set<String> results = defaultPlatformModules();
+            results.addAll(addModules);
+
+            if (excludeModules != null) {
+                for (String module : excludeModules) {
+                    results.remove(module);
+                }
+            }
+
+            List<String> list = new ArrayList<>(results);
+            Collections.sort(list);
+            saveToFile(outfile, list);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/jdk.packager/src/tools/java/redistributable-files/exclude_modules.list	Fri Aug 12 13:41:28 2016 -0700
@@ -0,0 +1,17 @@
+java.compact1
+java.compact2
+java.compact3
+java.se
+javafx.deploy
+jdk.deploy
+jdk.jlink
+jdk.javaws
+jdk.packager
+jdk.jdeps
+jdk.jartool
+jdk.internal.le
+jdk.internal.opt
+jdk.jshell
+jdk.deploy.controlpanel
+jdk.deploy.controlpanel.fx
+jdk.plugin
\ No newline at end of file