changeset 5975:ffae6092f803

Sync up SceneBuilder changes
author Yves Joan <yves.joan@oracle.com>
date Mon, 23 Dec 2013 13:59:52 +0100
parents 98b52a79d333
children 94331ac42150
files apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindow.fxml apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp.properties apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBar.fxml apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBarController.java apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBar.fxml apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBarController.java apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/preview/PreviewWindowController.java apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReport.css apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReport.fxml apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReportController.java apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonBuffer.java apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindow.fxml apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindowController.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorController.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorPlatform.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/i18n/SceneBuilderKit.properties apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/PasteJob.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/AbstractWrapInJob.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.css apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.fxml apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/WorkspaceController.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/gridpane/GridPaneMosaic.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/outline/AbstractOutline.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/outline/NodeOutline.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/gesture/mouse/SelectAndMoveGesture.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/css/CssContentMaker.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/hierarchy/AbstractHierarchyPanelController.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/InspectorPanelController.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/AutoSuggestEditor.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/StylesheetEditor.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/BoundsPopupEditor.fxml apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/KeyCombinationPopupEditor.fxml apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/KeyCombinationPopupEditor.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/library/LibraryPanelController.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/util/ContextMenuController.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMCollection.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMIntrinsic.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMObject.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMRefresher.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/TransientStateBackup.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/ChoiceBoxSampleData.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/ComboBoxSampleData.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/SampleDataGenerator.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/XYChartSampleData.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ChoiceBox.fxml apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ComboBox.fxml apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/LibraryFolderWatcher.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/UserLibrary.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/Metadata.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCharacterCombinationPropertyMetadata.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCodeCombinationPropertyMetadata.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCombinationPropertyMetadata.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/ClipboardDecoder.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/DesignHierarchyMask.java apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/util/Deprecation.java
diffstat 58 files changed, 3748 insertions(+), 884 deletions(-) [+]
line wrap: on
line diff
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindow.fxml	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindow.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -31,13 +31,14 @@
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
+
 <?import java.lang.*?>
 <?import java.net.*?>
 <?import javafx.scene.control.*?>
 <?import javafx.scene.layout.*?>
 <?scenebuilder-preview-i18n-resource i18n/SceneBuilderApp.properties?>
 
-<VBox id="DocumentWindow" alignment="CENTER" prefHeight="800.0" prefWidth="1200.0" spacing="0.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
+<VBox id="DocumentWindow" alignment="CENTER" prefHeight="800.0" prefWidth="1200.0" spacing="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
     <SplitPane fx:id="mainSplitPane" dividerPositions="0.656641604010025" focusTraversable="true" orientation="VERTICAL" prefHeight="200.0" prefWidth="160.0" VBox.vgrow="ALWAYS">
       <items>
@@ -49,14 +50,22 @@
                   <children>
                     <HBox id="HBox" alignment="CENTER" spacing="0.0" styleClass="panelHeader">
                       <children>
-                        <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="Library" HBox.hgrow="NEVER" />
+                        <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="%library" HBox.hgrow="NEVER" />
                         <StackPane fx:id="librarySearchPanelHost" maxHeight="-1.0" maxWidth="-1.0" minHeight="-1.0" minWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" style="" HBox.hgrow="ALWAYS" />
-                        <MenuButton fx:id="LibraryMenu" mnemonicParsing="false" styleClass="panelMenuButton" text="" HBox.hgrow="NEVER">
+                        <MenuButton fx:id="libraryMenuButton" mnemonicParsing="false" styleClass="panelMenuButton" text="" HBox.hgrow="NEVER">
                           <items>
-                            <CheckMenuItem mnemonicParsing="false" onAction="#onLibraryViewAsList" text="%library.panel.menu.view.list" fx:id="libraryViewAsList" />
-                            <CheckMenuItem mnemonicParsing="false" onAction="#onLibraryViewAsSections" selected="true" text="%library.panel.menu.view.sections" fx:id="libraryViewAsSections" />
+                            <CheckMenuItem fx:id="libraryViewAsList" mnemonicParsing="false" onAction="#onLibraryViewAsList" text="%library.panel.menu.view.list" />
+                            <CheckMenuItem fx:id="libraryViewAsSections" mnemonicParsing="false" onAction="#onLibraryViewAsSections" selected="true" text="%library.panel.menu.view.sections" />
                             <SeparatorMenuItem mnemonicParsing="false" />
                             <MenuItem mnemonicParsing="false" onAction="#onLibraryImportJarFxml" text="%library.panel.menu.import.jar.fxml" />
+                            <MenuItem fx:id="libraryImportSelection" mnemonicParsing="false" onAction="#onLibraryImportSelection" text="%library.panel.menu.import.selection" />
+                            <SeparatorMenuItem mnemonicParsing="false" />
+                            <Menu mnemonicParsing="false" text="%library.panel.menu.custom">
+                              <items>
+                                <MenuItem fx:id="libraryReveal" mnemonicParsing="false" onAction="#onLibraryRevealCustomFolder" text="Action 1" />
+                                <MenuItem fx:id="libraryReport" mnemonicParsing="false" onAction="#onLibraryShowJarAnalysisReport" text="%library.panel.menu.custom.report" />
+                              </items>
+                            </Menu>
                           </items>
                         </MenuButton>
                       </children>
@@ -68,29 +77,33 @@
                   <children>
                     <HBox id="HBox" alignment="CENTER" spacing="0.0" VBox.vgrow="NEVER">
                       <children>
-                        <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="Document" HBox.hgrow="NEVER" />
+                        <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="%document" HBox.hgrow="NEVER" />
                         <Pane maxWidth="1.7976931348623157E308" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="ALWAYS" />
-                        <MenuButton fx:id="HierarchyMenu" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" styleClass="panelMenuButton" text="">
+                        <MenuButton fx:id="" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" styleClass="panelMenuButton" text="">
                           <items>
-                            <RadioMenuItem mnemonicParsing="false" onAction="#onHierarchyShowInfo" selected="true" text="Show Info" fx:id="showInfoMenuItem">
-                              <toggleGroup>
-                                <ToggleGroup fx:id="hierarchyDisplayOptionTG" />
-                              </toggleGroup>
-                            </RadioMenuItem>
-                            <RadioMenuItem mnemonicParsing="false" onAction="#onHierarchyShowFxId" text="Show fx:id" toggleGroup="$hierarchyDisplayOptionTG" fx:id="showFxIdMenuItem" />
-                            <RadioMenuItem mnemonicParsing="false" onAction="#onHierarchyShowNodeId" text="Show Node Id" toggleGroup="$hierarchyDisplayOptionTG" fx:id="showNodeIdMenuItem" />
+                            <Menu mnemonicParsing="false" text="%hierarchy.displays">
+                              <items>
+                                <RadioMenuItem fx:id="showInfoMenuItem" mnemonicParsing="false" onAction="#onHierarchyShowInfo" selected="true" text="%hierarchy.show.info">
+                                  <toggleGroup>
+                                    <ToggleGroup fx:id="hierarchyDisplayOptionTG" />
+                                  </toggleGroup>
+                                </RadioMenuItem>
+                                <RadioMenuItem fx:id="showFxIdMenuItem" mnemonicParsing="false" onAction="#onHierarchyShowFxId" text="%hierarchy.show.fxid" toggleGroup="$hierarchyDisplayOptionTG" />
+                                <RadioMenuItem fx:id="showNodeIdMenuItem" mnemonicParsing="false" onAction="#onHierarchyShowNodeId" text="%hierarchy.show.nodeid" toggleGroup="$hierarchyDisplayOptionTG" />
+                              </items>
+                            </Menu>
                           </items>
                         </MenuButton>
                       </children>
                     </HBox>
                     <Accordion fx:id="documentAccordion" maxHeight="-1.0" VBox.vgrow="ALWAYS">
                       <panes>
-                        <TitledPane fx:id="Hierarchy" animated="true" text="Hierarchy">
+                        <TitledPane fx:id="Hierarchy" animated="true" text="%hierarchy">
                           <content>
                             <StackPane fx:id="hierarchyPanelHost" maxHeight="-1.0" style="-fx-padding: 0;" />
                           </content>
                         </TitledPane>
-                        <TitledPane fx:id="Info" animated="true" text="Controller">
+                        <TitledPane fx:id="Info" animated="true" text="%controller">
                           <content>
                             <StackPane fx:id="infoPanelHost" maxHeight="-1.0" />
                           </content>
@@ -111,24 +124,24 @@
               <children>
                 <HBox id="HBox" alignment="CENTER" spacing="0.0" VBox.vgrow="NEVER">
                   <children>
-                    <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="Inspector" HBox.hgrow="NEVER" />
+                    <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="%inspector" HBox.hgrow="NEVER" />
                     <StackPane fx:id="inspectorSearchPanelHost" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="ALWAYS" />
                     <MenuButton fx:id="InspectorMenu" contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" styleClass="panelMenuButton" text="" HBox.hgrow="NEVER">
                       <items>
-                        <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorShowAllAction" selected="true" text="Show All">
+                        <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorShowAllAction" selected="true" text="%inspector.show.all">
                           <toggleGroup>
                             <ToggleGroup fx:id="showTg" />
                           </toggleGroup>
                         </RadioMenuItem>
-                        <RadioMenuItem disable="false" mnemonicParsing="false" onAction="#onInspectorShowEditedAction" text="Show Edited" toggleGroup="$showTg" />
+                        <RadioMenuItem disable="false" mnemonicParsing="false" onAction="#onInspectorShowEditedAction" text="%inspector.show.edited" toggleGroup="$showTg" />
                         <SeparatorMenuItem mnemonicParsing="false" />
-                        <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewSectionsAction" selected="true" text="View Sections">
+                        <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewSectionsAction" selected="true" text="%inspector.view.sections">
                           <toggleGroup>
                             <ToggleGroup fx:id="viewTg" />
                           </toggleGroup>
                         </RadioMenuItem>
-                        <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewByPropertyNameAction" text="View by property name" toggleGroup="$viewTg" />
-                        <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewByPropertyTypeAction" text="View by property type" toggleGroup="$viewTg" />
+                        <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewByPropertyNameAction" text="%inspector.by.property.name" toggleGroup="$viewTg" />
+                        <RadioMenuItem mnemonicParsing="false" onAction="#onInspectorViewByPropertyTypeAction" text="%inspector.by.property.type" toggleGroup="$viewTg" />
                       </items>
                     </MenuButton>
                   </children>
@@ -142,7 +155,7 @@
           <children>
             <AnchorPane>
               <children>
-                <Label layoutX="0.0" layoutY="6.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="CSS Analyzer" />
+                <Label layoutX="0.0" layoutY="6.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="panelTitle" text="%csspanel" />
                 <HBox id="HBox" alignment="CENTER" layoutY="0.0" spacing="5.0" AnchorPane.rightAnchor="0.0">
                   <children>
                     <StackPane fx:id="cssPanelSearchPanelHost" prefHeight="-1.0" prefWidth="-1.0" />
@@ -161,8 +174,8 @@
                         </Menu>
                         <SeparatorMenuItem mnemonicParsing="false" />
                         <MenuItem mnemonicParsing="false" onAction="#onCssPanelCopyStyleablePathAction" text="%csspanel.copy.path" />
-                        <MenuItem mnemonicParsing="false" onAction="#onCssPanelShowStyledOnlyAction" text="%csspanel.hide.default.values" fx:id="cssPanelShowStyledOnlyMi" />
-                        <MenuItem mnemonicParsing="false" onAction="#onCssPanelSplitDefaultsAction" text="%csspanel.defaults.split" fx:id="cssPanelSplitDefaultsMi" />
+                        <MenuItem fx:id="cssPanelShowStyledOnlyMi" mnemonicParsing="false" onAction="#onCssPanelShowStyledOnlyAction" text="%csspanel.hide.default.values" />
+                        <MenuItem fx:id="cssPanelSplitDefaultsMi" mnemonicParsing="false" onAction="#onCssPanelSplitDefaultsAction" text="%csspanel.defaults.split" />
                       </items>
                     </MenuButton>
                   </children>
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/DocumentWindowController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -40,10 +40,13 @@
 import com.oracle.javafx.scenebuilder.app.preferences.PreferencesRecordGlobal;
 import com.oracle.javafx.scenebuilder.app.preview.BackgroundColorDialogController;
 import com.oracle.javafx.scenebuilder.app.preview.PreviewWindowController;
+import com.oracle.javafx.scenebuilder.app.report.JarAnalysisReportController;
 import com.oracle.javafx.scenebuilder.app.selectionbar.SelectionBarController;
 import com.oracle.javafx.scenebuilder.app.skeleton.SkeletonWindowController;
 import com.oracle.javafx.scenebuilder.app.template.FxmlTemplates;
 import com.oracle.javafx.scenebuilder.kit.editor.EditorController;
+import com.oracle.javafx.scenebuilder.kit.editor.EditorController.ControlAction;
+import com.oracle.javafx.scenebuilder.kit.editor.EditorController.EditAction;
 import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform;
 import com.oracle.javafx.scenebuilder.kit.editor.job.Job;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController;
@@ -59,7 +62,12 @@
 import com.oracle.javafx.scenebuilder.kit.editor.panel.util.dialog.AlertDialog;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.util.dialog.ErrorDialog;
 import com.oracle.javafx.scenebuilder.kit.editor.search.SearchController;
+import com.oracle.javafx.scenebuilder.kit.editor.selection.AbstractSelectionGroup;
+import com.oracle.javafx.scenebuilder.kit.editor.selection.ObjectSelectionGroup;
 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject;
+import com.oracle.javafx.scenebuilder.kit.library.user.UserLibrary;
+import com.sun.javafx.scene.control.behavior.KeyBinding;
 import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -71,19 +79,30 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.FileTime;
+import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.List;
 import javafx.beans.InvalidationListener;
 import javafx.beans.Observable;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
 import javafx.fxml.FXML;
 import javafx.geometry.Insets;
+import javafx.scene.Node;
 import javafx.scene.control.Accordion;
 import javafx.scene.control.CheckMenuItem;
+import javafx.scene.control.MenuButton;
+import javafx.scene.control.ComboBox;
 import javafx.scene.control.MenuItem;
 import javafx.scene.control.RadioMenuItem;
 import javafx.scene.control.SplitPane;
+import javafx.scene.control.TextInputControl;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.input.KeyEvent;
 import javafx.scene.layout.StackPane;
 import javafx.scene.layout.VBox;
 import javafx.stage.FileChooser;
@@ -97,6 +116,9 @@
     
     
     public enum DocumentControlAction {
+        COPY,
+        SELECT_ALL,
+        SELECT_NONE,
         SAVE_FILE,
         SAVE_AS_FILE,
         REVERT_FILE,
@@ -112,6 +134,7 @@
         TOGGLE_CSS_PANEL,
         TOGGLE_LEFT_PANEL,
         TOGGLE_RIGHT_PANEL,
+        TOGGLE_OUTLINES_VISIBILITY,
         TOGGLE_GUIDES_VISIBILITY,
         SHOW_PREVIEW_WINDOW,
         CHOOSE_BACKGROUND_COLOR,
@@ -125,6 +148,11 @@
         SHOW_SAMPLE_CONTROLLER
     }
     
+    public enum DocumentEditAction {
+        CUT,
+        PASTE
+    }
+    
     public enum ActionStatus {
         CANCELLED,
         DONE
@@ -141,18 +169,20 @@
     private final LibraryPanelController libraryPanelController = new LibraryPanelController(editorController);
     private final SelectionBarController selectionBarController = new SelectionBarController(editorController);
     private final MessageBarController messageBarController = new MessageBarController(editorController);
-    // The PreviewWindowController is created lazily because it needs an owner
-    // and computing it here would be too costly (impact on start-up time).
-    private PreviewWindowController previewWindowController = null;
     private final SearchController librarySearchController = new SearchController(editorController);
     private final SearchController inspectorSearchController = new SearchController(editorController);
     private final SearchController cssPanelSearchController = new SearchController(editorController);;
     private final SceneStyleSheetMenuController sceneStyleSheetMenuController = new SceneStyleSheetMenuController(this);
     private final CssPanelMenuController cssPanelMenuController = new CssPanelMenuController(cssPanelController);
     private final ResourceController resourceController = new ResourceController((this));
-    // The SkeletonWindowController is created lazily because it needs an owner
-    // and computing it here would be too costly (impact on start-up time).
+    // The controller below are created lazily because they need an owner
+    // and computing them here would be too costly (impact on start-up time):
+    // - PreviewWindowController
+    // - SkeletonWindowController
+    // - JarAnalysisReportController
+    private PreviewWindowController previewWindowController = null;
     private SkeletonWindowController skeletonWindowController = null;
+    private JarAnalysisReportController jarAnalysisReportController = null;
 
     @FXML private StackPane libraryPanelHost;
     @FXML private StackPane librarySearchPanelHost;
@@ -169,8 +199,11 @@
     @FXML private SplitPane leftRightSplitPane;
     @FXML private SplitPane libraryDocumentSplitPane;
     
+    @FXML private MenuButton libraryMenuButton;
+    @FXML private MenuItem libraryImportSelection;
     @FXML private CheckMenuItem libraryViewAsList;
     @FXML private CheckMenuItem libraryViewAsSections;
+    @FXML private MenuItem libraryReveal;
     
     @FXML private MenuItem cssPanelShowStyledOnlyMi;
     @FXML private MenuItem cssPanelSplitDefaultsMi;
@@ -188,6 +221,56 @@
     private FileTime loadFileTime;
     private Job saveJob;
     
+    private final EventHandler<KeyEvent> mainKeyEventFilter = new EventHandler<KeyEvent>() {
+
+        @Override
+        public void handle(KeyEvent event) {
+            //------------------------------------------------------------------
+            // TEXT INPUT CONTROL
+            //------------------------------------------------------------------
+            // Common editing actions handled natively and defined as application accelerators
+            // 
+            // The platform support is not mature/stable enough to rely on.
+            // Indeed, the behavior may differ :
+            // - when using system menu bar vs not using it
+            // - when using accelerators vs using menu items
+            // - depending on the focused control (TextField vs ComboBox)
+            // 
+            // On SB side, we decide for now to consume events that may be handled natively
+            // so ALL actions are defined in our ApplicationMenu class.
+            //
+            // This may be revisit when platform implementation will be more reliable.
+            //
+            final Node focusOwner = getScene().getFocusOwner();
+            final KeyCombination accelerator = getAccelerator(event);
+            if (isTextInputControlEditing(focusOwner) == true 
+                    && accelerator != null) {
+                for (KeyBinding binding : SBTextInputControlBindings.getBindings()) {
+                    // The event is handled natively
+                    if (binding.getSpecificity(null, event) > 0) {
+                        // 
+                        // When using system menu bar, the event is handled natively 
+                        // before the application receives it : we just consume the event 
+                        // so the editing action is not performed a second time by the app.
+                        if (menuBarController.getMenuBar().isUseSystemMenuBar()) {
+                            event.consume();
+                        }
+                        break;
+                    }
+                }
+            }
+            
+            // MenuItems define a single accelerator.
+            // BACK_SPACE key must be handled same way as DELETE key.
+            if (isTextInputControlEditing(focusOwner) == false 
+                    && KeyCode.BACK_SPACE.equals(event.getCode())) {
+                if (editorController.canPerformEditAction(EditAction.DELETE)) {
+                    editorController.performEditAction(EditAction.DELETE);
+                }
+            }
+        }
+    };
+    
     /*
      * DocumentWindowController
      */
@@ -336,6 +419,18 @@
         final boolean result;
         
         switch(controlAction) {
+            case COPY:
+                result = canPerformCopy();
+                break;
+                
+            case SELECT_ALL:
+                result = canPerformSelectAll();
+                break;
+                
+            case SELECT_NONE:
+                result = canPerformSelectNone();
+                break;
+                
             case PRINT_FILE:
                 result = editorController.getFxomDocument() != null;
                 break;
@@ -345,6 +440,7 @@
             case TOGGLE_CSS_PANEL:
             case TOGGLE_LEFT_PANEL:
             case TOGGLE_RIGHT_PANEL:
+            case TOGGLE_OUTLINES_VISIBILITY:
             case TOGGLE_GUIDES_VISIBILITY:
             case SHOW_PREVIEW_WINDOW:
                 result = true;
@@ -421,6 +517,18 @@
         final PreferencesRecordDocument recordDocument = pc.getRecordDocument(this);
         
         switch(controlAction) {
+            case COPY:
+                performCopy();
+                break;
+                
+            case SELECT_ALL:
+                performSelectAll();
+                break;
+                
+            case SELECT_NONE:
+                performSelectNone();
+                break;
+                
             case SHOW_PREVIEW_WINDOW:
                 if (previewWindowController == null) {
                     previewWindowController = new PreviewWindowController(editorController, getStage());
@@ -516,6 +624,11 @@
                 recordDocument.setDocumentVisible(documentSplitController.isTargetVisible());
                 break;
                 
+            case TOGGLE_OUTLINES_VISIBILITY:
+                contentPanelController.setOutlinesVisible(
+                        ! contentPanelController.isOutlinesVisible());
+                break;
+                
             case TOGGLE_GUIDES_VISIBILITY:
                 contentPanelController.setGuidesVisible(
                         ! contentPanelController.isGuidesVisible());
@@ -559,7 +672,45 @@
         }
     }
     
+    public boolean canPerformEditAction(DocumentEditAction editAction) {
+        final boolean result;
+        
+        switch(editAction) {
+            case CUT:
+                result = canPerformCut();
+                break;
+                
+            case PASTE:
+                result = canPerformPaste();
+                break;
+                
+            default:
+                result = false;
+                assert false;
+                break;
+        }
+       
+        return result;
+    }
     
+    public void performEditAction(DocumentEditAction editAction) {
+        assert canPerformEditAction(editAction);
+        
+        switch(editAction) {
+            case CUT:
+                performCut();
+                break;
+                
+            case PASTE:
+                performPaste();
+                break;
+                
+            default:
+                assert false;
+                break;
+        }
+    }
+                
     public boolean isLeftPanelVisible() {
         return leftSplitController.isTargetVisible();
     }
@@ -632,6 +783,13 @@
         assert libraryDocumentSplitPane.getItems().size() == 2;
         assert documentAccordion != null;
         assert documentAccordion.getPanes().isEmpty() == false;
+        assert libraryViewAsList != null;
+        assert libraryViewAsSections != null;
+        assert libraryReveal != null;
+        assert libraryMenuButton != null;
+        assert libraryImportSelection != null;
+        
+        mainSplitPane.addEventFilter(KeyEvent.KEY_PRESSED, mainKeyEventFilter);
         
         // Insert the menu bar
         assert getRoot() instanceof VBox;
@@ -708,6 +866,37 @@
                 messageBarController.setDocumentDirty(currentJob != saveJob);
             }
         });
+        
+        // Setup title of the Library Reveal menu item according the underlying o/s.
+        final String revealMenuKey;
+        if (EditorPlatform.IS_MAC) {
+            revealMenuKey = "menu.title.reveal.mac";
+        } else if (EditorPlatform.IS_WINDOWS) {
+            revealMenuKey = "menu.title.reveal.win";
+        } else {
+            assert EditorPlatform.IS_LINUX;
+            revealMenuKey = "menu.title.reveal.linux";
+        }
+        libraryReveal.setText(I18N.getString(revealMenuKey));
+        
+        // We need to tune the content of the library menu according if there's
+        // or not a selection likely to be dropped onto Library panel.
+        libraryMenuButton.showingProperty().addListener(new ChangeListener<Boolean>() {
+
+            @Override
+            public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
+                if (t1) {
+                    AbstractSelectionGroup asg = getEditorController().getSelection().getGroup();
+                    libraryImportSelection.setDisable(true);
+
+                    if (asg != null && asg instanceof ObjectSelectionGroup) {
+                        if (((ObjectSelectionGroup)asg).getItems().size() >= 1) {
+                            libraryImportSelection.setDisable(false);
+                        }
+                    }
+                }
+            }
+        });
     }
 
     @Override
@@ -723,7 +912,8 @@
     public boolean isFrontDocumentWindow() {
         return getStage().isFocused()
                 || (previewWindowController != null && previewWindowController.getStage().isFocused())
-                || (skeletonWindowController != null && skeletonWindowController.getStage().isFocused());
+                || (skeletonWindowController != null && skeletonWindowController.getStage().isFocused())
+                || (jarAnalysisReportController != null && jarAnalysisReportController.getStage().isFocused());
     }
 
     public void performCloseFrontDocumentWindow() {
@@ -735,6 +925,9 @@
         } else if (skeletonWindowController != null
                 && skeletonWindowController.getStage().isFocused()) {
             skeletonWindowController.closeWindow();
+        } else if (jarAnalysisReportController != null
+                && jarAnalysisReportController.getStage().isFocused()) {
+            jarAnalysisReportController.closeWindow();
         }
     }
 
@@ -807,17 +1000,19 @@
     @FXML
     void onHierarchyShowInfo(ActionEvent event) {
         hierarchyPanelController.setDisplayOption(AbstractHierarchyPanelController.DisplayOption.INFO);
-        
+        documentAccordion.setExpandedPane(documentAccordion.getPanes().get(0));
     }
     
     @FXML
     void onHierarchyShowFxId(ActionEvent event) {
         hierarchyPanelController.setDisplayOption(AbstractHierarchyPanelController.DisplayOption.FXID);
+        documentAccordion.setExpandedPane(documentAccordion.getPanes().get(0));
     }
     
     @FXML
     void onHierarchyShowNodeId(ActionEvent event) {
         hierarchyPanelController.setDisplayOption(AbstractHierarchyPanelController.DisplayOption.NODEID);
+        documentAccordion.setExpandedPane(documentAccordion.getPanes().get(0));
     }
     
     //
@@ -842,15 +1037,195 @@
         libraryPanelController.setDisplayMode(LibraryPanelController.DISPLAY_MODE.SECTIONS);
     }
 
+    // This method cannot be called if there is not a valid selection, a selection
+    // eligible for being dropped onto Library panel.
     @FXML
     void onLibraryImportSelection(ActionEvent event) {
-        System.out.println("[DocumentWindowController::onLibraryImportSelection] Not yet available"); //NOI18N
+        AbstractSelectionGroup asg = getEditorController().getSelection().getGroup();
+
+        if (asg != null && asg instanceof ObjectSelectionGroup) {
+            ObjectSelectionGroup osg = (ObjectSelectionGroup)asg;
+            
+            if (osg.getItems().size() >= 1) {
+                List<FXOMObject> selection = new ArrayList<FXOMObject>(osg.getItems());
+                libraryPanelController.performImportSelection(selection);
+            }
+        }
+    }
+    
+    @FXML
+    void onLibraryRevealCustomFolder(ActionEvent event) {
+        String userLibraryPath = ((UserLibrary) getEditorController().getLibrary()).getPath();
+        try {
+            EditorPlatform.revealInFileBrowser(new File(userLibraryPath));
+        } catch(IOException x) {
+            final ErrorDialog errorDialog = new ErrorDialog(null);
+            errorDialog.setMessage(I18N.getString("alert.reveal.failure.message", getStage().getTitle()));
+            errorDialog.setDetails(I18N.getString("alert.reveal.failure.details"));
+            errorDialog.setDebugInfoWithThrowable(x);
+            errorDialog.showAndWait();
+        }
+    }
+    
+    @FXML
+    void onLibraryShowJarAnalysisReport(ActionEvent event) {
+        if (jarAnalysisReportController == null) {
+            jarAnalysisReportController = new JarAnalysisReportController(getEditorController(), getStage());
+        }
+        
+        jarAnalysisReportController.openWindow();
     }
     
     /*
      * Private
      */
+
+    private boolean canPerformCopy() {
+        boolean result;
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            result = tic.getSelectedText() != null && tic.getSelectedText().isEmpty() == false;
+        } else {
+            result = getEditorController().canPerformControlAction(ControlAction.COPY);
+        }
+        return result;
+    }
+
+    private void performCopy() {
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            tic.copy();
+        } else {
+            this.getEditorController().performControlAction(ControlAction.COPY);
+        }
+    }
+
+    private boolean canPerformSelectAll() {
+        boolean result;
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            result = tic.getText() != null && tic.getText().isEmpty() == false;
+            final String selectedText = tic.getSelectedText();
+            // Check if the TextInputControl is not already ALL selected
+            if (selectedText != null && selectedText.length() == tic.getText().length()) {
+                result = false;
+            }
+        } else {
+            result = getEditorController().canPerformControlAction(ControlAction.SELECT_ALL);
+        }
+        return result;
+    }
+
+    private void performSelectAll() {
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            tic.selectAll();
+        } else {
+            this.getEditorController().performControlAction(ControlAction.SELECT_ALL);
+        }
+    }
+
+    private boolean canPerformSelectNone() {
+        boolean result;
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            result = tic.getSelectedText() != null && tic.getSelectedText().isEmpty() == false;
+        } else {
+            result = getEditorController().canPerformControlAction(ControlAction.SELECT_NONE);
+        }
+        return result;
+    }
+
+    private void performSelectNone() {
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            tic.deselect();
+        } else {
+            this.getEditorController().performControlAction(ControlAction.SELECT_NONE);
+        }
+    }
     
+    private boolean canPerformCut() {
+        boolean result;
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            result = tic.getSelectedText() != null && tic.getSelectedText().isEmpty() == false;
+        } else {
+            result = getEditorController().canPerformEditAction(EditAction.CUT);
+        }
+        return result;
+    }
+    
+    private void performCut() {
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            tic.cut();
+        } else {
+            this.getEditorController().performEditAction(EditAction.CUT);
+        }
+    }
+
+    private boolean canPerformPaste() {
+        boolean result;
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            result = Clipboard.getSystemClipboard().hasString();
+        } else {
+            result = getEditorController().canPerformEditAction(EditAction.PASTE);
+        }
+        return result;
+    }
+    
+    private void performPaste() {
+        final Node focusOwner = this.getScene().getFocusOwner();
+        if (isTextInputControlEditing(focusOwner)) {
+            final TextInputControl tic = getTextInputControl(focusOwner);
+            tic.paste();
+        } else {
+            this.getEditorController().performEditAction(EditAction.PASTE);
+        }
+    }
+
+    /**
+     * Returns true if the specified node is either a TextInputControl or a ComboBox.
+     */
+    private boolean isTextInputControlEditing(Node node) {
+        return (node instanceof TextInputControl
+                || node instanceof ComboBox);
+    }
+
+    private TextInputControl getTextInputControl(Node node) {
+        assert isTextInputControlEditing(node);
+        final TextInputControl tic;
+        if (node instanceof TextInputControl) {
+            tic = (TextInputControl) node;
+        } else {
+            assert node instanceof ComboBox;
+            final ComboBox<?> cb = (ComboBox<?>) node;
+            tic = cb.getEditor();
+        }
+        return tic;
+    }
+    
+    private KeyCombination getAccelerator(final KeyEvent event) {
+        KeyCombination result = null;
+        for (KeyCombination kc : menuBarController.getAccelerators()) {
+            if (kc.match(event)) {
+                result = kc;
+                break;
+            }
+        }
+        return result;
+    }
+
     private void updateStageTitle() {
         getStage().setTitle(makeTitle(editorController.getFxomDocument()));
     }
@@ -1207,3 +1582,18 @@
         }
     }
 }
+
+/**
+ * This class setup key bindings for the TextInputControl type classes and
+ * provide a way to access the key binding list.
+ */
+class SBTextInputControlBindings extends com.sun.javafx.scene.control.behavior.TextInputControlBindings {
+
+    private SBTextInputControlBindings() {
+        assert false;
+    }
+
+    public static List<KeyBinding> getBindings() {
+        return BINDINGS;
+    }
+}
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp.properties	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/i18n/SceneBuilderApp.properties	Mon Dec 23 13:59:52 2013 +0100
@@ -133,7 +133,11 @@
 menu.title.choose.background.color = Choose Background Color\u2026
 menu.title.theme = JavaFX Theme
 menu.title.theme.modena = Modena (JavaFX 8)
+menu.title.theme.modena.touch = Modena Touch (JavaFX 8)
 menu.title.theme.caspian = Caspian (JavaFX 2)
+menu.title.theme.caspian.embedded = Caspian Embedded (JavaFX 2)
+menu.title.theme.caspian.embedded.qvga = Caspian Embedded QVGA (JavaFX 2)
+menu.title.theme.caspian.high.contrast = High Contrast, for Caspian only (JavaFX 2)
 menu.title.scene.stylesheets = Scene Style Sheets
 menu.title.add.stylesheet = Add a Style Sheet\u2026
 menu.title.remove.stylesheet = Remove a Style Sheet
@@ -151,10 +155,34 @@
 menu.title.scene.builder.help = Scene Builder Help
 menu.title.about = About Scene Builder
 
+# -----------------------------------------------------------------------------
+# Document
+# -----------------------------------------------------------------------------
+document = Document
 
 # -----------------------------------------------------------------------------
-# Document Window
+# Hierarchy
 # -----------------------------------------------------------------------------
+hierarchy = Hierarchy
+hierarchy.displays = Hierarchy displays
+hierarchy.show.info = Info
+hierarchy.show.fxid = fx:id
+hierarchy.show.nodeid = Node Id
+
+# -----------------------------------------------------------------------------
+# Controller
+# -----------------------------------------------------------------------------
+controller = Controller
+
+# -----------------------------------------------------------------------------
+# Inspector
+# -----------------------------------------------------------------------------
+inspector = Inspector
+inspector.show.all = Show All
+inspector.show.edited = Show Edited
+inspector.view.sections = View Sections
+inspector.by.property.name = View by property name
+inspector.by.property.type = View by property type
 
 # -----------------------------------------------------------------------------
 # Preferences Window
@@ -178,7 +206,6 @@
 # -----------------------------------------------------------------------------
 # Preview Window
 # -----------------------------------------------------------------------------
-preview.constructing = Constructing Preview content ...
 preview.background.color = Background Color
 preview.no.document = No document
 preview.not.node = Not a Node
@@ -203,10 +230,10 @@
 # -----------------------------------------------------------------------------
 # Library Menu within Library panel
 # -----------------------------------------------------------------------------
-# Import of FXML file is not yet ready
+library = Library
 library.panel.menu.import.jar.fxml = Import JAR/FXML file
+library.panel.menu.import.selection = Import Selection
 # Messages below are temporarily unused
-#library.panel.menu.import.selection = Import Selection
 #library.panel.menu.category.view = View Library Category
 #library.panel.menu.category.create = Create Library Category
 #library.panel.menu.category.remove = Remove Library Category
@@ -215,6 +242,8 @@
 #library.panel.menu.item.remove = Remove Custom Item
 library.panel.menu.view.list = View as List
 library.panel.menu.view.sections = View as Sections
+library.panel.menu.custom = Custom Library Folder
+library.panel.menu.custom.report = Show JAR Analysis Report
 
 # -----------------------------------------------------------------------------
 # About Window
@@ -323,6 +352,7 @@
 # -----------------------------------------------------------------------------
 # CSS Panel
 # -----------------------------------------------------------------------------
+csspanel = CSS Analyzer
 csspanel.copy.path = Copy Styleable Path
 csspanel.rules = Rules
 csspanel.show.default.values = Show Properties with Default Values
@@ -339,4 +369,13 @@
 skeleton.add.comments = Comments
 skeleton.format.full = Full
 # Parameter is a fxml file name
-skeleton.window.title = Sample Skeleton for ''{0}'' Controller Class
\ No newline at end of file
+skeleton.window.title = Sample Skeleton for ''{0}'' Controller Class
+
+# -----------------------------------------------------------------------------
+# JAR Analysis Report dialog
+# -----------------------------------------------------------------------------
+# The parameter is a time stamp
+jar.analysis.report.timestamp = Analysis done on {0}
+jar.analysis.report.title = JAR Analysis Report
+jar.analysis.exception = Exception for:
+jar.analysis.not.node = Not a Node:
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBar.fxml	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBar.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -31,207 +31,209 @@
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
-
 <?import java.lang.*?>
 <?import javafx.scene.control.*?>
 <?import javafx.scene.layout.*?>
 <?scenebuilder-preview-i18n-resource ../i18n/SceneBuilderApp.properties?>
 
-<StackPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
-    <children>
-        <MenuBar fx:id="menuBar">
-            <menus>
-                <Menu fx:id="fileMenu" mnemonicParsing="false" text="%menu.title.file">
-                    <items>
-                        <MenuItem fx:id="newMenuItem" mnemonicParsing="false" text="%menu.title.new" />
-                        <Menu fx:id="newTemplateMenuItem" mnemonicParsing="false" text="%menu.title.new.template">
-                            <items>
-                                <MenuItem fx:id="newAlertDialogMenuItem" mnemonicParsing="false" text="%menu.title.new.alert.dialog" />
-                                <MenuItem fx:id="newBasicAppMenuItem" mnemonicParsing="false" text="%menu.title.new.basic.app" />
-                                <MenuItem fx:id="newComplexAppMenuItem" mnemonicParsing="false" text="%menu.title.new.complex.app" />
-                                <SeparatorMenuItem mnemonicParsing="false" />
-                                <MenuItem fx:id="newAlertDialogCssMenuItem" mnemonicParsing="false" text="%menu.title.new.alert.dialog.css" />
-                                <MenuItem fx:id="newAlertDialogI18nMenuItem" mnemonicParsing="false" text="%menu.title.new.alert.dialog.i18n" />
-                                <MenuItem fx:id="newBasicAppCssMenuItem" mnemonicParsing="false" text="%menu.title.new.basic.app.css" />
-                                <MenuItem fx:id="newBasicAppI18nMenuItem" mnemonicParsing="false" text="%menu.title.new.basic.app.i18n" />
-                                <MenuItem fx:id="newComplexAppCssMenuItem" mnemonicParsing="false" text="%menu.title.new.complex.app.css" />
-                                <MenuItem fx:id="newComplexAppI18nMenuItem" mnemonicParsing="false" text="%menu.title.new.complex.app.i18n" />
-                            </items>
-                        </Menu>
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="openMenuItem" mnemonicParsing="false" text="%menu.title.open" />
-                        <Menu fx:id="openRecentMenu" mnemonicParsing="false" text="%menu.title.open.recent" >              
-                            <items>
-                                <MenuItem mnemonicParsing="false" text="Action 1" />
-                            </items>
-                        </Menu>
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="saveMenuItem" mnemonicParsing="false" text="%menu.title.save" />
-                        <MenuItem fx:id="saveAsMenuItem" mnemonicParsing="false" text="%menu.title.save.as" />
-                        <MenuItem fx:id="revertMenuItem" mnemonicParsing="false" text="%menu.title.revert" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="revealMenuItem" mnemonicParsing="false" text="Reveal (setup at runtime)" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="closeMenuItem" mnemonicParsing="false" text="%menu.title.close" />
-                        <SeparatorMenuItem fx:id="separatorAbovePreferencesMenuItem" mnemonicParsing="false" />
-                        <MenuItem fx:id="showPreferencesMenuItem" mnemonicParsing="false" text="%menu.title.preferences" />
-                        <MenuItem fx:id="exitMenuItem" mnemonicParsing="false" text="%menu.title.quit" />
-                    </items>
+<StackPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
+  <children>
+    <MenuBar fx:id="menuBar">
+      <menus>
+        <Menu mnemonicParsing="false" text="%menu.title.file" fx:id="fileMenu">
+          <items>
+            <MenuItem mnemonicParsing="false" text="%menu.title.new" fx:id="newMenuItem" />
+            <Menu mnemonicParsing="false" text="%menu.title.new.template" fx:id="newTemplateMenuItem">
+              <items>
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.alert.dialog" fx:id="newAlertDialogMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.basic.app" fx:id="newBasicAppMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.complex.app" fx:id="newComplexAppMenuItem" />
+                <SeparatorMenuItem mnemonicParsing="false" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.alert.dialog.css" fx:id="newAlertDialogCssMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.alert.dialog.i18n" fx:id="newAlertDialogI18nMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.basic.app.css" fx:id="newBasicAppCssMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.basic.app.i18n" fx:id="newBasicAppI18nMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.complex.app.css" fx:id="newComplexAppCssMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.new.complex.app.i18n" fx:id="newComplexAppI18nMenuItem" />
+              </items>
+            </Menu>
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.open" fx:id="openMenuItem" />
+            <Menu mnemonicParsing="false" text="%menu.title.open.recent" fx:id="openRecentMenu">
+              <items>
+                <MenuItem mnemonicParsing="false" text="Action 1" />
+              </items>
+            </Menu>
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.save" fx:id="saveMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.save.as" fx:id="saveAsMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.revert" fx:id="revertMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="Reveal (setup at runtime)" fx:id="revealMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.close" fx:id="closeMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" fx:id="separatorAbovePreferencesMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.preferences" fx:id="showPreferencesMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.quit" fx:id="exitMenuItem" />
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%menu.title.edit">
+          <items>
+            <MenuItem mnemonicParsing="false" text="%menu.title.undo" fx:id="undoMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.redo" fx:id="redoMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.cut" fx:id="cutMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.copy" fx:id="copyMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.paste" fx:id="pasteMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.paste.into" fx:id="pasteIntoMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.duplicate" fx:id="duplicateMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.delete" fx:id="deleteMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.select.all" fx:id="selectAllMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.select.none" fx:id="selectNoneMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.select.parent" fx:id="selectParentMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.select.next" fx:id="selectNextMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.select.previous" fx:id="selectPreviousMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.trim" fx:id="trimMenuItem" />
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%menu.title.view">
+          <items>
+            <MenuItem mnemonicParsing="false" text="%menu.title.content" fx:id="gotoContentMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.properties" fx:id="gotoPropertiesMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.layout" fx:id="gotoLayoutMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.code" fx:id="gotoCodeMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.hide.library.panel" fx:id="toggleLibraryPanelMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.hide.document.panel" fx:id="toggleHierarchyPanelMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.show.bottom.panel" fx:id="toggleCSSPanelMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.hide.left.panel" fx:id="toggleLeftPanelMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.hide.right.panel" fx:id="toggleRightPanelMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.show.outlines" fx:id="toggleOutlinesMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.show.sample.data" fx:id="toggleSampleDataMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.disable.guides" fx:id="toggleAlignmentGuidesMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <Menu mnemonicParsing="false" text="%menu.title.zoom" fx:id="zoomMenu" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.show.sample.controller.skeleton" fx:id="showSampleControllerMenuItem" />
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%menu.title.insert" fx:id="insertMenu" />
+        <Menu mnemonicParsing="false" text="%menu.title.modify">
+          <items>
+            <MenuItem mnemonicParsing="false" text="%menu.title.fit" fx:id="fitToParentMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.use.computed.sizes" fx:id="useComputedSizesMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <Menu mnemonicParsing="false" text="%menu.title.grid">
+              <items>
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.move.row.above" fx:id="moveRowAboveMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.move.row.below" fx:id="moveRowBelowMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.move.column.before" fx:id="moveColumnBeforeMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.move.column.after" fx:id="moveColumnAfterMenuItem" />
+                <SeparatorMenuItem mnemonicParsing="false" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.add.row.above" fx:id="addRowAboveMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.add.row.below" fx:id="addRowBelowMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.add.column.before" fx:id="addColumnBeforeMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.add.column.after" fx:id="addColumnAfterMenuItem" />
+                <SeparatorMenuItem mnemonicParsing="false" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.increase.row.span" fx:id="increaseRowSpanMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.decrease.row.span" fx:id="decreaseRowSpanMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.increase.column.span" fx:id="increaseColumnSpanMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.grid.decrease.column.span" fx:id="decreaseColumnSpanMenuItem" />
+              </items>
+            </Menu>
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <Menu mnemonicParsing="false" text="%menu.title.add.effect" fx:id="addEffectMenu" />
+            <Menu mnemonicParsing="false" text="%menu.title.add.popup" fx:id="addPopupControlMenu" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.edit.included.default" fx:id="editIncludedFileMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.reveal.included.default" fx:id="revealIncludedFileMenuItem" />
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%menu.title.arrange">
+          <items>
+            <MenuItem mnemonicParsing="false" text="%menu.title.front" fx:id="bringToFrontMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.back" fx:id="sendToBackMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.forward" fx:id="bringForwardMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.backward" fx:id="sendBackwardMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <Menu mnemonicParsing="false" text="%menu.title.wrap">
+              <items>
+                <MenuItem mnemonicParsing="false" text="AnchorPane" fx:id="wrapInAnchorPaneMenuItem" />
+                <MenuItem mnemonicParsing="false" text="GridPane" fx:id="wrapInGridPaneMenuItem" />
+                <MenuItem mnemonicParsing="false" text="HBox" fx:id="wrapInHBoxMenuItem" />
+                <MenuItem mnemonicParsing="false" text="Pane" fx:id="wrapInPaneMenuItem" />
+                <MenuItem mnemonicParsing="false" text="ScrollPane" fx:id="wrapInScrollPaneMenuItem" />
+                <MenuItem mnemonicParsing="false" text="SplitPane" fx:id="wrapInSplitPaneMenuItem" />
+                <MenuItem mnemonicParsing="false" text="StackPane" fx:id="wrapInStackPaneMenuItem" />
+                <MenuItem mnemonicParsing="false" text="TabPane" fx:id="wrapInTabPaneMenuItem" />
+                <MenuItem mnemonicParsing="false" text="TitledPane" fx:id="wrapInTitledPaneMenuItem" />
+                <MenuItem mnemonicParsing="false" text="ToolBar" fx:id="wrapInToolBarMenuItem" />
+                <MenuItem mnemonicParsing="false" text="VBox" fx:id="wrapInVBoxMenuItem" />
+                <MenuItem mnemonicParsing="false" text="Group" fx:id="wrapInGroupMenuItem" />
+              </items>
+            </Menu>
+            <MenuItem mnemonicParsing="false" text="%menu.title.unwrap" fx:id="unwrapMenuItem" />
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%menu.title.preview">
+          <items>
+            <MenuItem mnemonicParsing="false" text="%menu.title.show.preview" fx:id="showPreviewMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.choose.background.color" fx:id="chooseBackgroundColorMenuItem" />
+            <SeparatorMenuItem mnemonicParsing="false" />
+            <Menu mnemonicParsing="false" text="%menu.title.theme">
+              <items>
+                <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.modena" fx:id="modenaThemeMenuItem" />
+                <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.modena.touch" fx:id="modenaTouchThemeMenuItem" />
+                <SeparatorMenuItem mnemonicParsing="false" />
+                <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.caspian" fx:id="caspianThemeMenuItem" />
+                <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.caspian.embedded" fx:id="caspianEmbeddedThemeMenuItem" />
+                <RadioMenuItem mnemonicParsing="false" text="%menu.title.theme.caspian.embedded.qvga" fx:id="caspianEmbeddedQVGAThemeMenuItem" />
+                <SeparatorMenuItem mnemonicParsing="false" />
+                <CheckMenuItem mnemonicParsing="false" text="%menu.title.theme.caspian.high.contrast" fx:id="caspianHighContrastThemeMenuItem"/>
+              </items>
+            </Menu>
+            <Menu mnemonicParsing="false" text="%menu.title.scene.stylesheets">
+              <items>
+                <MenuItem mnemonicParsing="false" text="%menu.title.add.stylesheet" fx:id="addSceneStyleSheetMenuItem" />
+                <Menu mnemonicParsing="false" text="%menu.title.remove.stylesheet" fx:id="removeSceneStyleSheetMenu">
+                  <items>
+                    <MenuItem disable="true" mnemonicParsing="false" text="%scenestylesheet.none" />
+                  </items>
                 </Menu>
-                <Menu mnemonicParsing="false" text="%menu.title.edit">
-                    <items>
-                        <MenuItem fx:id="undoMenuItem" mnemonicParsing="false" text="%menu.title.undo" />
-                        <MenuItem fx:id="redoMenuItem" mnemonicParsing="false" text="%menu.title.redo" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="cutMenuItem" mnemonicParsing="false" text="%menu.title.cut" />
-                        <MenuItem fx:id="copyMenuItem" mnemonicParsing="false" text="%menu.title.copy" />
-                        <MenuItem fx:id="pasteMenuItem" mnemonicParsing="false" text="%menu.title.paste" />
-                        <MenuItem fx:id="pasteIntoMenuItem" mnemonicParsing="false" text="%menu.title.paste.into" />
-                        <MenuItem fx:id="duplicateMenuItem" mnemonicParsing="false" text="%menu.title.duplicate" />
-                        <MenuItem fx:id="deleteMenuItem" mnemonicParsing="false" text="%menu.title.delete" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="selectAllMenuItem" mnemonicParsing="false" text="%menu.title.select.all" />
-                        <MenuItem fx:id="selectNoneMenuItem" mnemonicParsing="false" text="%menu.title.select.none" />
-                        <MenuItem fx:id="selectParentMenuItem" mnemonicParsing="false" text="%menu.title.select.parent" />
-                        <MenuItem fx:id="selectNextMenuItem" mnemonicParsing="false" text="%menu.title.select.next" />
-                        <MenuItem fx:id="selectPreviousMenuItem" mnemonicParsing="false" text="%menu.title.select.previous" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="trimMenuItem" mnemonicParsing="false" text="%menu.title.trim" />
-                    </items>
+                <Menu mnemonicParsing="false" text="%menu.title.open.stylesheet" fx:id="openSceneStyleSheetMenu">
+                  <items>
+                    <MenuItem disable="true" mnemonicParsing="false" text="%scenestylesheet.none" />
+                  </items>
                 </Menu>
-                <Menu mnemonicParsing="false" text="%menu.title.view">
-                    <items>
-                        <MenuItem fx:id="gotoContentMenuItem" mnemonicParsing="false" text="%menu.title.content" />
-                        <MenuItem fx:id="gotoPropertiesMenuItem" mnemonicParsing="false" text="%menu.title.properties" />
-                        <MenuItem fx:id="gotoLayoutMenuItem" mnemonicParsing="false" text="%menu.title.layout" />
-                        <MenuItem fx:id="gotoCodeMenuItem" mnemonicParsing="false" text="%menu.title.code" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="toggleLibraryPanelMenuItem" mnemonicParsing="false" text="%menu.title.hide.library.panel" />
-                        <MenuItem fx:id="toggleHierarchyPanelMenuItem" mnemonicParsing="false" text="%menu.title.hide.document.panel" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="toggleCSSPanelMenuItem" mnemonicParsing="false" text="%menu.title.show.bottom.panel" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="toggleLeftPanelMenuItem" mnemonicParsing="false" text="%menu.title.hide.left.panel" />
-                        <MenuItem fx:id="toggleRightPanelMenuItem" mnemonicParsing="false" text="%menu.title.hide.right.panel" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="toggleOutlinesMenuItem" mnemonicParsing="false" text="%menu.title.show.outlines" />
-                        <MenuItem fx:id="toggleSampleDataMenuItem" mnemonicParsing="false" text="%menu.title.show.sample.data" />
-                        <MenuItem fx:id="toggleAlignmentGuidesMenuItem" mnemonicParsing="false" text="%menu.title.disable.guides" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <Menu fx:id="zoomMenu" mnemonicParsing="false" text="%menu.title.zoom" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="showSampleControllerMenuItem" mnemonicParsing="false" text="%menu.title.show.sample.controller.skeleton" />
-                    </items>
-                </Menu>
-                <Menu fx:id="insertMenu" mnemonicParsing="false" text="%menu.title.insert" />
-                <Menu mnemonicParsing="false" text="%menu.title.modify">
-                    <items>
-                        <MenuItem fx:id="fitToParentMenuItem" mnemonicParsing="false" text="%menu.title.fit" />
-                        <MenuItem fx:id="useComputedSizesMenuItem" mnemonicParsing="false" text="%menu.title.use.computed.sizes" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <Menu mnemonicParsing="false" text="%menu.title.grid">
-                            <items>
-                                <MenuItem fx:id="selectNextRowMenuItem" mnemonicParsing="false" text="%menu.title.grid.select.next.row" />
-                                <MenuItem fx:id="selectNextColumnMenuItem" mnemonicParsing="false" text="%menu.title.grid.select.next.column" />
-                                <SeparatorMenuItem mnemonicParsing="false" />
-                                <MenuItem fx:id="moveRowAboveMenuItem" mnemonicParsing="false" text="%menu.title.grid.move.row.above" />
-                                <MenuItem fx:id="moveRowBelowMenuItem" mnemonicParsing="false" text="%menu.title.grid.move.row.below" />
-                                <MenuItem fx:id="moveColumnBeforeMenuItem" mnemonicParsing="false" text="%menu.title.grid.move.column.before" />
-                                <MenuItem fx:id="moveColumnAfterMenuItem" mnemonicParsing="false" text="%menu.title.grid.move.column.after" />
-                                <SeparatorMenuItem mnemonicParsing="false" />
-                                <MenuItem fx:id="addRowAboveMenuItem" mnemonicParsing="false" text="%menu.title.grid.add.row.above" />
-                                <MenuItem fx:id="addRowBelowMenuItem" mnemonicParsing="false" text="%menu.title.grid.add.row.below" />
-                                <MenuItem fx:id="addColumnBeforeMenuItem" mnemonicParsing="false" text="%menu.title.grid.add.column.before" />
-                                <MenuItem fx:id="addColumnAfterMenuItem" mnemonicParsing="false" text="%menu.title.grid.add.column.after" />
-                                <SeparatorMenuItem mnemonicParsing="false" />
-                                <MenuItem fx:id="increaseRowSpanMenuItem" mnemonicParsing="false" text="%menu.title.grid.increase.row.span" />
-                                <MenuItem fx:id="decreaseRowSpanMenuItem" mnemonicParsing="false" text="%menu.title.grid.decrease.row.span" />
-                                <MenuItem fx:id="increaseColumnSpanMenuItem" mnemonicParsing="false" text="%menu.title.grid.increase.column.span" />
-                                <MenuItem fx:id="decreaseColumnSpanMenuItem" mnemonicParsing="false" text="%menu.title.grid.decrease.column.span" />
-                            </items>
-                        </Menu>
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <Menu fx:id="addEffectMenu" mnemonicParsing="false" text="%menu.title.add.effect" />
-                        <Menu fx:id="addPopupControlMenu" mnemonicParsing="false" text="%menu.title.add.popup" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="editIncludedFileMenuItem" mnemonicParsing="false" text="%menu.title.edit.included.default" />
-                        <MenuItem fx:id="revealIncludedFileMenuItem" mnemonicParsing="false" text="%menu.title.reveal.included.default" />
-                    </items>
-                </Menu>
-                <Menu mnemonicParsing="false" text="%menu.title.arrange">
-                    <items>
-                        <MenuItem fx:id="bringToFrontMenuItem" mnemonicParsing="false" text="%menu.title.front" />
-                        <MenuItem fx:id="sendToBackMenuItem" mnemonicParsing="false" text="%menu.title.back" />
-                        <MenuItem fx:id="bringForwardMenuItem" mnemonicParsing="false" text="%menu.title.forward" />
-                        <MenuItem fx:id="sendBackwardMenuItem" mnemonicParsing="false" text="%menu.title.backward" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <Menu mnemonicParsing="false" text="%menu.title.wrap">
-                            <items>
-                                <MenuItem fx:id="wrapInAnchorPaneMenuItem" mnemonicParsing="false" text="AnchorPane" />
-                                <MenuItem fx:id="wrapInGridPaneMenuItem" mnemonicParsing="false" text="GridPane" />
-                                <MenuItem fx:id="wrapInHBoxMenuItem" mnemonicParsing="false" text="HBox" />
-                                <MenuItem fx:id="wrapInPaneMenuItem" mnemonicParsing="false" text="Pane" />
-                                <MenuItem fx:id="wrapInScrollPaneMenuItem" mnemonicParsing="false" text="ScrollPane" />
-                                <MenuItem fx:id="wrapInSplitPaneMenuItem" mnemonicParsing="false" text="SplitPane" />
-                                <MenuItem fx:id="wrapInStackPaneMenuItem" mnemonicParsing="false" text="StackPane" />
-                                <MenuItem fx:id="wrapInTabPaneMenuItem" mnemonicParsing="false" text="TabPane" />
-                                <MenuItem fx:id="wrapInTitledPaneMenuItem" mnemonicParsing="false" text="TitledPane" />
-                                <MenuItem fx:id="wrapInToolBarMenuItem" mnemonicParsing="false" text="ToolBar" />
-                                <MenuItem fx:id="wrapInVBoxMenuItem" mnemonicParsing="false" text="VBox" />
-                                <MenuItem fx:id="wrapInGroupMenuItem" mnemonicParsing="false" text="Group" />
-                            </items>
-                        </Menu>
-                        <MenuItem fx:id="unwrapMenuItem" mnemonicParsing="false" text="%menu.title.unwrap" />
-                    </items>
-                </Menu>
-                <Menu mnemonicParsing="false" text="%menu.title.preview">
-                    <items>
-                        <MenuItem fx:id="showPreviewMenuItem" mnemonicParsing="false" text="%menu.title.show.preview" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <MenuItem fx:id="chooseBackgroundColorMenuItem" mnemonicParsing="false" text="%menu.title.choose.background.color" />
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                        <Menu mnemonicParsing="false" text="%menu.title.theme">
-                            <items>
-                                <RadioMenuItem fx:id="modenaThemeMenuItem" mnemonicParsing="false" text="%menu.title.theme.modena" />
-                                <RadioMenuItem fx:id="caspianThemeMenuItem" mnemonicParsing="false" text="%menu.title.theme.caspian" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" />
-                            </items>
-                        </Menu>
-                        <Menu mnemonicParsing="false" text="%menu.title.scene.stylesheets">
-                            <items>
-                                <MenuItem fx:id="addSceneStyleSheetMenuItem" mnemonicParsing="false" text="%menu.title.add.stylesheet" />
-                                <Menu fx:id="removeSceneStyleSheetMenu" mnemonicParsing="false" text="%menu.title.remove.stylesheet">
-                                    <items>
-                                        <MenuItem disable="true" mnemonicParsing="false" text="%scenestylesheet.none" />
-                                    </items>
-                                </Menu>
-                                <Menu fx:id="openSceneStyleSheetMenu" mnemonicParsing="false" text="%menu.title.open.stylesheet">
-                                    <items>
-                                        <MenuItem disable="true" mnemonicParsing="false" text="%scenestylesheet.none" />
-                                    </items>
-                                </Menu>
-                            </items>
-                        </Menu>
-                        <Menu mnemonicParsing="false" text="%menu.title.internationalization">
-                            <items>
-                                <MenuItem fx:id="setResourceMenuItem" mnemonicParsing="false" text="%menu.title.set.resource" />
-                                <MenuItem fx:id="removeResourceMenuItem" mnemonicParsing="false" text="%menu.title.remove.resource" />
-                                <MenuItem fx:id="revealResourceMenuItem" mnemonicParsing="false" text="%menu.title.reveal.resource" />
-                            </items>
-                        </Menu>
-                    </items>
-                </Menu>
-                <Menu fx:id="windowMenu" mnemonicParsing="false" text="%menu.title.window">
-                    <items>
-                        <SeparatorMenuItem mnemonicParsing="false" />
-                    </items>
-                </Menu>
-                <Menu mnemonicParsing="false" text="%menu.title.help">
-                    <items>
-                        <MenuItem fx:id="helpMenuItem" mnemonicParsing="false" text="%menu.title.scene.builder.help" />
-                        <MenuItem fx:id="aboutMenuItem" mnemonicParsing="false" text="%menu.title.about" />
-                    </items>
-                </Menu>
-            </menus>
-        </MenuBar>
-    </children>
+              </items>
+            </Menu>
+            <Menu mnemonicParsing="false" text="%menu.title.internationalization">
+              <items>
+                <MenuItem mnemonicParsing="false" text="%menu.title.set.resource" fx:id="setResourceMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.remove.resource" fx:id="removeResourceMenuItem" />
+                <MenuItem mnemonicParsing="false" text="%menu.title.reveal.resource" fx:id="revealResourceMenuItem" />
+              </items>
+            </Menu>
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%menu.title.window" fx:id="windowMenu">
+          <items>
+            <SeparatorMenuItem mnemonicParsing="false" />
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%menu.title.help">
+          <items>
+            <MenuItem mnemonicParsing="false" text="%menu.title.scene.builder.help" fx:id="helpMenuItem" />
+            <MenuItem mnemonicParsing="false" text="%menu.title.about" fx:id="aboutMenuItem" />
+          </items>
+        </Menu>
+      </menus>
+    </MenuBar>
+  </children>
 </StackPane>
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBarController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/menubar/MenuBarController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -33,6 +33,7 @@
 
 import com.oracle.javafx.scenebuilder.app.DocumentWindowController;
 import com.oracle.javafx.scenebuilder.app.DocumentWindowController.DocumentControlAction;
+import com.oracle.javafx.scenebuilder.app.DocumentWindowController.DocumentEditAction;
 import com.oracle.javafx.scenebuilder.app.SceneBuilderApp;
 import com.oracle.javafx.scenebuilder.app.SceneBuilderApp.ApplicationControlAction;
 import com.oracle.javafx.scenebuilder.app.i18n.I18N;
@@ -53,6 +54,7 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -66,6 +68,7 @@
 import javafx.event.EventHandler;
 import javafx.fxml.FXML;
 import javafx.fxml.FXMLLoader;
+import javafx.scene.control.CheckMenuItem;
 import javafx.scene.control.Menu;
 import javafx.scene.control.MenuBar;
 import javafx.scene.control.MenuItem;
@@ -207,10 +210,6 @@
     @FXML
     private MenuItem useComputedSizesMenuItem;
     @FXML
-    private MenuItem selectNextRowMenuItem;
-    @FXML
-    private MenuItem selectNextColumnMenuItem;
-    @FXML
     private MenuItem moveRowAboveMenuItem;
     @FXML
     private MenuItem moveRowBelowMenuItem;
@@ -279,9 +278,17 @@
     @FXML
     private MenuItem showPreviewMenuItem;
     @FXML
-    private MenuItem modenaThemeMenuItem;
+    private RadioMenuItem modenaThemeMenuItem;
     @FXML
-    private MenuItem caspianThemeMenuItem;
+    private RadioMenuItem modenaTouchThemeMenuItem;
+    @FXML
+    private RadioMenuItem caspianThemeMenuItem;
+    @FXML
+    private CheckMenuItem caspianHighContrastThemeMenuItem;
+    @FXML
+    private RadioMenuItem caspianEmbeddedThemeMenuItem;
+    @FXML
+    private RadioMenuItem caspianEmbeddedQVGAThemeMenuItem;
     @FXML
     private MenuItem chooseBackgroundColorMenuItem;
     @FXML
@@ -305,6 +312,7 @@
     private MenuItem aboutMenuItem;
 
     private static final KeyCombination.Modifier modifier;
+    private final Map<KeyCombination, MenuItem> keyToMenu = new HashMap<>();
 
     static {
         if (EditorPlatform.IS_MAC) {
@@ -422,8 +430,6 @@
 
         assert fitToParentMenuItem != null;
         assert useComputedSizesMenuItem != null;
-        assert selectNextRowMenuItem != null;
-        assert selectNextColumnMenuItem != null;
         assert moveRowAboveMenuItem != null;
         assert moveRowBelowMenuItem != null;
         assert moveColumnBeforeMenuItem != null;
@@ -459,7 +465,11 @@
 
         assert showPreviewMenuItem != null;
         assert modenaThemeMenuItem != null;
+        assert modenaTouchThemeMenuItem != null;
         assert caspianThemeMenuItem != null;
+        assert caspianHighContrastThemeMenuItem != null;
+        assert caspianEmbeddedThemeMenuItem != null;
+        assert caspianEmbeddedQVGAThemeMenuItem != null;
         assert chooseBackgroundColorMenuItem != null;
         assert addSceneStyleSheetMenuItem != null;
         assert removeSceneStyleSheetMenu != null;
@@ -549,11 +559,11 @@
             // http://windows.microsoft.com/en-US/windows7/Keyboard-shortcuts
             redoMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.Y, modifier));
         }
-        copyMenuItem.setUserData(new ControlActionController(ControlAction.COPY));
+        copyMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.COPY));
         copyMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.C, modifier));
-        cutMenuItem.setUserData(new EditActionController(EditAction.CUT));
+        cutMenuItem.setUserData(new DocumentEditActionController(DocumentEditAction.CUT));
         cutMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.X, modifier));
-        pasteMenuItem.setUserData(new EditActionController(EditAction.PASTE));
+        pasteMenuItem.setUserData(new DocumentEditActionController(DocumentEditAction.PASTE));
         pasteMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.V, modifier));
         pasteIntoMenuItem.setUserData(new EditActionController(EditAction.PASTE_INTO));
         pasteIntoMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.V, KeyCombination.SHIFT_DOWN, modifier));
@@ -561,12 +571,12 @@
         duplicateMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.D, modifier));
         deleteMenuItem.setUserData(new EditActionController(EditAction.DELETE));
         deleteMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.DELETE));
-        selectAllMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_ALL));
+        selectAllMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.SELECT_ALL));
         selectAllMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.A, modifier));
-        selectNoneMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NONE));
+        selectNoneMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.SELECT_NONE));
         selectNoneMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.A, KeyCombination.SHIFT_DOWN, modifier));
         selectParentMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_PARENT));
-        selectParentMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.L, modifier));
+        selectParentMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.UP, modifier));
         selectNextMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT));
         selectNextMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.RIGHT, modifier));
         selectPreviousMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_PREVIOUS));
@@ -661,7 +671,20 @@
             }
         });
         toggleRightPanelMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.DIGIT8, modifier));
-//        toggleOutlinesMenuItem.setUserData(new ControlActionController(ControlAction.));
+        toggleOutlinesMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.TOGGLE_OUTLINES_VISIBILITY) {
+            @Override
+            public String getTitle() {
+                final String titleKey;
+                if (documentWindowController == null) {
+                    titleKey = "menu.title.hide.outlines";
+                } else if (documentWindowController.getContentPanelController().isOutlinesVisible()) {
+                    titleKey = "menu.title.hide.outlines";
+                } else {
+                    titleKey = "menu.title.show.outlines";
+                }
+                return I18N.getString(titleKey);
+            }
+        });
         toggleOutlinesMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.E, modifier));
         toggleSampleDataMenuItem.setUserData(new ControlActionController(ControlAction.TOGGLE_SAMPLE_DATA) {
             @Override
@@ -719,8 +742,6 @@
         fitToParentMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.K, modifier));
         useComputedSizesMenuItem.setUserData(new EditActionController(EditAction.USE_COMPUTED_SIZES));
         useComputedSizesMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.K, KeyCombination.SHIFT_DOWN, modifier));
-        selectNextRowMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT_ROW));
-        selectNextColumnMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT_COLUMN));
         moveRowAboveMenuItem.setUserData(new EditActionController(EditAction.MOVE_ROW_ABOVE));
         moveRowBelowMenuItem.setUserData(new EditActionController(EditAction.MOVE_ROW_BELOW));
         moveColumnBeforeMenuItem.setUserData(new EditActionController(EditAction.MOVE_COLUMN_BEFORE));
@@ -789,8 +810,12 @@
         showPreviewMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.P, modifier));
         chooseBackgroundColorMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.CHOOSE_BACKGROUND_COLOR));
         chooseBackgroundColorMenuItem.setDisable(true);
+        caspianHighContrastThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST));
         caspianThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.CASPIAN));
+        caspianEmbeddedThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.CASPIAN_EMBEDDED));
+        caspianEmbeddedQVGAThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA));
         modenaThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.MODENA));
+        modenaTouchThemeMenuItem.setUserData(new SetThemeActionController(EditorPlatform.Theme.MODENA_TOUCH));
 
         addSceneStyleSheetMenuItem.setUserData(new DocumentControlActionController(DocumentControlAction.ADD_SCENE_STYLE_SHEET));
         updateOpenAndRemoveSceneStyleSheetMenus();
@@ -888,6 +913,9 @@
             }
         } else {
             i.setOnAction(onActionEventHandler);
+            if (i.getAccelerator() != null) {
+                keyToMenu.put(i.getAccelerator(), i);
+            }
         }
     }
 
@@ -906,7 +934,20 @@
             final String title;
             if (i.getUserData() instanceof MenuItemController) {
                 final MenuItemController c = (MenuItemController) i.getUserData();
-                disable = !c.canPerform();
+                boolean canPerform;
+                try {
+                    canPerform = c.canPerform();
+                } catch(RuntimeException x) {
+                    // This catch is protection against a bug in canPerform().
+                    // It avoids to block all the items in the menu in case
+                    // of crash in canPerform() (see DTL-6164).
+                    canPerform = false;
+                    final Exception xx 
+                            = new Exception(c.getClass().getSimpleName() 
+                            + ".canPerform() did break for menu item " + i, x); //NOI18N
+                    xx.printStackTrace();
+                }
+                disable = !canPerform;
                 title = c.getTitle();
                 selected = c.isSelected();
             } else {
@@ -945,7 +986,7 @@
         final MenuItemController c = (MenuItemController) i.getUserData();
         c.perform();
     }
-
+    
     /*
      * Private (zoom menu)
      */
@@ -1329,6 +1370,33 @@
 
     }
 
+    class DocumentEditActionController extends MenuItemController {
+
+        private final DocumentEditAction editAction;
+
+        public DocumentEditActionController(DocumentEditAction editAction) {
+            this.editAction = editAction;
+        }
+
+        @Override
+        public boolean canPerform() {
+            boolean result;
+            if (documentWindowController == null) {
+                result = false;
+            } else {
+                result = documentWindowController.canPerformEditAction(editAction);
+            }
+            return result;
+        }
+
+        @Override
+        public void perform() {
+            assert canPerform() : "editAction=" + editAction;
+            documentWindowController.performEditAction(editAction);
+        }
+
+    }
+
     class DocumentControlActionController extends MenuItemController {
 
         private final DocumentControlAction controlAction;
@@ -1450,28 +1518,126 @@
 
         @Override
         public boolean canPerform() {
-            return (documentWindowController != null);
+            boolean res = documentWindowController != null;
+            final EditorPlatform.Theme currentTheme
+                    = documentWindowController.getEditorController().getTheme();
+            // CASPIAN_HIGH_CONTRAST can be selected only if another CASPIAN
+            // theme is active.
+            if (theme == EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST
+                    && (currentTheme == EditorPlatform.Theme.MODENA || currentTheme == EditorPlatform.Theme.MODENA_TOUCH)) {
+                res = false;
+                caspianHighContrastThemeMenuItem.setSelected(false);
+            }
+            return res;
         }
 
         @Override
         public void perform() {
             assert documentWindowController != null;
-            documentWindowController.getEditorController().setTheme(theme);
+
+            EditorPlatform.Theme overiddingTheme = theme;
+
+            switch (theme) {
+                case CASPIAN:
+                    if (caspianHighContrastThemeMenuItem.isSelected()) {
+                        overiddingTheme = EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST;
+                    }
+                    break;
+                case CASPIAN_EMBEDDED:
+                    if (caspianHighContrastThemeMenuItem.isSelected()) {
+                        overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_HIGH_CONTRAST;
+                    }
+                    break;
+                case CASPIAN_EMBEDDED_QVGA:
+                    if (caspianHighContrastThemeMenuItem.isSelected()) {
+                        overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST;
+                    }
+                    break;
+                case CASPIAN_HIGH_CONTRAST:
+                    final EditorPlatform.Theme currentTheme
+                            = documentWindowController.getEditorController().getTheme();
+                    switch (currentTheme) {
+                        case CASPIAN:
+                            if (caspianHighContrastThemeMenuItem.isSelected()) {
+                                overiddingTheme = EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST;
+                            }
+                            break;
+                        case CASPIAN_EMBEDDED:
+                            if (caspianHighContrastThemeMenuItem.isSelected()) {
+                                overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_HIGH_CONTRAST;
+                            }
+                            break;
+                        case CASPIAN_EMBEDDED_QVGA:
+                            if (caspianHighContrastThemeMenuItem.isSelected()) {
+                                overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST;
+                            }
+                            break;
+                        case CASPIAN_HIGH_CONTRAST:
+                            if (!caspianHighContrastThemeMenuItem.isSelected()) {
+                                overiddingTheme = EditorPlatform.Theme.CASPIAN;
+                            }
+                            break;
+                        case CASPIAN_EMBEDDED_HIGH_CONTRAST:
+                            if (!caspianHighContrastThemeMenuItem.isSelected()) {
+                                overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED;
+                            }
+                            break;
+                        case CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST:
+                            if (!caspianHighContrastThemeMenuItem.isSelected()) {
+                                overiddingTheme = EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA;
+                            }
+                            break;
+                        default:
+                            // All known 6 Caspian cases are already handled above.
+                            assert false;
+                            break;
+                    }
+                    break;
+                default:
+                    // Modena
+                    break;
+            }
+
+            documentWindowController.getEditorController().setTheme(overiddingTheme);
         }
 
         @Override
         public boolean isSelected() {
-            boolean result;
+            boolean res;
 
             if (documentWindowController == null) {
-                result = false;
+                res = false;
             } else {
                 final EditorPlatform.Theme currentTheme
                         = documentWindowController.getEditorController().getTheme();
-                result = currentTheme == theme;
+
+                switch (theme) {
+                    // CASPIAN_HIGH_CONTRAST can be selected only if another CASPIAN
+                    // theme is active.
+                    case CASPIAN_HIGH_CONTRAST:
+                        if (currentTheme == EditorPlatform.Theme.MODENA || currentTheme == EditorPlatform.Theme.MODENA_TOUCH) {
+                            res = false;
+                        } else {
+                            res = true;
+                        }
+                        break;
+                    case CASPIAN:
+                        res = (currentTheme == theme || currentTheme == EditorPlatform.Theme.CASPIAN_HIGH_CONTRAST);
+                        break;
+                    case CASPIAN_EMBEDDED:
+                        res = (currentTheme == theme || currentTheme == EditorPlatform.Theme.CASPIAN_EMBEDDED_HIGH_CONTRAST);
+                        break;
+                    case CASPIAN_EMBEDDED_QVGA:
+                        res = (currentTheme == theme || currentTheme == EditorPlatform.Theme.CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST);
+                        break;
+                    default:
+                        // Modena
+                        res = currentTheme == theme;
+                        break;
+                }
             }
 
-            return result;
+            return res;
         }
     }
 
@@ -1525,6 +1691,14 @@
         }
     }
 
+    public MenuItem getMenuItem(KeyCombination key) {
+        return keyToMenu.get(key);
+    }
+
+    public Set<KeyCombination> getAccelerators() {
+        return keyToMenu.keySet();
+    }
+
     /**
      * *************************************************************************
      * Static inner class
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBar.fxml	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBar.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -44,29 +44,33 @@
     <HBox fx:id="messageBox" alignment="CENTER" spacing="5.0" styleClass="message-bar">
       <children>
         <StackPane fx:id="selectionBarHost" prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="ALWAYS" />
-        <Label fx:id="messageLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mouseTransparent="true" style="&#10;" text="Message" HBox.hgrow="ALWAYS" />
-        <HBox id="messageBox" alignment="CENTER_RIGHT" fillHeight="true" prefHeight="-1.0" prefWidth="-1.0" spacing="0.0" HBox.hgrow="NEVER">
+        <HBox fx:id="messagePart" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
           <children>
-            <Button fx:id="messageButton" alignment="CENTER" maxHeight="1.7976931348623157E308" minHeight="-1.0" minWidth="20.0" mnemonicParsing="false" onAction="#onOpenCloseAction" text="" HBox.hgrow="ALWAYS">
-              <graphic>
-                <ImageView id="warning" pickOnBounds="true" visible="true">
-                  <image>
-                    <Image preserveRatio="true" smooth="true" url="@warning.png" />
-                  </image>
-                </ImageView>
-              </graphic>
-              <tooltip>
-                  <Tooltip text="%message.bar.details" />
-              </tooltip>
-            </Button>
-            <Label fx:id="statusLabel" contentDisplay="CENTER" focusTraversable="false" graphicTextGap="0.0" maxHeight="1.7976931348623157E308" minWidth="30.0" prefWidth="30.0" text="" HBox.hgrow="ALWAYS">
-              <tooltip>
-                <Tooltip text="%message.bar.file.dirty" />
-              </tooltip>
-              <HBox.margin>
-                <Insets />
-              </HBox.margin>
-            </Label>
+            <Label fx:id="messageLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mouseTransparent="true" style="&#10;" text="Message" HBox.hgrow="ALWAYS" />
+            <HBox id="messageBox" alignment="CENTER_RIGHT" fillHeight="true" prefHeight="-1.0" prefWidth="-1.0" spacing="0.0" HBox.hgrow="NEVER">
+             <children>
+                <Button fx:id="messageButton" alignment="CENTER" maxHeight="1.7976931348623157E308" minHeight="-1.0" minWidth="20.0" mnemonicParsing="false" onAction="#onOpenCloseAction" text="">
+                  <graphic>
+                    <ImageView id="warning" pickOnBounds="true" visible="true">
+                      <image>
+                        <Image preserveRatio="true" smooth="true" url="@warning.png" />
+                      </image>
+                    </ImageView>
+                  </graphic>
+                  <tooltip>
+                      <Tooltip text="%message.bar.details" />
+                  </tooltip>
+                </Button>
+                <Label fx:id="statusLabel" contentDisplay="CENTER" focusTraversable="false" graphicTextGap="0.0" maxHeight="1.7976931348623157E308" minWidth="30.0" prefWidth="30.0" text="">
+                  <tooltip>
+                    <Tooltip text="%message.bar.file.dirty" />
+                  </tooltip>
+                  <HBox.margin>
+                    <Insets />
+                  </HBox.margin>
+                </Label>
+              </children>
+            </HBox>
           </children>
         </HBox>
       </children>
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBarController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/message/MessageBarController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -37,12 +37,11 @@
 import com.oracle.javafx.scenebuilder.kit.editor.panel.util.AbstractFxmlPanelController;
 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
 import java.net.URL;
-import java.util.Timer;
-import java.util.TimerTask;
-import javafx.application.Platform;
+import javafx.animation.FadeTransition;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
 import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
 import javafx.fxml.FXML;
 import javafx.scene.control.Button;
 import javafx.scene.control.Label;
@@ -50,7 +49,9 @@
 import javafx.scene.image.Image;
 import javafx.scene.image.ImageView;
 import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
 import javafx.scene.layout.StackPane;
+import javafx.util.Duration;
 
 /**
  *
@@ -70,6 +71,8 @@
     private Label statusLabel;
     @FXML
     private StackPane selectionBarHost;
+    @FXML
+    private HBox messagePart;
 
     private final ImageView fileDirtyImage;
     private Tooltip statusLabelTooltip = null;
@@ -194,6 +197,7 @@
         // no need to display anything in the message bar.
         if (entry != null && logSize > previousTotalNumOfMessages) {
             // We mask the host
+            HBox.setHgrow(messagePart, Priority.ALWAYS);
             getSelectionBarHost().getChildren().get(0).setVisible(false);
             getSelectionBarHost().setManaged(false);
             messageLabel.setManaged(true);
@@ -218,64 +222,31 @@
             messageLabel.setText(entry.getText());
             messageLabel.setVisible(true);
             
-            // We go back to the host after a given time
-            // The fading based code commented out below do not seem to be
-            // reliable in the sense that when sending slowly 10 messages in a
-            // row you get 1 or 2 where the display time isn't correct, fading
-            // duration abrupt, ...
-            // For now we use a timer to switch back abruptly. But fact is the
-            // time the message remains visible do not seem more stable than
-            // with the fading transition.
-            final Timer timer = new Timer(true);
-            final TimerTask timerTask = new TimerTask() {
+            // We go back to the host after a given time            
+            FadeTransition showHost = new FadeTransition(Duration.seconds(1), messagePart);
+            showHost.setFromValue(1.0);
+            showHost.setToValue(0.0);
+            showHost.setDelay(Duration.seconds(2));
+            showHost.setOnFinished(new EventHandler<ActionEvent>() {
 
                 @Override
-                public void run() {
-                    Platform.runLater(new Runnable() {
-
-                        @Override
-                        public void run() {
-                            messageLabel.setVisible(false);
-                            messageLabel.setGraphic(null);
-                            messageLabel.setManaged(false);
-                            if (getEditorController().getMessageLog().getWarningEntryCount() == 0) {
-                                messageButton.setVisible(false);
-                                messageButton.setManaged(false);
-                            }
-                                resetStyle();
-                            getSelectionBarHost().setManaged(true);
-                            getSelectionBarHost().getChildren().get(0).setOpacity(1.0);
-                            getSelectionBarHost().getChildren().get(0).setVisible(true);
-                        }
-                    });
-                    // I don't need to use the timer later on so by cancelling
-                    // it here I free resources that otherwise would prevent
-                    // the JVM from exiting.
-                    timer.cancel();
+                public void handle(ActionEvent t) {
+                    messageLabel.setVisible(false);
+                    messageLabel.setGraphic(null);
+                    messageLabel.setManaged(false);
+                    if (getEditorController().getMessageLog().getWarningEntryCount() == 0) {
+                        messageButton.setVisible(false);
+                        messageButton.setManaged(false);
+                    }
+                    resetStyle();
+                    getSelectionBarHost().setManaged(true);
+                    getSelectionBarHost().getChildren().get(0).setOpacity(1.0);
+                    getSelectionBarHost().getChildren().get(0).setVisible(true);
+                    messagePart.setOpacity(1.0);
+                    HBox.setHgrow(messagePart, Priority.NEVER);
                 }
-            };
-            timer.schedule(timerTask, 2000); // milliseconds
-            
-//            FadeTransition showHost = new FadeTransition(Duration.seconds(1), messageLabel);
-//            showHost.setFromValue(1.0);
-//            showHost.setToValue(0.0);
-//            showHost.setDelay(Duration.seconds(3));
-//            showHost.setOnFinished(new EventHandler<ActionEvent>() {
-//
-//                @Override
-//                public void handle(ActionEvent t) {
-//                    messageLabel.setVisible(false);
-//                    messageButton.setVisible(false);
-//                    if (entry.getType() == MessageLogEntry.Type.INFO) {
-//                        messageLabel.getStyleClass().remove("message-label-info");
-//                    } else {
-//                        messageLabel.getStyleClass().remove("message-label-warning-and-error");
-//                    }
-//                    getSelectionBarHost().getChildren().get(0).setOpacity(1.0);
-//                    getSelectionBarHost().getChildren().get(0).setVisible(true);
-//                }
-//            });
-//            showHost.play();
+            });
+            showHost.play();
         } else if (getEditorController().getMessageLog().getEntryCount() == 0) {
             if (messageWindowController != null && messageWindowController.isWindowOpened()) {
                 messageWindowController.closeWindow();
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/preview/PreviewWindowController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/preview/PreviewWindowController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -43,7 +43,10 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.MalformedURLException;
+import java.net.URL;
 import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.PropertyResourceBundle;
 import java.util.ResourceBundle;
 import java.util.Timer;
@@ -161,7 +164,7 @@
     protected void makeRoot() {
         // Until the timer used in requestUpdate() expires, so that the root of
         // the scene is updated to the real content, we set a placeholder.
-        StackPane sp = new StackPane(new Label(I18N.getString("preview.constructing")));
+        StackPane sp = new StackPane();
         sp.setPrefSize(WIDTH_WHEN_EMPTY, HEIGHT_WHEN_EMPTY);
         setRoot(sp);
 
@@ -205,7 +208,7 @@
 
     /**
      * There's a delay before the content of the preview is refreshed. If any
-     * further modification is brought to the layout before expiration of this
+     * further modification is brought to the layout before expiration of it
      * we restart the timer. The idea is to lower the resources used to refresh
      * the preview window content.
      */
@@ -246,16 +249,25 @@
                             }
 
                             Object sceneGraphRoot = clone.getSceneGraphRoot();
-                            final String themeStyleSheetString =
-                                    EditorPlatform.getThemeStylesheetURL(editorControllerTheme).toString();
+                            final List<String> themeStyleSheetStrings = new ArrayList<>();
+                            for (URL themeURL : EditorPlatform.getThemeStylesheetURLs(editorControllerTheme)) {
+                                themeStyleSheetStrings.add(themeURL.toString());
+                            }
 
                             if (sceneGraphRoot instanceof Parent) {
                                 ((Parent) sceneGraphRoot).setId(NID_PREVIEW_ROOT);
                                 setRoot((Parent) updateAutoResizeTransform((Parent) sceneGraphRoot));
                                 assert ((Parent) sceneGraphRoot).getScene() == null;
-                                ((Parent) sceneGraphRoot).getStylesheets().removeAll(themeStyleSheetString);
-                                ((Parent) sceneGraphRoot).getStylesheets().add(themeStyleSheetString);
                                 
+                                // At that stage current style sheets are the one defined within the FXML
+                                ObservableList<String> currentStyleSheets = ((Parent) sceneGraphRoot).getStylesheets();
+                                List<String> newStyleSheets = new ArrayList<>();
+                                
+                                for (String stylesheet : currentStyleSheets) {
+                                    newStyleSheets.add(stylesheet);
+                                }
+                                
+                                // Add style sheet set thanks Preview > Scene Style Sheets > Add a Style Sheet
                                 if (sceneStyleSheet != null) {
                                     for (File f : sceneStyleSheet) {
                                         String urlString = ""; //NOI18N
@@ -264,16 +276,21 @@
                                         } catch (MalformedURLException ex) {
                                             throw new RuntimeException("Bug in PreviewWindowController", ex); //NOI18N
                                         }
-                                        ((Parent) sceneGraphRoot).getStylesheets().removeAll(urlString);
-                                        ((Parent) sceneGraphRoot).getStylesheets().add(urlString);
+                                        newStyleSheets.add(urlString);
                                     }
                                 }
-                                                                
-                                // Not proven necessary as per my testing
-//                                ((Parent) sceneGraphRoot).applyCss();
+                                
+                                // Clean all styling
+                                ((Parent) sceneGraphRoot).getStylesheets().removeAll();
+                                
+                                // Add theme style sheet; order is significant ==> theme one always first
+                                newStyleSheets.addAll(0, themeStyleSheetStrings);
+                                
+                                // Apply the whole styling
+                               ((Parent) sceneGraphRoot).getStylesheets().addAll(newStyleSheets);
                             } else if (sceneGraphRoot instanceof Node) {
                                 StackPane sp = new StackPane();
-                                sp.getStylesheets().add(themeStyleSheetString);
+                                sp.getStylesheets().addAll(0, themeStyleSheetStrings);
                                 
                                 if (sceneStyleSheet != null) {
                                     for (File f : sceneStyleSheet) {
@@ -314,11 +331,12 @@
             }
         };
 
-        // If there is no opened document while Preview window is built we want
-        // it to come up immediately.
         long delay = 0;
 
-        if (editorController.getFxomDocument() != null) {
+        // A long delay makes sense only if we have a valid document and
+        // the preview window is already opened.
+        // When opening preview window we want it fast.
+        if (editorController.getFxomDocument() != null && getStage().isShowing()) {
             delay = 1000;
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReport.css	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.scroll-pane, .scroll-pane:focused, .scroll-pane:selected, .scroll-pane:pressed, .scroll-pane:hover {
+    -fx-background-color: null;
+    -fx-padding: 0px;
+    -fx-border-width: 1px;
+    -fx-border-color: lightgrey;
+}
+
+.header {
+}
+
+.body {
+    -fx-font-family: monospace;
+    -fx-fill: slategray;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReport.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+  All rights reserved. Use is subject to license terms.
+
+  This file is available and licensed under the following license:
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  - Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+  - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the distribution.
+  - Neither the name of Oracle Corporation nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+<?import java.lang.*?>
+<?import java.net.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.text.*?>
+
+<StackPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+    <children>
+        <VBox prefHeight="400.0" prefWidth="600.0">
+            <children>
+                <Label fx:id="timestampLabel" text="%jar.analysis.report.timestamp">
+                <VBox.margin>
+                  <Insets bottom="7.0" />
+                </VBox.margin>
+                </Label>
+<ScrollPane prefViewportHeight="350.0" prefViewportWidth="600.0" VBox.vgrow="ALWAYS" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+<content><TextFlow fx:id="textFlow" focusTraversable="true" VBox.vgrow="ALWAYS" />
+</content>
+<VBox.margin>
+<Insets />
+</VBox.margin>
+</ScrollPane>
+                <Button defaultButton="true" mnemonicParsing="false" onAction="#onCopyAction" text="%label.copy">
+                <VBox.margin>
+                  <Insets top="7.0" />
+                </VBox.margin></Button>
+            </children>
+            <StackPane.margin>
+                <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
+            </StackPane.margin>
+        </VBox>
+    </children>
+    <stylesheets>
+        <URL value="@JarAnalysisReport.css" />
+    </stylesheets>
+</StackPane>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/report/JarAnalysisReportController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.oracle.javafx.scenebuilder.app.report;
+
+import com.oracle.javafx.scenebuilder.app.i18n.I18N;
+import com.oracle.javafx.scenebuilder.kit.editor.EditorController;
+import com.oracle.javafx.scenebuilder.kit.editor.panel.util.AbstractFxmlWindowController;
+import com.oracle.javafx.scenebuilder.kit.library.user.UserLibrary;
+import com.oracle.javafx.scenebuilder.kit.library.util.JarReport;
+import com.oracle.javafx.scenebuilder.kit.library.util.JarReportEntry;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import javafx.collections.ListChangeListener;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+import javafx.scene.input.Clipboard;
+import javafx.scene.input.DataFormat;
+import javafx.stage.Window;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import javafx.scene.Node;
+import javafx.scene.text.Text;
+import javafx.scene.text.TextFlow;
+import javafx.stage.WindowEvent;
+
+/**
+ *
+ */
+public class JarAnalysisReportController extends AbstractFxmlWindowController {
+    
+    @FXML
+    TextFlow textFlow;
+    @FXML
+    Label timestampLabel;
+
+    @FXML
+    void onCopyAction(ActionEvent event) {
+        final Map<DataFormat, Object> content = new HashMap<>();
+        StringBuilder sb = new StringBuilder();
+
+        for (Node item : textFlow.getChildrenUnmodifiable()) {
+            if (item instanceof Text) {
+                sb.append(((Text)item).getText());
+            }
+        }
+        
+        content.put(DataFormat.PLAIN_TEXT, sb.toString());
+        Clipboard.getSystemClipboard().setContent(content);
+    }
+
+    private final EditorController editorController;
+    private final String TIMESTAMP_PATTERN = "h:mm a EEEEEEEEE d MMM. yyyy"; //NOI18N
+    private final SimpleDateFormat TIMESTAMP_DATE_FORMAT = new SimpleDateFormat(TIMESTAMP_PATTERN);
+    private int prefixCounter = 0;
+    private boolean dirty = false;
+
+    public JarAnalysisReportController(EditorController editorController, Window owner) {
+        super(JarAnalysisReportController.class.getResource("JarAnalysisReport.fxml"), I18N.getBundle(), owner); //NOI18N
+        this.editorController = editorController;
+    }
+
+    @Override
+    public void onCloseRequest(WindowEvent event) {
+        getStage().close();
+    }
+    
+    @Override
+    public void openWindow() {
+        super.openWindow();
+        
+        if (dirty) {
+            update();
+        }
+    }
+    
+    @Override
+    protected void controllerDidCreateStage() {
+        // Setup window title
+        getStage().setTitle(I18N.getString("jar.analysis.report.title"));
+    }
+
+    @Override
+    protected void controllerDidLoadFxml() {
+        assert textFlow != null;
+        assert timestampLabel != null;
+                
+        UserLibrary lib = (UserLibrary)editorController.getLibrary();
+        lib.getJarReports().addListener(new ListChangeListener<JarReport>() {
+
+            @Override
+            public void onChanged(ListChangeListener.Change<? extends JarReport> change) {
+                update();
+            }
+        });
+        
+        update();
+    }
+    
+    private void update() {
+        // No need to eat CPU if the skeleton window isn't opened
+        if (getStage().isShowing()) {
+            textFlow.getChildren().clear();
+            
+            updateTimeStampLabel();
+            
+            UserLibrary lib = (UserLibrary)editorController.getLibrary();
+            
+            for (JarReport report : lib.getJarReports()) {
+                for (JarReportEntry entry : report.getEntries()) {
+                    if (entry.getStatus() != JarReportEntry.Status.OK) {
+                        if (entry.getKlass() != null && entry.getException() != null) {
+                            // We use a Text instance for header and another one
+                            // for full stack in order to style them separately
+                            StringBuilder sb = new StringBuilder();
+                            sb.append(getSectionPrefix()).append(I18N.getString("jar.analysis.exception"));
+                            sb.append(" ").append(entry.getName()); //NOI18N
+                            Text text = new Text();
+                            text.setText(sb.toString());
+                            text.getStyleClass().add("header"); //NOI18N
+                            textFlow.getChildren().add(text);
+                            
+                            StringBuilder sb2 = new StringBuilder();
+                            sb2.append(getFullStack(entry.getException()));
+                            Text text2 = new Text();
+                            text2.setText(sb2.toString());
+                            text2.getStyleClass().add("body"); //NOI18N
+                            textFlow.getChildren().add(text2);
+                        }
+                    } else if (! entry.isNode()) {
+                        StringBuilder sb = new StringBuilder();
+                        sb.append(getSectionPrefix()).append(I18N.getString("jar.analysis.not.node"));
+                        sb.append(" ").append(entry.getName()); //NOI18N
+                        Text text = new Text();
+                        text.setText(sb.toString());
+                        text.getStyleClass().add("header"); //NOI18N
+                        textFlow.getChildren().add(text);
+                    }
+                }
+            }
+
+            dirty = false;
+        } else {
+            dirty = true;
+        }
+    }
+    
+    // The very first section must start on top, it is only for the next one we
+    // need a separator.
+    private String getSectionPrefix() {
+        if (prefixCounter == 0) {
+            prefixCounter++;
+            return ""; //NOI18N
+        } else {
+            return "\n\n"; //NOI18N
+        }
+    }
+    
+    private StringBuilder getFullStack(Throwable t) {
+        StringBuilder res = new StringBuilder("\n"); //NOI18N
+        StringWriter writer = new StringWriter();
+            t.printStackTrace(new PrintWriter(writer, true));
+            res.append(writer.getBuffer().toString());
+        return res;
+    }
+    
+    private void updateTimeStampLabel() {
+        UserLibrary lib = (UserLibrary)editorController.getLibrary();
+        Date date = (Date)lib.getExplorationDate();
+        String timestampValue = TIMESTAMP_DATE_FORMAT.format(date);
+        timestampLabel.setText(I18N.getString("jar.analysis.report.timestamp", timestampValue));
+    }
+}
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonBuffer.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonBuffer.java	Mon Dec 23 13:59:52 2013 +0100
@@ -35,6 +35,7 @@
 import com.oracle.javafx.scenebuilder.app.i18n.I18N;
 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMPropertyT;
 import java.lang.reflect.TypeVariable;
 import java.net.URL;
 import java.util.Map;
@@ -59,6 +60,7 @@
     private final StringBuilder classLine = new StringBuilder();
     private final StringBuilder header = new StringBuilder();
     private final StringBuilder initialize = new StringBuilder();
+    private final StringBuilder handlers = new StringBuilder();
 
     enum TEXT_TYPE {
 
@@ -155,6 +157,7 @@
         constructClassLine();
         String documentName = DocumentWindowController.makeTitle(document);
 
+        // All that depends on fx:id
         Map<String, FXOMObject> fxids = document.collectFxIds();
 
         for (FXOMObject value : fxids.values()) {
@@ -199,6 +202,14 @@
         if (textFormat == FORMAT_TYPE.FULL) {
             addImportsFor(imports, URL.class, ResourceBundle.class);
         }
+        
+        // Event handlers
+        for (FXOMPropertyT property : document.getFxomRoot().collectEventHandlers()) {
+            handlers.append(INDENT).append("@FXML\n").append(INDENT).append("void "); //NOI18N
+            final String methodName = property.getValue().replace("#", ""); //NOI18N
+            handlers.append(methodName);
+            handlers.append("(ActionEvent event) {\n\n").append(INDENT).append("}\n\n"); //NOI18N
+        }
 
         // This method must be called once asserts has been populated.
         constructInitialize();
@@ -239,6 +250,7 @@
         }
 
         code.append(variables);
+        code.append(handlers);
         code.append(initialize);
         code.append("}\n"); //NOI18N
 
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindow.fxml	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindow.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -45,7 +45,7 @@
                 <TextArea fx:id="textArea" editable="false" focusTraversable="false" prefHeight="500.0" VBox.vgrow="ALWAYS" />
                 <HBox alignment="BASELINE_RIGHT" prefWidth="600.0" spacing="20.0">
                     <children>
-                        <Button fx:id="copyButton" mnemonicParsing="false" onAction="#onCopyAction" text="%label.copy" HBox.hgrow="ALWAYS" />
+                        <Button mnemonicParsing="false" onAction="#onCopyAction" text="%label.copy" HBox.hgrow="ALWAYS" />
                         <HBox alignment="BASELINE_RIGHT" spacing="5.0" HBox.hgrow="ALWAYS">
                             <children>
                                 <CheckBox fx:id="commentCheckBox" mnemonicParsing="false" text="%skeleton.add.comments">
--- a/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindowController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderApp/src/com/oracle/javafx/scenebuilder/app/skeleton/SkeletonWindowController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -58,8 +58,6 @@
 public class SkeletonWindowController extends AbstractFxmlWindowController {
 
     @FXML
-    Button copyButton;
-    @FXML
     CheckBox commentCheckBox;
     @FXML
     CheckBox formatCheckBox;
@@ -80,6 +78,7 @@
     }
 
     private final EditorController editorController;
+    private boolean dirty = false;
 
     public SkeletonWindowController(EditorController editorController, Window owner) {
         super(SkeletonWindowController.class.getResource("SkeletonWindow.fxml"), I18N.getBundle(), owner); //NOI18N
@@ -110,6 +109,15 @@
     public void onCloseRequest(WindowEvent event) {
         getStage().close();
     }
+    
+    @Override
+    public void openWindow() {
+        super.openWindow();
+        
+        if (dirty) {
+            update();
+        }
+    }
 
     /*
      * AbstractFxmlWindowController
@@ -117,7 +125,6 @@
     @Override
     protected void controllerDidLoadFxml() {
         super.controllerDidLoadFxml();
-        assert copyButton != null;
         assert commentCheckBox != null;
         assert formatCheckBox != null;
         assert textArea != null;
@@ -159,192 +166,27 @@
     }
 
     private void update() {
-        updateTitle();
-        final SkeletonBuffer buf = new SkeletonBuffer(editorController.getFxomDocument());
+        // No need to eat CPU if the skeleton window isn't opened
+        if (getStage().isShowing()) {
+            updateTitle();
+            final SkeletonBuffer buf = new SkeletonBuffer(editorController.getFxomDocument());
 
-        if (commentCheckBox.isSelected()) {
-            buf.setTextType(TEXT_TYPE.WITH_COMMENTS);
+            if (commentCheckBox.isSelected()) {
+                buf.setTextType(TEXT_TYPE.WITH_COMMENTS);
+            } else {
+                buf.setTextType(TEXT_TYPE.WITHOUT_COMMENTS);
+            }
+
+            if (formatCheckBox.isSelected()) {
+                buf.setFormat(FORMAT_TYPE.FULL);
+            } else {
+                buf.setFormat(FORMAT_TYPE.COMPACT);
+            }
+
+            textArea.setText(buf.toString());
+            dirty = false;
         } else {
-            buf.setTextType(TEXT_TYPE.WITHOUT_COMMENTS);
+            dirty = true;
         }
-
-        if (formatCheckBox.isSelected()) {
-            buf.setFormat(FORMAT_TYPE.FULL);
-        } else {
-            buf.setFormat(FORMAT_TYPE.COMPACT);
-        }
-        
-        textArea.setText(buf.toString());
     }
-
-//    private String generateSkeleton(TEXT_TYPE textType) {
-//        final String INDENT = "    "; //NOI18N
-//        Map<String, FXOMObject> fxids = editorController.getFxomDocument().collectFxIds();
-//        Set<String> imports = new TreeSet<>();
-//        StringBuilder variables = new StringBuilder();
-//        StringBuilder asserts = new StringBuilder();
-//        
-//        for (String key : fxids.keySet()) {
-//            final FXOMObject value = fxids.get(key);
-////            if (value.isEmpty()) {
-////                continue;
-////            }
-////            if (value.size() > 1) {
-////                variables.append(INDENT).append("// WARNING: fx:id=\"").append(key) //NOI18N
-////                        .append("\" cannot be injected: several objects share the same fx:id;\n\n"); //NOI18N
-////            } else if (Utils.isValidFxmlId(key)) {
-//                final Object obj = value.getSceneGraphObject();
-//                final Class<?> type = obj.getClass();
-//
-////                if (ComponentDictionary.lookupDefinition(type, false) == null && !type.equals(ToggleGroup.class)) {
-////                    Utils.println("Class '" + type.getSimpleName() + "' has no definition: skipping fx:id=\"" + key + "\"");
-////                    continue;
-////                }
-//
-//                addImportsFor(imports, FXML.class, type);
-//                variables.append(INDENT).append("@FXML"); //NOI18N
-//                
-//                if (textType == TEXT_TYPE.WITH_COMMENTS) {
-//                    variables.append(" // fx:id=\"").append(key).append("\""); //NOI18N
-//                }
-//                
-//                variables.append("\n"); //NOI18N
-//                variables.append(INDENT).append("private ").append(type.getSimpleName()); //NOI18N
-//                final TypeVariable<? extends Class<?>>[] parameters = type.getTypeParameters();
-//                
-//                if (parameters.length > 0) {
-//                    variables.append("<"); //NOI18N
-//                    String sep = ""; //NOI18N
-//                    for (TypeVariable<?> t : parameters) {
-//                        variables.append(sep).append("?"); //NOI18N
-//                        sep = ", "; //NOI18N
-//                    }
-//                    variables.append(">"); //NOI18N
-//                }
-//                
-//                if (textType == TEXT_TYPE.WITH_COMMENTS) {
-//                    variables.append(" ").append(key).append("; // Value injected by FXMLLoader\n\n"); //NOI18N
-//                } else {
-//                    variables.append(" ").append(key).append(";\n\n"); //NOI18N
-//                }
-//                
-//                asserts.append(INDENT).append(INDENT).append("assert ").append(key).append(" != null : ") //NOI18N
-//                        .append("\"fx:id=\\\"").append(key).append("\\\" was not injected: check your FXML file ") //NOI18N
-////                        .append("'").append(project.isUntitledProject() ? project.getProjectName() : project.getProjectFxmlFile().getName()) //NOI18N
-//                        .append("'.\";\n"); //NOI18N
-////            } else {
-////                variables.append(INDENT).append("// WARNING: fx:id=\"").append(key) //NOI18N
-////                        .append("\" cannot be injected: it is not a valid Java Identifier;\n\n"); //NOI18N
-////            }
-//        }
-//
-//        addImportsFor(imports, URL.class, ResourceBundle.class);
-//        
-//        // GLOP
-//        StringBuilder glop = new StringBuilder();
-//        for (String ouaf : imports) {
-//            glop.append(ouaf);
-//        }
-//        return glop.toString();
-//
-////        final StringBuilder handlerCode = new StringBuilder();
-////        final Map<String, Set<TargetPropertyValue>> handlers = Collections.unmodifiableMap(context.handlers);
-////        final TreeSet<String> handlerNames = new TreeSet<>(handlers.keySet());
-////        for (String name : handlerNames) {
-////            if (!name.startsWith("#") || name.startsWith("##")) {
-////                continue; //NOI18N
-////            }
-////            final String methodName = name.substring(1);
-////            if (!Utils.isValidFxmlId(methodName)) {
-////                handlerCode.append(INDENT)
-////                        .append("// WARNING: cannot create handler for '") //NOI18N
-////                        .append(name).append("': not a valid method name\n\n"); //NOI18N
-////            } else {
-////                TreeSet<String> comments = new TreeSet<>();
-////                Class<?> eventClass = null;
-////                for (TargetPropertyValue tpv : handlers.get(name)) {
-////                    comments.add(describeHandler(tpv));
-////                    if (!tpv.getProperty().isProp()) {
-////                        eventClass = Event.class;
-////                    } else {
-////                        eventClass = commonEventClass(eventClass, tpv.getProperty().getProp().getType());
-////                    }
-////                }
-////                if (textType == TEXT_TYPE.WITH_COMMENTS) {
-////                    for (String s : comments) {
-////                        handlerCode.append(INDENT).append(s);
-////                    }
-////                }
-////                handlerCode.append(INDENT).append("@FXML\n"); //NOI18N
-////                handlerCode.append(INDENT).append("void ").append(methodName).append("(") //NOI18N
-////                        .append(eventClass.getSimpleName()).append(" event) {\n"); //NOI18N
-////                if (textType == TEXT_TYPE.WITH_COMMENTS) {
-////                    handlerCode.append(INDENT).append(INDENT).append("// handle the event here\n"); //NOI18N
-////                }
-////                handlerCode.append(INDENT).append("}\n\n"); //NOI18N
-////                addImportsFor(imports, eventClass);
-////            }
-////        }
-////
-////        final StringBuilder controller = new StringBuilder();
-////        String controllerName = project.getScreenData().getControllerClass();
-////        if (controllerName == null || controllerName.isEmpty()) {
-////            controllerName = "PleaseProvideControllerClassName"; //NOI18N
-////        }
-////        String simpleName = controllerName.replace("$", "."); //NOI18N
-////        int dot = simpleName.lastIndexOf('.');
-////        if (dot > -1) {
-////            simpleName = simpleName.substring(dot + 1);
-////        }
-////        if (textType == TEXT_TYPE.WITH_COMMENTS) {
-////            controller.append("/**\n").append(" * ") //NOI18N
-////                    .append(format("menu.view.sample.controller.skeleton.header.line1", project.getProjectName()))
-////                    .append("\n").append(" * ") //NOI18N
-////                    .append(format("menu.view.sample.controller.skeleton.header.line2"))
-////                    .append("\n").append(" **/\n\n"); //NOI18N
-////        }
-////        if (!controllerName.contains("$")) { //NOI18N
-////            int lastdot = controllerName.lastIndexOf('.');
-////            if (lastdot > 0) {
-////                controller.append("package ").append(controllerName.substring(0, lastdot)).append(";\n\n"); //NOI18N
-////            }
-////        }
-////        for (String imp : imports) {
-////            controller.append(imp);
-////        }
-////        controller.append("\n\n"); //NOI18N
-////        controller.append("public "); //NOI18N
-////        if (controllerName.contains("$")) { //NOI18N
-////            controller.append("static "); //NOI18N
-////        }
-////        controller.append("class ").append(simpleName).append(" {\n\n"); //NOI18N
-////        if (textType == TEXT_TYPE.WITH_COMMENTS) {
-////            controller.append(INDENT).append("@FXML // ResourceBundle that was given to the FXMLLoader\n") //NOI18N
-////                    .append(INDENT).append("private ResourceBundle resources;\n\n") //NOI18N
-////                    .append(INDENT).append("@FXML // URL location of the FXML file that was given to the FXMLLoader\n") //NOI18N
-////                    .append(INDENT).append("private URL location;\n\n"); //NOI18N
-////        } else {
-////            controller.append(INDENT).append("@FXML\n") //NOI18N
-////                    .append(INDENT).append("private ResourceBundle resources;\n\n") //NOI18N
-////                    .append(INDENT).append("@FXML\n") //NOI18N
-////                    .append(INDENT).append("private URL location;\n\n"); //NOI18N
-////        }
-////        controller.append(variables);
-////        controller.append("\n"); //NOI18N
-////        controller.append(handlerCode.toString());
-////        if (textType == TEXT_TYPE.WITH_COMMENTS) {
-////            controller.append(INDENT).append("@FXML // This method is called by the FXMLLoader when initialization is complete\n"); //NOI18N
-////        } else {
-////            controller.append(INDENT).append("@FXML\n"); //NOI18N
-////        }
-////        controller.append(INDENT).append("void initialize() {\n") //NOI18N
-////                .append(asserts.toString()).append("\n"); //NOI18N
-////        if (textType == TEXT_TYPE.WITH_COMMENTS) {
-////            controller.append(INDENT).append(INDENT).append("// Initialize your logic here: all @FXML variables will have been injected\n"); //NOI18N
-////        }
-////        controller.append("\n") //NOI18N
-////                .append(INDENT).append("}\n\n"); //NOI18N
-////        controller.append("}\n"); //NOI18N
-////        return controller.toString();
-//    }
 }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -51,6 +51,7 @@
 import com.oracle.javafx.scenebuilder.kit.editor.job.gridpane.GridPaneJobUtils.Position;
 import com.oracle.javafx.scenebuilder.kit.editor.job.gridpane.MoveColumnJob;
 import com.oracle.javafx.scenebuilder.kit.editor.job.gridpane.MoveRowJob;
+import com.oracle.javafx.scenebuilder.kit.editor.job.wrap.AbstractWrapInJob;
 import com.oracle.javafx.scenebuilder.kit.editor.job.wrap.UnwrapJob;
 import com.oracle.javafx.scenebuilder.kit.editor.job.wrap.WrapInAnchorPaneJob;
 import com.oracle.javafx.scenebuilder.kit.editor.job.wrap.WrapInGridPaneJob;
@@ -102,6 +103,7 @@
 import javafx.beans.value.ObservableListValue;
 import javafx.beans.value.ObservableValue;
 import javafx.collections.ObservableList;
+import javafx.scene.Parent;
 import javafx.scene.effect.Effect;
 import javafx.scene.input.Clipboard;
 import javafx.util.Callback;
@@ -183,10 +185,7 @@
         SELECT_NEXT,
         SELECT_PREVIOUS,
         TOGGLE_CSS_SELECTION,
-        TOGGLE_SAMPLE_DATA,
-        // Candidates for Modify - GridPane
-        SELECT_NEXT_ROW,
-        SELECT_NEXT_COLUMN,
+        TOGGLE_SAMPLE_DATA
     }
     
     private final Selection selection = new Selection();
@@ -858,63 +857,51 @@
                 break;
             }
             case WRAP_IN_ANCHOR_PANE: {
-                final WrapInAnchorPaneJob job = new WrapInAnchorPaneJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.layout.AnchorPane.class);
                 break;
             }
             case WRAP_IN_GRID_PANE: {
-                final WrapInGridPaneJob job = new WrapInGridPaneJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.layout.GridPane.class);
                 break;
             }
             case WRAP_IN_GROUP: {
-                final WrapInGroupJob job = new WrapInGroupJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.Group.class);
                 break;
             }
             case WRAP_IN_HBOX: {
-                final WrapInHBoxJob job = new WrapInHBoxJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.layout.HBox.class);
                 break;
             }
             case WRAP_IN_PANE: {
-                final WrapInPaneJob job = new WrapInPaneJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.layout.Pane.class);
                 break;
             }
             case WRAP_IN_SCROLL_PANE: {
-                final WrapInScrollPaneJob job = new WrapInScrollPaneJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.control.ScrollPane.class);
                 break;
             }
             case WRAP_IN_SPLIT_PANE: {
-                final WrapInSplitPaneJob job = new WrapInSplitPaneJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.control.SplitPane.class);
                 break;
             }
             case WRAP_IN_STACK_PANE: {
-                final WrapInStackPaneJob job = new WrapInStackPaneJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.layout.StackPane.class);
                 break;
             }
             case WRAP_IN_TAB_PANE: {
-                final WrapInTabPaneJob job = new WrapInTabPaneJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.control.TabPane.class);
                 break;
             }
             case WRAP_IN_TITLED_PANE: {
-                final WrapInTitledPaneJob job = new WrapInTitledPaneJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.control.TitledPane.class);
                 break;
             }
             case WRAP_IN_TOOL_BAR: {
-                final WrapInToolBarJob job = new WrapInToolBarJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.control.ToolBar.class);
                 break;
             }
             case WRAP_IN_VBOX: {
-                final WrapInVBoxJob job = new WrapInVBoxJob(this);
-                jobManager.push(job);
+                performWrap(javafx.scene.layout.VBox.class);
                 break;
             }
             default:
@@ -1040,63 +1027,51 @@
                 break;
             }
             case WRAP_IN_ANCHOR_PANE: {
-                final WrapInAnchorPaneJob job = new WrapInAnchorPaneJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.layout.AnchorPane.class);
                 break;
             }
             case WRAP_IN_GRID_PANE: {
-                final WrapInGridPaneJob job = new WrapInGridPaneJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.layout.GridPane.class);
                 break;
             }
             case WRAP_IN_GROUP: {
-                final WrapInGroupJob job = new WrapInGroupJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.Group.class);
                 break;
             }
             case WRAP_IN_HBOX: {
-                final WrapInHBoxJob job = new WrapInHBoxJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.layout.HBox.class);
                 break;
             }
             case WRAP_IN_PANE: {
-                final WrapInPaneJob job = new WrapInPaneJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.layout.Pane.class);
                 break;
             }
             case WRAP_IN_SCROLL_PANE: {
-                final WrapInScrollPaneJob job = new WrapInScrollPaneJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.control.ScrollPane.class);
                 break;
             }
             case WRAP_IN_SPLIT_PANE: {
-                final WrapInSplitPaneJob job = new WrapInSplitPaneJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.control.SplitPane.class);
                 break;
             }
             case WRAP_IN_STACK_PANE: {
-                final WrapInStackPaneJob job = new WrapInStackPaneJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.layout.StackPane.class);
                 break;
             }
             case WRAP_IN_TAB_PANE: {
-                final WrapInTabPaneJob job = new WrapInTabPaneJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.control.TabPane.class);
                 break;
             }
             case WRAP_IN_TITLED_PANE: {
-                final WrapInTitledPaneJob job = new WrapInTitledPaneJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.control.TitledPane.class);
                 break;
             }
             case WRAP_IN_TOOL_BAR: {
-                final WrapInToolBarJob job = new WrapInToolBarJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.control.ToolBar.class);
                 break;
             }
             case WRAP_IN_VBOX: {
-                final WrapInVBoxJob job = new WrapInVBoxJob(this);
-                result = job.isExecutable();
+                result = canPerformWrap(javafx.scene.layout.VBox.class);
                 break;
             }
             default:
@@ -1287,26 +1262,60 @@
     
     /**
      * Performs the 'wrap' edit action. This action creates an object
-     * matching the specified library item and reparent all the selected objects
+     * matching the specified class and reparent all the selected objects
      * below this new object.
      * 
-     * @param wrappingLibraryItem the library item describing the wrapping object
+     * @param wrappingClass the wrapping class
      */
-    public void performWrap(Object wrappingLibraryItem) {
-        throw new UnsupportedOperationException("Not yet implemented"); //NOI18N
+    public void performWrap(Class<? extends Parent> wrappingClass) {
+        assert canPerformWrap(wrappingClass);
+        final AbstractWrapInJob job = AbstractWrapInJob.getWrapInJob(this, wrappingClass);
+        jobManager.push(job);
     }
     
     /**
-     * Returns true if the 'wrap' action is permitted with the specified 
-     * library item.
-     * 
-     * @param wrappingLibraryItem the item describing the wrapping object.
+     * Returns true if the 'wrap' action is permitted with the specified class.
+     *
+     * @param wrappingClass the wrapping class.
      * @return true if the 'wrap' action is permitted.
      */
-    public boolean canPerformWrap(Object wrappingLibraryItem) {
-        throw new UnsupportedOperationException("Not yet implemented"); //NOI18N
+    public boolean canPerformWrap(Class<? extends Parent> wrappingClass) {
+        if (getClassesSupportingWrapping().contains(wrappingClass) == false) {
+            return false;
+        }
+        final AbstractWrapInJob job = AbstractWrapInJob.getWrapInJob(this, wrappingClass);
+        return job.isExecutable();
     }
-    
+
+    private static List<Class<? extends Parent>> classesSupportingWrapping;
+
+    /**
+     * Return the list of classes that can be passed to 
+     * {@link EditorController#performWrap(java.lang.Class)}.
+     * 
+     * @return the list of classes.
+     */
+    public synchronized static Collection<Class<? extends Parent>> getClassesSupportingWrapping() {
+        if (classesSupportingWrapping == null) {
+            classesSupportingWrapping = new ArrayList<>();
+            classesSupportingWrapping.add(javafx.scene.layout.AnchorPane.class);
+            classesSupportingWrapping.add(javafx.scene.layout.GridPane.class);
+            classesSupportingWrapping.add(javafx.scene.Group.class);
+            classesSupportingWrapping.add(javafx.scene.layout.HBox.class);
+            classesSupportingWrapping.add(javafx.scene.layout.Pane.class);
+            classesSupportingWrapping.add(javafx.scene.control.ScrollPane.class);
+            classesSupportingWrapping.add(javafx.scene.control.SplitPane.class);
+            classesSupportingWrapping.add(javafx.scene.layout.StackPane.class);
+            classesSupportingWrapping.add(javafx.scene.control.TabPane.class);
+            classesSupportingWrapping.add(javafx.scene.control.TitledPane.class);
+            classesSupportingWrapping.add(javafx.scene.control.ToolBar.class);
+            classesSupportingWrapping.add(javafx.scene.layout.VBox.class);
+            classesSupportingWrapping = Collections.unmodifiableList(classesSupportingWrapping);
+        }
+        
+        return classesSupportingWrapping;
+    }
+
     /**
      * Performs the copy control action.
      */
@@ -1461,7 +1470,28 @@
             selection.select(nextSibling);
         } else {
             assert asg instanceof GridSelectionGroup; // Because of (1)
-            // Map to the SELECT_NEXT_ROW/SELECT_NEXT_COLUMN control action
+            final GridSelectionGroup gsg = (GridSelectionGroup) asg;
+            final FXOMObject gridPane = gsg.getParentObject();
+            final DesignHierarchyMask mask = new DesignHierarchyMask(gridPane);
+            assert gridPane instanceof FXOMInstance;
+            final Set<Integer> indexes = gsg.getIndexes();
+            assert indexes.size() == 1; // Because of (1)
+            int selectedIndex = indexes.iterator().next();
+            int nextIndex = selectedIndex + 1;
+            int size = 0;
+            switch (gsg.getType()) {
+                case ROW:
+                    size = mask.getRowsSize();
+                    break;
+                case COLUMN:
+                    size = mask.getColumnsSize();
+                    break;
+                default:
+                    assert false;
+                    break;
+            }
+            assert nextIndex < size; // Because of (1)
+            selection.select((FXOMInstance) gridPane, gsg.getType(), nextIndex);
         }
     }
 
@@ -1487,7 +1517,27 @@
             final FXOMObject selectedObject = items.iterator().next();
             return selectedObject.getNextSlibing() != null;
         } else if (asg instanceof GridSelectionGroup) {
-            // Map to the SELECT_NEXT_ROW/SELECT_NEXT_COLUMN control action
+            final GridSelectionGroup gsg = (GridSelectionGroup) asg;
+            final Set<Integer> indexes = gsg.getIndexes();
+            if (indexes.size() != 1) {
+                return false;
+            }
+            final FXOMObject gridPane = gsg.getParentObject();
+            final DesignHierarchyMask mask = new DesignHierarchyMask(gridPane);
+            int size = 0;
+            switch (gsg.getType()) {
+                case ROW:
+                    size = mask.getRowsSize();
+                    break;
+                case COLUMN:
+                    size = mask.getColumnsSize();
+                    break;
+                default:
+                    assert false;
+                    break;
+            }
+            final int index = indexes.iterator().next();
+            return index < size - 1;
         } else {
             assert selection.getGroup() == null :
                     "Add implementation for " + selection.getGroup(); //NOI18N
@@ -1512,7 +1562,15 @@
             selection.select(previousSibling);
         } else {
             assert asg instanceof GridSelectionGroup; // Because of (1)
-            // Map to the SELECT_PREVIOUS_ROW/SELECT_PREVIOUS_COLUMN control action
+            final GridSelectionGroup gsg = (GridSelectionGroup) asg;
+            final FXOMObject gridPane = gsg.getParentObject();
+            assert gridPane instanceof FXOMInstance;
+            final Set<Integer> indexes = gsg.getIndexes();
+            assert indexes.size() == 1; // Because of (1)
+            int selectedIndex = indexes.iterator().next();
+            int previousIndex = selectedIndex - 1;
+            assert previousIndex >= 0; // Because of (1)
+            selection.select((FXOMInstance) gridPane, gsg.getType(), previousIndex);
         }
     }
     
@@ -1538,7 +1596,13 @@
             final FXOMObject selectedObject = items.iterator().next();
             return selectedObject.getPreviousSlibing() != null;
         } else if (asg instanceof GridSelectionGroup) {
-            // Map to the SELECT_PREVIOUS_ROW/SELECT_PREVIOUS_COLUMN control action
+            final GridSelectionGroup gsg = (GridSelectionGroup) asg;
+            final Set<Integer> indexes = gsg.getIndexes();
+            if (indexes.size() != 1) {
+                return false;
+            }
+            final int index = indexes.iterator().next();
+            return index > 0;
         } else {
             assert selection.getGroup() == null :
                     "Add implementation for " + selection.getGroup(); //NOI18N
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorPlatform.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/EditorPlatform.java	Mon Dec 23 13:59:52 2013 +0100
@@ -75,33 +75,71 @@
     public enum Theme {
 
         MODENA,
-        CASPIAN
+        MODENA_TOUCH,
+        CASPIAN,
+        CASPIAN_HIGH_CONTRAST,
+        CASPIAN_EMBEDDED,
+        CASPIAN_EMBEDDED_HIGH_CONTRAST,
+        CASPIAN_EMBEDDED_QVGA,
+        CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST
     }
 
     private final static URL caspianThemeUrl = Deprecation.getCaspianStylesheetURL();
+    private final static URL caspianHighContrastThemeUrl = Deprecation.getCaspianHighContrastStylesheetURL();
+    private final static URL caspianEmbeddedThemeUrl = Deprecation.getCaspianEmbeddedStylesheetURL();
+    private final static URL caspianEmbeddedQVGAThemeUrl = Deprecation.getCaspianEmbeddedQVGAStylesheetURL();
+    private final static URL caspianVirtualKeyboardThemeUrl = Deprecation.getCaspianVirtualKeyboardStylesheetURL();
     private final static URL modenaThemeUrl = Deprecation.getModenaStylesheetURL();
+    private final static URL modenaTouchThemeUrl = Deprecation.getModenaTouchStylesheetURL();
 
     /**
-     * Returns url for locating the specified stylesheet in jfxrt.jar.
+     * Returns the list of url for locating the specified set of stylesheet in jfxrt.jar.
      *
-     * @param theme theme for which url should be computed
-     * @return url for locating the specified stylesheet.
+     * @param theme theme for which list of url should be computed
+     * @return list of url for locating the specified stylesheet.
      */
-    public static URL getThemeStylesheetURL(Theme theme) {
-        final URL result;
+    public static List<URL> getThemeStylesheetURLs(Theme theme) {
+        final List<URL> result = new ArrayList<>();
 
         switch (theme) {
             default:
-                result = null;
                 break;
             case MODENA:
-                result = modenaThemeUrl;
+                result.add(modenaThemeUrl);
+                break;
+            case MODENA_TOUCH:
+                result.add(modenaThemeUrl);
+                result.add(modenaTouchThemeUrl);
                 break;
             case CASPIAN:
-                result = caspianThemeUrl;
+                result.add(caspianThemeUrl);
+                break;
+            case CASPIAN_HIGH_CONTRAST:
+                result.add(caspianThemeUrl);
+                result.add(caspianHighContrastThemeUrl);
+                break;
+            case CASPIAN_EMBEDDED:
+                result.add(caspianThemeUrl);
+                result.add(caspianEmbeddedThemeUrl);
+                break;
+            case CASPIAN_EMBEDDED_HIGH_CONTRAST:
+                result.add(caspianThemeUrl);
+                result.add(caspianEmbeddedThemeUrl);
+                result.add(caspianHighContrastThemeUrl);
+                break;
+            case CASPIAN_EMBEDDED_QVGA:
+                result.add(caspianThemeUrl);
+                result.add(caspianEmbeddedThemeUrl);
+                result.add(caspianEmbeddedQVGAThemeUrl);
+                break;
+            case CASPIAN_EMBEDDED_QVGA_HIGH_CONTRAST:
+                result.add(caspianThemeUrl);
+                result.add(caspianEmbeddedThemeUrl);
+                result.add(caspianEmbeddedQVGAThemeUrl);
+                result.add(caspianHighContrastThemeUrl);
                 break;
         }
-        assert result != null : "Missing logic for " + theme;
+        assert !result.isEmpty() : "Missing logic for " + theme;
 
         return result;
     }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/i18n/SceneBuilderKit.properties	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/i18n/SceneBuilderKit.properties	Mon Dec 23 13:59:52 2013 +0100
@@ -72,6 +72,11 @@
 inspector.error.title = Property error
 inspector.error.message = Invalid value
 inspector.error.details = {0} is invalid for {1}
+inspector.keycombination.modifier = Modifier
+inspector.keycombination.mainkey = Main Key
+inspector.keycombination.none = none
+inspector.keycombination.clear = Clear All
+inspector.keycombination.null = none
 inspector.list.remove = Remove
 inspector.list.moveup = Move up
 inspector.list.movedown = Move down
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/PasteJob.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/PasteJob.java	Mon Dec 23 13:59:52 2013 +0100
@@ -73,49 +73,52 @@
                     = clipboardDecoder.decode(fxomDocument);
             assert newObjects != null; // But possible empty
 
-            // Retrieve the target FXOMObject :
-            // If the document is empty (root object is null), then the target 
-            // object is null.
-            // If the selection is root or is empty, the target object is
-            // the root object.
-            // Otherwise, the target object is the selection common ancestor.
-            final FXOMObject targetObject;
-            if (fxomDocument.getFxomRoot() == null) {
-                targetObject = null;
-            } else {
-                final Selection selection = getEditorController().getSelection();
-                final FXOMObject rootObject = fxomDocument.getFxomRoot();
-                if (selection.isEmpty() || selection.isSelected(rootObject)) {
-                    targetObject = rootObject;
+            if (newObjects.isEmpty() == false) {
+                
+                // Retrieve the target FXOMObject :
+                // If the document is empty (root object is null), then the target 
+                // object is null.
+                // If the selection is root or is empty, the target object is
+                // the root object.
+                // Otherwise, the target object is the selection common ancestor.
+                final FXOMObject targetObject;
+                if (fxomDocument.getFxomRoot() == null) {
+                    targetObject = null;
                 } else {
-                    targetObject = selection.getAncestor();
+                    final Selection selection = getEditorController().getSelection();
+                    final FXOMObject rootObject = fxomDocument.getFxomRoot();
+                    if (selection.isEmpty() || selection.isSelected(rootObject)) {
+                        targetObject = rootObject;
+                    } else {
+                        targetObject = selection.getAncestor();
+                    }
                 }
-            }
-            assert (targetObject != null) || (fxomDocument.getFxomRoot() == null);
+                assert (targetObject != null) || (fxomDocument.getFxomRoot() == null);
 
-            if (targetObject == null) {
-                // Document is empty : only one object can be inserted
-                if (newObjects.size() == 1) {
-                    final FXOMObject newObject0 = newObjects.get(0);
-                    final SetDocumentRootJob subJob = new SetDocumentRootJob(
-                            newObject0,
-                            getEditorController());
-                    result.add(subJob);
-                    result.add(new UpdateSelectionJob(newObject0, getEditorController()));
-                }
-            } else {
-                // Build InsertAsSubComponent jobs
-                final DesignHierarchyMask targetMask = new DesignHierarchyMask(targetObject);
-                if (targetMask.isAcceptingSubComponent(newObjects)) {
-                    for (FXOMObject newObject : newObjects) {
-                        final InsertAsSubComponentJob subJob = new InsertAsSubComponentJob(
-                                newObject,
-                                targetObject,
-                                targetMask.getSubComponentCount(),
+                if (targetObject == null) {
+                    // Document is empty : only one object can be inserted
+                    if (newObjects.size() == 1) {
+                        final FXOMObject newObject0 = newObjects.get(0);
+                        final SetDocumentRootJob subJob = new SetDocumentRootJob(
+                                newObject0,
                                 getEditorController());
                         result.add(subJob);
+                        result.add(new UpdateSelectionJob(newObject0, getEditorController()));
                     }
-                    result.add(new UpdateSelectionJob(newObjects, getEditorController()));
+                } else {
+                    // Build InsertAsSubComponent jobs
+                    final DesignHierarchyMask targetMask = new DesignHierarchyMask(targetObject);
+                    if (targetMask.isAcceptingSubComponent(newObjects)) {
+                        for (FXOMObject newObject : newObjects) {
+                            final InsertAsSubComponentJob subJob = new InsertAsSubComponentJob(
+                                    newObject,
+                                    targetObject,
+                                    targetMask.getSubComponentCount(),
+                                    getEditorController());
+                            result.add(subJob);
+                        }
+                        result.add(new UpdateSelectionJob(newObjects, getEditorController()));
+                    }
                 }
             }
         }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/AbstractWrapInJob.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/AbstractWrapInJob.java	Mon Dec 23 13:59:52 2013 +0100
@@ -55,6 +55,7 @@
 import javafx.geometry.Bounds;
 import javafx.geometry.Point2D;
 import javafx.scene.Node;
+import javafx.scene.Parent;
 import javafx.scene.layout.Region;
 
 /**
@@ -70,6 +71,41 @@
     public AbstractWrapInJob(EditorController editorController) {
         super(editorController);
     }
+    
+    public static AbstractWrapInJob getWrapInJob(
+            EditorController editorController, 
+            Class<? extends Parent> wrappingClass) {
+        
+        assert EditorController.getClassesSupportingWrapping().contains(wrappingClass);
+        final AbstractWrapInJob job;
+        if (wrappingClass == javafx.scene.layout.AnchorPane.class) {
+            job = new WrapInAnchorPaneJob(editorController);
+        } else if (wrappingClass == javafx.scene.layout.GridPane.class) {
+            job = new WrapInGridPaneJob(editorController);
+        } else if (wrappingClass == javafx.scene.Group.class) {
+            job = new WrapInGroupJob(editorController);
+        } else if (wrappingClass == javafx.scene.layout.HBox.class) {
+            job = new WrapInHBoxJob(editorController);
+        } else if (wrappingClass == javafx.scene.layout.Pane.class) {
+            job = new WrapInPaneJob(editorController);
+        } else if (wrappingClass == javafx.scene.control.ScrollPane.class) {
+            job = new WrapInScrollPaneJob(editorController);
+        } else if (wrappingClass == javafx.scene.control.SplitPane.class) {
+            job = new WrapInSplitPaneJob(editorController);
+        } else if (wrappingClass == javafx.scene.layout.StackPane.class) {
+            job = new WrapInStackPaneJob(editorController);
+        } else if (wrappingClass == javafx.scene.control.TabPane.class) {
+            job = new WrapInTabPaneJob(editorController);
+        } else if (wrappingClass == javafx.scene.control.TitledPane.class) {
+            job = new WrapInTitledPaneJob(editorController);
+        } else if (wrappingClass == javafx.scene.control.ToolBar.class) {
+            job = new WrapInToolBarJob(editorController);
+        } else {
+            assert wrappingClass == javafx.scene.layout.VBox.class; // Because of (1)
+            job = new WrapInVBoxJob(editorController);
+        }
+        return job;
+    }
 
     @Override
     public boolean isExecutable() {
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.css	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.css	Mon Dec 23 13:59:52 2013 +0100
@@ -230,3 +230,16 @@
     -fx-border-style: dotted;
     -fx-border-color: black;
 }
+
+
+/*******************************************************************************
+ *                                                                             *
+ * Resize Shadow                                                               *
+ *                                                                             *
+ ******************************************************************************/
+
+.outline-ring {
+    -fx-stroke: rgba(0,0,0,0.2);
+    -fx-stroke-type: inside;
+    -fx-fill: rgba(0,0,0,0.01);
+}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.fxml	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanel.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -31,18 +31,17 @@
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
+
 <?import java.lang.*?>
 <?import java.net.*?>
-<?import java.util.*?>
 <?import javafx.geometry.*?>
 <?import javafx.scene.*?>
 <?import javafx.scene.control.*?>
 <?import javafx.scene.layout.*?>
-<?import javafx.scene.paint.*?>
 <?import javafx.scene.shape.*?>
 <?import javafx.scene.text.*?>
 
-<ScrollPane fx:id="scrollPane" fitToHeight="true" fitToWidth="true" hvalue="0.5" minWidth="300.0" prefHeight="500.0" prefWidth="700.0" vvalue="0.5" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
+<ScrollPane fx:id="scrollPane" fitToHeight="true" fitToWidth="true" hvalue="0.5" minWidth="300.0" prefHeight="500.0" prefWidth="700.0" vvalue="0.5" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <content>
     <StackPane fx:id="workspacePane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" style="">
       <children>
@@ -67,6 +66,7 @@
         </Group>
         <Pane fx:id="glassLayer" focusTraversable="true">
           <children>
+            <Group fx:id="outlineLayer" mouseTransparent="true" />
             <Group fx:id="pringLayer" />
             <Group fx:id="handleLayer" />
             <Group fx:id="rudderLayer" mouseTransparent="true" />
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -57,6 +57,7 @@
 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.TreeTableViewDriver;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.VBoxDriver;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.handles.AbstractHandles;
+import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.outline.NodeOutline;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.util.BoundsUnion;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.util.Picker;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.util.ScrollPaneBooster;
@@ -65,6 +66,7 @@
 import com.oracle.javafx.scenebuilder.kit.editor.selection.Selection;
 import com.oracle.javafx.scenebuilder.kit.editor.util.ContextMenuController;
 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject;
 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask;
 import com.oracle.javafx.scenebuilder.kit.util.Deprecation;
@@ -127,13 +129,12 @@
     @FXML private Group scalingGroup;
     @FXML private Group contentGroup;
     @FXML private Pane glassLayer;
+    @FXML private Group outlineLayer;
     @FXML private Group pringLayer;
     @FXML private Group handleLayer;
     @FXML private Group rudderLayer;
     
-    private boolean outlinesVisible;
     private boolean guidesVisible = true;
-    private boolean sampleDataVisible;
     private Paint pringColor = Color.rgb(238, 168, 47);
     private Paint guidesColor = Color.RED;
     
@@ -149,6 +150,7 @@
     private boolean tracingEvents; // For debugging purpose
     
     private final Picker picker = new Picker();
+    private final List<NodeOutline> outlines = new ArrayList<>();
     
     /*
      * Public
@@ -198,7 +200,7 @@
      * @return true if this content panel displays outlines.
      */
     public boolean isOutlinesVisible() {
-        return outlinesVisible;
+        return (contentGroup != null) && (contentGroup.isVisible() == false);
     }
 
     /**
@@ -206,7 +208,13 @@
      * @param outlinesVisible true if outlines should be visible.
      */
     public void setOutlinesVisible(boolean outlinesVisible) {
-        this.outlinesVisible = outlinesVisible;
+        if (outlinesVisible != isOutlinesVisible()) {
+            if (outlinesVisible) {
+                beginShowingOutlines();
+            } else {
+                endShowingOutlines();
+            }
+        }
     }
 
     /**
@@ -226,25 +234,6 @@
     public void setGuidesVisible(boolean guidesVisible) {
         this.guidesVisible = guidesVisible;
     }
-
-    /**
-     * Returns true if sample data are displayed in this content panel.
-     * 
-     * @return true if sample data are displayed in this content panel.
-     */
-    public boolean isSampleDataVisible() {
-        return sampleDataVisible;
-    }
-
-    /**
-     * Enables or disables sample data display in this content panel.
-     * 
-     * @param sampleDataVisible true if sample data should be visible in this content panel.
-     */
-    public void setSampleDataVisible(boolean sampleDataVisible) {
-        this.sampleDataVisible = sampleDataVisible;
-    }
-    
     
     /**
      * Returns the color used by this content panel to draw parent rings.
@@ -545,6 +534,15 @@
     
     
     /**
+     * @treatAsPrivate Returns the outline layer container.
+     * @return the outline layer container.
+     */
+    public Group getOutlineLayer() {
+        return outlineLayer;
+    }
+    
+    
+    /**
      * @treatAsPrivate Returns the parent ring layer container.
      * @return the parent ring layer container.
      */
@@ -671,6 +669,9 @@
         }
         
         workspaceController.setFxomDocument(fxomDocument);
+        if (isOutlinesVisible()) {
+            updateOutlines();
+        }
         if (currentModeController != null) {
             currentModeController.fxomDocumentDidChange(oldDocument);
         }
@@ -742,6 +743,9 @@
         assert glassLayer != null;
         assert glassLayer.isMouseTransparent() == false;
         assert glassLayer.isFocusTraversable();
+        assert outlineLayer != null;
+        assert outlineLayer.isMouseTransparent();
+        assert outlineLayer.isFocusTraversable() == false;
         assert pringLayer != null;
         assert pringLayer.isMouseTransparent() == false;
         assert pringLayer.isFocusTraversable() == false;
@@ -752,6 +756,7 @@
         assert rudderLayer.isMouseTransparent() == true;
         assert rudderLayer.isFocusTraversable() == false;
         
+        outlineLayer.setManaged(false);
         pringLayer.setManaged(false);
         handleLayer.setManaged(false);
         rudderLayer.setManaged(false);
@@ -806,6 +811,9 @@
         //  - new scene graph must replace the old one below contentHook
         //  - mode controller must be informed so that it can updates handles
         workspaceController.sceneGraphDidChange();
+        if (isOutlinesVisible()) {
+            updateOutlines();
+        }
         if (currentModeController != null) {
             currentModeController.fxomDocumentDidRefreshSceneGraph();
         }
@@ -929,8 +937,8 @@
     private void themeDidChange() {
         if (contentGroup != null) {
             final EditorPlatform.Theme theme = getEditorController().getTheme();
-            final URL themeStyleSheet = EditorPlatform.getThemeStylesheetURL(theme);
-            workspaceController.setThemeStyleSheet(themeStyleSheet.toString());
+            final List<URL> themeStyleSheets = EditorPlatform.getThemeStylesheetURLs(theme);
+            workspaceController.setThemeStyleSheets(themeStyleSheets);
         }
     }
     
@@ -958,4 +966,129 @@
         isolationGroup.getChildren().add(contentGroup);
     }
     
+    
+    /*
+     * Private (outline layer)
+     */
+    
+    private void beginShowingOutlines() {
+        assert contentGroup.isVisible();
+        
+        contentGroup.setVisible(false);
+        updateOutlines();
+    }
+    
+    private void endShowingOutlines() {
+        assert contentGroup.isVisible() == false;
+
+        final List<Node> outlineNodes = outlineLayer.getChildren();
+        for (NodeOutline o : outlines) {
+            assert outlineNodes.contains(o.getRootNode());
+            outlineNodes.remove(o.getRootNode());
+        }
+        outlines.clear();
+        contentGroup.setVisible(true);
+    }
+    
+    private void updateOutlines() {
+        assert isOutlinesVisible();
+        
+        // Collects fxom objects associated to a node in the fxom document
+        final List<FXOMObject> allNodes = collectNodes();
+        
+        for (int i = 0, count = allNodes.size(); i < count; i++) {
+            assert allNodes.get(i) instanceof FXOMInstance;
+            final FXOMInstance nodeInstance = (FXOMInstance) allNodes.get(i);
+            if (i < outlines.size()) {
+                final NodeOutline currentOutline = outlines.get(i);
+                if (currentOutline.getFxomObject() != nodeInstance) {
+                    replaceOutline(i, nodeInstance);
+               } else {
+                    switch(currentOutline.getState()) {
+                        case CLEAN:
+                            break;
+                        case NEEDS_RECONCILE:
+                            // scene graph associated to currentOutline has changed but h is still compatible
+                            currentOutline.reconcile();
+                            break;
+                        case NEEDS_REPLACE:
+                            // currentOutline is no longer compatible with the new scene graph object 
+                            replaceOutline(i, nodeInstance);
+                            break;
+                    }
+                }
+            } else {
+                addOutline(outlines.size(), nodeInstance);
+            }
+        }
+        for (int i = allNodes.size(), count = outlines.size(); i < count; i++) {
+            removeOutline(allNodes.size());
+        }
+        assert outlines.size() == allNodes.size();
+    }
+    
+    private void addOutline(int i, FXOMInstance nodeInstance) {
+        assert outlines.size() == outlineLayer.getChildren().size();
+        
+        final NodeOutline newOutline = new NodeOutline(this, nodeInstance);
+        outlines.add(i, newOutline);
+        outlineLayer.getChildren().add(i, newOutline.getRootNode());
+        
+        assert outlines.size() == outlineLayer.getChildren().size();
+        assert outlines.get(i).getRootNode() == outlineLayer.getChildren().get(i);
+    }
+    
+    private void replaceOutline(int i, FXOMInstance nodeInstance) {
+        removeOutline(i);
+        addOutline(i, nodeInstance);
+    }
+    
+    
+    private void removeOutline(int i) {
+        assert outlines.size() == outlineLayer.getChildren().size();
+        assert outlines.get(i).getRootNode() == outlineLayer.getChildren().get(i);
+        
+        outlines.remove(i);
+        outlineLayer.getChildren().remove(i);
+        
+        assert outlines.size() == outlineLayer.getChildren().size();
+    }
+    
+    private List<FXOMObject> collectNodes() {
+        final List<FXOMObject> result = new ArrayList<>();
+        
+        final List<FXOMObject> candidates = new ArrayList<>();
+        final FXOMDocument fxomDocument = getEditorController().getFxomDocument();
+        if ((fxomDocument != null) && (fxomDocument.getFxomRoot() != null)) {
+            candidates.add(fxomDocument.getFxomRoot());
+        } 
+        
+        while (candidates.isEmpty() == false) {
+            final FXOMObject candidate = candidates.get(0);
+            candidates.remove(0);
+            if (candidate.isNode()) {
+                final Node sgo = (Node) candidate.getSceneGraphObject();
+                if (sgo.getScene() == getPanelRoot().getScene()) {
+                    result.add(candidate);
+                }
+            }
+            final DesignHierarchyMask m = new DesignHierarchyMask(candidate);
+            if (m.isAcceptingSubComponent()) {
+                for (int i = 0, c = m.getSubComponentCount(); i < c; i++) {
+                    final FXOMObject subComponent = m.getSubComponentAtIndex(i);
+                    candidates.add(subComponent);
+                }
+            }
+            for (DesignHierarchyMask.Accessory a : DesignHierarchyMask.Accessory.values()) {
+                if (m.isAcceptingAccessory(a)) {
+                    final FXOMObject accessoryObject = m.getAccessory(a);
+                    if ((accessoryObject != null) && accessoryObject.isNode()) {
+                        candidates.add(accessoryObject);
+                    }
+                }
+            }
+        }
+        
+        return result;
+    }
 }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/WorkspaceController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/WorkspaceController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -33,6 +33,7 @@
 
 import com.oracle.javafx.scenebuilder.kit.editor.i18n.I18N;
 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
+import java.net.URL;
 import java.util.List;
 import javafx.animation.FadeTransition;
 import javafx.application.Platform;
@@ -140,24 +141,24 @@
         updateScalingGroup();
     }
     
-    public String getThemeStyleSheet() {
-        final String result;
+    public List<String> getThemeStyleSheets() {
+        final List<String> result;
         if (contentGroup.getStylesheets().isEmpty()) {
             result = null;
         } else {
-            result = contentGroup.getStylesheets().get(0);
+            result = contentGroup.getStylesheets();
         }
         return result;
     }
     
-    public void setThemeStyleSheet(String themeStyleSheet) {
+    public void setThemeStyleSheets(List<URL> themeStyleSheets) {
         assert contentGroup.getParent() instanceof Group;
         final Group isolationGroup = (Group) contentGroup.getParent();
         assert isolationGroup.getStyleClass().contains("root");
         
         isolationGroup.getStylesheets().clear();
-        if (themeStyleSheet != null) {
-            isolationGroup.getStylesheets().add(themeStyleSheet);
+        for (URL url : themeStyleSheets) {
+            isolationGroup.getStylesheets().add(url.toString());
         }
         isolationGroup.applyCss();
     }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/gridpane/GridPaneMosaic.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/gridpane/GridPaneMosaic.java	Mon Dec 23 13:59:52 2013 +0100
@@ -103,16 +103,16 @@
         this.shouldCreateSensors = shouldCreateSensors;
         
         final List<Node> topChildren = topGroup.getChildren();
-        topChildren.add(gridPath);
-        topChildren.add(hgapLinesGroup);
-        topChildren.add(vgapLinesGroup);
+        topChildren.add(gridPath);              // Mouse transparent
+        topChildren.add(hgapLinesGroup);        // Mouse transparent
+        topChildren.add(vgapLinesGroup);        // Mouse transparent
         topChildren.add(northTrayGroup);
         topChildren.add(southTrayGroup);
         topChildren.add(westTrayGroup);
         topChildren.add(eastTrayGroup);
-        topChildren.add(targetCellShadow);
-        topChildren.add(targetGapShadowV);
-        topChildren.add(targetGapShadowH);
+        topChildren.add(targetCellShadow);      // Mouse transparent
+        topChildren.add(targetGapShadowV);      // Mouse transparent
+        topChildren.add(targetGapShadowH);      // Mouse transparent
         topChildren.add(hgapSensorsGroup);
         topChildren.add(vgapSensorsGroup);
         gridAreaQuad.addToPath(gridPath);
@@ -121,6 +121,9 @@
         gridPath.getStyleClass().add("gap");
         gridPath.getStyleClass().add(baseStyleClass);
         
+        hgapLinesGroup.setMouseTransparent(true);
+        vgapLinesGroup.setMouseTransparent(true);
+        
         targetCellShadow.setMouseTransparent(true);
         targetCellShadow.getStyleClass().add("gap");
         targetCellShadow.getStyleClass().add("selected");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/outline/AbstractOutline.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.outline;
+
+import com.oracle.javafx.scenebuilder.kit.editor.panel.content.AbstractDecoration;
+import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject;
+import java.util.List;
+import javafx.geometry.Bounds;
+import javafx.geometry.Point2D;
+import javafx.scene.shape.ClosePath;
+import javafx.scene.shape.LineTo;
+import javafx.scene.shape.MoveTo;
+import javafx.scene.shape.Path;
+import javafx.scene.shape.PathElement;
+
+/**
+ *
+ */
+public abstract class AbstractOutline<T> extends AbstractDecoration<T> {
+
+    public static final String OUTLINE_RING_CLASS = "outline-ring"; //NOI18N
+
+    
+    protected final Path ringPath = new Path();
+    private final MoveTo moveTo0 = new MoveTo();
+    private final LineTo lineTo1 = new LineTo();
+    private final LineTo lineTo2 = new LineTo();
+    private final LineTo lineTo3 = new LineTo();
+    
+    public AbstractOutline(ContentPanelController contentPanelController,
+            FXOMObject fxomObject, Class<T> sceneGraphClass) {
+        super(contentPanelController, fxomObject, sceneGraphClass);
+        
+        final List<PathElement> ringElements = ringPath.getElements();
+        ringElements.add(moveTo0);
+        ringElements.add(lineTo1);
+        ringElements.add(lineTo2);
+        ringElements.add(lineTo3);
+        ringElements.add(new ClosePath());
+        ringPath.getStyleClass().add(OUTLINE_RING_CLASS);
+        ringPath.setMouseTransparent(true);
+        getRootNode().getChildren().add(ringPath);
+    }
+    
+    /*
+     * AbstractDecoration
+     */
+    
+    @Override
+    protected void layoutDecoration() {
+        final Bounds b = getSceneGraphObjectBounds();
+        
+        final boolean snapToPixel = true;
+        final Point2D p0 = sceneGraphObjectToDecoration(b.getMinX(), b.getMinY(), snapToPixel);
+        final Point2D p1 = sceneGraphObjectToDecoration(b.getMaxX(), b.getMinY(), snapToPixel);
+        final Point2D p2 = sceneGraphObjectToDecoration(b.getMaxX(), b.getMaxY(), snapToPixel);
+        final Point2D p3 = sceneGraphObjectToDecoration(b.getMinX(), b.getMaxY(), snapToPixel);
+        
+        moveTo0.setX(p0.getX());
+        moveTo0.setY(p0.getY());
+        lineTo1.setX(p1.getX());
+        lineTo1.setY(p1.getY());
+        lineTo2.setX(p2.getX());
+        lineTo2.setY(p2.getY());
+        lineTo3.setX(p3.getX());
+        lineTo3.setY(p3.getY());
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/driver/outline/NodeOutline.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.outline;
+
+import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
+import javafx.geometry.Bounds;
+import javafx.geometry.Point2D;
+import javafx.scene.Node;
+import javafx.scene.transform.Transform;
+
+/**
+ *
+ */
+public class NodeOutline extends AbstractOutline<Node> {
+    
+    public NodeOutline(ContentPanelController contentPanelController, 
+            FXOMInstance fxomInstance) {
+        super(contentPanelController, fxomInstance, Node.class);
+    }
+    
+    
+    /*
+     * AbstractOutline
+     */
+    
+    @Override
+    public Bounds getSceneGraphObjectBounds() {
+        return getSceneGraphObject().getLayoutBounds();
+    }
+
+    @Override
+    public Transform getSceneGraphToSceneTransform() {
+        return getSceneGraphObject().getLocalToSceneTransform();
+    }
+
+    @Override
+    public Point2D sceneGraphObjectToScene(double x, double y) {
+        return getSceneGraphObject().localToScene(x, y);
+    }
+
+    @Override
+    public Point2D sceneToSceneGraphObject(double x, double y) {
+        return getSceneGraphObject().sceneToLocal(x, y);
+    }
+
+    @Override
+    protected void startListeningToSceneGraphObject() {
+        startListeningToLayoutBounds(getSceneGraphObject());
+        startListeningToLocalToSceneTransform(getSceneGraphObject());
+    }
+
+    @Override
+    protected void stopListeningToSceneGraphObject() {
+        stopListeningToLayoutBounds(getSceneGraphObject());
+        stopListeningToLocalToSceneTransform(getSceneGraphObject());
+    }
+    
+}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/gesture/mouse/SelectAndMoveGesture.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/content/gesture/mouse/SelectAndMoveGesture.java	Mon Dec 23 13:59:52 2013 +0100
@@ -168,7 +168,8 @@
             selectedHitObject = selection.lookupSelectedAncestor(hitObject); // Case B.2
         }
         
-        if (selectedHitObject != null) {
+        final FXOMObject fxomRoot = hitObject.getFxomDocument().getFxomRoot();
+        if ((selectedHitObject != null) && (selectedHitObject != fxomRoot)) {
                 
             assert selection.getGroup() instanceof ObjectSelectionGroup;
             
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/css/CssContentMaker.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/css/CssContentMaker.java	Mon Dec 23 13:59:52 2013 +0100
@@ -357,9 +357,9 @@
 //        System.out.println("===========================");
 //        System.out.println("\n\n");
 //        printStyles(allStyles);
+        List<Style> matchingStyles = removeUserAgentStyles(allStyles);
         List<Style> notApplied = new ArrayList<>();
-        for (Object obj : allStyles) {
-            Style style = (Style) obj;
+        for (Style style : matchingStyles) {
             if (!appliedStyles.contains(style)) {
                 notApplied.add(style);
             }
@@ -367,13 +367,27 @@
         for (Style style : notApplied) {
             if (style.getDeclaration().getProperty().equals(cssMeta.getProperty())) {
                 // We need to retrieve from allStyles, in case a lookup is shared by appliedStyles and notApplied
-                CssStyle cssStyle = retrieveStyle(allStyles, style);
+                CssStyle cssStyle = retrieveStyle(matchingStyles, style);
                 ret.add(cssStyle);
             }
         }
         return ret;
     }
 
+    private static List<Style> removeUserAgentStyles(List<Style> allStyles) {
+        // With SB 2, we apply explicitly Modena/Caspian theme css on user scene graph.
+        // The rules that appear with an AUTHOR origin has already been considered as USER_AGENT.
+        // So when an internal css method (such as impl_getMatchingStyles()) is called,
+        // we need here to remove all USER_AGENT styles, to avoid doublons.
+        List<Style> matchingStyles = new ArrayList<>();
+        for (Style style : allStyles) {
+            if (!(style.getDeclaration().getRule().getOrigin() == StyleOrigin.USER_AGENT)) {
+                matchingStyles.add(style);
+            }
+        }
+        return matchingStyles;
+    }
+    
 //    private static void printStyles(List<Style> styles) {
 //        for (Style style : styles) {
 //            printStyle(style);
@@ -869,12 +883,13 @@
                 List<CssStyle> notAppliedStyles = ps == null ? Collections.<CssStyle>emptyList() : ps.getNotAppliedStyles();
                 boolean hasModel = modelState().get() != null;
                 if (hasModel) {
-                    List<Style> styles = Deprecation.getMatchingStyles(getStyleable(), target);
-                    for (Style style : styles) {
+                    List<Style> allStyles = Deprecation.getMatchingStyles(getStyleable(), target);
+                    List<Style> matchingStyles = removeUserAgentStyles(allStyles);
+                    for (Style style : matchingStyles) {
                         CssStyle cssStyle = new CssStyle(style);
                         if (cssStyle.getOrigin() == StyleOrigin.USER_AGENT && !notAppliedStyles.contains(cssStyle)) {
                             if (getStyleable().getProperty().equals(cssStyle.getCssProperty())) {
-                                cssStyle = retrieveStyle(styles, style);
+                                cssStyle = retrieveStyle(matchingStyles, style);
                                 ret.add(cssStyle);
                             }
                         }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/hierarchy/AbstractHierarchyPanelController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/hierarchy/AbstractHierarchyPanelController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -186,6 +186,7 @@
     public AbstractHierarchyPanelController(URL fxmlURL, EditorController editorController) {
         super(fxmlURL, I18N.getBundle(), editorController);
         promptLabel.getStyleClass().add("hierarchy-prompt-label");
+        promptLabel.setMouseTransparent(true);
     }
 
     /**
@@ -1074,6 +1075,9 @@
         // Do not invoke dragController.end here because we always receive a
         // DRAG_EXITED event which will perform the termination
         event.setDropCompleted(true);
+        
+        // Give the focus to the hierarchy
+        getPanelControl().requestFocus();
     }
 
     private void handleOnDragEntered(final DragEvent event) {
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/InspectorPanelController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/InspectorPanelController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -63,6 +63,7 @@
 import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.DividerPositionsEditor;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.TextAlignmentEditor;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.popupeditors.BoundsPopupEditor;
+import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.popupeditors.KeyCombinationPopupEditor;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.popupeditors.PaintPopupEditor;
 import com.oracle.javafx.scenebuilder.kit.editor.panel.util.AbstractFxmlPanelController;
 import com.oracle.javafx.scenebuilder.kit.editor.selection.GridSelectionGroup;
@@ -87,6 +88,7 @@
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.IntegerPropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.Point3DPropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.StringPropertyMetadata;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination.KeyCombinationPropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.list.ListValuePropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.paint.PaintPropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.util.InspectorPath;
@@ -199,6 +201,7 @@
     private String searchPattern;
     private SectionId previousExpandedSection;
     private PropertyEditor lastPropertyEditorValueChanged = null;
+    private boolean resetInProgress = false;
     //
     // Editor pools
     private final Stack<Editor> i18nStringEditorPool = new Stack<>();
@@ -223,6 +226,7 @@
     private final Stack<Editor> point3DEditorPool = new Stack<>();
     private final Stack<Editor> dividerPositionsEditorPool = new Stack<>();
     private final Stack<Editor> textAlignmentEditorPool = new Stack<>();
+    private final Stack<Editor> keyCombinationPopupEditorPool = new Stack<>();
     // ...
     //
     // Subsection title pool
@@ -282,6 +286,7 @@
         editorPools.put(Point3DEditor.class, point3DEditorPool);
         editorPools.put(DividerPositionsEditor.class, dividerPositionsEditorPool);
         editorPools.put(TextAlignmentEditor.class, textAlignmentEditorPool);
+        editorPools.put(KeyCombinationPopupEditor.class, keyCombinationPopupEditorPool);
         // ...
     }
 
@@ -582,6 +587,7 @@
         // - reset the value
 //        System.out.println("Refresh all the editors in use...");
 
+        resetInProgress = true;
         for (Editor editor : editorsInUse) {
 
             if (editor instanceof PropertyEditor) {
@@ -595,6 +601,7 @@
             }
             setEditorValueFromSelection(editor);
         }
+        resetInProgress = false;
     }
 
     private void buildExpandedSection() {
@@ -1094,6 +1101,9 @@
         propertyEditor.addIndeterminateListener(new ChangeListener<Boolean>() {
             @Override
             public void changed(ObservableValue<? extends Boolean> ov, Boolean oldValue, Boolean newValue) {
+                if (resetInProgress) {
+                    return;
+                }
                 if (!newValue) {
                     // value is not anymore indeterminate: commit the current value
                     updateValueInModel(propertyEditor, null, propertyEditor.getValue());
@@ -1329,6 +1339,9 @@
         } else if (propMeta instanceof Point3DPropertyMetadata) {
             // Point3D editor
             propertyEditor = makePropertyEditor(Point3DEditor.class, propMeta);
+        } else if (propMeta instanceof KeyCombinationPropertyMetadata) {
+            // KeyCombination editor
+            propertyEditor = makePropertyEditor(KeyCombinationPopupEditor.class, propMeta);
         } else {
             // Generic editor
             propertyEditor = makePropertyEditor(GenericEditor.class, propMeta);
@@ -1645,6 +1658,12 @@
             } else {
                 propertyEditor = new TextAlignmentEditor(propMeta, selectedClasses);
             }
+        } else if (editorClass == KeyCombinationPopupEditor.class) {
+            if (propertyEditor != null) {
+                ((KeyCombinationPopupEditor) propertyEditor).reset(propMeta, selectedClasses);
+            } else {
+                propertyEditor = new KeyCombinationPopupEditor(propMeta, selectedClasses);
+            }
         } else {
             if (propertyEditor != null) {
                 ((GenericEditor) propertyEditor).reset(propMeta, selectedClasses);
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/AutoSuggestEditor.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/AutoSuggestEditor.java	Mon Dec 23 13:59:52 2013 +0100
@@ -360,7 +360,9 @@
                 @Override
                 public void handle(ActionEvent t) {
                     entryField.setText(suggestItem);
-                    AutoSuggestEditor.this.getCommitListener().handle(null);
+                    if (AutoSuggestEditor.this.getCommitListener() != null) {
+                        AutoSuggestEditor.this.getCommitListener().handle(null);
+                    }
                 }
             });
             menuButton.getItems().add(menuItem);
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/StylesheetEditor.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/StylesheetEditor.java	Mon Dec 23 13:59:52 2013 +0100
@@ -34,6 +34,8 @@
 import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform;
 import com.oracle.javafx.scenebuilder.kit.editor.i18n.I18N;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.ValuePropertyMetadata;
+import com.oracle.javafx.scenebuilder.kit.util.Deprecation;
+import com.sun.javafx.css.StyleManager;
 import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
@@ -52,6 +54,7 @@
 import javafx.fxml.FXML;
 import javafx.scene.Node;
 import javafx.scene.Parent;
+import javafx.scene.Scene;
 import javafx.scene.control.Button;
 import javafx.scene.control.MenuItem;
 import javafx.scene.control.TextField;
@@ -197,7 +200,6 @@
     void chooseStylesheet(ActionEvent event) {
 
         String[] extensions = {"*.css"}; //NOI18N
-        // !! Do we need a wrapper, as we had in SB 1.1, to allow tests to bypass the dialog ?
         FileChooser fileChooser = new FileChooser();
         fileChooser.setTitle(I18N.getString("inspector.select.css"));
         fileChooser.getExtensionFilters().add(
@@ -223,6 +225,12 @@
         // Add editor item
         addItem(new StylesheetItem(this, url));
 
+        // Workaround for RT-34863: Reload of an updated css file has no effect.
+        // This reset the whole CSS from top. Would need to be moved on the FXOM side.
+        Scene scene = root.getScene();
+        StyleManager.getInstance().forget(scene);
+        Deprecation.reapplyCSS(scene.getRoot());
+
         userUpdateValueProperty(getValue());
     }
 
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/BoundsPopupEditor.fxml	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/BoundsPopupEditor.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
+
 <!--
   Copyright (c) 2012, 2013, Oracle and/or its affiliates.
   All rights reserved. Use is subject to license terms.
@@ -30,87 +31,80 @@
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
+
 <?import java.lang.*?>
 <?import javafx.scene.control.*?>
 <?import javafx.scene.layout.*?>
 
-<GridPane hgap="10.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="171.0" prefWidth="181.0" stylesheets="file:/C:/wksfx/sb20/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/Inspector.css" vgap="5.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
-      <children>
-        <Label text="min:" />
-        <Label text="max:" GridPane.rowIndex="1" />
-        <Label text="size:" GridPane.rowIndex="2" />
-        <HBox spacing="10.0" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0">
-          <children>
-            <VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-              <children>
+<GridPane hgap="7.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" stylesheets="@../Inspector.css" vgap="5.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+    <children>
+        <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" text="min:" />
+        <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" text="max:" GridPane.rowIndex="1" />
+        <Label maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" text="size:" GridPane.rowIndex="2" />
+        <VBox alignment="CENTER" GridPane.columnIndex="1" HBox.hgrow="ALWAYS">
+            <children>
                 <Label styleClass="label, small-label" text="X" />
                 <Label fx:id="minX" text="10" />
-              </children>
-            </VBox>
-            <VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-              <children>
+            </children>
+        </VBox>
+        <VBox alignment="CENTER" GridPane.columnIndex="1" GridPane.rowIndex="1" HBox.hgrow="ALWAYS">
+            <children>
+                <Label styleClass="label, small-label" text="X" />
+                <Label fx:id="maxX" text="10" />
+            </children>
+        </VBox>
+        <VBox alignment="CENTER" GridPane.columnIndex="1" GridPane.rowIndex="2" HBox.hgrow="ALWAYS">
+            <children>
+                <Label styleClass="label, small-label" text="Width" />
+                <Label fx:id="width" text="10" />
+            </children>
+        </VBox>
+        <VBox alignment="CENTER" GridPane.columnIndex="2" HBox.hgrow="ALWAYS">
+            <children>
                 <Label styleClass="label, small-label" text="Y" />
                 <Label fx:id="minY" text="10" />
-              </children>
-            </VBox>
-            <VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-              <children>
+            </children>
+        </VBox>
+        <VBox alignment="CENTER" GridPane.columnIndex="3" HBox.hgrow="ALWAYS">
+            <children>
                 <Label styleClass="label, small-label" text="Z" />
                 <Label fx:id="minZ" text="0" />
-              </children>
-            </VBox>
-          </children>
-        </HBox><HBox spacing="10.0" GridPane.columnIndex="1" GridPane.rowIndex="1" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
-<children>
-<VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-<children>
-<Label styleClass="label, small-label" text="X" />
-<Label fx:id="maxX" text="10" />
-</children>
-</VBox>
-<VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-<children>
-<Label styleClass="label, small-label" text="Y" />
-<Label fx:id="maxY" text="10" />
-</children>
-</VBox>
-<VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-<children>
-<Label styleClass="label, small-label" text="Z" />
-<Label fx:id="maxZ" text="0" />
-</children>
-</VBox>
-</children>
-</HBox><HBox spacing="10.0" GridPane.columnIndex="1" GridPane.rowIndex="2" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
-<children>
-<VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-<children>
-<Label styleClass="label, small-label" text="Width" />
-<Label fx:id="width" text="10" />
-</children>
-</VBox>
-<VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-<children>
-<Label styleClass="label, small-label" text="Height" />
-<Label fx:id="height" text="10" />
-</children>
-</VBox>
-<VBox alignment="CENTER" HBox.hgrow="ALWAYS">
-<children>
-<Label styleClass="label, small-label" text="Depth" />
-<Label fx:id="depth" text="0" />
-</children>
-</VBox>
-</children>
-</HBox>
-      </children>
-      <columnConstraints>
-        <ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" maxWidth="110.0" minWidth="10.0" prefWidth="67.0" />
-        <ColumnConstraints hgrow="ALWAYS" maxWidth="152.0" minWidth="10.0" prefWidth="152.0" />
-      </columnConstraints>
-      <rowConstraints>
+            </children>
+        </VBox>
+        <VBox alignment="CENTER" GridPane.columnIndex="2" GridPane.rowIndex="1" HBox.hgrow="ALWAYS">
+            <children>
+                <Label styleClass="label, small-label" text="Y" />
+                <Label fx:id="maxY" text="10" />
+            </children>
+        </VBox>
+        <VBox alignment="CENTER" GridPane.columnIndex="3" GridPane.rowIndex="1" HBox.hgrow="ALWAYS">
+            <children>
+                <Label styleClass="label, small-label" text="Z" />
+                <Label fx:id="maxZ" text="0" />
+            </children>
+        </VBox>
+        <VBox alignment="CENTER" GridPane.columnIndex="2" GridPane.rowIndex="2" HBox.hgrow="ALWAYS">
+            <children>
+                <Label styleClass="label, small-label" text="Height" />
+                <Label fx:id="height" text="10" />
+            </children>
+        </VBox>
+        <VBox alignment="CENTER" GridPane.columnIndex="3" GridPane.rowIndex="2" HBox.hgrow="ALWAYS">
+            <children>
+                <Label styleClass="label, small-label" text="Depth" />
+                <Label fx:id="depth" text="0" />
+            </children>
+        </VBox>
+    </children>
+    <columnConstraints>
+        <ColumnConstraints halignment="RIGHT" hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" />
+        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="-Infinity" />
+        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" />
+        <ColumnConstraints hgrow="ALWAYS" maxWidth="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" />
+    </columnConstraints>
+    <rowConstraints>
         <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
         <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
         <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
-      </rowConstraints>
-    </GridPane>
+    </rowConstraints>
+</GridPane>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/KeyCombinationPopupEditor.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+  All rights reserved. Use is subject to license terms.
+
+  This file is available and licensed under the following license:
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+  - Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+  - Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the distribution.
+  - Neither the name of Oracle Corporation nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<?import java.lang.*?>
+<?import javafx.collections.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+
+<GridPane hgap="10.0" vgap="5.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
+  <columnConstraints>
+    <ColumnConstraints halignment="RIGHT" hgrow="ALWAYS" />
+    <ColumnConstraints halignment="LEFT" hgrow="ALWAYS" />
+  </columnConstraints>
+  <rowConstraints>
+    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
+    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
+    <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
+  </rowConstraints>
+<children>
+    <Label text="Main key" GridPane.rowIndex="1" />
+    <StackPane fx:id="mainKeySp" maxWidth="1.7976931348623157E308" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1" />
+    <Button fx:id="clearAllBt" mnemonicParsing="false" text="Clear all" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="2" /><Label text="Modifier 1" /><ChoiceBox prefHeight="25.0" prefWidth="94.0" GridPane.columnIndex="1" xmlns:fx="http://javafx.com/fxml">
+  <items>
+    <FXCollections fx:factory="observableArrayList">
+      <String fx:value="Item 1" />
+      <String fx:value="Item 2" />
+      <String fx:value="Item 3" />
+    </FXCollections>
+  </items>
+</ChoiceBox>
+</children>
+</GridPane>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/popupeditors/KeyCombinationPopupEditor.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.popupeditors;
+
+import com.oracle.javafx.scenebuilder.kit.editor.i18n.I18N;
+import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.AutoSuggestEditor;
+import com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.EditorUtils;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.ValuePropertyMetadata;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.control.Button;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.Label;
+import javafx.scene.input.KeyCharacterCombination;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.StackPane;
+import javafx.util.StringConverter;
+
+/**
+ * KeyCombination popup editor (for keyboard shortcuts).
+ *
+ */
+public class KeyCombinationPopupEditor extends PopupEditor {
+
+    @FXML
+    StackPane mainKeySp;
+    @FXML
+    Button clearAllBt;
+
+    private final GridPane gridPane;
+    private static final int NB_MODIFIERS_MAX = 5;
+    private final ArrayList<ModifierRow> modifierRows = new ArrayList<>();
+    private KeyCombination.ModifierValue alt;
+    private KeyCombination.ModifierValue control;
+    private KeyCombination.ModifierValue meta;
+    private KeyCombination.ModifierValue shift;
+    private KeyCombination.ModifierValue shortcut;
+    private MainKey mainKey;
+    private final KeyCombination.Modifier[] keyCombinationModifiers = {
+        KeyCombination.ALT_ANY, KeyCombination.ALT_DOWN,
+        KeyCombination.CONTROL_ANY, KeyCombination.CONTROL_DOWN,
+        KeyCombination.META_ANY, KeyCombination.META_DOWN,
+        KeyCombination.SHIFT_ANY, KeyCombination.SHIFT_DOWN,
+        KeyCombination.SHORTCUT_ANY, KeyCombination.SHORTCUT_DOWN};
+
+    @SuppressWarnings("LeakingThisInConstructor")
+    public KeyCombinationPopupEditor(ValuePropertyMetadata propMeta, Set<Class<?>> selectedClasses) {
+        super(propMeta, selectedClasses);
+        Parent root = EditorUtils.loadPopupFxml("KeyCombinationPopupEditor.fxml", this); //NOI18N
+        assert root instanceof GridPane;
+        gridPane = (GridPane) root;
+
+        initialize();
+    }
+
+    // Method to please FindBugs
+    private void initialize() {
+        // Build suggested key code list
+        List<Field> keyCodes = Arrays.asList(KeyCode.class.getFields());
+        List<String> keyCodesStr = new ArrayList<>();
+        for (Field keyCode : keyCodes) {
+            keyCodesStr.add(keyCode.getName());
+        }
+
+        mainKey = new MainKey(keyCodesStr);
+        mainKeySp.getChildren().add(mainKey.getNode());
+
+        clearAllBt.setText(I18N.getString("inspector.keycombination.clear"));
+        clearAllBt.setOnAction(new EventHandler<ActionEvent>() {
+
+            @Override
+            public void handle(ActionEvent t) {
+                resetPopupContent();
+                commit(null);
+            }
+        });
+
+        // Plug to the menu button.
+        plugEditor(this, gridPane);
+
+        buildUI();
+    }
+
+    private String getValueAsString(Object value) {
+        String valueAsString;
+        if (isIndeterminate()) {
+            valueAsString = "-"; //NOI18N
+        } else {
+            valueAsString = (value != null) ? value.toString() : I18N.getString("inspector.keycombination.null"); //NOI18N
+        }
+        return valueAsString;
+    }
+
+    //
+    // Interface PopupEditor.InputValue.
+    // Methods called by PopupEditor.
+    //
+    @Override
+    public void setPopupContentValue(Object value) {
+
+        if (value != null) {
+            // Empty the editor
+            resetState();
+            resetUI();
+            assert value instanceof KeyCombination;
+            // Apply the new keyCombination
+            buildContent((KeyCombination) value);
+        } else {
+            resetPopupContent();
+        }
+
+        // Update the menu button string
+        displayValueAsString(getValueAsString(value));
+    }
+
+    @Override
+    public void resetPopupContent() {
+        // Set the editor to its initial value
+        resetState();
+        buildUI();
+        displayValueAsString(getValueAsString(null));
+    }
+
+    private void resetState() {
+        modifierRows.clear();
+        mainKey.setKeyCode(null);
+    }
+
+    private void resetUI() {
+        gridPane.getChildren().clear();
+        gridPane.getRowConstraints().clear();
+    }
+
+    private void buildContent(KeyCombination keyCombination) {
+        assert keyCombination != null;
+
+        // Build the modifiers rows
+        modifierRows.clear();
+        KeyCombination.Modifier modifier1 = null;
+        alt = keyCombination.getAlt();
+        if (alt != KeyCombination.ModifierValue.UP) {
+            if (alt == KeyCombination.ModifierValue.DOWN) {
+                modifier1 = KeyCombination.ALT_DOWN;
+            } else if (alt == KeyCombination.ModifierValue.ANY) {
+                modifier1 = KeyCombination.ALT_ANY;
+            }
+            createModifierRow(modifier1);
+        }
+
+        KeyCombination.Modifier modifier2 = null;
+        control = keyCombination.getControl();
+        if (control != KeyCombination.ModifierValue.UP) {
+            if (control == KeyCombination.ModifierValue.DOWN) {
+                modifier2 = KeyCombination.CONTROL_DOWN;
+            } else if (control == KeyCombination.ModifierValue.ANY) {
+                modifier2 = KeyCombination.CONTROL_ANY;
+            }
+            createModifierRow(modifier2);
+        }
+
+        KeyCombination.Modifier modifier3 = null;
+        meta = keyCombination.getMeta();
+        if (meta != KeyCombination.ModifierValue.UP) {
+            if (meta == KeyCombination.ModifierValue.DOWN) {
+                modifier3 = KeyCombination.META_DOWN;
+            } else if (meta == KeyCombination.ModifierValue.ANY) {
+                modifier3 = KeyCombination.META_ANY;
+            }
+            createModifierRow(modifier3);
+        }
+
+        KeyCombination.Modifier modifier4 = null;
+        shift = keyCombination.getShift();
+        if (shift != KeyCombination.ModifierValue.UP) {
+            if (shift == KeyCombination.ModifierValue.DOWN) {
+                modifier4 = KeyCombination.SHIFT_DOWN;
+            } else if (shift == KeyCombination.ModifierValue.ANY) {
+                modifier4 = KeyCombination.SHIFT_ANY;
+            }
+            createModifierRow(modifier4);
+        }
+
+        KeyCombination.Modifier modifier5 = null;
+        shortcut = keyCombination.getShortcut();
+        if (shortcut != KeyCombination.ModifierValue.UP) {
+            if (shortcut == KeyCombination.ModifierValue.DOWN) {
+                modifier5 = KeyCombination.SHORTCUT_DOWN;
+            } else if (shortcut == KeyCombination.ModifierValue.ANY) {
+                modifier5 = KeyCombination.SHORTCUT_ANY;
+            }
+            createModifierRow(modifier5);
+        }
+
+        // Handle the main key
+        KeyCode keyCode = null;
+        if (keyCombination instanceof KeyCodeCombination) {
+            keyCode = ((KeyCodeCombination) keyCombination).getCode();
+        } else if (keyCombination instanceof KeyCharacterCombination) {
+            keyCode = KeyCode.getKeyCode(((KeyCharacterCombination) keyCombination).getCharacter());
+        }
+        mainKey.setKeyCode(keyCode);
+
+        // Build the UI
+        buildUI();
+
+        commit(keyCombination);
+    }
+
+    private void commit(KeyCombination keyCombination) {
+        commitValue(keyCombination, getValueAsString(keyCombination));
+    }
+    
+    private KeyCombination createKeyCombination() {
+        if (mainKey.isEmpty()) {
+            return null;
+        }
+        KeyCodeCombination keyComb = null;
+        List<KeyCombination.Modifier> modifiers = new ArrayList<>();
+        for (ModifierRow modifier : modifierRows) {
+            if (!modifier.isEmpty()) {
+                if (modifiers.contains(modifier.getModifier())) {
+                    // doublon: invalid
+                    return null;
+                }
+                modifiers.add(modifier.getModifier());
+            }
+        }
+        if (modifiers.isEmpty()) {
+            // no modifier: invalid
+            return null;
+        }
+        try {
+            keyComb = new KeyCodeCombination(mainKey.getKeyCode(), modifiers.toArray(new KeyCombination.Modifier[1]));
+        } catch (IllegalArgumentException | NullPointerException ex) {
+            System.out.println("Invalid key combination" + ex); //NOI18N
+        } catch (RuntimeException ex) {
+            System.out.println(ex.getMessage() + ex);
+        }
+        return keyComb;
+    }
+
+    private List<KeyCombination.Modifier> getModifierConstants() {
+        ArrayList<KeyCombination.Modifier> mods = new ArrayList<>();
+        for (KeyCombination.Modifier modifier : keyCombinationModifiers) {
+            boolean alreadyUsed = false;
+            for (ModifierRow row : modifierRows) {
+                if (!row.isEmpty()) {
+                    if (row.getModifier().getKey().equals(modifier.getKey())) {
+                        // modifier already used
+                        alreadyUsed = true;
+                        break;
+                    }
+                }
+            }
+            if (!alreadyUsed) {
+                mods.add(modifier);
+            }
+        }
+        mods.add(null);
+        Collections.sort(mods, new ModifierComparator());
+        return mods;
+    }
+
+    private static class ModifierComparator implements Comparator<KeyCombination.Modifier> {
+
+        @Override
+        public int compare(KeyCombination.Modifier o1, KeyCombination.Modifier o2) {
+            if (o1 == null || o2 == null) {
+                return -1;
+            }
+            String str1 = o1.getKey().toString() + o1.getValue().toString();
+            String str2 = o2.getKey().toString() + o2.getValue().toString();
+            return str1.compareTo(str2);
+        }
+    }
+
+    private ChoiceBox<KeyCombination.Modifier> createModifierChoiceBox(KeyCombination.Modifier modifier) {
+        final ChoiceBox<KeyCombination.Modifier> modifierChoiceBox = new ChoiceBox<>();
+        EditorUtils.makeWidthStretchable(modifierChoiceBox);
+        modifierChoiceBox.setConverter(new ModifierConverter());
+        modifierChoiceBox.getItems().setAll(getModifierConstants());
+        if (modifier != null) {
+            modifierChoiceBox.getSelectionModel().select(modifier);
+        }
+
+        modifierChoiceBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<KeyCombination.Modifier>() {
+            @Override
+            public void changed(ObservableValue<? extends KeyCombination.Modifier> observable,
+                    KeyCombination.Modifier oldValue, KeyCombination.Modifier newValue) {
+                if (!mainKey.isEmpty()) {
+                    KeyCombination kc = createKeyCombination();
+                    if (kc != null) {
+                        commit(kc);
+                    }
+                }
+                buildUI();
+            }
+        });
+        return modifierChoiceBox;
+    }
+
+    private void buildUI() {
+        resetUI();
+
+        // Cleanup: remove empty rows
+        ArrayList<ModifierRow> emptyRows = new ArrayList<>();
+        for (ModifierRow row : modifierRows) {
+            if (row.isEmpty()) {
+                emptyRows.add(row);
+            }
+        }
+        modifierRows.removeAll(emptyRows);
+
+        int lineIndex = 0;
+        for (ModifierRow row : modifierRows) {
+            addModifierRow(row, lineIndex);
+            lineIndex++;
+        }
+
+        // add an empty row
+        boolean added = false;
+        if (modifierRows.size() < NB_MODIFIERS_MAX) {
+            added = addEmptyModifierIfNeeded();
+        }
+        if (added) {
+            lineIndex++;
+        }
+
+        // add mainKey
+        Label mainKeyLabel = new Label(I18N.getString("inspector.keycombination.mainkey"));
+        gridPane.add(mainKeyLabel, 0, lineIndex);
+        gridPane.add(mainKey.getNode(), 1, lineIndex);
+        lineIndex++;
+
+        // add reset button
+        gridPane.add(clearAllBt, 1, lineIndex);
+    }
+
+    private boolean addEmptyModifierIfNeeded() {
+        for (ModifierRow row : modifierRows) {
+            if (row.isEmpty()) {
+                return false;
+            }
+        }
+        addModifierRow(createModifierRow(null), modifierRows.size() - 1);
+        return true;
+    }
+
+    private void addModifierRow(ModifierRow row, int lineIndex) {
+        row.getLabel().setText(I18N.getString("inspector.keycombination.modifier")
+                + " " + (lineIndex + 1)); //NOI18N
+        gridPane.add(row.getLabel(), 0, lineIndex);
+        gridPane.add(row.getChoiceBox(), 1, lineIndex);
+    }
+
+    private ModifierRow createModifierRow(KeyCombination.Modifier modifier) {
+        ChoiceBox<KeyCombination.Modifier> choiceBox = createModifierChoiceBox(modifier);
+        ModifierRow row = new ModifierRow(choiceBox);
+        modifierRows.add(row);
+        return row;
+    }
+
+    @SuppressWarnings("LeakingThisInConstructor")
+    private class MainKey extends AutoSuggestEditor {
+
+        public MainKey(List<String> suggestedKeys) {
+            super("", null, suggestedKeys); //NOI18N
+            ChangeListener<String> textPropertyChange = new ChangeListener<String>() {
+
+                @Override
+                public void changed(ObservableValue<? extends String> ov, String prevText, String newText) {
+                    if (!newText.isEmpty()) {
+                        KeyCombination kc = createKeyCombination();
+                        if (kc != null) {
+                            commit(kc);
+                        }
+                    }
+                }
+            };
+            getTextField().textProperty().addListener(textPropertyChange);
+        }
+
+        public Node getNode() {
+            return getValueEditor();
+        }
+
+        public void setKeyCode(KeyCode keyCode) {
+            setValue((keyCode != null) ? keyCode.toString() : "");//NOI18N
+        }
+
+        public KeyCode getKeyCode() {
+            String valStr = getTextField().getText();
+            if (valStr.isEmpty()) {
+                return null;
+            }
+            if (valStr.length() == 1) {
+                // single character : put it in uppercase for convenience (lowercase char are not supported)
+                valStr = valStr.toUpperCase(Locale.ROOT);
+            }
+
+            KeyCode keyCode = null;
+            try {
+                keyCode = KeyCode.valueOf(valStr);
+            } catch (Exception ex) {
+                System.out.println("Cannot find key code for " + valStr + "\n" + ex); //NOI18N
+            }
+            return keyCode;
+        }
+
+        public boolean isEmpty() {
+            return getKeyCode() == null;
+        }
+    }
+
+    private static class ModifierRow {
+
+        private Label label;
+        private ChoiceBox<KeyCombination.Modifier> choiceBox;
+
+        public ModifierRow(ChoiceBox<KeyCombination.Modifier> choiceBox) {
+            this.label = new Label();
+            this.choiceBox = choiceBox;
+        }
+
+        public Label getLabel() {
+            return label;
+        }
+
+        public void setLabel(Label label) {
+            this.label = label;
+        }
+
+        public ChoiceBox<KeyCombination.Modifier> getChoiceBox() {
+            return choiceBox;
+        }
+
+        public void setChoiceBox(ChoiceBox<KeyCombination.Modifier> choiceBox) {
+            this.choiceBox = choiceBox;
+        }
+
+        public KeyCombination.Modifier getModifier() {
+            return choiceBox.getSelectionModel().getSelectedItem();
+        }
+
+        public boolean isEmpty() {
+            return getModifier() == null;
+        }
+    }
+
+    private static class ModifierConverter extends StringConverter<KeyCombination.Modifier> {
+
+        @Override
+        public String toString(KeyCombination.Modifier object) {
+            if (object == null) {
+                return I18N.getString("inspector.keycombination.none");
+            }
+            return object.getKey() + "_" + object.getValue(); //NOI18N 
+        }
+
+        @Override
+        public KeyCombination.Modifier fromString(String string) {
+            if (string.equals(I18N.getString("inspector.keycombination.none"))) {
+                return null;
+            }
+            if (string.startsWith(KeyCode.ALT.getName())) {
+                if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) {
+                    return KeyCombination.ALT_DOWN;
+                } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) {
+                    return KeyCombination.ALT_ANY;
+                }
+            }
+            if (string.startsWith(KeyCode.CONTROL.getName())) {
+                if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) {
+                    return KeyCombination.CONTROL_DOWN;
+                } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) {
+                    return KeyCombination.CONTROL_ANY;
+                }
+            }
+            if (string.startsWith(KeyCode.META.getName())) {
+                if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) {
+                    return KeyCombination.META_DOWN;
+                } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) {
+                    return KeyCombination.META_ANY;
+                }
+            }
+            if (string.startsWith(KeyCode.SHIFT.getName())) {
+                if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) {
+                    return KeyCombination.SHIFT_DOWN;
+                } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) {
+                    return KeyCombination.SHIFT_ANY;
+                }
+            }
+            if (string.startsWith(KeyCode.SHORTCUT.getName())) {
+                if (string.endsWith(KeyCombination.ModifierValue.DOWN.name())) {
+                    return KeyCombination.SHORTCUT_DOWN;
+                } else if (string.endsWith(KeyCombination.ModifierValue.ANY.name())) {
+                    return KeyCombination.SHORTCUT_ANY;
+                }
+            }
+            return null;
+        }
+    }
+
+}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/library/LibraryPanelController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/library/LibraryPanelController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -155,6 +155,13 @@
         processImportJarFxml(importedFiles);
     }
     
+    /**
+     * @treatAsPrivate Perform the import of the selection
+     */
+    public void performImportSelection(List<FXOMObject> objects) {
+        processInternalImport(objects);
+    }
+    
     /*
      * AbstractPanelController
      */
@@ -519,7 +526,7 @@
 //                System.out.println("libPane onDragDropped");
                 AbstractDragSource dragSource = getEditorController().getDragController().getDragSource();
                 if (dragSource != null && dragSource instanceof DocumentDragSource) {
-                    processInternalImport((DocumentDragSource)dragSource);
+                    processInternalImport(((DocumentDragSource)dragSource).getDraggedObjects());
                 } else {
                     initiateImportDialog = false;
                     jarAndFxmlFiles.clear();
@@ -622,7 +629,7 @@
     // SceneBuilder (from Content or Hierarchy).
     // We stop the watching thread to avoid potential parsing of a file that
     // would not yet be properly finalized on disk.
-    private void processInternalImport(DocumentDragSource source) {
+    private void processInternalImport(List<FXOMObject> objects) {
         String userLibraryPathString = ((UserLibrary) getEditorController().getLibrary()).getPath();
         Path libPath = Paths.get(userLibraryPathString);
         ((UserLibrary) getEditorController().getLibrary()).stopWatching();
@@ -631,7 +638,7 @@
         try {
             // The selection can be multiple, in which case each asset is processed
             // separately. The handling of dependencies will be addressed later on.
-            for (FXOMObject asset : source.getDraggedObjects()) {
+            for (FXOMObject asset : objects) {
                 // Create an FXML layout as a String
                 ArrayList<FXOMObject> selection = new ArrayList<>();
                 selection.add(asset);
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/util/ContextMenuController.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/util/ContextMenuController.java	Mon Dec 23 13:59:52 2013 +0100
@@ -88,8 +88,6 @@
     private final MenuItem wrapInGroupMenuItem;
     private final MenuItem unwrapMenuItem;
     private final Menu gridPaneMenu;
-    private final MenuItem selectNextRowMenuItem;
-    private final MenuItem selectNextColumnMenuItem;
     private final MenuItem moveRowAboveMenuItem;
     private final MenuItem moveRowBelowMenuItem;
     private final MenuItem moveColumnBeforeMenuItem;
@@ -230,16 +228,10 @@
                 wrapInVBoxMenuItem,
                 wrapInGroupMenuItem);
         unwrapMenuItem = new MenuItem("Unwrap");
-        wrapInGroupMenuItem.setOnAction(onActionEventHandler);
+        unwrapMenuItem.setOnAction(onActionEventHandler);
         unwrapMenuItem.setUserData(new EditActionController(EditAction.UNWRAP));
         // GridPane specifics
         gridPaneMenu = new Menu("GridPane");
-        selectNextRowMenuItem = new MenuItem("Select Next Row");
-        selectNextRowMenuItem.setOnAction(onActionEventHandler);
-        selectNextRowMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT_ROW));
-        selectNextColumnMenuItem = new MenuItem("Select Next Column");
-        selectNextColumnMenuItem.setOnAction(onActionEventHandler);
-        selectNextColumnMenuItem.setUserData(new ControlActionController(ControlAction.SELECT_NEXT_COLUMN));
         moveRowAboveMenuItem = new MenuItem("Move Row Above");
         moveRowAboveMenuItem.setOnAction(onActionEventHandler);
         moveRowAboveMenuItem.setUserData(new EditActionController(EditAction.MOVE_ROW_ABOVE));
@@ -337,9 +329,6 @@
                 contextMenu.getItems().addAll(
                         deleteMenuItem,
                         new SeparatorMenuItem(),
-                        selectNextRowMenuItem,
-                        selectNextColumnMenuItem,
-                        new SeparatorMenuItem(),
                         moveRowAboveMenuItem,
                         moveRowBelowMenuItem,
                         moveColumnBeforeMenuItem,
@@ -444,9 +433,6 @@
         // Add actions on the GridPane rows/columns
         if (canPerformGridPaneActions()) {
             gridPaneMenu.getItems().addAll(
-                    selectNextRowMenuItem,
-                    selectNextColumnMenuItem,
-                    new SeparatorMenuItem(),
                     moveRowAboveMenuItem,
                     moveRowBelowMenuItem,
                     moveColumnBeforeMenuItem,
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMCollection.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMCollection.java	Mon Dec 23 13:59:52 2013 +0100
@@ -119,6 +119,12 @@
      */
 
     @Override
+    public List<FXOMObject> getChildObjects() {
+        return Collections.unmodifiableList(items);
+    }
+
+
+    @Override
     public FXOMObject searchWithSceneGraphObject(Object sceneGraphObject) {
         FXOMObject result;
         
@@ -211,6 +217,15 @@
         }
     }
 
+    @Override
+    protected void collectEventHandlers(List<FXOMPropertyT> result) {
+        if (getSceneGraphObject() != null) {
+            for (FXOMObject i : items) {
+                i.collectEventHandlers(result);
+            }
+        }
+    }
+
     /*
      * FXOMNode
      */
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java	Mon Dec 23 13:59:52 2013 +0100
@@ -33,6 +33,7 @@
 
 import com.oracle.javafx.scenebuilder.kit.fxom.glue.GlueElement;
 import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -130,6 +131,20 @@
      */
 
     @Override
+    public List<FXOMObject> getChildObjects() {
+        final List<FXOMObject> result = new ArrayList<>();
+        
+        for (FXOMProperty p : properties.values()) {
+            if (p instanceof FXOMPropertyC) {
+                final FXOMPropertyC pc = (FXOMPropertyC) p;
+                result.addAll(pc.getValues());
+            }
+        }
+        return result;
+    }
+
+
+    @Override
     public FXOMObject searchWithSceneGraphObject(Object sceneGraphObject) {
         FXOMObject result;
         
@@ -271,6 +286,27 @@
         }
     }
 
+    @Override
+    protected void collectEventHandlers(List<FXOMPropertyT> result) {
+        if (getSceneGraphObject() != null) {
+            for (FXOMProperty p : properties.values()) {
+                if (p instanceof FXOMPropertyT) {
+                    final FXOMPropertyT pt = (FXOMPropertyT) p;
+                    if (pt.getValue().startsWith("#")) {
+                        result.add(pt);
+                    }
+                }
+            }
+            for (FXOMProperty p : properties.values()) {
+                if (p instanceof FXOMPropertyC) {
+                    for (FXOMObject v : ((FXOMPropertyC)p).getValues()) {
+                        v.collectEventHandlers(result);
+                    }
+                }
+            }
+        }
+    }
+
     /*
      * FXOMNode
      */
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMIntrinsic.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMIntrinsic.java	Mon Dec 23 13:59:52 2013 +0100
@@ -33,6 +33,7 @@
 
 import com.oracle.javafx.scenebuilder.kit.fxom.glue.GlueElement;
 import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -114,6 +115,13 @@
      */
 
     @Override
+    public List<FXOMObject> getChildObjects() {
+        // Intrinsics have not children
+        return Collections.emptyList();
+    }
+
+
+    @Override
     public FXOMObject searchWithSceneGraphObject(Object sceneGraphObject) {
         FXOMObject result;
         
@@ -177,6 +185,10 @@
         // Nothing to collect in this kind of object
     }
 
+    @Override
+    protected void collectEventHandlers(List<FXOMPropertyT> result) {
+        // Nothing to collect in this kind of object
+    }
 
 
     /*
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMObject.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMObject.java	Mon Dec 23 13:59:52 2013 +0100
@@ -393,6 +393,16 @@
     
     protected abstract void collectObjectWithSceneGraphObjectClass(Class<?> sceneGraphObjectClass, List<FXOMObject> result);
     
+    public List<FXOMPropertyT> collectEventHandlers() {
+        final List<FXOMPropertyT> result = new ArrayList<>();
+        
+        collectEventHandlers(result);
+        
+        return result;
+    }
+    
+    protected abstract void collectEventHandlers(List<FXOMPropertyT> result);
+    
     /*
      * Utilities
      */
@@ -410,6 +420,8 @@
         return result;
     }
     
+    public abstract List<FXOMObject> getChildObjects();
+    
     public boolean isDescendantOf(FXOMObject other) {
         final boolean result;
         
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMRefresher.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/FXOMRefresher.java	Mon Dec 23 13:59:52 2013 +0100
@@ -56,7 +56,9 @@
                                         document.getLocation(), 
                                         document.getClassLoader(),
                                         document.getResources());
+            final TransientStateBackup backup = new TransientStateBackup(document);
             refreshDocument(document, newDocument);
+            backup.restore();
         } catch(IOException x) {
             final StringBuilder sb = new StringBuilder();
             sb.append("Bug in ");
@@ -79,7 +81,9 @@
         }
     }
     
-    
+    /*
+     * Private (stylesheet)
+     */
     
     private void refreshDocument(FXOMDocument currentDocument, FXOMDocument newDocument) {
 //        if (currentDocument.getSceneGraphRoot() instanceof Parent) {
@@ -167,25 +171,25 @@
             refreshFxomObject(currentObject, newObject);
         }
     }
-    
-    
-    private void reloadStylesheets(final Parent p) {
-        assert p != null;
-        assert p.getScene() != null;
-        
-        if (p.getStylesheets().isEmpty() == false) {
-            final List<String> stylesheets = new ArrayList<>();
-            stylesheets.addAll(p.getStylesheets());
-//            p.getStylesheets().clear();
-//            p.impl_processCSS(true);
-            p.getStylesheets().setAll(stylesheets);
-//            p.impl_processCSS(true);
-        }
-        for (Node child : p.getChildrenUnmodifiable()) {
-            if (child instanceof Parent) {
-                reloadStylesheets((Parent)child);
-            }
-        }
-        
-    }
+//    
+//    
+//    private void reloadStylesheets(final Parent p) {
+//        assert p != null;
+//        assert p.getScene() != null;
+//        
+//        if (p.getStylesheets().isEmpty() == false) {
+//            final List<String> stylesheets = new ArrayList<>();
+//            stylesheets.addAll(p.getStylesheets());
+////            p.getStylesheets().clear();
+////            p.impl_processCSS(true);
+//            p.getStylesheets().setAll(stylesheets);
+////            p.impl_processCSS(true);
+//        }
+//        for (Node child : p.getChildrenUnmodifiable()) {
+//            if (child instanceof Parent) {
+//                reloadStylesheets((Parent)child);
+//            }
+//        }
+//        
+//    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/TransientStateBackup.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.javafx.scenebuilder.kit.fxom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javafx.scene.control.Accordion;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TitledPane;
+
+/**
+ *
+ */
+class TransientStateBackup {
+    
+    private final FXOMDocument fxomDocument;
+    private final Map<FXOMObject, FXOMObject> tabPaneMap = new HashMap<>();
+    private final Map<FXOMObject, FXOMObject> accordionMap = new HashMap<>();
+
+    public TransientStateBackup(FXOMDocument fxomDocument) {
+        assert fxomDocument != null;
+        
+        this.fxomDocument = fxomDocument;
+        
+        final List<FXOMObject> candidates = new ArrayList<>();
+        if (this.fxomDocument.getFxomRoot() != null) {
+            candidates.add(this.fxomDocument.getFxomRoot());
+        }
+        
+        while (candidates.isEmpty() == false) {
+            final FXOMObject candidate = candidates.get(0);
+            candidates.remove(0);
+            
+            final Object sceneGraphObject = candidate.getSceneGraphObject();
+            if (sceneGraphObject instanceof TabPane) {
+                final TabPane tabPane = (TabPane) sceneGraphObject;
+                final Tab currentTab = tabPane.getSelectionModel().getSelectedItem();
+                if (currentTab != null) {
+                    final FXOMObject tabObject 
+                            = candidate.searchWithSceneGraphObject(currentTab);
+                    if (tabObject != null) {
+                        tabPaneMap.put(candidate, tabObject);
+                    }
+                }
+            } else if (sceneGraphObject instanceof Accordion) {
+                final Accordion accordion  = (Accordion) sceneGraphObject;
+                final TitledPane currentTitledPane = accordion.getExpandedPane();
+                if (currentTitledPane != null) {
+                    final FXOMObject titledPaneObject
+                            = candidate.searchWithSceneGraphObject(currentTitledPane);
+                    if (titledPaneObject != null) {
+                        accordionMap.put(candidate, titledPaneObject);
+                    }
+                }
+            }
+            
+            candidates.addAll(candidate.getChildObjects());
+        }
+    }
+    
+    public void restore() {
+        final List<FXOMObject> candidates = new ArrayList<>();
+        if (this.fxomDocument.getFxomRoot() != null) {
+            candidates.add(this.fxomDocument.getFxomRoot());
+        }
+        
+        while (candidates.isEmpty() == false) {
+            final FXOMObject candidate = candidates.get(0);
+            candidates.remove(0);
+            
+            final Object sceneGraphObject = candidate.getSceneGraphObject();
+            if (sceneGraphObject instanceof TabPane) {
+                final TabPane tabPane = (TabPane) sceneGraphObject;
+                final FXOMObject tabObject = tabPaneMap.get(candidate);
+                if ((tabObject != null) && (tabObject.getParentObject() == candidate)) {
+                    assert tabObject.getSceneGraphObject() instanceof Tab;
+                    final Tab tab = (Tab) tabObject.getSceneGraphObject();
+                    assert tabPane.getTabs().contains(tab);
+                    tabPane.getSelectionModel().select(tab);
+                }
+            } else if (sceneGraphObject instanceof Accordion) {
+                final Accordion accordion  = (Accordion) sceneGraphObject;
+                final FXOMObject titlePaneObject = accordionMap.get(candidate);
+                if ((titlePaneObject != null) && (titlePaneObject.getParentObject() == candidate)) {
+                    assert titlePaneObject.getSceneGraphObject() instanceof TitledPane;
+                    final TitledPane titledPane = (TitledPane) titlePaneObject.getSceneGraphObject();
+                    assert accordion.getPanes().contains(titledPane);
+                    accordion.setExpandedPane(titledPane);
+                }
+            }
+            
+            candidates.addAll(candidate.getChildObjects());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/ChoiceBoxSampleData.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.javafx.scenebuilder.kit.fxom.sampledata;
+
+import java.util.ArrayList;
+import java.util.List;
+import javafx.scene.control.ChoiceBox;
+
+/**
+ *
+ */
+class ChoiceBoxSampleData extends AbstractSampleData {
+    
+    private final List<String> samples = new ArrayList<>();
+
+    public ChoiceBoxSampleData() {
+        for (int i = 0; i < 20; i++) {
+            samples.add(lorem(i));
+        }
+    }
+
+    /*
+     * AbstractSampleData
+     */
+    
+    @Override
+    public void applyTo(Object sceneGraphObject) {
+        assert sceneGraphObject != null;
+        
+        @SuppressWarnings("unchecked")        
+        final ChoiceBox<String> choiceBox = (ChoiceBox<String>) sceneGraphObject;
+        choiceBox.getItems().clear();
+        choiceBox.getItems().addAll(samples);
+        choiceBox.getSelectionModel().select(samples.get(0));
+    }
+    
+    @Override
+    public void removeFrom(Object sceneGraphObject) {
+        assert sceneGraphObject != null;
+        
+        @SuppressWarnings("unchecked")        
+        final ChoiceBox<String> choiceBox = (ChoiceBox<String>) sceneGraphObject;
+        choiceBox.getItems().clear();
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/ComboBoxSampleData.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.javafx.scenebuilder.kit.fxom.sampledata;
+
+import java.util.ArrayList;
+import java.util.List;
+import javafx.scene.control.ComboBox;
+
+/**
+ *
+ */
+class ComboBoxSampleData extends AbstractSampleData {
+    
+    private final List<String> samples = new ArrayList<>();
+
+    public ComboBoxSampleData() {
+        for (int i = 0; i < 20; i++) {
+            samples.add(lorem(i));
+        }
+    }
+
+    /*
+     * AbstractSampleData
+     */
+    
+    @Override
+    public void applyTo(Object sceneGraphObject) {
+        assert sceneGraphObject != null;
+        
+        @SuppressWarnings("unchecked")        
+        final ComboBox<String> comboBox = (ComboBox<String>) sceneGraphObject;
+        comboBox.getItems().clear();
+        comboBox.getItems().addAll(samples);
+        comboBox.getSelectionModel().select(samples.get(0));
+    }
+    
+    @Override
+    public void removeFrom(Object sceneGraphObject) {
+        assert sceneGraphObject != null;
+        
+        @SuppressWarnings("unchecked")        
+        final ComboBox<String> comboBox = (ComboBox<String>) sceneGraphObject;
+        comboBox.getItems().clear();
+    }
+    
+}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/SampleDataGenerator.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/SampleDataGenerator.java	Mon Dec 23 13:59:52 2013 +0100
@@ -40,6 +40,9 @@
 import java.util.HashMap;
 import java.util.Map;
 import javafx.scene.chart.PieChart;
+import javafx.scene.chart.XYChart;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.ComboBox;
 import javafx.scene.control.ListView;
 import javafx.scene.control.TableView;
 import javafx.scene.control.TreeTableView;
@@ -64,7 +67,29 @@
             newData = null;
         } else {
             final Class<?> sceneGraphClass = sceneGraphObject.getClass();
-            if (sceneGraphClass == ListView.class) {
+            if (sceneGraphClass == ChoiceBox.class) {
+                final ChoiceBox<?> choiceBox = (ChoiceBox) sceneGraphObject;
+                if (choiceBox.getItems().isEmpty()) {
+                    if (currentData instanceof ChoiceBoxSampleData) {
+                        newData = currentData;
+                    } else {
+                        newData = new ChoiceBoxSampleData();
+                    }
+                } else {
+                    newData = null;
+                }
+            } else if (sceneGraphClass == ComboBox.class) {
+                final ComboBox<?> comboBox = (ComboBox) sceneGraphObject;
+                if (comboBox.getItems().isEmpty()) {
+                    if (currentData instanceof ComboBoxSampleData) {
+                        newData = currentData;
+                    } else {
+                        newData = new ComboBoxSampleData();
+                    }
+                } else {
+                    newData = null;
+                }
+            } else if (sceneGraphClass == ListView.class) {
                 final ListView<?> listView = (ListView) sceneGraphObject;
                 if (listView.getItems().isEmpty()) {
                     if (currentData instanceof ListViewSampleData) {
@@ -119,6 +144,17 @@
                 } else {
                     newData = null;
                 }
+            } else if (XYChartSampleData.isKnownXYChart(sceneGraphObject)) {
+                final XYChart<?,?> xyChart = (XYChart) sceneGraphObject;
+                if (xyChart.getData().isEmpty()) {
+                    if (currentData instanceof XYChartSampleData) {
+                        newData = currentData;
+                    } else {
+                        newData = new XYChartSampleData();
+                    }
+                } else {
+                    newData = null;
+                }
             } else {
                 newData = null;
             }
@@ -186,12 +222,12 @@
 //        
 //        if (obj instanceof ListView) {
 //            @SuppressWarnings("unchecked")
-//            final ListView<Object> pieChart = (ListView)obj;
-//            return visitList(pieChart);
+//            final ListView<Object> xyChart = (ListView)obj;
+//            return visitList(xyChart);
 //        } else if (obj instanceof TreeView) {
 //            @SuppressWarnings("unchecked")
-//            final TreeView<Object> pieChart = (TreeView)obj;
-//            return visitTree(pieChart);
+//            final TreeView<Object> xyChart = (TreeView)obj;
+//            return visitTree(xyChart);
 //        } else if (obj instanceof TableView) {
 //            @SuppressWarnings("unchecked")
 //            final TableView<Object> tableView = (TableView)obj;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/fxom/sampledata/XYChartSampleData.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.oracle.javafx.scenebuilder.kit.fxom.sampledata;
+
+import java.util.ArrayList;
+import java.util.List;
+import javafx.scene.chart.AreaChart;
+import javafx.scene.chart.Axis;
+import javafx.scene.chart.BarChart;
+import javafx.scene.chart.BubbleChart;
+import javafx.scene.chart.CategoryAxis;
+import javafx.scene.chart.LineChart;
+import javafx.scene.chart.NumberAxis;
+import javafx.scene.chart.ScatterChart;
+import javafx.scene.chart.StackedAreaChart;
+import javafx.scene.chart.StackedBarChart;
+import javafx.scene.chart.XYChart;
+
+/**
+ *
+ */
+class XYChartSampleData extends AbstractSampleData {
+    
+    private final List<XYChart.Series<Object,Object>> samples = new ArrayList<>();
+    private final List<String> categories = new ArrayList<>();
+    private Class<?> sampleXAxisClass;
+    private Class<?> sampleYAxisClass;
+
+    public static boolean isKnownXYChart(Object obj) {
+        final boolean result;
+        
+        if (obj instanceof XYChart) {
+            final Class<?> objClass = obj.getClass();
+            result = (objClass == BarChart.class 
+                    || objClass == AreaChart.class
+                    || objClass == BubbleChart.class
+                    || objClass == LineChart.class
+                    || objClass == ScatterChart.class
+                    || objClass == StackedBarChart.class
+                    || objClass == StackedAreaChart.class);
+        } else {
+            result = false;
+        }
+        
+        return result;
+    }
+
+    /*
+     * AbstractSampleData
+     */
+    
+    @Override
+    public void applyTo(Object sceneGraphObject) {
+        assert sceneGraphObject instanceof XYChart;
+        
+        @SuppressWarnings("unchecked")        
+        final XYChart<Object,Object> xyChart = (XYChart<Object,Object>) sceneGraphObject;
+        updateSamples(xyChart);
+        xyChart.getData().clear();
+        xyChart.getData().addAll(samples);
+        if (xyChart.getXAxis().getClass() == CategoryAxis.class) {
+            @SuppressWarnings("unchecked")        
+            final CategoryAxis axis = (CategoryAxis)(Axis<?>) xyChart.getXAxis();
+            axis.getCategories().setAll(categories);
+        }
+        if (xyChart.getYAxis().getClass() == CategoryAxis.class) {
+            @SuppressWarnings("unchecked")        
+            final CategoryAxis axis = (CategoryAxis)(Axis<?>) xyChart.getYAxis();
+            axis.getCategories().setAll(categories);
+        }
+    }
+    
+    @Override
+    public void removeFrom(Object sceneGraphObject) {
+        assert sceneGraphObject instanceof XYChart;
+        
+        @SuppressWarnings("unchecked")        
+        final XYChart<Object,Object> xyChart = (XYChart<Object,Object>) sceneGraphObject;
+        xyChart.getData().clear();
+        if (xyChart.getXAxis().getClass() == CategoryAxis.class) {
+            final CategoryAxis axis = (CategoryAxis)(Axis<?>) xyChart.getXAxis();
+            axis.getCategories().clear();
+        }
+        if (xyChart.getYAxis().getClass() == CategoryAxis.class) {
+            final CategoryAxis axis = (CategoryAxis)(Axis<?>) xyChart.getYAxis();
+            axis.getCategories().clear();
+        }
+    }
+    
+    
+    /*
+     * Private
+     */
+    
+    private void updateSamples(XYChart<?,?> xyChart) {
+        
+        final Class<?> xAxisClass = xyChart.getXAxis().getClass();
+        final Class<?> yAxisClass = xyChart.getYAxis().getClass();
+        
+        if ((xAxisClass != sampleXAxisClass) || (yAxisClass != sampleYAxisClass)) {
+            sampleXAxisClass = xAxisClass;
+            sampleYAxisClass = yAxisClass;
+            
+            for (int i = 0; i < 3; i++) {
+                final XYChart.Series<Object, Object> serie = new XYChart.Series<>();
+                for (int j = 0; j < 10; j++) {
+                    final Object xValue = makeValue(sampleXAxisClass, i);
+                    final Object yValue = makeValue(sampleYAxisClass, i);
+                    final XYChart.Data<Object, Object> data = new XYChart.Data<>(xValue, yValue);
+                    serie.getData().add(data);
+
+                }
+                samples.add(serie);
+            }
+            
+            categories.clear();
+            if ((sampleXAxisClass == CategoryAxis.class) || (sampleYAxisClass == CategoryAxis.class)) {
+                for (int j = 0; j < 10; j++) {
+                    categories.add(String.valueOf(2000 + j));
+                }
+            }
+        }
+    }
+    
+    private Object makeValue(Class<?> axisClass, int index) {
+        final Object result;
+        
+        if (axisClass == NumberAxis.class) {
+            result = Math.random() * 100.0;
+        } else if (axisClass == CategoryAxis.class) {
+            result = String.valueOf(2000 + index);
+        } else {
+            assert false : "Unexpected Axis subclass" + axisClass;
+            result = String.valueOf(index);
+        }
+        
+        return result;
+    }
+}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ChoiceBox.fxml	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ChoiceBox.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -37,12 +37,4 @@
 <?import javafx.scene.layout.*?>
 <?import javafx.scene.paint.*?>
 
-<ChoiceBox xmlns:fx="http://javafx.com/fxml">
-  <items>
-    <FXCollections fx:factory="observableArrayList">
-      <String fx:value="Item 1" />
-      <String fx:value="Item 2" />
-      <String fx:value="Item 3" />
-    </FXCollections>
-  </items>
-</ChoiceBox>
+<ChoiceBox xmlns:fx="http://javafx.com/fxml" prefWidth="150.0" />
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ComboBox.fxml	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/builtin/ComboBox.fxml	Mon Dec 23 13:59:52 2013 +0100
@@ -37,12 +37,4 @@
 <?import javafx.scene.layout.*?>
 <?import javafx.scene.paint.*?>
 
-<ComboBox xmlns:fx="http://javafx.com/fxml">
-  <items>
-    <FXCollections fx:factory="observableArrayList">
-      <String fx:value="Item 1" />
-      <String fx:value="Item 2" />
-      <String fx:value="Item 3" />
-    </FXCollections>
-  </items>
-</ComboBox>
+<ComboBox xmlns:fx="http://javafx.com/fxml" prefWidth="150.0" />
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/LibraryFolderWatcher.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/LibraryFolderWatcher.java	Mon Dec 23 13:59:52 2013 +0100
@@ -54,6 +54,7 @@
 import java.nio.file.WatchService;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
@@ -81,6 +82,7 @@
         
         try {
             library.updateExplorationCount(0);
+            library.updateExplorationDate(new Date());
             runDiscovery();
             runWatching();
         } catch(InterruptedException x) {
@@ -243,6 +245,7 @@
 
         library.addItems(newItems);
         library.updateExplorationCount(library.getExplorationCount()+1);
+        library.updateExplorationDate(new Date());
     }
     
     
@@ -300,6 +303,7 @@
         library.addItems(newItems);
         library.updateJarReports(new ArrayList<>(jarReports));
         library.updateExplorationCount(library.getExplorationCount()+1);
+        library.updateExplorationDate(new Date());
     }
     
     
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/UserLibrary.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/library/user/UserLibrary.java	Mon Dec 23 13:59:52 2013 +0100
@@ -50,11 +50,14 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.Date;
 import java.util.List;
 import java.util.TreeSet;
 import javafx.application.Platform;
 import javafx.beans.property.ReadOnlyIntegerProperty;
+import javafx.beans.property.ReadOnlyObjectProperty;
 import javafx.beans.property.SimpleIntegerProperty;
+import javafx.beans.property.SimpleObjectProperty;
 import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 
@@ -73,7 +76,8 @@
     
     private final ObservableList<JarReport> jarReports = FXCollections.observableArrayList();
     private final SimpleIntegerProperty explorationCountProperty = new SimpleIntegerProperty();
-    
+    private final SimpleObjectProperty<Date> explorationDateProperty = new SimpleObjectProperty<>();
+
     private State state = State.READY;
     private Exception exception;
     private LibraryFolderWatcher watcher;
@@ -153,7 +157,15 @@
     public ReadOnlyIntegerProperty explorationCountProperty() {
         return explorationCountProperty;
     }
+    
+    public Object getExplorationDate() {
+        return explorationDateProperty.get();
+    }
 
+    public ReadOnlyObjectProperty<Date> explorationDateProperty() {
+        return explorationDateProperty;
+    }
+    
     public void setFilter(List<String> classnames) throws FileNotFoundException, IOException {
         if (classnames != null && classnames.size() > 0) {
             File filterFile = new File(getFilterFileName());
@@ -275,7 +287,6 @@
         }
     }
     
-    
     void updateExplorationCount(int count) {
         if (Platform.isFxApplicationThread()) {
             explorationCountProperty.set(count);
@@ -289,6 +300,19 @@
         }
     }
     
+    void updateExplorationDate(Date date) {
+        if (Platform.isFxApplicationThread()) {
+            explorationDateProperty.set(date);
+        } else {
+            Platform.runLater(new Runnable() {
+                @Override
+                public void run() {
+                    explorationDateProperty.set(date);
+                }
+            });
+        }
+    }
+    
     /*
      * Library
      */
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/Metadata.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/Metadata.java	Mon Dec 23 13:59:52 2013 +0100
@@ -36,6 +36,7 @@
  */
 
 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination.KeyCombinationPropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.paint.PaintPropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.paint.ColorPropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.klass.ComponentClassMetadata;
@@ -2074,7 +2075,7 @@
             new StringPropertyMetadata(
                 idName,
                 true, /* readWrite */
-                null, /* defaultValue */
+                "", /* defaultValue */
                 new InspectorPath("Properties", "JavaFX CSS", 0));
     private final ValuePropertyMetadata imagePropertyMetadata =
             new ImagePropertyMetadata(
@@ -2114,7 +2115,7 @@
             new StringPropertyMetadata(
                 labelName,
                 true, /* readWrite */
-                null, /* defaultValue */
+                "", /* defaultValue */
                 new InspectorPath("Properties", "Specific", 24));
     private final ComponentPropertyMetadata labelForPropertyMetadata =
             new ComponentPropertyMetadata(
@@ -3289,13 +3290,7 @@
                 true, /* readWrite */
                 1.0, /* defaultValue */
                 new InspectorPath("Properties", "Stroke", 1));
-    private final ValuePropertyMetadata style_NULL_PropertyMetadata =
-            new StringPropertyMetadata(
-                styleName,
-                true, /* readWrite */
-                null, /* defaultValue */
-                new InspectorPath("Properties", "JavaFX CSS", 1));
-    private final ValuePropertyMetadata style__PropertyMetadata =
+    private final ValuePropertyMetadata stylePropertyMetadata =
             new StringPropertyMetadata(
                 styleName,
                 true, /* readWrite */
@@ -3653,18 +3648,12 @@
                 tabsName,
                 TabMetadata,
                 true); /* collection */
-    private final ValuePropertyMetadata text__PropertyMetadata =
+    private final ValuePropertyMetadata textPropertyMetadata =
             new StringPropertyMetadata(
                 textName,
                 true, /* readWrite */
                 "", /* defaultValue */
                 new InspectorPath("Properties", "Text", 2));
-    private final ValuePropertyMetadata text_NULL_PropertyMetadata =
-            new StringPropertyMetadata(
-                textName,
-                true, /* readWrite */
-                null, /* defaultValue */
-                new InspectorPath("Properties", "Text", 2));
     private final ValuePropertyMetadata textAlignmentPropertyMetadata =
             new EnumerationPropertyMetadata(
                 textAlignmentName,
@@ -3781,7 +3770,7 @@
             new StringPropertyMetadata(
                 titleName,
                 true, /* readWrite */
-                null, /* defaultValue */
+                "", /* defaultValue */
                 new InspectorPath("Properties", "Specific", 35));
     private final ValuePropertyMetadata titleSidePropertyMetadata =
             new EnumerationPropertyMetadata(
@@ -4636,7 +4625,7 @@
         LabeledMetadata.getProperties().add(lineSpacingPropertyMetadata);
         LabeledMetadata.getProperties().add(mnemonicParsing_true_PropertyMetadata);
         LabeledMetadata.getProperties().add(styleClass_c37_PropertyMetadata);
-        LabeledMetadata.getProperties().add(text__PropertyMetadata);
+        LabeledMetadata.getProperties().add(textPropertyMetadata);
         LabeledMetadata.getProperties().add(textAlignmentPropertyMetadata);
         LabeledMetadata.getProperties().add(textFillPropertyMetadata);
         LabeledMetadata.getProperties().add(textOverrunPropertyMetadata);
@@ -4690,7 +4679,6 @@
         MenuMetadata.getProperties().add(onShowingPropertyMetadata);
         MenuMetadata.getProperties().add(onShownPropertyMetadata);
         MenuMetadata.getProperties().add(styleClass_c27_PropertyMetadata);
-        MenuMetadata.getProperties().add(text__PropertyMetadata);
 
         MenuBarMetadata.getProperties().add(menusPropertyMetadata);
         MenuBarMetadata.getProperties().add(styleClass_c18_PropertyMetadata);
@@ -4707,9 +4695,9 @@
         MenuItemMetadata.getProperties().add(mnemonicParsing_true_PropertyMetadata);
         MenuItemMetadata.getProperties().add(onActionPropertyMetadata);
         MenuItemMetadata.getProperties().add(onMenuValidationPropertyMetadata);
-        MenuItemMetadata.getProperties().add(style_NULL_PropertyMetadata);
+        MenuItemMetadata.getProperties().add(stylePropertyMetadata);
         MenuItemMetadata.getProperties().add(styleClass_c32_PropertyMetadata);
-        MenuItemMetadata.getProperties().add(text_NULL_PropertyMetadata);
+        MenuItemMetadata.getProperties().add(textPropertyMetadata);
         MenuItemMetadata.getProperties().add(visiblePropertyMetadata);
 
         MeshViewMetadata.getProperties().add(meshPropertyMetadata);
@@ -4786,7 +4774,7 @@
         NodeMetadata.getProperties().add(scaleXPropertyMetadata);
         NodeMetadata.getProperties().add(scaleYPropertyMetadata);
         NodeMetadata.getProperties().add(scaleZPropertyMetadata);
-        NodeMetadata.getProperties().add(style__PropertyMetadata);
+        NodeMetadata.getProperties().add(stylePropertyMetadata);
         NodeMetadata.getProperties().add(styleClass_empty_PropertyMetadata);
         NodeMetadata.getProperties().add(transformsPropertyMetadata);
         NodeMetadata.getProperties().add(translateXPropertyMetadata);
@@ -4882,7 +4870,7 @@
         PopupControlMetadata.getProperties().add(opacityPropertyMetadata);
         PopupControlMetadata.getProperties().add(prefHeight_COMPUTED_PropertyMetadata);
         PopupControlMetadata.getProperties().add(prefWidth_COMPUTED_PropertyMetadata);
-        PopupControlMetadata.getProperties().add(style_NULL_PropertyMetadata);
+        PopupControlMetadata.getProperties().add(stylePropertyMetadata);
         PopupControlMetadata.getProperties().add(styleClass_empty_PropertyMetadata);
         PopupControlMetadata.getProperties().add(width_Double_0_PropertyMetadata);
         PopupControlMetadata.getProperties().add(x_NaN_PropertyMetadata);
@@ -5074,9 +5062,9 @@
         TabMetadata.getProperties().add(onCloseRequestPropertyMetadata);
         TabMetadata.getProperties().add(onSelectionChangedPropertyMetadata);
         TabMetadata.getProperties().add(selected_Boolean_ro_PropertyMetadata);
-        TabMetadata.getProperties().add(style_NULL_PropertyMetadata);
+        TabMetadata.getProperties().add(stylePropertyMetadata);
         TabMetadata.getProperties().add(styleClass_c19_PropertyMetadata);
-        TabMetadata.getProperties().add(text_NULL_PropertyMetadata);
+        TabMetadata.getProperties().add(textPropertyMetadata);
         TabMetadata.getProperties().add(tooltipPropertyMetadata);
 
         TabPaneMetadata.getProperties().add(focusTraversable_true_PropertyMetadata);
@@ -5106,9 +5094,9 @@
         TableColumnBaseMetadata.getProperties().add(resizable_Boolean_PropertyMetadata);
         TableColumnBaseMetadata.getProperties().add(sortablePropertyMetadata);
         TableColumnBaseMetadata.getProperties().add(sortNodePropertyMetadata);
-        TableColumnBaseMetadata.getProperties().add(style_NULL_PropertyMetadata);
+        TableColumnBaseMetadata.getProperties().add(stylePropertyMetadata);
         TableColumnBaseMetadata.getProperties().add(styleClass_c38_PropertyMetadata);
-        TableColumnBaseMetadata.getProperties().add(text__PropertyMetadata);
+        TableColumnBaseMetadata.getProperties().add(textPropertyMetadata);
         TableColumnBaseMetadata.getProperties().add(visiblePropertyMetadata);
         TableColumnBaseMetadata.getProperties().add(width_Double_ro_PropertyMetadata);
 
@@ -5131,7 +5119,7 @@
         TextMetadata.getProperties().add(fontSmoothingType_GRAY_PropertyMetadata);
         TextMetadata.getProperties().add(lineSpacingPropertyMetadata);
         TextMetadata.getProperties().add(strikethroughPropertyMetadata);
-        TextMetadata.getProperties().add(text__PropertyMetadata);
+        TextMetadata.getProperties().add(textPropertyMetadata);
         TextMetadata.getProperties().add(textAlignmentPropertyMetadata);
         TextMetadata.getProperties().add(textOriginPropertyMetadata);
         TextMetadata.getProperties().add(underlinePropertyMetadata);
@@ -5164,7 +5152,7 @@
         TextInputControlMetadata.getProperties().add(length_Integer_ro_PropertyMetadata);
         TextInputControlMetadata.getProperties().add(promptTextPropertyMetadata);
         TextInputControlMetadata.getProperties().add(styleClass_c46_PropertyMetadata);
-        TextInputControlMetadata.getProperties().add(text__PropertyMetadata);
+        TextInputControlMetadata.getProperties().add(textPropertyMetadata);
 
         TilePaneMetadata.getProperties().add(alignment_TOP_LEFT_PropertyMetadata);
         TilePaneMetadata.getProperties().add(contentBiasPropertyMetadata);
@@ -5208,7 +5196,7 @@
         TooltipMetadata.getProperties().add(onShownPropertyMetadata);
         TooltipMetadata.getProperties().add(opacityPropertyMetadata);
         TooltipMetadata.getProperties().add(styleClass_c15_PropertyMetadata);
-        TooltipMetadata.getProperties().add(text__PropertyMetadata);
+        TooltipMetadata.getProperties().add(textPropertyMetadata);
         TooltipMetadata.getProperties().add(textAlignmentPropertyMetadata);
         TooltipMetadata.getProperties().add(textOverrunPropertyMetadata);
         TooltipMetadata.getProperties().add(width_Double_0_PropertyMetadata);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCharacterCombinationPropertyMetadata.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination;
+
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.value.ComplexPropertyMetadata;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.value.EnumerationPropertyMetadata;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.value.StringPropertyMetadata;
+import com.oracle.javafx.scenebuilder.kit.metadata.util.InspectorPath;
+import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName;
+import javafx.scene.input.KeyCharacterCombination;
+import javafx.scene.input.KeyCombination;
+
+/**
+ *
+ */
+public class KeyCharacterCombinationPropertyMetadata extends ComplexPropertyMetadata<KeyCharacterCombination> {
+    
+    /*
+     * NOTE : KeyCharacterCombination singularity
+     * 
+     * Same as KeyCodeCombination => see comments in KeyCodeCombination
+     */
+    private static final String DUMMY = "dummy"; //NOI18N
+
+    private final EnumerationPropertyMetadata altMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("alt"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata controlMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("control"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata metaMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("meta"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata shiftMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("shift"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata shortcutMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("shortcut"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final StringPropertyMetadata characterMetadata
+            = new StringPropertyMetadata(new PropertyName("character"), //NOI18N
+            true, null, InspectorPath.UNUSED);
+
+    public KeyCharacterCombinationPropertyMetadata(PropertyName name, boolean readWrite, 
+            KeyCharacterCombination defaultValue, InspectorPath inspectorPath) {
+        super(name, KeyCharacterCombination.class, readWrite, defaultValue, inspectorPath);
+    }
+
+    @Override
+    protected KeyCharacterCombination castValue(Object value) {
+        return (KeyCharacterCombination) value;
+    }
+    
+    @Override
+    protected void updateFxomInstanceWithValue(FXOMInstance valueInstance, KeyCharacterCombination value) {
+        altMetadata.setValue(valueInstance, value.getAlt().toString());
+        controlMetadata.setValue(valueInstance, value.getControl().toString());
+        metaMetadata.setValue(valueInstance, value.getMeta().toString());
+        shiftMetadata.setValue(valueInstance, value.getShift().toString());
+        shortcutMetadata.setValue(valueInstance, value.getShortcut().toString());
+        characterMetadata.setValue(valueInstance, value.getCharacter());
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCodeCombinationPropertyMetadata.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination;
+
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.value.ComplexPropertyMetadata;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.value.EnumerationPropertyMetadata;
+import com.oracle.javafx.scenebuilder.kit.metadata.util.InspectorPath;
+import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+
+/**
+ *
+ */
+public class KeyCodeCombinationPropertyMetadata extends ComplexPropertyMetadata<KeyCodeCombination> {
+
+    /*
+     * NOTE : KeyCodeCombination singularity
+     * 
+     * Default value for 'alt', 'control', 'meta', 'shift' and 'shortcut' is 'UP'. 
+     * However FXMLLoader refuses to load:
+     * 
+     *     <KeyCombinationCode code='PASTE' />
+     * 
+     * Properties must be explicitely specified even when they have the default value.
+     * 
+     *     <KeyCombinationCode code='PASTE' alt='UP' control='UP' meta='UP' shift='UP' shortcut='UP' />
+     * 
+     * To force this behavior, the EnumerationPropertyMetadata below are all
+     * set with a dummy default value.
+     */
+    private static final String DUMMY = "dummy"; //NOI18N
+    
+    private final EnumerationPropertyMetadata altMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("alt"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata controlMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("control"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata metaMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("meta"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata shiftMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("shift"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata shortcutMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("shortcut"), //NOI18N
+            KeyCombination.ModifierValue.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+    private final EnumerationPropertyMetadata codeMetadata
+            = new EnumerationPropertyMetadata(new PropertyName("code"), //NOI18N
+            KeyCode.class, DUMMY, true, 
+            InspectorPath.UNUSED);
+
+    public KeyCodeCombinationPropertyMetadata(PropertyName name, boolean readWrite, 
+            KeyCodeCombination defaultValue, InspectorPath inspectorPath) {
+        super(name, KeyCodeCombination.class, readWrite, defaultValue, inspectorPath);
+    }
+
+    @Override
+    protected KeyCodeCombination castValue(Object value) {
+        return (KeyCodeCombination) value;
+    }
+    
+    @Override
+    protected void updateFxomInstanceWithValue(FXOMInstance valueInstance, KeyCodeCombination value) {
+        altMetadata.setValue(valueInstance, value.getAlt().toString());
+        controlMetadata.setValue(valueInstance, value.getControl().toString());
+        metaMetadata.setValue(valueInstance, value.getMeta().toString());
+        shiftMetadata.setValue(valueInstance, value.getShift().toString());
+        shortcutMetadata.setValue(valueInstance, value.getShortcut().toString());
+        codeMetadata.setValue(valueInstance, value.getCode().toString());
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/property/value/keycombination/KeyCombinationPropertyMetadata.java	Mon Dec 23 13:59:52 2013 +0100
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.oracle.javafx.scenebuilder.kit.metadata.property.value.keycombination;
+
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMIntrinsic;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMProperty;
+import com.oracle.javafx.scenebuilder.kit.fxom.FXOMPropertyC;
+import com.oracle.javafx.scenebuilder.kit.metadata.property.value.ComplexPropertyMetadata;
+import com.oracle.javafx.scenebuilder.kit.metadata.util.InspectorPath;
+import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName;
+import javafx.scene.input.KeyCharacterCombination;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+
+/**
+ *
+ */
+public class KeyCombinationPropertyMetadata extends ComplexPropertyMetadata<KeyCombination> {
+
+    private final KeyCodeCombinationPropertyMetadata keyCodeCombinationMetadata;
+    private final KeyCharacterCombinationPropertyMetadata keyCharacterCombinationMetadata;
+
+    public KeyCombinationPropertyMetadata(PropertyName name, boolean readWrite, 
+            KeyCombination defaultValue, InspectorPath inspectorPath) {
+        super(name, KeyCombination.class, readWrite, defaultValue, inspectorPath);
+        keyCodeCombinationMetadata = new KeyCodeCombinationPropertyMetadata(name, readWrite, null, inspectorPath);
+        keyCharacterCombinationMetadata = new KeyCharacterCombinationPropertyMetadata(name, readWrite, null, inspectorPath);
+    }
+
+    /*
+     * ComplexPropertyMetadata
+     */
+    @Override
+    protected KeyCombination castValue(Object value) {
+        return (KeyCombination) value;
+    }
+
+
+    @Override
+    protected void updateFxomPropertyWithValue(FXOMProperty fxomProperty, KeyCombination value) {
+        assert fxomProperty instanceof FXOMPropertyC;
+        assert value != null;
+
+        final FXOMPropertyC fxomPropertyC = (FXOMPropertyC) fxomProperty;
+        assert fxomPropertyC.getValues().size() == 1;
+
+        FXOMObject valueObject = fxomPropertyC.getValues().get(0);
+        if (valueObject instanceof FXOMInstance) {
+            final FXOMInstance currentValueInstance = (FXOMInstance) valueObject;
+            final Class<?> currentValueClass = currentValueInstance.getDeclaredClass();
+
+            if (currentValueClass != value.getClass()) {
+                // Eg current value is a KeyCodeCombination, new value is a KeyCharacterCombination
+                final FXOMDocument fxomDocument = fxomProperty.getFxomDocument();
+                final FXOMInstance valueInstance = new FXOMInstance(fxomDocument, value.getClass());
+                updateFxomInstanceWithValue(valueInstance, value);
+                valueInstance.addToParentProperty(0, fxomPropertyC);
+                valueObject.removeFromParentProperty();
+            } else {
+                updateFxomInstanceWithValue(currentValueInstance, value);
+            }
+        } else {
+            assert valueObject instanceof FXOMIntrinsic;
+
+            final FXOMDocument fxomDocument = fxomProperty.getFxomDocument();
+            final FXOMInstance valueInstance = new FXOMInstance(fxomDocument, value.getClass());
+            updateFxomInstanceWithValue(valueInstance, value);
+            valueInstance.addToParentProperty(0, fxomPropertyC);
+            valueObject.removeFromParentProperty();
+        }
+    }
+
+    @Override
+    protected void updateFxomInstanceWithValue(FXOMInstance valueInstance, KeyCombination value) {
+        if (value instanceof KeyCodeCombination) {
+            keyCodeCombinationMetadata.updateFxomInstanceWithValue(valueInstance, (KeyCodeCombination) value);
+        } else {
+            assert value instanceof KeyCharacterCombination;
+            keyCharacterCombinationMetadata.updateFxomInstanceWithValue(valueInstance, (KeyCharacterCombination) value);
+        }
+    }
+
+}
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/ClipboardDecoder.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/ClipboardDecoder.java	Mon Dec 23 13:59:52 2013 +0100
@@ -41,8 +41,10 @@
 import com.oracle.javafx.scenebuilder.kit.metadata.property.PropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.DoublePropertyMetadata;
 import com.oracle.javafx.scenebuilder.kit.metadata.property.value.ImagePropertyMetadata;
+import java.io.File;
 import java.io.IOException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -50,7 +52,6 @@
 import javafx.scene.image.Image;
 import javafx.scene.image.ImageView;
 import javafx.scene.input.Clipboard;
-import javafx.scene.input.DataFormat;
 
 /**
  *
@@ -100,18 +101,40 @@
             }
         }
         
-        // DataFormat.IMAGE
-        if ((result == null) 
-                && clipboard.hasContent(DataFormat.IMAGE)) {
-            final Object content = clipboard.getContent(DataFormat.IMAGE);
-            if (content instanceof Image) {
-                final Image image = (Image) content;
-                try {
-                    final FXOMDocument transientDoc = 
-                            makeFxomDocumentFromImageURL(image, 200.0);
-                    result = Arrays.asList(transientDoc.getFxomRoot());
-                } catch(IOException x) {
-                    result = null;
+        // DataFormat.FILES
+        if ((result == null) && clipboard.hasFiles()) {
+            result = new ArrayList<>();
+            for (File f : clipboard.getFiles()) {
+                if (f.getAbsolutePath().endsWith(".fxml")) { //NOI18N
+                    try {
+                        final String fxmlText 
+                                = FXOMDocument.readContentFromURL(f.toURI().toURL());
+                        final FXOMDocument transientDoc = new FXOMDocument(
+                                fxmlText,
+                                targetDocument.getLocation(),
+                                targetDocument.getClassLoader(),
+                                targetDocument.getResources());
+                        final FXOMObject fxomObject = transientDoc.getFxomRoot();
+                        fxomObject.moveToFxomDocument(targetDocument);
+                        result.add(fxomObject);
+                    } catch(IOException x) {
+                        // Then we silently ignore this file
+                    }
+                } else {
+                    // Try load the file has an image
+                    try {
+                        final String fileURL = f.toURI().toURL().toString();
+                        final Image image = new Image(fileURL);
+                        if (image.isError() == false) {
+                            final FXOMDocument transientDoc = 
+                                    makeFxomDocumentFromImageURL(image, 200.0);
+                            final FXOMObject fxomObject = transientDoc.getFxomRoot();
+                            fxomObject.moveToFxomDocument(targetDocument);
+                            result.add(fxomObject);
+                       }
+                    } catch(IOException x) {
+                        // Then we silently ignore this file
+                    }
                 }
             }
         }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/DesignHierarchyMask.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/metadata/util/DesignHierarchyMask.java	Mon Dec 23 13:59:52 2013 +0100
@@ -69,6 +69,7 @@
 import javafx.scene.layout.AnchorPane;
 import javafx.scene.layout.GridPane;
 import javafx.scene.layout.Pane;
+import javafx.scene.text.Text;
 
 /**
  *
@@ -550,6 +551,7 @@
                 || sceneGraphObject instanceof TableColumn
                 || sceneGraphObject instanceof TextInputControl
                 || sceneGraphObject instanceof TitledPane
+                || sceneGraphObject instanceof Text
                 || sceneGraphObject instanceof Tooltip) {
             propertyName = new PropertyName("text");
         }
--- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/util/Deprecation.java	Fri Dec 20 15:48:27 2013 -0800
+++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/util/Deprecation.java	Mon Dec 23 13:59:52 2013 +0100
@@ -85,6 +85,10 @@
     public static ObservableMap<StyleableProperty<?>, List<Style>> getStyleMap(Node node) {
         return node.impl_getStyleMap();
     }
+    
+    public static void reapplyCSS(Node node) {
+        node.impl_reapplyCSS();
+    }
 
     // Retrieve the node of the Styleable.
     public static Node getNode(Styleable styleable) {
@@ -196,9 +200,39 @@
     }
     
     
+    public static URL getCaspianHighContrastStylesheetURL() {
+        final String resourceName = "com/sun/javafx/scene/control/skin/caspian/highcontrast.bss"; //NOI18N
+        return ClassLoader.getSystemResource(resourceName);
+    }
+    
+    
+    public static URL getCaspianVirtualKeyboardStylesheetURL() {
+        final String resourceName = "com/sun/javafx/scene/control/skin/caspian/fxvk.bss"; //NOI18N
+        return ClassLoader.getSystemResource(resourceName);
+    }
+    
+    
+    public static URL getCaspianEmbeddedStylesheetURL() {
+        final String resourceName = "com/sun/javafx/scene/control/skin/caspian/embedded.bss"; //NOI18N
+        return ClassLoader.getSystemResource(resourceName);
+    }
+    
+    
+    public static URL getCaspianEmbeddedQVGAStylesheetURL() {
+        final String resourceName = "com/sun/javafx/scene/control/skin/caspian/embedded-qvga.bss"; //NOI18N
+        return ClassLoader.getSystemResource(resourceName);
+    }
+    
+    
     public static URL getModenaStylesheetURL() {
         final String resourceName = "com/sun/javafx/scene/control/skin/modena/modena.bss"; //NOI18N
         return ClassLoader.getSystemResource(resourceName);
     }
+    
+    
+    public static URL getModenaTouchStylesheetURL() {
+        final String resourceName = "com/sun/javafx/scene/control/skin/modena/touch.bss"; //NOI18N
+        return ClassLoader.getSystemResource(resourceName);
+    }
 
 }