changeset 5617:3772b13b9c98

Automated merge with ssh://jfxsrc.us.oracle.com//javafx/8.0/MASTER/jfx/rt
author kcr
date Sat, 02 Nov 2013 06:58:02 -0700
parents 13131fdaa7df 5e8a8d2136eb
children fbb8a4ffac02
files apps/samples/Ensemble8/src/app/java/ensemble/samplepage/BackPage.java apps/samples/Ensemble8/src/app/java/ensemble/samplepage/FrontPage.java apps/samples/Ensemble8/src/app/java/ensemble/samplepage/IPhoneLayout.java apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SlidingPages.java apps/samples/Ensemble8/src/app/java/ensemble/samplepage/Sources.java apps/samples/Ensemble8/src/app/java/ensemble/sampleproject/SampleProjectBuilder.java apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesCaspian.css apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesCaspianDesktop.css apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesCommonDesktop.css apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesHelvetica.css apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesIOS.css apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesIOSDesktop.css apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/back-btn.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/back-btn@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/forward-btn.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/forward-btn@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/home-btn.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/home-btn@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/list-btn.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/list-btn@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-blue-btn.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-blue-btn@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-empty.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-empty@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-light-blue-btn.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-light-blue-btn@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/search-btn.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/search-btn@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/search.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/search@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/toolbar.png apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/toolbar@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images/Duke-Lego3.jpg apps/samples/Ensemble8/src/app/resources/ensemble/images/corner-bottom.png apps/samples/Ensemble8/src/app/resources/ensemble/images/corner-top.png apps/samples/Ensemble8/src/app/resources/ensemble/images/home-background.png apps/samples/Ensemble8/src/app/resources/ensemble/images/home-background@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images/pagination-dot-selected.png apps/samples/Ensemble8/src/app/resources/ensemble/images/pagination-dot-selected@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images/pagination-dot.png apps/samples/Ensemble8/src/app/resources/ensemble/images/pagination-dot@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-back-page-background.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-box.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-box@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-page-background-shadow.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-page-background.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-paper-border.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-paper-lines.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-paper.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-source-text.png apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-source-text@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images/section-ribbon.png apps/samples/Ensemble8/src/app/resources/ensemble/images/section-ribbon@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/images/tile-border.png apps/samples/Ensemble8/src/app/resources/ensemble/images/tile-border@2x.png apps/samples/Ensemble8/src/app/resources/ensemble/sampleproject/SampleProject.zip build.properties
diffstat 462 files changed, 8933 insertions(+), 2767 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Oct 31 17:45:18 2013 -0700
+++ b/.hgignore	Sat Nov 02 06:58:02 2013 -0700
@@ -17,6 +17,7 @@
 ^modules/[a-zA-Z0-9_]*/build/
 ^apps/build/
 ^apps/.*/build/
+^netbeans/.*/build/
 ^tests/.*/build/
 bin/
 dist/
--- a/apps/samples/Ensemble8/src/app/java/ensemble/EnsembleApp.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/EnsembleApp.java	Sat Nov 02 06:58:02 2013 -0700
@@ -39,8 +39,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import javafx.application.Application;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.geometry.Insets;
@@ -55,6 +53,7 @@
 import javafx.scene.layout.Pane;
 import javafx.scene.layout.Region;
 import javafx.scene.paint.Color;
+import javafx.scene.text.Font;
 import javafx.scene.transform.Scale;
 import javafx.stage.Screen;
 import javafx.stage.Stage;
@@ -74,7 +73,7 @@
     public static final boolean PRELOAD_PREVIEW_IMAGES = true;
     public static final boolean SHOW_HIGHLIGHTS = IS_DESKTOP;
     public static final boolean SHOW_MENU = IS_DESKTOP;
-    public static final boolean SELECT_IOS_THEME = IS_MAC || IS_IOS;
+    public static final boolean SELECT_IOS_THEME = false;
     private static final int TOOL_BAR_BUTTON_SIZE = 30;
     private Scene scene;
     private Pane root;
@@ -99,9 +98,6 @@
     }
 
     @Override public void init() throws Exception {
-        // LOAD FONTS
-    //    Font font = Font.loadFont(EnsembleApp.class.getResource("fonts/BreeSerif-Regular.ttf").toString(),10);
-     //   System.out.println("font = " + font);
         // CREATE ROOT
         root = new Pane() {
             @Override protected void layoutChildren() {
@@ -126,32 +122,10 @@
                 searchPopover.setLayoutY((int)searchBoxBottomCenter.getY()+20);
             }
         };
-        // CREATE MENUBAR/STATUSBAR SPACER
-        if (IS_IOS) {
-            Region statusSpacer = new Region();
-            statusSpacer.setPrefHeight(20);
-            root.getChildren().add(statusSpacer);
-        }
+        // CREATE MENUBAR
         if (SHOW_MENU) {
             menuBar = new MenuBar();
             menuBar.setUseSystemMenuBar(true);
-            Menu themeMenu = new Menu("Theme");
-            final RadioMenuItem caspianThemeMenuItem = new RadioMenuItem("Caspian");
-            final RadioMenuItem iOSThemeMenuItem = new RadioMenuItem("iOS");
-            final ToggleGroup tg = new ToggleGroup();
-            caspianThemeMenuItem.setToggleGroup(tg);
-            iOSThemeMenuItem.setToggleGroup(tg);
-            tg.selectToggle(SELECT_IOS_THEME ? iOSThemeMenuItem : caspianThemeMenuItem);
-            tg.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
-                @Override public void changed(ObservableValue<? extends Toggle> arg0, Toggle oldValue, Toggle newValue) {
-                    if (newValue != null) {
-                        setStylesheets(newValue == iOSThemeMenuItem);
-                    }
-                }
-            });
-            themeMenu.getItems().addAll(caspianThemeMenuItem,iOSThemeMenuItem);
-            menuBar.getMenus().add(themeMenu);
-            
             ToggleGroup screenSizeToggle = new ToggleGroup();
             menuBar.getMenus().add(
                     MenuBuilder.create()
@@ -179,13 +153,17 @@
         root.getChildren().add(toolBar);
         backButton = new Button();
         backButton.setId("back");
+        backButton.getStyleClass().add("left-pill");
         backButton.setPrefSize(TOOL_BAR_BUTTON_SIZE, TOOL_BAR_BUTTON_SIZE);
         forwardButton = new Button();
         forwardButton.setId("forward");
+        forwardButton.getStyleClass().add("center-pill");
         forwardButton.setPrefSize(TOOL_BAR_BUTTON_SIZE, TOOL_BAR_BUTTON_SIZE);
         homeButton = new Button();
         homeButton.setId("home");
         homeButton.setPrefSize(TOOL_BAR_BUTTON_SIZE, TOOL_BAR_BUTTON_SIZE);
+        homeButton.getStyleClass().add("right-pill");
+        HBox navButtons = new HBox(0,backButton,forwardButton,homeButton);
         listButton = new ToggleButton();
         listButton.setId("list");
         listButton.setPrefSize(TOOL_BAR_BUTTON_SIZE, TOOL_BAR_BUTTON_SIZE);
@@ -201,7 +179,7 @@
             listButton.setGraphic(new Region());
             searchButton.setGraphic(new Region());
         }
-        toolBar.addLeftItems(backButton,forwardButton,homeButton,listButton);
+        toolBar.addLeftItems(navButtons,listButton);
         toolBar.addRightItems(searchBox);
 
         // create PageBrowser
@@ -291,19 +269,10 @@
     }
 
     private void setStylesheets(boolean isIOsSelected) {
-        List<String> stylesheets = new ArrayList<>(5);
-        String base = "/ensemble/EnsembleStyles" + (isIOsSelected ? "IOS" : "Caspian");
-        stylesheets.add("/ensemble/EnsembleStylesCommon.css");
-        stylesheets.add(base + ".css");
-        if (IS_DESKTOP) {
-            stylesheets.add("/ensemble/EnsembleStylesCommonDesktop.css");
-            stylesheets.add(base + "Desktop.css");
-        }
-        if (IS_MAC || IS_IOS) {
-            stylesheets.add("/ensemble/EnsembleStylesHelvetica.css");
-        }                    
-        stylesheets.add("http://fonts.googleapis.com/css?family=Bree+Serif");
-        scene.getStylesheets().setAll(stylesheets);
+        scene.getStylesheets().setAll(
+            "http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600",
+            "/ensemble/EnsembleStylesCommon.css"
+        );
     }    
     
     @Override public void start(final Stage stage) throws Exception {
@@ -314,10 +283,6 @@
         }
         setStylesheets(SELECT_IOS_THEME);
         stage.setScene(scene);
-        // SHOW STAGE
-        if (IS_IOS) {
-            setupIosStage(stage, scene);
-        }
         // START FULL SCREEN IF WANTED
         if (PlatformFeatures.START_FULL_SCREEN) {
             Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
@@ -336,49 +301,4 @@
     public static void main(String[] args) {
         launch(args);
     }
-
-    private void setupIosStage(Stage stage, Scene scene) {}
-//    private void setupIosStage(final Stage stage,final Scene scene) {
-//        // Synthisize Scroll Events from mouse drag events
-//        IosScrollEventSynthesizer scrollEventSynthesizer = new IosScrollEventSynthesizer(scene);
-//        javafx.ext.ios.IOSApplication.setStatusBarStyleAnimated(javafx.ext.ios.StatusBarStyle.DEFAULT, false);
-//        final double SCREEN_WIDTH = Screen.getPrimary().getBounds().getWidth();
-//        final double SCREEN_HEIGHT = Screen.getPrimary().getBounds().getHeight();
-//        stage.setX(0.0); //to avoid centerOnScreen() calculations
-//        stage.setY(0.0);
-//        stage.setWidth(SCREEN_WIDTH);
-//        stage.setHeight(SCREEN_HEIGHT);
-//        Screen.getScreens().addListener(new ListChangeListener(){
-//            @Override public void onChanged(ListChangeListener.Change change) {
-//                if(Screen.getScreens().size() > 0) {
-//                    switch(Screen.getPrimary().getOrientation()) {
-//                        case Screen.OrientationPortraitUpsideDown:
-//                        case Screen.OrientationPortrait:
-//                            stage.setWidth(SCREEN_WIDTH);
-//                            stage.setHeight(SCREEN_HEIGHT);
-//                            break;
-//                        case Screen.OrientationLandscapeLeft:
-//                        case Screen.OrientationLandscapeRight:
-//                            stage.setWidth(SCREEN_HEIGHT);
-////                                stage.setHeight(SCREEN_WIDTH);
-//                            break;
-//                    }
-//                    switch(Screen.getPrimary().getOrientation()) {
-//                        case Screen.OrientationPortraitUpsideDown:
-//                            javafx.ext.ios.IOSApplication.setStatusBarOrientationAnimated(javafx.ext.ios.StatusBarOrientation.PORTRAIT_UPSIDE_DOWN, false);
-//                            break;
-//                        case Screen.OrientationPortrait:
-//                            javafx.ext.ios.IOSApplication.setStatusBarOrientationAnimated(javafx.ext.ios.StatusBarOrientation.PORTRAIT, false);
-//                            break;
-//                        case Screen.OrientationLandscapeLeft:
-//                            javafx.ext.ios.IOSApplication.setStatusBarOrientationAnimated(javafx.ext.ios.StatusBarOrientation.LANDSCAPE_RIGHT, false);
-//                            break;
-//                        case Screen.OrientationLandscapeRight:
-//                            javafx.ext.ios.IOSApplication.setStatusBarOrientationAnimated(javafx.ext.ios.StatusBarOrientation.LANDSCAPE_LEFT, false);
-//                            break;
-//                    }
-//                }
-//            }
-//        });
-//    }
 }
--- a/apps/samples/Ensemble8/src/app/java/ensemble/HomePage.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/HomePage.java	Sat Nov 02 06:58:02 2013 -0700
@@ -36,8 +36,10 @@
 import javafx.beans.property.ReadOnlyStringWrapper;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
+import javafx.css.PseudoClass;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
+import javafx.geometry.Bounds;
 import javafx.geometry.Pos;
 import javafx.scene.Node;
 import javafx.scene.control.Button;
@@ -72,24 +74,6 @@
  * The home page for ensemble.
  */
 public class HomePage extends ListView<HomePage.HomePageRow> implements Callback<ListView<HomePage.HomePageRow>, ListCell<HomePage.HomePageRow>>, ChangeListener<Number>, Page{
-    private static final Effect RIBBON_EFFECT = BlendBuilder.create()
-            .topInput(
-                    InnerShadowBuilder.create()
-                            .color(Color.rgb(0, 0, 0, 0.75))
-                            .offsetX(1)
-                            .offsetY(1)
-                            .radius(1)
-                            .blurType(BlurType.ONE_PASS_BOX)
-                            .build())
-            .bottomInput(
-                    DropShadowBuilder.create()
-                            .color(Color.rgb(255, 255, 255, 0.33))
-                            .offsetX(1)
-                            .offsetY(1)
-                            .radius(0)
-                            .blurType(BlurType.ONE_PASS_BOX)
-                            .build())
-            .build();
     private static final int ITEM_WIDTH = 216;
     private static final int ITEM_HEIGHT = 162;
     private static final int ITEM_GAP = 32;
@@ -98,15 +82,13 @@
     private int numberOfColumns = -1;
     private final HomePageRow HIGHLIGHTS_ROW = new HomePageRow(RowType.Highlights,null,null);
     private final PageBrowser pageBrowser;
-    private final ReadOnlyStringProperty titleProperty = new ReadOnlyStringWrapper("JavaFX Ensemble");
+    private final ReadOnlyStringProperty titleProperty = new ReadOnlyStringWrapper();
 
     public HomePage(PageBrowser pageBrowser) {
         this.pageBrowser = pageBrowser;
-        getStyleClass().clear();
         setId("HomePage");
         // don't use any of the standard ListView CSS
-        //   getStyleClass().clear();
-
+        getStyleClass().clear();
         // listen for when the list views width changes and recalculate number of columns
         widthProperty().addListener(this);
         // set our custom cell factory
@@ -133,8 +115,7 @@
     @Override public void changed(ObservableValue<? extends Number> observableValue, Number number, Number newWidth) {
         // calculate new number of columns that will fit
         double width = newWidth.doubleValue();
-        width -= MIN_MARGIN + MIN_MARGIN;
-        width += ITEM_GAP;
+        width -= 60;
         final int newNumOfColumns = Math.max(1, (int) (width / (ITEM_WIDTH + ITEM_GAP)));
         // our size may have changed, so see if we need to rebuild items list
         if (numberOfColumns != newNumOfColumns) {
@@ -189,11 +170,13 @@
     private Map<SampleInfo, Button> buttonCache = new WeakHashMap<>();
 
     private static int cellCount = 0;
-    
+    private static final PseudoClass TITLE_PSEUDO_CLASS = PseudoClass.getPseudoClass(RowType.Title.toString());
+
     private class HomeListCell extends ListCell<HomePageRow> implements Callback<Integer,Node>,  Skin<HomeListCell> {
         private static final double HIGHLIGHTS_HEIGHT = 430;
-        private static final double RIBBON_HEIGHT = 58;
-        private static final double DEFAULT_HEIGHT = 208;
+        private static final double RIBBON_HEIGHT = 60;
+        private static final double DEFAULT_HEIGHT = 230;
+        private static final double DEFAULT_WIDTH = 100;
         private double height = DEFAULT_HEIGHT;
         int cellIndex;
         private RowType oldRowType = null;
@@ -208,24 +191,34 @@
             setSkin(this);
         }
 
-        @Override
-        protected double computeMaxHeight(double d) {
+        @Override protected double computeMaxHeight(double d) {
             return height;
         }
 
-        @Override
-        protected double computePrefHeight(double d) {
+        @Override protected double computePrefHeight(double d) {
             return height;
         }
 
-        @Override
-        protected double computeMinHeight(double d) {
+        @Override protected double computeMinHeight(double d) {
             return height;
         }
-        
+
+        @Override protected double computeMaxWidth(double height) {
+            return Double.MAX_VALUE;
+        }
+
+        @Override protected double computePrefWidth(double height) {
+            return DEFAULT_WIDTH;
+        }
+
+        @Override protected double computeMinWidth(double height) {
+            return DEFAULT_WIDTH;
+        }
+
         // CELL METHODS
         @Override protected void updateItem(HomePageRow item, boolean empty) {
             super.updateItem(item, empty);
+            box.pseudoClassStateChanged(TITLE_PSEUDO_CLASS,item !=null && item.rowType == RowType.Title);
             if (item == null) {
                 oldRowType = null;
                 box.getChildren().clear();
@@ -241,14 +234,15 @@
                                 pagination = new Pagination(Samples.HIGHLIGHTS.length);
                                 pagination.getStyleClass().add(Pagination.STYLE_CLASS_BULLET);
                                 pagination.setMaxWidth(USE_PREF_SIZE);
+                                pagination.setMaxHeight(USE_PREF_SIZE);
                                 pagination.setPageFactory(this);
                                 paginationCache = new WeakReference<>(pagination);
                             }
                             if (highlightRibbon == null) {
                                 highlightRibbon = new ImageView(new Image(getClass().getResource("images/highlights-ribbon.png").toExternalForm()));
                                 highlightRibbon.setManaged(false);
-                                highlightRibbon.layoutXProperty().bind(pagination.layoutXProperty().subtract(4));
-                                highlightRibbon.layoutYProperty().bind(pagination.layoutYProperty().subtract(4));
+                                highlightRibbon.layoutXProperty().bind(pagination.layoutXProperty().add(5));
+                                highlightRibbon.layoutYProperty().bind(pagination.layoutYProperty().add(5));
                             }
                             box.setAlignment(Pos.CENTER);
                             box.getChildren().setAll(pagination, highlightRibbon);
@@ -258,11 +252,11 @@
                         height = RIBBON_HEIGHT;
                         SectionRibbon ribbon = ribbonsCache.get(item.title);
                         if (ribbon == null) {
-                            ribbon = new SectionRibbon(item.title);
+                            ribbon = new SectionRibbon(item.title.toUpperCase());
                             ribbonsCache.put(item.title, ribbon);
                         }
                         box.getChildren().setAll(ribbon);
-                        box.setAlignment(Pos.CENTER_LEFT);
+                        box.setAlignment(Pos.CENTER);
                         break;
                     case Samples:
                         height = DEFAULT_HEIGHT;
@@ -333,25 +327,34 @@
         }
     }
 
-    private static class SectionRibbon extends Region {
-        private Text textNode = new Text();
+    private static class SectionRibbon extends Text {
         public SectionRibbon(String text) {
-            textNode.setText(text);
-            getStyleClass().add("section-ribbon");
-            textNode.setFill(Color.web("#0059a9"));
-            textNode.setStyle("-fx-font-family: 'Bree Serif'; -fx-font-size: 16");
-            setPrefHeight(38);
-            setMaxWidth(USE_PREF_SIZE);
-            textNode.setEffect(RIBBON_EFFECT);
-            getChildren().add(textNode);
-        }
-
-        public void setText(String text) {
-            textNode.setText(text);
-        }
-
-        @Override protected void layoutChildren() {
-            textNode.relocate(30, snapPosition((getHeight() - textNode.getBoundsInParent().getHeight()) / 2) - 3);
+            super(text);
+            getStyleClass().add("section-ribbon-text");
         }
     }
+//    private static class SectionRibbon extends Region {
+//        private Text textNode = new Text();
+//        public SectionRibbon(String text) {
+//            textNode.setText(text);
+//            textNode.getStyleClass().add("section-ribbon-text");
+//            getStyleClass().add("section-ribbon");
+//            setPrefHeight(50);
+//            setMaxWidth(USE_PREF_SIZE);
+//    //        textNode.setEffect(RIBBON_EFFECT);
+//            getChildren().add(textNode);
+//        }
+//
+//        public void setText(String text) {
+//            textNode.setText(text);
+//        }
+//
+//        @Override protected void layoutChildren() {
+//            final Bounds textBounds = textNode.getBoundsInParent();
+//            System.out.println("textBounds = " + textBounds);
+//            System.out.println("getWidth() = " + getWidth());
+//            textNode.relocate(0,
+//                    snapPosition((getHeight() - textBounds.getHeight()) / 2) - 3);
+//        }
+//    }
 }
--- a/apps/samples/Ensemble8/src/app/java/ensemble/PageBrowser.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/PageBrowser.java	Sat Nov 02 06:58:02 2013 -0700
@@ -31,6 +31,7 @@
  */
 package ensemble;
 
+import ensemble.samplepage.SourcePage;
 import javafx.beans.property.BooleanProperty;
 import javafx.beans.property.ReadOnlyBooleanProperty;
 import javafx.beans.property.ReadOnlyStringProperty;
@@ -52,6 +53,7 @@
     public static final String HOME_URL = "home";
     private HomePage homePage;
     private Page currentPage;
+    private SamplePage samplePage;
     private String currentPageUrl;
     private DocsPage docsPage;
     private LinkedList<String> pastHistory = new LinkedList<>();
@@ -137,7 +139,7 @@
             docsPage.goToUrl(url);
             getChildren().add(currentPage.getNode());
         } else if (sample != null) {
-            currentPage = new SamplePage(sample,url,this);
+            currentPage = updateSamplePage(sample, url);
             getChildren().add(currentPage.getNode());
         } else if (url.startsWith("sample://")) {
             String samplePath = url.substring("sample://".length());
@@ -146,7 +148,21 @@
             }
             sample = Samples.ROOT.sampleForPath(samplePath);
             if (sample != null) {
-                currentPage = new SamplePage(sample,url,this);
+                currentPage = updateSamplePage(sample, url);
+                getChildren().add(currentPage.getNode());
+            } else {
+                throw new UnsupportedOperationException("Unknown sample url ["+url+"]");
+            }
+        } else if (url.startsWith("sample-src://")) {
+            String samplePath = url.substring("sample-src://".length());
+            if (samplePath.contains("?")) {
+                samplePath = samplePath.substring(0, samplePath.indexOf('?') - 1);
+            }
+            sample = Samples.ROOT.sampleForPath(samplePath);
+            if (sample != null) {
+                SourcePage sourcePage = new SourcePage();
+                sourcePage.setSampleInfo(sample);
+                currentPage = sourcePage;
                 getChildren().add(currentPage.getNode());
             } else {
                 throw new UnsupportedOperationException("Unknown sample url ["+url+"]");
@@ -170,4 +186,13 @@
     public String getCurrentPageUrl() {
         return currentPageUrl;
     }
+
+    private SamplePage updateSamplePage(SampleInfo sample, String url) {
+        if (samplePage == null) {
+            samplePage = new SamplePage(sample, url, this);
+        } else {
+            samplePage.update(sample, url);
+        }
+        return samplePage;
+    }
 }
--- a/apps/samples/Ensemble8/src/app/java/ensemble/SampleInfo.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/SampleInfo.java	Sat Nov 02 06:58:02 2013 -0700
@@ -44,6 +44,7 @@
 import javafx.application.ConditionalFeature;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
+import javafx.geometry.Insets;
 import javafx.geometry.Pos;
 import javafx.geometry.Side;
 import javafx.scene.Node;
@@ -52,13 +53,8 @@
 import javafx.scene.control.Label;
 import javafx.scene.image.Image;
 import javafx.scene.image.ImageView;
-import javafx.scene.layout.Background;
-import javafx.scene.layout.BackgroundImage;
-import javafx.scene.layout.BackgroundPosition;
-import javafx.scene.layout.BackgroundRepeat;
-import javafx.scene.layout.BackgroundSize;
-import javafx.scene.layout.Pane;
-import javafx.scene.layout.Region;
+import javafx.scene.layout.*;
+import javafx.scene.paint.Color;
 
 /**
  * Descriptor for a ensemble sample. Everything the ui needs is determined at 
@@ -152,14 +148,21 @@
         Region label = new Region();
         if (previewUrl != null) {
             String url = getClass().getResource(previewUrl).toExternalForm();
-            label.setBackground(new Background(
-                new BackgroundImage(
-                    getImage(url), 
-                    BackgroundRepeat.NO_REPEAT, 
-                    BackgroundRepeat.NO_REPEAT, 
-                    new BackgroundPosition(Side.LEFT,5,false, Side.TOP,5,false), 
-                    new BackgroundSize(206, 152, false, false, false, false)
-                )));
+            label.setBackground(
+                    new Background(
+                            new BackgroundFill[]{
+                                new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)
+                            },
+                            new BackgroundImage[]{
+                                new BackgroundImage(
+                                    getImage(url),
+                                    BackgroundRepeat.NO_REPEAT,
+                                    BackgroundRepeat.NO_REPEAT,
+                                    new BackgroundPosition(Side.LEFT,5,false, Side.TOP,5,false),
+                                    new BackgroundSize(206, 152, false, false, false, false)
+                                )
+                            }
+                    ));
         }
         label.getStyleClass().add("sample-medium-preview");
         label.setMinSize(216, 162);
--- a/apps/samples/Ensemble8/src/app/java/ensemble/control/BendingPages.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/control/BendingPages.java	Sat Nov 02 06:58:02 2013 -0700
@@ -97,6 +97,16 @@
         this.backPage.set(backPage);
     }
 
+    public void reset() {
+        if (animation != null) {
+            animation.stop();
+        }
+        state = State.CLOSED;
+        setTarget();
+        update();
+        fixMouseTransparency();
+    }
+
     @Override
     protected void layoutChildren() {
         super.layoutChildren();
@@ -155,6 +165,14 @@
     public void setGripSize(double gripSize) {
         this.gripSize.set(gripSize);
     }
+
+    private void fixMouseTransparency() {
+        if (state == State.OPENED) {
+            frontPage.get().setMouseTransparent(true);
+        } else if (state == State.CLOSED) {
+            frontPage.get().setMouseTransparent(false);
+        }
+    }
     
     static enum AnimationState { NO_ANIMATION, FOLLOWING_MOVING_MOUSE, 
             FOLLOWING_DRAGGING_MOUSE, ANIMATION 
@@ -367,11 +385,7 @@
                 .build();
         animation.play();
         animState = ANIMATION;
-        if (state == State.OPENED) {
-            frontPage.get().setMouseTransparent(true);
-        } else if (state == State.CLOSED) {
-            frontPage.get().setMouseTransparent(false);
-        }
+        fixMouseTransparency();
     }
     
     /**
--- a/apps/samples/Ensemble8/src/app/java/ensemble/control/Popover.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/control/Popover.java	Sat Nov 02 06:58:02 2013 -0700
@@ -336,7 +336,7 @@
         
         title = new Text(page.getPageTitle());
         title.getStyleClass().add("popover-title");
-        title.setFill(Color.WHITE);
+        //debtest title.setFill(Color.WHITE);
         title.setTextOrigin(VPos.CENTER);
         title.setTranslateX(newPageX + (int) ((pageWidth - title.getLayoutBounds().getWidth()) / 2d));
         titlesPane.getChildren().add(title);
--- a/apps/samples/Ensemble8/src/app/java/ensemble/control/SearchBox.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/control/SearchBox.java	Sat Nov 02 06:58:02 2013 -0700
@@ -49,7 +49,7 @@
     private final Region icon = new Region();
 
     public SearchBox() {
-        getStyleClass().setAll("search-box");
+        getStyleClass().addAll("search-box");
         icon.getStyleClass().setAll("search-box-icon");
         innerBackground.getStyleClass().setAll("search-box-inner");
         setPromptText("Search");
--- a/apps/samples/Ensemble8/src/app/java/ensemble/control/TitledToolBar.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/control/TitledToolBar.java	Sat Nov 02 06:58:02 2013 -0700
@@ -58,7 +58,7 @@
     public void setTitleText(String text) { titleText.set(text);}
 
     public TitledToolBar() {
-        getStyleClass().add("ensmeble-tool-bar");
+        getStyleClass().addAll("tool-bar","ensmeble-tool-bar");
         titleLabel.getStyleClass().add("title");
         titleLabel.setManaged(false);
         titleLabel.textProperty().bind(titleText);
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/BackPage.java	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2008, 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 ensemble.samplepage;
-
-import javafx.geometry.HPos;
-import javafx.geometry.VPos;
-import javafx.scene.layout.Region;
-
-
-/**
- *
- */
-class BackPage extends Region {
-    private Sources sources;
-    private final SamplePage samplePage;
-
-    BackPage(final SamplePage samplePage) {
-        this.samplePage = samplePage;
-        getStyleClass().add("sample-back-page");
-        sources = new Sources(samplePage);
-        getChildren().setAll(sources);
-    }
-
-    @Override protected void layoutChildren() {
-        super.layoutChildren();
-        if (getWidth() > getHeight()) {
-            // Landscape layout
-            final double RIGHT = 60;
-            final double LEFT = 80;
-            double w = getWidth() - RIGHT - LEFT;
-            layoutInArea(sources, LEFT, SamplePage.INDENT, w, getHeight() - SamplePage.INDENT * 2, 0, HPos.LEFT, VPos.TOP);
-        } else {
-            // Portrait layout
-            final double TOP = 80;
-            final double RIGHT = SamplePage.INDENT;
-            final double BOTTOM = 70;
-            layoutInArea(sources, SamplePage.INDENT, TOP, getWidth() - RIGHT - SamplePage.INDENT, getHeight() - BOTTOM - TOP, 0, HPos.LEFT, VPos.TOP);
-        }
-    }
-}
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/Description.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/Description.java	Sat Nov 02 06:58:02 2013 -0700
@@ -31,82 +31,116 @@
  */
 package ensemble.samplepage;
 
-
+import ensemble.EnsembleApp;
 import ensemble.SampleInfo;
 import ensemble.SampleInfo.URL;
 import ensemble.generated.Samples;
-import static ensemble.samplepage.FrontPage.*;
-import static ensemble.samplepage.SamplePage.*;
-import ensemble.util.FeatureChecker;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
-import javafx.scene.control.Hyperlink;
-import javafx.scene.control.Label;
-import javafx.scene.control.LabelBuilder;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.control.ScrollPaneBuilder;
-import javafx.scene.layout.ColumnConstraintsBuilder;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.GridPaneBuilder;
-import javafx.scene.layout.VBox;
-import javafx.scene.layout.VBoxBuilder;
+import javafx.geometry.Insets;
+import javafx.scene.control.*;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.*;
+import javafx.scene.text.Text;
 
+import static ensemble.samplepage.SamplePageContent.title;
+import static ensemble.samplepage.SamplePage.INDENT;
 
 /**
- *
+ * Description Section on Sample Page
  */
-public class Description extends VBox {
-    
+public class Description extends GridPane {
+    private static final Image ORANGE_ARROW = new Image(EnsembleApp.class.getResource("images/orange-arrrow.png").toExternalForm());
     private final SamplePage samplePage;
-    private final SampleInfo sampleInfo;
-    private Label description;
+    private final Label description;
+    private final VBox relatedDocumentsList;
+    private final VBox relatedSamples;
     
     public Description(final SamplePage samplePage) {
-        super(INDENT);
+        setVgap(INDENT);
+        setHgap(INDENT);
         this.samplePage = samplePage;
-        this.sampleInfo = samplePage.sample;
         getStyleClass().add("sample-page-box");
-        VBox relatedDocumentsList = VBoxBuilder.create().build();
+
+        // Setup Columns
+        ColumnConstraints leftColumn = new ColumnConstraints();
+        leftColumn.setPercentWidth(50);
+        ColumnConstraints rightColumn = new ColumnConstraints();
+        rightColumn.setPercentWidth(50);
+        getColumnConstraints().addAll(leftColumn,rightColumn);
+
+        // Add Description
+        Text descriptionTitle = title("DESCRIPTION");
+        setConstraints(descriptionTitle,0,0,2,1);
+        description = new Label();
+        description.setWrapText(true);
+        description.setMinHeight(Label.USE_PREF_SIZE);
+        description.setPadding(new Insets(8,0,8,0));
+        setConstraints(description, 0, 1, 2, 1);
+
+        // Add View Source Hyperlink
+        Hyperlink sourceBtn = new Hyperlink("VIEW SOURCE");
+        setConstraints(sourceBtn,0,2,2,1);
+        sourceBtn.getStyleClass().add("sample-page-box-title");
+        sourceBtn.setGraphic(new ImageView(ORANGE_ARROW));
+        sourceBtn.setContentDisplay(ContentDisplay.RIGHT);
+        sourceBtn.setOnAction(event -> {
+            samplePage.pageBrowser.goToPage(samplePage.getUrl().replaceFirst("sample://", "sample-src://"));
+        });
+
+        // Add Related Documents
+        Text relatedDocumentsTitle = title("RELATED DOCUMENTS");
+        setConstraints(relatedDocumentsTitle,0,3);
+        relatedDocumentsList = new VBox();
+        ScrollPane relatedDocumentsScrollPane = new ScrollPane(relatedDocumentsList);
+        setConstraints(relatedDocumentsScrollPane,0,4);
+        relatedDocumentsScrollPane.setFitToHeight(true);
+        relatedDocumentsScrollPane.setFitToWidth(true);
+        relatedDocumentsScrollPane.prefHeightProperty().bind(heightProperty());
+        relatedDocumentsScrollPane.getStyleClass().clear();
+
+        // Add Related Samples
+        Text relatedSamplesTitle = title("RELATED SAMPLES");
+        setConstraints(relatedSamplesTitle,1,3);
+        relatedSamples = new VBox();
+        setConstraints(relatedSamples,1,4);
+
+        getChildren().addAll(
+                descriptionTitle,
+                description,
+                relatedDocumentsTitle,
+                relatedDocumentsScrollPane,
+                relatedSamplesTitle,
+                relatedSamples
+                );
+        if (!EnsembleApp.IS_EMBEDDED) getChildren().add(sourceBtn);
+
+        // listen for when sample changes
+        samplePage.registerSampleInfoUpdater(sampleInfo -> {
+            update(sampleInfo);
+            return null;
+        });
+    }
+
+    private void update(SampleInfo sampleInfo) {
+        relatedDocumentsList.getChildren().clear();
         for (final URL docUrl : sampleInfo.getDocURLs()) {
             Hyperlink link = new Hyperlink(docUrl.getName());
-            link.setOnAction(new EventHandler<ActionEvent>() {
-                @Override
-                public void handle(ActionEvent t) {
-                    samplePage.pageBrowser.goToPage(docUrl.getURL());
-                }
+            link.setOnAction(t -> {
+                samplePage.pageBrowser.goToPage(docUrl.getURL());
             });
+            link.setTooltip(new Tooltip(docUrl.getName()));
             relatedDocumentsList.getChildren().add(link);
         }
         for (final String classpath : sampleInfo.apiClasspaths) {
             Hyperlink link = new Hyperlink(classpath.replace('$', '.'));
-            link.setOnAction(new EventHandler<ActionEvent>() {
-                @Override
-                public void handle(ActionEvent t) {
-                    samplePage.pageBrowser.goToPage(samplePage.apiClassToUrl(classpath));
-                }
+            link.setOnAction(t -> {
+                samplePage.pageBrowser.goToPage(samplePage.apiClassToUrl(classpath));
             });
             relatedDocumentsList.getChildren().add(link);
         }
-        ScrollPane relatedDocumentsScrollPane = ScrollPaneBuilder.create()
-                .content(relatedDocumentsList)
-                .fitToHeight(true)
-                .fitToWidth(true)
-                .pannable(true)
-                .build();
-        relatedDocumentsScrollPane.prefHeightProperty().bind(heightProperty());
-        relatedDocumentsScrollPane.getStyleClass().clear();
-        
-        VBox relatedDocuments = VBoxBuilder.create()
-                .children(
-                    title("RELATED DOCUMENTS"), 
-                    relatedDocumentsScrollPane
-                )
-                .build();
-        
-        VBox relatedSamples = VBoxBuilder.create()
-                .children(title("RELATED SAMPLES"))
-                .build();
-        
+        relatedSamples.getChildren().clear();
         for (final SampleInfo.URL sampleURL : sampleInfo.getRelatedSampleURLs()) {
             if (Samples.ROOT.sampleForPath(sampleURL.getURL()) != null) { //Check if sample exists
                 Hyperlink sampleLink = new Hyperlink(sampleURL.getName());
@@ -120,26 +154,7 @@
                 relatedSamples.getChildren().add(sampleLink);
             }
         }
-        GridPane gridPane = GridPaneBuilder.create()
-                .columnConstraints(
-                    ColumnConstraintsBuilder.create()
-                        .percentWidth(50)
-                        .build(), 
-                    ColumnConstraintsBuilder.create()
-                        .percentWidth(50)
-                        .build()
-                )
-                .build();
-        gridPane.addRow(0, relatedDocuments, relatedSamples);
-        
-        description = LabelBuilder.create()
-                .text(sampleInfo.description)
-                .wrapText(true)
-                .minHeight(Label.USE_PREF_SIZE)
-                .build();
-        
-        getChildren().addAll(
-                title("DESCRIPTION"), description, 
-                gridPane);
+        description.setText(sampleInfo.description);
     }
+
 }
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/FrontPage.java	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2008, 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 ensemble.samplepage;
-
-
-import static ensemble.samplepage.SamplePage.INDENT;
-import javafx.scene.Node;
-import javafx.scene.Parent;
-import javafx.scene.control.Label;
-import javafx.scene.control.LabelBuilder;
-import javafx.scene.layout.Region;
-
-
-/**
- *
- */
-class FrontPage extends Region {
-    
-    private Node playground;
-    private Description description;
-    private Parent sampleNode;
-    private SampleContainer sampleContainer;
-    final SamplePage samplePage;
-
-    FrontPage(final SamplePage samplePage) {
-        this.samplePage = samplePage;
-        getStyleClass().add("sample-page-front");
-        sampleNode = samplePage.sampleInfo.getSampleNode();
-        sampleContainer = new SampleContainer(sampleNode);
-        sampleContainer.getStyleClass().add("sample-page-sample-node");
-        if (samplePage.sample.needsPlayground()) {
-            playground = new PlaygroundNode(samplePage);
-            getChildren().add(playground);
-        }
-        description = new Description(samplePage);
-        setStyle("-fx-background-color: rgb(238, 238, 238);");
-        getChildren().addAll(description, sampleContainer);
-    }
-
-    @Override protected void layoutChildren() {
-        super.layoutChildren();
-        
-        double maxWidth = getWidth() - 2 * INDENT;
-        double maxHeight = getHeight() - 2 * INDENT;
-        
-        boolean landscape = getWidth() >= getHeight();
-        boolean wide = getWidth() >= getHeight() * 1.5;
-        if (wide) {
-
-            // Sample on right, everything else on left
-            double x = Math.round(getWidth() / 2 + INDENT / 2);
-            double w = getWidth() - INDENT - x;
-            sampleContainer.resizeRelocate(x, INDENT, (getWidth() - 3 * INDENT) / 2, maxHeight);
-            if (playground != null) {
-                double h = (getHeight() - INDENT * 3) / 2;
-                description.resizeRelocate(INDENT, INDENT, w, h);
-                playground.resizeRelocate(INDENT, Math.round(INDENT * 2 + h), w, h);
-            } else {
-                description.resizeRelocate(INDENT, INDENT, w, maxHeight);
-            }
-        } else {
-
-            // Sample on top, everything else on bottom
-            sampleContainer.resizeRelocate(INDENT, INDENT, maxWidth, (getHeight() - 3 * INDENT) / 2);
-            double y = Math.round(getHeight() / 2 + INDENT / 2);
-            if (landscape) {
-                double h = getHeight() - INDENT - y;
-                if (playground != null) {
-                    double w = (getWidth() - INDENT * 3) / 2;
-                    playground.resizeRelocate(INDENT, y, w, h);
-                    description.resizeRelocate(Math.round(INDENT * 2 + w), y, w, h);
-                } else {
-                    description.resizeRelocate(INDENT, y, maxWidth, h);
-                }
-            } else {
-                double w = getWidth() - INDENT * 2;
-                if (playground != null) {
-                    double h = (getHeight() - INDENT * 2 - y) / 2;
-                    playground.resizeRelocate(INDENT, y, w, h);
-                    description.resizeRelocate(INDENT, Math.round(y + h + INDENT), w, h);
-                } else {
-                    double h = getHeight() - INDENT - y;
-                    description.resizeRelocate(INDENT, y, w, h);
-                }
-            }
-        }
-    }
-
-    static Label title(String text) {
-        return LabelBuilder.create().text(text).styleClass("sample-page-box-title").build();
-    }
-}
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/IPhoneLayout.java	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2008, 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 ensemble.samplepage;
-
-import javafx.beans.binding.ObjectBinding;
-import javafx.geometry.Pos;
-import javafx.scene.Parent;
-import javafx.scene.control.Toggle;
-import javafx.scene.control.ToggleButtonBuilder;
-import javafx.scene.control.ToggleGroup;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.HBoxBuilder;
-import javafx.scene.layout.Region;
-
-/**
- *
- */
-public class IPhoneLayout extends Region {
-    
-    private PlaygroundTabs playground;
-    private Parent sampleNode;
-    private SampleContainer sample;
-    private Description description;
-    private Sources sources;
-    private Parent iPhoneTabs;
-    
-    public IPhoneLayout(SamplePage samplePage) {
-        sample = new SampleContainer(sampleNode = samplePage.sampleInfo.getSampleNode());
-        description = new Description(samplePage);
-        sources = new Sources(samplePage);
-        if (samplePage.sample.needsPlayground()) {
-            playground = new PlaygroundTabs(samplePage);
-            getChildren().add(playground);
-        }
-        iPhoneTabs = buildIPhoneTabs();
-        getStyleClass().add("sample-page-iphone");
-        getChildren().addAll(sample, description, sources, iPhoneTabs);
-    }
-
-    @Override protected void layoutChildren() {
-        super.layoutChildren();
-        
-        double w = getWidth();
-        double bh = iPhoneTabs.prefHeight(w);
-        double sh = getHeight() - bh;
-        
-        if (playground != null) {
-            playground.resizeRelocate(0, 0, w, sh);
-        }
-        sample.resizeRelocate(0, 0, w, sh);
-        description.resizeRelocate(0, 0, w, sh);
-        sources.resizeRelocate(0, 0, w, sh);
-        iPhoneTabs.resizeRelocate(0, sh, w, bh);
-    }
-    
-    private Parent buildIPhoneTabs() {
-        final ToggleGroup shownPage = new ToggleGroup();
-        ObjectBinding<Object> selectedToggleUserData = new ObjectBinding<Object>() {
-
-                    {
-                        bind(shownPage.selectedToggleProperty());
-                    }
-
-                    @Override
-                    protected Object computeValue() {
-                        Toggle selectedToggle = shownPage.getSelectedToggle();
-                        if (selectedToggle == null) {
-                            return null;
-                        } else {
-                            return selectedToggle.getUserData();
-                        }
-                    }
-                };
-        if (playground != null) {
-            playground.visibleProperty().bind(selectedToggleUserData.isEqualTo(playground));
-        }
-        sample.visibleProperty().bind(selectedToggleUserData.isEqualTo(sample));
-        description.visibleProperty().bind(selectedToggleUserData.isEqualTo(description));
-        sources.visibleProperty().bind(selectedToggleUserData.isEqualTo(sources));
-        
-        HBox hbox = HBoxBuilder.create()
-                .styleClass("sample-page-iphone-bottom-bar")
-                .alignment(Pos.CENTER)
-                .children(
-                    ToggleButtonBuilder.create()
-                        .text("Description")
-                        .toggleGroup(shownPage)
-                        .userData(description)
-                        .build(),
-                    ToggleButtonBuilder.create()
-                        .text("Sample")
-                        .toggleGroup(shownPage)
-                        .selected(true)
-                        .userData(sample)
-                        .build()
-                ).build();
-        if (playground != null) {
-            hbox.getChildren().add(
-                    ToggleButtonBuilder.create()
-                        .text("Playground")
-                        .toggleGroup(shownPage)
-                        .userData(playground)
-                        .build());
-        }
-        hbox.getChildren().add(
-                ToggleButtonBuilder.create()
-                    .text("Sources")
-                    .toggleGroup(shownPage)
-                    .userData(sources)
-                    .build());
-        return hbox;
-    }
-}
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/PlaygroundNode.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/PlaygroundNode.java	Sat Nov 02 06:58:02 2013 -0700
@@ -32,18 +32,21 @@
 package ensemble.samplepage;
 
 
-import static ensemble.samplepage.FrontPage.*;
+import static ensemble.samplepage.SamplePageContent.*;
+
+import javafx.geometry.Pos;
 import javafx.scene.layout.Priority;
 import javafx.scene.layout.VBox;
 
 
 /**
- *
+ * Playground section on Sample Page
  */
 public class PlaygroundNode extends VBox {
 
     public PlaygroundNode(SamplePage samplePage) {
         PlaygroundTabs playgroundTabs = new PlaygroundTabs(samplePage);
+        setAlignment(Pos.TOP_LEFT);
         getChildren().setAll(
                 title("PLAYGROUND"), 
                 playgroundTabs);
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/PlaygroundTabs.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/PlaygroundTabs.java	Sat Nov 02 06:58:02 2013 -0700
@@ -31,6 +31,7 @@
  */
 package ensemble.samplepage;
 
+import ensemble.SampleInfo;
 import ensemble.playground.PlaygroundProperty;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
@@ -74,6 +75,7 @@
 import javafx.scene.paint.Color;
 import javafx.scene.paint.Paint;
 import javafx.scene.shape.Rectangle;
+import javafx.util.Callback;
 import javafx.util.StringConverter;
 
 /**
@@ -81,19 +83,70 @@
  */
 class PlaygroundTabs extends TabPane {
     private final SamplePage samplePage;
+    private final GridPane grid;
 
     PlaygroundTabs(final SamplePage samplePage) {
         this.samplePage = samplePage;
-        GridPane grid = new GridPane();
+        grid = new GridPane();
         grid.setHgap(SamplePage.INDENT);
         grid.setVgap(SamplePage.INDENT);
         grid.setPadding(new Insets(SamplePage.INDENT));
+        samplePage.registerSampleInfoUpdater(new Callback<SampleInfo, Void>() {
+
+            @Override
+            public Void call(SampleInfo sampleInfo) {
+                update(sampleInfo);
+                return null;
+            }
+        });
+        getStyleClass().add("floating");
+        ScrollPane scrollPane = new ScrollPane(grid);
+        scrollPane.getStyleClass().clear();
+        Tab tab = new Tab("Properties");
+        tab.setContent(scrollPane);
+        getTabs().add(tab);
+        setMinSize(100, 100);
+    }
+
+    private PropertyController newPropertyController(PlaygroundProperty playgroundProperty, Object object, Object property) {
+        if (playgroundProperty.propertyName.equals("getStrokeDashArray")) {
+            return new StrokeDashArrayPropertyController(playgroundProperty, object, (ObservableList<Double>) property);
+        }
+        if (property instanceof DoubleProperty) {
+            DoubleProperty prop = (DoubleProperty) property;
+            return new DoublePropertyController(playgroundProperty, object, prop);
+        } else if (property instanceof IntegerProperty) {
+            IntegerProperty prop = (IntegerProperty) property;
+            return new IntegerPropertyController(playgroundProperty, object, prop);
+        } else if (property instanceof BooleanProperty) {
+            BooleanProperty prop = (BooleanProperty) property;
+            return new BooleanPropertyController(playgroundProperty, object, prop);
+        } else if (property instanceof StringProperty) {
+            StringProperty prop = (StringProperty) property;
+            return new StringPropertyController(playgroundProperty, object, prop);
+        } else if (property instanceof ObjectProperty) {
+            final ObjectProperty prop = (ObjectProperty) property;
+            if (prop.get() instanceof Color) {
+                return new ColorPropertyController(playgroundProperty, object, prop);
+            }
+            if (prop.get() instanceof String) {
+                return new StringPropertyController(playgroundProperty, object, prop);
+            }
+            if (prop.get() != null && prop.get().getClass().isEnum()) {
+                return new EnumPropertyController(playgroundProperty, object, prop, (Enum) prop.get());
+            }
+        }
+        return null;
+    }
+
+    private void update(SampleInfo sampleInfo) {
+        grid.getChildren().clear();
         int rowIndex = 0;
-        for (PlaygroundProperty prop : samplePage.sample.playgroundProperties) {
+        for (PlaygroundProperty prop : sampleInfo.playgroundProperties) {
             try {
-                Object object = samplePage.sampleInfo.getApp();
+                Object object = samplePage.sampleRuntimeInfoProperty.get().getApp();
                 if (prop.fieldName != null) {
-                    Field declaredField = samplePage.sampleInfo.getClz().getDeclaredField(prop.fieldName);
+                    Field declaredField = samplePage.sampleRuntimeInfoProperty.get().getClz().getDeclaredField(prop.fieldName);
                     declaredField.setAccessible(true);
                     object = declaredField.get(object);
                 }
@@ -154,44 +207,6 @@
                 Logger.getLogger(SamplePage.class.getName()).log(Level.SEVERE, null, ex);
             }
         }
-        getStyleClass().add("floating");
-        ScrollPane scrollPane = new ScrollPane(grid);
-        scrollPane.getStyleClass().clear();
-        Tab tab = new Tab("Properties");
-        tab.setContent(scrollPane);
-        getTabs().add(tab);
-        setMinSize(100, 100);
-    }
-
-    private PropertyController newPropertyController(PlaygroundProperty playgroundProperty, Object object, Object property) {
-        if (playgroundProperty.propertyName.equals("getStrokeDashArray")) {
-            return new StrokeDashArrayPropertyController(playgroundProperty, object, (ObservableList<Double>) property);
-        }
-        if (property instanceof DoubleProperty) {
-            DoubleProperty prop = (DoubleProperty) property;
-            return new DoublePropertyController(playgroundProperty, object, prop);
-        } else if (property instanceof IntegerProperty) {
-            IntegerProperty prop = (IntegerProperty) property;
-            return new IntegerPropertyController(playgroundProperty, object, prop);
-        } else if (property instanceof BooleanProperty) {
-            BooleanProperty prop = (BooleanProperty) property;
-            return new BooleanPropertyController(playgroundProperty, object, prop);
-        } else if (property instanceof StringProperty) {
-            StringProperty prop = (StringProperty) property;
-            return new StringPropertyController(playgroundProperty, object, prop);
-        } else if (property instanceof ObjectProperty) {
-            final ObjectProperty prop = (ObjectProperty) property;
-            if (prop.get() instanceof Color) {
-                return new ColorPropertyController(playgroundProperty, object, prop);
-            }
-            if (prop.get() instanceof String) {
-                return new StringPropertyController(playgroundProperty, object, prop);
-            }
-            if (prop.get() != null && prop.get().getClass().isEnum()) {
-                return new EnumPropertyController(playgroundProperty, object, prop, (Enum) prop.get());
-            }
-        }
-        return null;
     }
 
     private class PropertyController {
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SampleContainer.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SampleContainer.java	Sat Nov 02 06:58:02 2013 -0700
@@ -36,9 +36,8 @@
 import javafx.scene.Parent;
 import javafx.scene.layout.Region;
 
-
 /**
- *
+ * Container for a Sample, responsible for sizing and centering sample
  */
 public class SampleContainer extends Region {
         
@@ -50,13 +49,8 @@
         resizable = sampleNode.isResizable() && 
                 (sampleNode.maxWidth(-1) == 0 || sampleNode.maxWidth(-1) > sampleNode.minWidth(-1))
                 && (sampleNode.maxHeight(-1) == 0 || sampleNode.maxHeight(-1) > sampleNode.minHeight(-1));
-//            System.out.println("sampleNode.isResizable() = " + sampleNode.isResizable());
-//            System.out.println("sampleNode.maxWidth(-1) = " + sampleNode.maxWidth(-1));
-//            System.out.println("sampleNode.minWidth(-1) = " + sampleNode.minWidth(-1));
-//            System.out.println("sampleNode.maxHeight(-1) = " + sampleNode.maxHeight(-1));
-//            System.out.println("sampleNode.minHeight(-1) = " + sampleNode.minHeight(-1));
-//            System.out.println("resizable = " + resizable);
         getChildren().add(sampleNode);
+        getStyleClass().add("sample-container");
     }
 
     @Override protected void layoutChildren() {
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SamplePage.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SamplePage.java	Sat Nov 02 06:58:02 2013 -0700
@@ -31,65 +31,60 @@
  */
 package ensemble.samplepage;
 
-import ensemble.EnsembleApp;
 import ensemble.Page;
 import ensemble.PageBrowser;
 import ensemble.SampleInfo;
-import ensemble.control.BendingPages;
-import ensemble.util.Utils;
-import java.util.regex.Pattern;
+import static ensemble.SampleInfo.SampleRuntimeInfo;
+
+import javafx.beans.binding.ObjectBinding;
+import javafx.beans.binding.StringBinding;
+import javafx.beans.property.ObjectProperty;
 import javafx.beans.property.ReadOnlyStringProperty;
-import javafx.beans.property.ReadOnlyStringWrapper;
-import javafx.geometry.Point2D;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
 import javafx.scene.Node;
-import javafx.scene.layout.Region;
-import javafx.scene.paint.Color;
+import javafx.scene.layout.StackPane;
+import javafx.util.Callback;
 
 /**
  * Page for showing a sample
  */
-public class SamplePage extends Region implements Page {
+public class SamplePage extends StackPane implements Page {
     static final double INDENT = 8;
-    SampleInfo sample;
+    final ObjectProperty<SampleInfo> sampleInfoProperty = new SimpleObjectProperty<>();
+    private final StringProperty titleProperty = new SimpleStringProperty();
     PageBrowser pageBrowser;
-    private final ReadOnlyStringProperty titleProperty;
-    final SampleInfo.SampleRuntimeInfo sampleInfo;
+    final ObjectProperty<SampleRuntimeInfo> sampleRuntimeInfoProperty = new SimpleObjectProperty<>();
 
-    public SamplePage(SampleInfo sample, String url, final PageBrowser pageBrowser) {
-        this.sample = sample;
+    public SamplePage(SampleInfo sampleInfo, String url, final PageBrowser pageBrowser) {
+        sampleInfoProperty.set(sampleInfo);
         this.pageBrowser = pageBrowser;
         getStyleClass().add("sample-page");
-        titleProperty = new ReadOnlyStringWrapper(sample.name);
-        sampleInfo = sample.buildSampleNode();
+        titleProperty.bind(new StringBinding() {
+            { bind(sampleInfoProperty); }
+            @Override protected String computeValue() {
+                SampleInfo sample = SamplePage.this.sampleInfoProperty.get();
+                if (sample != null) {
+                    return sample.name;
+                } else {
+                    return null;
+                }
+            }
+        });
+        sampleRuntimeInfoProperty.bind(new ObjectBinding<SampleRuntimeInfo>() {
+            { bind(sampleInfoProperty); }
+            @Override protected SampleRuntimeInfo computeValue() {
+                return sampleInfoProperty.get().buildSampleNode();
+            }
+        });
 
-        if (EnsembleApp.IS_IPHONE) {
-            IPhoneLayout iPhoneLayout = new IPhoneLayout(this);
-            iPhoneLayout.prefWidthProperty().bind(widthProperty());
-            iPhoneLayout.prefHeightProperty().bind(heightProperty());
-            getChildren().setAll(iPhoneLayout);
-        } else {
-            FrontPage frontPage = new FrontPage(this);
-            BackPage backPage = new BackPage(this);
+        SamplePageContent frontPage = new SamplePageContent(this);
+        getChildren().setAll(frontPage);
+    }
 
-            if (EnsembleApp.IS_EMBEDDED || EnsembleApp.IS_IOS) {
-                SlidingPages slidingPages = new SlidingPages();
-                slidingPages.prefWidthProperty().bind(widthProperty());
-                slidingPages.prefHeightProperty().bind(heightProperty());
-                slidingPages.setFrontPage(frontPage);
-                slidingPages.setBackPage(backPage);
-                getChildren().setAll(slidingPages);
-            } else {
-                
-                BendingPages bendingPages = new BendingPages();
-                bendingPages.prefWidthProperty().bind(widthProperty());
-                bendingPages.prefHeightProperty().bind(heightProperty());
-                bendingPages.setFrontPage(frontPage);
-                bendingPages.setBackPage(backPage);
-                bendingPages.setColors(Color.rgb(3, 95, 188), Color.rgb(4, 164, 231), Color.rgb(0, 57, 117));
-                bendingPages.setClosedOffset(new Point2D(50, 40));
-                getChildren().setAll(bendingPages);
-            }
-        }
+    public void update(SampleInfo sampleInfo, String url) {
+        sampleInfoProperty.set(sampleInfo);
     }
 
     @Override public ReadOnlyStringProperty titleProperty() {
@@ -97,11 +92,11 @@
     }
 
     @Override public String getTitle() {
-        return sample.name;
+        return titleProperty.get();
     }
 
     @Override public String getUrl() {
-        return "sample://"+sample.ensemblePath;
+        return "sample://" + sampleInfoProperty.get().ensemblePath;
     }
 
     @Override public Node getNode() {
@@ -117,97 +112,15 @@
         }
     }
 
-    private String shCoreJs;
-    private String shBrushJScript;
-    private String shCoreDefaultCss;
-    
-    private static final Pattern JAVA_DOC_PATTERN = Pattern.compile("(^\\s+\\*$\\s)?^\\s+\\*\\s+@.*$\\s",Pattern.MULTILINE);
-    String convertToHTML(String source) {
-        // load syntax highlighter
-        if (shCoreJs == null) {
-            shCoreJs = Utils.loadFile(EnsembleApp.class.getResource("syntaxhighlighter/shCore.js")) +";";
-        }
-        if (shBrushJScript == null) {
-            shBrushJScript = Utils.loadFile(EnsembleApp.class.getResource("syntaxhighlighter/shBrushJava.js"));
-        }
-        if (shCoreDefaultCss == null) {
-            shCoreDefaultCss = Utils.loadFile(EnsembleApp.class.getResource("syntaxhighlighter/shCoreDefault.css")).replaceAll("!important","");
-        }
-        // split copy right and source
-        String[] parts = source.split("\\*/",2);
-        String copyRight = null;
-        if (parts.length > 1) {
-            copyRight = parts[0]+"*/";
-            source = parts[1];
-        }
-        // remove JavaDoc @xxxx lines
-        source = JAVA_DOC_PATTERN.matcher(source).replaceAll("");
-        // escape < & >
-        source = source.replaceAll("&","&amp;");
-        source = source.replaceAll("<","&lt;");
-        source = source.replaceAll(">","&gt;");
-        source = source.replaceAll("\"","&quot;");
-        source = source.replaceAll("\'","&apos;");
-        // create content
-        StringBuilder html = new StringBuilder();
-        html.append("<html>\n");
-        html.append("    <head>\n");
-        html.append("    <script type=\"text/javascript\">\n");
-        html.append(shCoreJs);
-        html.append('\n');
-        html.append(shBrushJScript);
-        html.append("    </script>\n");
-        html.append("    <style>\n");
-        html.append(shCoreDefaultCss);
-        html.append('\n');
-        html.append("        .syntaxhighlighter {\n");
-        html.append("			overflow: visible;\n");
-        if (EnsembleApp.IS_MAC) {
-            html.append("			font: 12px Ayuthaya !important; line-height: 150% !important; \n");
-            html.append("		}\n");
-            html.append("		code { font: 12px Ayuthaya !important; line-height: 150% !important; } \n");
-        } else {
-            html.append("			font: 12px monospace !important; line-height: 150% !important; \n");
-            html.append("		}\n");
-            html.append("		code { font: 12px monospace !important; line-height: 150% !important; } \n");
-        }
-        html.append("		.syntaxhighlighter .preprocessor { color: #060 !important; }\n");
-        html.append("		.syntaxhighlighter .comments, .syntaxhighlighter .comments a  { color: #009300 !important; }\n");
-        html.append("		.syntaxhighlighter .string  { color: #555 !important; }\n");
-        html.append("		.syntaxhighlighter .value  { color: blue !important; }\n");
-        html.append("		.syntaxhighlighter .keyword  { color: #000080 !important; }\n");
-        html.append("		.hidden { display: none; }\n");
-        html.append("           .showing { display: block; }\n");
-        html.append("           .button {\n");
-        html.append("               font: 12px \"Consolas\", \"Bitstream Vera Sans Mono\", \"Courier New\", Courier, monospace !important;\n");
-        html.append("               color: #009300 !important;\n");
-        html.append("               text-decoration: underline;\n");
-        html.append("               display: inline;\n");
-        html.append("               cursor:pointer;\n");
-        html.append("           }\n");
-        html.append("    </style>\n");
-        html.append("    </head>\n");
-        html.append("<body>\n");
-        if (copyRight != null) {
-            html.append("    <div onclick='document.getElementById(\"licenceText\").className = \"showing\";document.getElementById(\"licenseBtn\").className = \"hidden\";' id=\"licenseBtn\" class=\"button\">/* ....Show License.... */</div>\n");
-            html.append("    <div id=\"licenceText\"class=\"hidden\">\n");
-            html.append("    <pre class=\"brush: java;gutter: false;toolbar: false;\">\n");
-            html.append(copyRight);
-            html.append('\n');
-            html.append("    </pre>\n");
-            html.append("    </div>\n");
-        }
-        html.append("    <pre class=\"brush: java;gutter: false;toolbar: false;\">\n");
-        html.append(source);
-        html.append('\n');
-        html.append("    </pre>\n");
-        html.append("    <script type=\"text/javascript\"> SyntaxHighlighter.all(); </script>\n");
-        html.append("</body>\n");
-        html.append("</html>\n");
-        
-//        System.out.println("------------------------------------------------------------");
-//        System.out.println(html);
-//        System.out.println("------------------------------------------------------------");
-        return html.toString();
+    /**
+     * This method is equivalent to bind(ObjectBinding) as it would invoke
+     * updater immediately as well as on any change to SampleInfo
+     * @param updater a method that updates content for a given SampleInfo
+     */
+    void registerSampleInfoUpdater(final Callback<SampleInfo, Void> updater) {
+        sampleInfoProperty.addListener((ov, t, sampleInfo) -> {
+            updater.call(sampleInfo);
+        });
+        updater.call(sampleInfoProperty.get());
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SamplePageContent.java	Sat Nov 02 06:58:02 2013 -0700
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2008, 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 ensemble.samplepage;
+
+import ensemble.SampleInfo;
+import javafx.scene.Node;
+import javafx.scene.layout.Region;
+import javafx.scene.text.Text;
+import javafx.util.Callback;
+
+import static ensemble.samplepage.SamplePage.INDENT;
+
+/**
+ * The content for Sample Page
+ */
+class SamplePageContent extends Region {
+    
+    private Node playground;
+    private Description description;
+    private SampleContainer sampleContainer;
+    private boolean needsPlayground;
+    final SamplePage samplePage;
+
+    SamplePageContent(final SamplePage samplePage) {
+        this.samplePage = samplePage;
+        playground = new PlaygroundNode(samplePage);
+        description = new Description(samplePage);
+        samplePage.registerSampleInfoUpdater(new Callback<SampleInfo, Void>() {
+
+            @Override
+            public Void call(SampleInfo sampleInfo) {
+                update(sampleInfo);
+                return null;
+            }
+        });
+    }
+
+    @Override protected void layoutChildren() {
+        super.layoutChildren();
+        
+        double maxWidth = getWidth() - 2 * INDENT;
+        double maxHeight = getHeight() - 2 * INDENT;
+        
+        boolean landscape = getWidth() >= getHeight();
+        boolean wide = getWidth() >= getHeight() * 1.5;
+        if (wide) {
+            // Sample on right, everything else on left
+            double x = Math.round(getWidth() / 2 + INDENT / 2);
+            double w = getWidth() - INDENT - x;
+            sampleContainer.resizeRelocate(x, INDENT, (getWidth() - 3 * INDENT) / 2, maxHeight);
+            if (needsPlayground) {
+                double h = (getHeight() - INDENT * 3) / 2;
+                description.resizeRelocate(INDENT, INDENT, w, h);
+                playground.resizeRelocate(INDENT, Math.round(INDENT * 2 + h), w, h);
+            } else {
+                description.resizeRelocate(INDENT, INDENT, w, maxHeight);
+            }
+        } else {
+            // Sample on top, everything else on bottom
+            sampleContainer.resizeRelocate(INDENT, INDENT, maxWidth, (getHeight() - 3 * INDENT) / 2);
+            double y = Math.round(getHeight() / 2 + INDENT / 2);
+            if (landscape) {
+                double h = getHeight() - INDENT - y;
+                if (needsPlayground) {
+                    double w = (getWidth() - INDENT * 3) / 2;
+                    playground.resizeRelocate(INDENT, y, w, h);
+                    description.resizeRelocate(Math.round(INDENT * 2 + w), y, w, h);
+                } else {
+                    description.resizeRelocate(INDENT, y, maxWidth, h);
+                }
+            } else {
+                double w = getWidth() - INDENT * 2;
+                if (needsPlayground) {
+                    double h = (getHeight() - INDENT * 2 - y) / 2;
+                    playground.resizeRelocate(INDENT, y, w, h);
+                    description.resizeRelocate(INDENT, Math.round(y + h + INDENT), w, h);
+                } else {
+                    double h = getHeight() - INDENT - y;
+                    description.resizeRelocate(INDENT, y, w, h);
+                }
+            }
+        }
+    }
+
+    static Text title(String text) {
+        Text title = new Text(text);
+        title.getStyleClass().add("sample-page-box-title");
+        return title;
+    }
+
+    private void update(SampleInfo sampleInfo) {
+        sampleContainer = new SampleContainer(samplePage.sampleRuntimeInfoProperty.get().getSampleNode());
+        sampleContainer.getStyleClass().add("sample-page-sample-node");
+        needsPlayground = sampleInfo.needsPlayground();
+        if (needsPlayground) {
+            getChildren().setAll(playground, description, sampleContainer);
+        } else {
+            getChildren().setAll(description, sampleContainer);
+        }
+    }
+}
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SlidingPages.java	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2008, 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 ensemble.samplepage;
-
-import javafx.animation.TranslateTransitionBuilder;
-import javafx.beans.binding.DoubleBinding;
-import javafx.beans.binding.DoubleExpression;
-import javafx.beans.binding.ObjectBinding;
-import javafx.beans.binding.ObjectExpression;
-import javafx.event.EventHandler;
-import javafx.geometry.Point2D;
-import javafx.scene.Node;
-import javafx.scene.image.ImageView;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.Region;
-import javafx.scene.shape.Polygon;
-
-/**
- *
- */
-public class SlidingPages extends Region {
-    
-    private Region frontPage;
-    private Region backPage;
-    private ImageView actionNode;
-    private SelfPageSlide slide;
-    private Polygon clip;
-
-    public SlidingPages() {
-        actionNode = new ImageView("ensemble/images/corner-top.png");
-        actionNode.setFitWidth(100);
-        actionNode.setFitHeight(100);
-        actionNode.setPickOnBounds(true);
-        getChildren().add(actionNode);
-    }
-
-    @Override protected void layoutChildren() {
-        super.layoutChildren();
-        if (frontPage != null) {
-            frontPage.resize(getWidth(), getHeight());
-        }
-//        if (actionNode != null) {
-//            actionNode.relocate(
-//                    getWidth() - actionNode.getLayoutBounds().getWidth(), 
-//                    getHeight() - actionNode.getLayoutBounds().getHeight());
-//        }
-        if (backPage != null) {
-            backPage.resize(getWidth(), getHeight());
-        }
-    }
-
-    public void setFrontPage(Region frontPage) {
-        if (this.frontPage != null) {
-            getChildren().remove(this.frontPage);
-            actionNode.layoutXProperty().unbind();
-            actionNode.layoutYProperty().unbind();
-        }
-        this.frontPage = frontPage;
-        if (frontPage != null) {
-            getChildren().add(getChildren().indexOf(actionNode), this.frontPage);
-            actionNode.translateXProperty().bind(frontPage.translateXProperty().add(frontPage.widthProperty()).subtract(actionNode.getLayoutBounds().getWidth()));
-            actionNode.translateYProperty().bind(frontPage.translateYProperty().add(frontPage.heightProperty()).subtract(actionNode.getLayoutBounds().getHeight()));
-            frontPage.clipProperty().bind(new ObjectBinding<Node>() {
-               
-                {
-                    bind(widthProperty(), heightProperty());
-                }
-
-                @Override
-                protected Node computeValue() {
-                    if (clip == null) {
-                        clip = new Polygon();
-                    }
-                    
-                    clip.getPoints().setAll(
-                            0d, 0d, 
-                            0d, getHeight(), 
-                            getWidth() - 68, getHeight(),
-                            getWidth() - 53, getHeight() - 8,
-                            getWidth() - 2, getHeight() - 66,
-                            getWidth(), getHeight() - 73,
-                            getWidth(), 0d
-                    );
-                    return clip;
-                }
-            });
-        }
-        setupSlide();
-    }
-
-    public void setBackPage(Region backPage) {
-        if (this.backPage != null) {
-            getChildren().remove(this.backPage);
-        }
-        this.backPage = backPage;
-        if (backPage != null) {
-            getChildren().add(0, this.backPage);
-        }
-        setupSlide();
-    }
-
-    private void setupSlide() {
-        if (frontPage == null || backPage == null) {
-            slide = null;
-            return;
-        }
-        slide = new SelfPageSlide(backPage, frontPage, actionNode, 0, 0, 
-                widthProperty().negate().add(actionNode.getLayoutBounds().getWidth()), 
-                heightProperty().negate().add(actionNode.getLayoutBounds().getHeight()));
-    }
-    
-    public static class SelfPageSlide {
-        private double fromX, fromY;
-        private DoubleExpression toX, toY;
-        private double delta;
-        private double step, prev;
-        private double actualFromX, actualFromY;
-        private Node targetScreen;
-        private Node baseScreen;
-        private ObjectExpression<Point2D> v2;
-        private DoubleExpression quadLenV2;
-
-//        protected void stopCurrentScreen() {
-//            screenNavigator.stop(currentScreen, false);
-//        }
-        
-        private double calcX(double v) {
-            return fromX * (1 - v) + toX.get() * v;
-        }
-        
-        private double calcY(double v) {
-            return fromY * (1 - v) + toY.get() * v;
-        }
-        
-        private double calcValue(double x, double y) {
-            return v2.get().dotProduct(x - fromX, y - fromY) / quadLenV2.get();
-        }
-
-        public SelfPageSlide(Node inCurrentScreen, Node inTargetScreen, final Node actionNode, final double fromX, final double fromY, final DoubleExpression toX, final DoubleExpression toY) {
-//            super(inCurrentScreen);
-            this.fromX = fromX;
-            this.fromY = fromY;
-            this.toX = toX;
-            this.toY = toY;
-            this.targetScreen = inTargetScreen;
-//            removeScreen = false;
-            v2 = new ObjectBinding<Point2D>() {
-                { bind(toX, toY); }
-                @Override protected Point2D computeValue() {
-                    return new Point2D(toX.get() - fromX, toY.get() - fromY);
-                }
-            };
-            quadLenV2 = new DoubleBinding() {
-                { bind(v2); }
-                @Override protected double computeValue() {
-                    return v2.get().getX() * v2.get().getX() + v2.get().getY() * v2.get().getY();
-                }
-            };
-            
-            actionNode.setOnMousePressed(new EventHandler<MouseEvent>() {
-                @Override public void handle(MouseEvent me) {
-                    identifyScreens();
-//                    stopCurrentScreen();
-//                    onTransitionStart();
-//                    targetScreen.toFront();
-                    delta = calcValue(
-                            targetScreen.getTranslateX() - me.getSceneX(), 
-                            targetScreen.getTranslateY() - me.getSceneY());
-                    actualFromX = targetScreen.getTranslateX();
-                    actualFromY = targetScreen.getTranslateY();
-                    prev = calcValue(me.getSceneX(), me.getSceneY());
-                    step = 0;
-                    me.consume();
-                }
-            });
-            actionNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
-                @Override public void handle(MouseEvent me) {
-                    double value = Math.min(Math.max(calcValue(me.getSceneX(), me.getSceneY()) + delta, 0), 1);
-                    targetScreen.setTranslateX(calcX(value));
-                    targetScreen.setTranslateY(calcY(value));
-                    if (value != prev) {
-                        step = value - prev;
-                        prev = value;
-                    }
-                    me.consume();
-                }
-            });
-            actionNode.setOnMouseReleased(new EventHandler<MouseEvent>() {
-                @Override public void handle(MouseEvent me) {
-                    double targetX;
-                    double targetY;
-                    if (me.isStillSincePress()) {
-                        double curValue = calcValue(targetScreen.getTranslateX(), targetScreen.getTranslateY());
-                        targetX = curValue < 0.5 ? toX.get() : fromX;
-                        targetY = curValue < 0.5 ? toY.get() : fromY;
-                    } else {
-                        targetX = step > 0 ? toX.get() : fromX;
-                        targetY = step > 0 ? toY.get() : fromY;
-                    }
-                    TranslateTransitionBuilder.create()
-                        .node(targetScreen)
-                        .toX(targetX)
-                        .toY(targetY)
-//                        .onFinished(targetY == actualFromY && targetX == actualFromX ? onTransitionCanceled : onTransitionFinished)
-                        .build().play();
-                    me.consume();
-                }
-            });
-        }
-
-        public void identifyScreens() {
-//            if (baseScreen == null) {
-//                CompoundScreen compoundScreen = targetScreen.getParentScreen();
-//                if (compoundScreen != null) {
-//                    baseScreen = compoundScreen.getBase();
-//                }
-//            }
-//            if (!(targetScreen.getTranslateY() == fromY && targetScreen.getTranslateX() == fromX)) {
-//                currentScreen = baseScreen;
-//                nextScreen = targetScreen;
-//            } else {
-//                currentScreen = targetScreen;
-//                nextScreen = baseScreen;
-//            }
-        }
-    }
-    
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SourcePage.java	Sat Nov 02 06:58:02 2013 -0700
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2008, 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 ensemble.samplepage;
+
+import ensemble.Page;
+import ensemble.SampleInfo;
+import javafx.beans.binding.StringBinding;
+import javafx.beans.property.*;
+import javafx.scene.Node;
+import javafx.scene.control.TabPane;
+
+/**
+ * Page showing tabs with all the source code and resources for a sample
+ */
+public class SourcePage extends TabPane implements Page {
+    private final ObjectProperty<SampleInfo> sampleInfoProperty = new SimpleObjectProperty<>();
+    private final StringProperty titleProperty = new SimpleStringProperty();
+
+    public SourcePage() {
+        getStyleClass().add("source-page");
+        titleProperty.bind(new StringBinding() {
+            { bind(sampleInfoProperty); }
+            @Override protected String computeValue() {
+                SampleInfo sample = sampleInfoProperty.get();
+                if (sample != null) {
+                    return sample.name+" :: Source";
+                } else {
+                    return null;
+                }
+            }
+        });
+        setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
+    }
+
+    public void setSampleInfo(SampleInfo sampleInfo) {
+        sampleInfoProperty.set(sampleInfo);
+        getTabs().clear();
+        for (SampleInfo.URL sourceURL : sampleInfo.getSources()) {
+            getTabs().add(new SourceTab(sourceURL));
+        }
+    }
+
+    @Override public ReadOnlyStringProperty titleProperty() {
+        return titleProperty;
+    }
+
+    @Override public String getTitle() {
+        return titleProperty.get();
+    }
+
+    @Override public String getUrl() {
+        return "sample-src://" + sampleInfoProperty.get().ensemblePath;
+    }
+
+    @Override public Node getNode() {
+        return this;
+    }
+}
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SourceTab.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/SourceTab.java	Sat Nov 02 06:58:02 2013 -0700
@@ -34,27 +34,26 @@
 import ensemble.EnsembleApp;
 import ensemble.SampleInfo.URL;
 import ensemble.util.Utils;
-import javafx.scene.control.ScrollPaneBuilder;
+import ensemble.util.WebViewWrapper;
+import javafx.application.ConditionalFeature;
+import javafx.application.Platform;
+import javafx.scene.control.ScrollPane;
 import javafx.scene.control.Tab;
 import javafx.scene.control.TextArea;
-import javafx.scene.control.TextAreaBuilder;
-import javafx.scene.control.TooltipBuilder;
+import javafx.scene.control.Tooltip;
 import javafx.scene.image.Image;
-import javafx.scene.image.ImageViewBuilder;
-import javafx.scene.layout.StackPaneBuilder;
-import javafx.scene.web.WebView;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.StackPane;
+
+import java.util.regex.Pattern;
 
 /**
- *
+ * Source code tab - Shows Syntax highlighted source if web view is available if not just plain text.
  */
 class SourceTab extends Tab {
-    private URL sourceURL;
-    private final SamplePage samplePage;
 
-    public SourceTab(URL sourceURL, final SamplePage samplePage) {
+    public SourceTab(URL sourceURL) {
         super(sourceURL.getName());
-        this.samplePage = samplePage;
-        this.sourceURL = sourceURL;
         String url = sourceURL.getURL();
         String ext = url.substring(url.lastIndexOf('.')).toLowerCase();
         switch (ext) {
@@ -62,26 +61,126 @@
             case ".css":
             case ".fxml":
                 String source = Utils.loadFile(getClass().getResource(url));
-                if (EnsembleApp.IS_EMBEDDED || EnsembleApp.IS_IOS) {
+                if (EnsembleApp.IS_EMBEDDED || EnsembleApp.IS_IOS || !Platform.isSupported(ConditionalFeature.WEB)) {
                     // TODO: Convert to TextFlow
                     //                    TextFlow textFlow = TextFlowBuilder.create()
                     //                            .build();
                     //
                     //                    Reader r = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(url)));
-                    TextArea textArea = TextAreaBuilder.create().text(source).style("-fx-font-family: 'Courier New';").build();
+                    TextArea textArea = new TextArea(source);
+                    textArea.setStyle("-fx-font-family: 'Courier New';");
+                    textArea.setEditable(false);
                     setContent(textArea);
                 } else {
-                    WebView webView = new WebView();
-                    webView.getEngine().loadContent(samplePage.convertToHTML(source));
-                    setContent(webView);
+                    String html = convertToHTML(source);
+                    setContent(WebViewWrapper.createWebView(html));
                 }
                 break;
             case ".jpg":
             case ".png":
-                setContent(ScrollPaneBuilder.create().fitToHeight(true).fitToWidth(true).content(StackPaneBuilder.create().children(ImageViewBuilder.create().image(new Image(url)).build()).build()).build());
+                ImageView imageView = new ImageView(new Image(url));
+                StackPane stackPane = new StackPane(imageView);
+                ScrollPane scrollPane = new ScrollPane(stackPane);
+                scrollPane.setFitToHeight(true);
+                scrollPane.setFitToWidth(true);
+                setContent(scrollPane);
                 break;
         }
-        setTooltip(TooltipBuilder.create().text(url).build());
+        setTooltip(new Tooltip(url));
     }
-    
+
+    private static final Pattern JAVA_DOC_PATTERN = Pattern.compile("(^\\s+\\*$\\s)?^\\s+\\*\\s+@.*$\\s",Pattern.MULTILINE);
+    private static String shCoreJs;
+    private static String shBrushJScript;
+    private static String shCoreDefaultCss;
+
+    private static String convertToHTML(String source) {
+        // load syntax highlighter
+        if (shCoreJs == null) {
+            shCoreJs = Utils.loadFile(EnsembleApp.class.getResource("syntaxhighlighter/shCore.js")) +";";
+        }
+        if (shBrushJScript == null) {
+            shBrushJScript = Utils.loadFile(EnsembleApp.class.getResource("syntaxhighlighter/shBrushJava.js"));
+        }
+        if (shCoreDefaultCss == null) {
+            shCoreDefaultCss = Utils.loadFile(EnsembleApp.class.getResource("syntaxhighlighter/shCoreDefault.css")).replaceAll("!important","");
+        }
+        // split copy right and source
+        String[] parts = source.split("\\*/",2);
+        String copyRight = null;
+        if (parts.length > 1) {
+            copyRight = parts[0]+"*/";
+            source = parts[1];
+        }
+        // remove JavaDoc @xxxx lines
+        source = JAVA_DOC_PATTERN.matcher(source).replaceAll("");
+        // escape < & >
+        source = source.replaceAll("&","&amp;");
+        source = source.replaceAll("<","&lt;");
+        source = source.replaceAll(">","&gt;");
+        source = source.replaceAll("\"","&quot;");
+        source = source.replaceAll("\'","&apos;");
+        // create content
+        StringBuilder html = new StringBuilder();
+        html.append("<html>\n");
+        html.append("    <head>\n");
+        html.append("    <script type=\"text/javascript\">\n");
+        html.append(shCoreJs);
+        html.append('\n');
+        html.append(shBrushJScript);
+        html.append("    </script>\n");
+        html.append("    <style>\n");
+        html.append(shCoreDefaultCss);
+        html.append('\n');
+        html.append("        .syntaxhighlighter {\n");
+        html.append("			overflow: visible;\n");
+        if (EnsembleApp.IS_MAC) {
+            html.append("			font: 12px Ayuthaya !important; line-height: 150% !important; \n");
+            html.append("		}\n");
+            html.append("		code { font: 12px Ayuthaya !important; line-height: 150% !important; } \n");
+        } else {
+            html.append("			font: 12px monospace !important; line-height: 150% !important; \n");
+            html.append("		}\n");
+            html.append("		code { font: 12px monospace !important; line-height: 150% !important; } \n");
+        }
+        html.append("		.syntaxhighlighter .preprocessor { color: #060 !important; }\n");
+        html.append("		.syntaxhighlighter .comments, .syntaxhighlighter .comments a  { color: #009300 !important; }\n");
+        html.append("		.syntaxhighlighter .string  { color: #555 !important; }\n");
+        html.append("		.syntaxhighlighter .value  { color: blue !important; }\n");
+        html.append("		.syntaxhighlighter .keyword  { color: #000080 !important; }\n");
+        html.append("		.hidden { display: none; }\n");
+        html.append("           .showing { display: block; }\n");
+        html.append("           .button {\n");
+        html.append("               font: 12px \"Consolas\", \"Bitstream Vera Sans Mono\", \"Courier New\", Courier, monospace !important;\n");
+        html.append("               color: #009300 !important;\n");
+        html.append("               text-decoration: underline;\n");
+        html.append("               display: inline;\n");
+        html.append("               cursor:pointer;\n");
+        html.append("           }\n");
+        html.append("        body {background-color: #f4f4f4;}\n");
+        html.append("    </style>\n");
+        html.append("    </head>\n");
+        html.append("<body>\n");
+        if (copyRight != null) {
+            html.append("    <div onclick='document.getElementById(\"licenceText\").className = \"showing\";document.getElementById(\"licenseBtn\").className = \"hidden\";' id=\"licenseBtn\" class=\"button\">/* ....Show License.... */</div>\n");
+            html.append("    <div id=\"licenceText\"class=\"hidden\">\n");
+            html.append("    <pre class=\"brush: java; gutter: false; toolbar: false; quick-code: false;\">\n");
+            html.append(copyRight);
+            html.append('\n');
+            html.append("    </pre>\n");
+            html.append("    </div>\n");
+        }
+        html.append("    <pre class=\"brush: java; gutter: false; toolbar: false; quick-code: false;\">\n");
+        html.append(source);
+        html.append('\n');
+        html.append("    </pre>\n");
+        html.append("    <script type=\"text/javascript\"> SyntaxHighlighter.all(); </script>\n");
+        html.append("</body>\n");
+        html.append("</html>\n");
+
+//        System.out.println("------------------------------------------------------------");
+//        System.out.println(html);
+//        System.out.println("------------------------------------------------------------");
+        return html.toString();
+    }
 }
--- a/apps/samples/Ensemble8/src/app/java/ensemble/samplepage/Sources.java	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2008, 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 ensemble.samplepage;
-
-import ensemble.SampleInfo;
-import ensemble.sampleproject.SampleProjectBuilder;
-import java.io.File;
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.geometry.Pos;
-import javafx.scene.control.Button;
-import javafx.scene.control.ButtonBuilder;
-import javafx.scene.control.TabPane;
-import javafx.scene.control.TabPaneBuilder;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.HBoxBuilder;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.VBox;
-import javafx.stage.FileChooser;
-import javax.swing.filechooser.FileSystemView;
-
-/**
- *
- */
-public class Sources extends VBox {
-    
-    private Button copy;
-    private Button saveAsProject;
-    private HBox buttons;
-    private TabPane tabPane;
-
-    public Sources(final SamplePage samplePage) {
-        super(SamplePage.INDENT);
-        saveAsProject = ButtonBuilder.create().text("Save As Project").build();
-        saveAsProject.setOnAction(new EventHandler<ActionEvent>() {
-             @Override public void handle(ActionEvent actionEvent) {
-                 File initialDir = FileSystemView.getFileSystemView().getDefaultDirectory();
-                 FileChooser fileChooser = new FileChooser();
-                 fileChooser.setTitle("Save Netbeans Project As:");
-                 fileChooser.setInitialDirectory(initialDir);
-                 File result = fileChooser.showSaveDialog(saveAsProject.getScene().getWindow());
-                 if (result != null) {
-                     SampleProjectBuilder.createSampleProject(result, samplePage.sample);
-                 }
-             }
-         });        
-        buttons = HBoxBuilder.create().spacing(SamplePage.INDENT).alignment(Pos.BOTTOM_RIGHT).children(saveAsProject).build();
-        tabPane = TabPaneBuilder.create().minWidth(50).minHeight(50).styleClass("floating").build();
-        for (SampleInfo.URL sourceURL : samplePage.sample.getSources()) {
-            tabPane.getTabs().add(new SourceTab(sourceURL, samplePage));
-        }
-        VBox.setVgrow(tabPane, Priority.ALWAYS);
-        getChildren().setAll(buttons, tabPane);
-    }
-}
--- a/apps/samples/Ensemble8/src/app/java/ensemble/sampleproject/SampleProjectBuilder.java	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2008, 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 ensemble.sampleproject;
-
-import ensemble.SampleInfo;
-import ensemble.util.Utils;
-import java.io.*;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-import javafx.scene.Node;
-
-/**
- * Helper class to build an IDE project for a sample and open it in the IDE
- */
-public class SampleProjectBuilder {
- 
-    public static void createSampleProject(File projectDir, SampleInfo sampleInfo) {
-        String nodeLoc = Node.class.getResource("Node.class").toExternalForm();
-        String javafxrtPath = nodeLoc.substring(4, nodeLoc.indexOf('!'));
-        try {
-            File f = new File(new URI(javafxrtPath));
-            javafxrtPath = f.getAbsolutePath();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        String sep = System.getProperty("file.separator");
-        if (sep.equals("\\")) {
-            javafxrtPath = javafxrtPath.replaceAll("\\" + sep, "/");
-        }
-        // extract project name
-        String projectName = projectDir.toURI().toString();
-        projectName = projectName.substring(projectName.lastIndexOf('/') + 1);
-        // create destDir
-        projectDir.mkdirs();
-        // unzip project template
-        try {
-            ZipInputStream zipinputstream = new ZipInputStream(
-                    SampleProjectBuilder.class.getResourceAsStream("SampleProject.zip"));
-            ZipEntry zipentry;
-            while ((zipentry = zipinputstream.getNextEntry()) != null) {
-                //for each entry to be extracted
-                String entryName = zipentry.getName();
-                File entryFile = new File(projectDir, entryName);
-                if (zipentry.isDirectory()) {
-                    entryFile.mkdirs();
-                } else {
-                    // assume all are text files, load text file into string so we can process it
-                    StringBuilder sb = new StringBuilder();
-                    String line;
-                    BufferedReader reader = new BufferedReader(new InputStreamReader(zipinputstream));
-                    while ((line = reader.readLine()) != null) {
-                        sb.append(line);
-                        sb.append('\n');
-                    }
-                    String contents = sb.toString();
-                    // replace any place holders
-                    contents = contents.replaceAll("ENSEMBLESAMPLE", projectName);
-                    contents = contents.replaceAll("APPLICATIONCLASS", sampleInfo.appClass);
-                    contents = contents.replaceAll("PATHTOJAVAFXRTJAR", javafxrtPath);
-                    // save out file
-                    FileWriter fileWriter = new FileWriter(entryFile);
-                    fileWriter.write(contents);
-                    fileWriter.flush();
-                    fileWriter.close();
-                }
-                zipinputstream.closeEntry();
-            }
-            zipinputstream.close();
-            //Put resources like images under src/
-            File srcDestDir = new File(projectDir.getPath() + "/src/");
-            loadSampleResourceUrls(srcDestDir, sampleInfo.resourceUrls);
-            // open project in netbeans
-            //TODO:      loadProject(projectDir, mainSrcFile);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private static void loadSampleResourceUrls(File destDir, String[] resourceUrlArray) {
-        List<String> resourceUrlList = Arrays.asList(resourceUrlArray);
-        //create resource files for each of the resources we use
-        if (!resourceUrlList.isEmpty()) {
-            for (String oneResourceUrl : resourceUrlList) {
-                String resourceSubdir = oneResourceUrl.substring(0, oneResourceUrl.lastIndexOf('/'));
-                try {
-                    File parentDir = new File(destDir.getPath() + resourceSubdir);
-                    parentDir.mkdirs();
-                    Utils.copyFile(new URL(SampleProjectBuilder.class.getResource(oneResourceUrl).toExternalForm()),
-                            destDir.getPath() + oneResourceUrl);
-
-                } catch (MalformedURLException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/samples/Ensemble8/src/app/java/ensemble/util/WebViewWrapper.java	Sat Nov 02 06:58:02 2013 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package ensemble.util;
+
+
+import javafx.scene.Node;
+import javafx.scene.web.WebView;
+
+
+public class WebViewWrapper {
+
+    public static Node createWebView(String html) {
+        WebView webView = new WebView();
+        webView.getEngine().loadContent(html);
+        return webView;
+    }
+
+}
--- a/apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesCaspian.css	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2008, 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.
- */
-.ensmeble-tool-bar {
-    -fx-padding: 6 5 7 5;
-    -fx-background-color: linear-gradient(
-        to bottom,
-        derive(-fx-color,34%) 0%,
-        derive(-fx-color,-18%) 98%,
-        derive(-fx-color,-60%) 100%
-    );
-    -fx-base: #58636a;
-    -fx-background: #58636a;
-    -fx-shadow-highlight-color: rgba(255,255,255,0.2);
-    -fx-outer-border: linear-gradient(
-        to bottom,
-        derive(-fx-color,-9%) 0%, 
-        derive(-fx-color,-45%) 100%
-    );
-}
-.ensmeble-tool-bar .title {
-    -fx-font-family: "Arial";
-    -fx-font-weight: bold;
-    -fx-font-size: 20;
-    -fx-text-fill: white;
-}
-.ensmeble-tool-bar #back{
-    -fx-background-radius: 5 0 0 5, 5 0 0 5, 4 0 0 4, 3 0 0 3;
-    -fx-content-display: graphic-only;
-}
-.ensmeble-tool-bar #back:focused {
-    -fx-background-radius: 6.4 0 0 6.4, 5 0 0 5, 4 0 0 4, 3 0 0 3;
-    -fx-background-insets: -1.4 0 -1.4 -1.4, 0 1 0 0, 1, 2;
-}
-.ensmeble-tool-bar #forward {
-    -fx-background-insets: 0 0 -1 0, 0, 1 1 1 0, 2 2 2 1;
-    -fx-background-radius: 0;
-}
-.ensmeble-tool-bar #forward:focused {
-    -fx-background-insets: 0 0 -1 0, 0, 1 1 1 0, 2 2 2 1;
-    -fx-background-radius: 0;
-    -fx-background-insets: -1.4 0 -1.4 0, 0 1 0 1, 1 1 1 1, 2 2 2 2;
-}
-.ensmeble-tool-bar #home {
-    -fx-background-insets: 0 0 -1 0, 0, 1 1 1 0, 2 2 2 1;
-    -fx-background-radius: 0 5 5 0, 0 5 5 0, 0 4 4 0, 0 3 3 0;
-}
-.ensmeble-tool-bar #home:focused {
-    -fx-background-insets: -1.4 -1.4 -1.4 0, 0 1 0 1, 1 1 1 1, 2 2 2 1;
-    -fx-background-radius: 0 6.4 6.4 0, 0 5 5 0, 0 4 4 0, 0 3 3 0;
-}
-.ensmeble-tool-bar .button Region, .ensmeble-tool-bar .toggle-button Region {
-    -fx-background-color: white;
-    -fx-scale-shape: false;
-}
-.ensmeble-tool-bar #back Region{
-    -fx-shape: "M0,7L11,0L11,14Z";
-}
-.ensmeble-tool-bar #forward Region{
-    -fx-shape: "M0,0L11,7L0,14Z";
-}
-.ensmeble-tool-bar #home Region{
-    -fx-shape: "M1,8.239V14h3.5V7.5h4V14H12V8.239L6.5,3L1,8.239z M11,4.5V1H9.1L9.062,2.448L6.5,0L0,6.5v0.7h0.5l6-5.826l6,5.826H13V6.5L11,4.5z";
-}
-.ensmeble-tool-bar #list Region{
-    -fx-shape: "M1,2h14c0.553,0,1-0.448,1-1s-0.447-1-1-1H1C0.448,0,0,0.448,0,1S0.448,2,1,2zM15,5.875H1c-0.552,0-1,0.448-1,1c0,0.553,0.448,1,1,1h14c0.553,0,1-0.447,1-1C16,6.323,15.553,5.875,15,5.875z M15,11.75H1c-0.552,0-1,0.447-1,1s0.448,1,1,1h14c0.553,0,1-0.447,1-1S15.553,11.75,15,11.75z";
-}
-.ensmeble-tool-bar #search{
-    -fx-padding: 3 10 3 15 !important;
-}
-.ensmeble-tool-bar #search Region{
-    -fx-shape: "M13.814,13.386l-3.396-3.398c0.953-1.059,1.533-2.462,1.533-4c0-3.305-2.678-5.982-5.981-5.982c-3.304,0-5.982,2.678-5.982,5.982S2.666,11.97,5.97,11.97c1.052,0,2.042-0.271,2.899-0.748l3.555,3.555L13.814,13.386zM1.975,5.988c0-2.207,1.789-3.995,3.995-3.995c2.206,0,3.995,1.788,3.995,3.995c0,2.205-1.789,3.996-3.995,3.996C3.764,9.984,1.975,8.193,1.975,5.988z";
-}
-/* style Sample Buttons on the home page */
-.search-box {
-    -fx-background-color: rgba(255,255,255,0.3) , #41494e;
-    -fx-background-insets: 1 0 -1 0,0;
-    -fx-background-radius: 18;
-    -fx-padding: 0 0 0 30;
-}
-.search-box:focused {
-    -fx-background-color: -fx-focus-color;
-    -fx-background-insets: -0.4px;
-}
-.search-box-icon {
-    /* THIN -fx-shape: "M14,13.587l-3.45-3.45c0.968-1.076,1.558-2.5,1.558-4.062C12.107,2.72,9.388,0,6.032,0C2.676,0-0.043,2.72-0.043,6.075s2.72,6.075,6.075,6.075c1.069,0,2.074-0.276,2.946-0.761l3.61,3.609L14,13.587z M1.975,6.075c0-2.24,1.816-4.057,4.057-4.057c2.241,0,4.057,1.817,4.057,4.057c0,2.241-1.816,4.058-4.057,4.058C3.791,10.133,1.975,8.316,1.975,6.075z";*/
-    /* TOO BOLD -fx-shape: "M10.871,9.796c0.826-1.062,1.275-2.368,1.275-3.723C12.146,2.724,9.422,0,6.073,0C2.725,0,0,2.724,0,6.073c0,3.349,2.725,6.072,6.073,6.072c0.913,0,1.816-0.206,2.633-0.599l3.422,3.421l1.957-1.957L10.871,9.796z M6.073,2.788c1.812,0,3.286,1.474,3.286,3.285S7.884,9.358,6.073,9.358S2.788,7.885,2.788,6.073S4.261,2.788,6.073,2.788z";*/
-    -fx-shape: "M10.728,9.893c0.889-1.081,1.375-2.435,1.375-3.842C12.103,2.714,9.388,0,6.051,0C2.715,0,0,2.714,0,6.051c0,3.338,2.715,6.052,6.051,6.052c0.954,0,1.898-0.227,2.744-0.656l3.479,3.478l1.743-1.742L10.728,9.893z M6.051,2.484c1.966,0,3.566,1.602,3.566,3.566c0,1.968-1.6,3.567-3.566,3.567c-1.967,0-3.566-1.6-3.566-3.567C2.485,4.086,4.084,2.484,6.051,2.484z";
-    -fx-scale-shape: false;
-    -fx-background-color: #aaaaaa;
-}
-.search-box-inner {
-    -fx-background-color: white;
-    -fx-background-insets: 1;
-    -fx-background-radius: 17;
-}
-
-/* *****************************************************************************
-   * POPOVERS
-   ****************************************************************************/
-.popover .button {
-    -fx-base: #58636a;
-    -fx-background: #58636a;
-    -fx-shadow-highlight-color: rgba(255,255,255,0.2);
-    -fx-outer-border: linear-gradient(
-        to bottom,
-        derive(-fx-color,-30%) 0%, 
-        derive(-fx-color,-50%) 100%
-    );
-    -fx-padding: 5 10 5 10;
-    -fx-font-weight: bold;
-    -fx-text-fill: white;
-}
-.popover-tree-list-cell {
-    -fx-background-color: white;
-    -fx-border-color: transparent transparent #dfdfdf transparent;
-    -fx-padding: 0 30 0 12;
-    -fx-font-family: "Arial";
-    -fx-font-size: 15px;
-    -fx-font-weight: bold;
-    -fx-text-fill: #363636;
-}
--- a/apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesCaspianDesktop.css	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2008, 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.
- */
-.ensmeble-tool-bar .title {
-    -fx-effect: dropshadow( three-pass-box , #3d4346 , 0 , 0 , 0 , -1 );
-}
-.ensmeble-tool-bar .button Region, .ensmeble-tool-bar .toggle-button Region {
-    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.8) , 0 , 0 , 0 , -1 );
-}
-.sample-button:hover {
-    -fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.8) , 10, 0.5 , 0 , 0);
-}
-.sample-button:focused {
-    -fx-effect: dropshadow( three-pass-box , -fx-focus-color , 3, 0.5 , 0 , 0);
-}
-.search-box-inner {
-    -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7) , 7, 0 , 0 , 1 );
-}
\ No newline at end of file
--- a/apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesCommon.css	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesCommon.css	Sat Nov 02 06:58:02 2013 -0700
@@ -29,270 +29,72 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
- 
-/* *****************************************************************************
-   * CUSTOM SCROLLBARS
-   ****************************************************************************/
-/* popover scroll bars */
-.popover .scroll-bar:horizontal {
-    -fx-background-color: white;
-    -fx-padding: 4px 2px 6px 2px;
-}
-.popover .scroll-bar:vertical {
-    -fx-background-color: white;
-    -fx-padding: 2px 6px 2px 4px;
-}
-.popover .scroll-bar > .thumb {
-    -fx-background-color: #777, #f9f9f9;
-    -fx-background-insets: -1, 0;
-    -fx-opacity: 0.8;
-}
-.popover .scroll-bar > .thumb:hover {
-    -fx-opacity: 1;
-}
-.popover .scroll-bar > .track {
-    -fx-background-color: #eee;
-}
-.popover .scroll-bar:horizontal > .increment-button, 
-.popover .scroll-bar:horizontal > .decrement-button {
-    -fx-background-color: null;
-    -fx-padding: 2px 0 2px 0;
-}
-.popover .scroll-bar:vertical > .increment-button, 
-.popover .scroll-bar:vertical > .decrement-button {
-    -fx-background-color: null;
-    -fx-padding: 0 2px 0 2px;
-}
-.popover .scroll-bar > .decrement-button > .decrement-arrow, 
-.popover .scroll-bar > .increment-button > .increment-arrow,
-.popover .scroll-bar > .track-background{
-    -fx-background-color: null;
-    -fx-shape: null;
-}
-/* homepage scroll bars */
-#HomePage .scroll-bar:horizontal {
-    -fx-background-color: null;
-    -fx-padding: 6px 2px 6px 2px;
-}
-#HomePage .scroll-bar:vertical {
-    -fx-background-color: null;
-    -fx-padding: 2px 6px 2px 6px;
-}
-#HomePage .scroll-bar > .thumb {
-    -fx-background-color: #333, #f9f9f9;
-    -fx-background-insets: -1, 0;
-    -fx-opacity: 0.8;
-}
-#HomePage .scroll-bar > .thumb:hover {
-    -fx-opacity: 1;
-}
-#HomePage .scroll-bar > .track {
-    -fx-background-color: #38434b;
-}
-#HomePage .scroll-bar:horizontal > .increment-button, 
-#HomePage .scroll-bar:horizontal > .decrement-button {
-    -fx-background-color: null;
-    -fx-padding: 2px 0 2px 0;
-}
-#HomePage .scroll-bar:vertical > .increment-button, 
-#HomePage .scroll-bar:vertical > .decrement-button {
-    -fx-background-color: null;
-    -fx-padding: 0 2px 0 2px;
-}
-#HomePage .scroll-bar > .decrement-button > .decrement-arrow, 
-#HomePage .scroll-bar > .increment-button > .increment-arrow,
-#HomePage .scroll-bar > .track-background{
-    -fx-background-color: null;
-    -fx-shape: null;
-}
-/* source code scroll bars */
-.sample-back-page .scroll-bar:horizontal {
-    -fx-background-color: white;
-    -fx-padding: 4px 2px 6px 2px;
-}
-.sample-back-page .scroll-bar:vertical {
-    -fx-background-color: white;
-    -fx-padding: 2px 6px 2px 4px;
-}
-.sample-back-page .scroll-bar > .thumb {
-    -fx-background-color: #777, #f9f9f9;
-    -fx-background-insets: -1, 0;
-    -fx-opacity: 0.8;
-}
-.sample-back-page .scroll-bar > .thumb:hover {
-    -fx-opacity: 1;
-}
-.sample-back-page .scroll-bar > .track {
-    -fx-background-color: #eee;
-}
-.sample-back-page .scroll-bar:horizontal > .increment-button, 
-.sample-back-page .scroll-bar:horizontal > .decrement-button {
-    -fx-background-color: null;
-    -fx-padding: 2px 0 2px 0;
-}
-.sample-back-page .scroll-bar:vertical > .increment-button, 
-.sample-back-page .scroll-bar:vertical > .decrement-button {
-    -fx-background-color: null;
-    -fx-padding: 0 2px 0 2px;
-}
-.sample-back-page .scroll-bar > .decrement-button > .decrement-arrow, 
-.sample-back-page .scroll-bar > .increment-button > .increment-arrow,
-.sample-back-page .scroll-bar > .track-background{
-    -fx-background-color: null;
-    -fx-shape: null;
-}
 
 /* *****************************************************************************
    * HOME PAGE
    ****************************************************************************/
-#HomePage {
-    /*-fx-background-size: cover;*/
-    -fx-background-size: 100% 100%;
-    -fx-background-image: url("images/home-background.png");
-}
-.home-page-cell {
-    -fx-padding: 10 0 10 0;
-}
 #HomePage .pagination {
     -fx-arrows-visible: false;
     -fx-page-information-visible: false;
 }
-#HomePage .pagination > .pagination-control > .control-box > .bullet-button {   
-    -fx-background-color: transparent;
-    -fx-background-image: url("images/pagination-dot.png");
-    -fx-background-repeat: no-repeat;
-    -fx-background-position: center;
+.section-ribbon-text {
+    -fx-font-family: "Source Sans Pro ExtraLight";
+    -fx-font-size: 36;
+    -fx-fill: white;
 }
-
-#HomePage .pagination > .pagination-control > .control-box > .bullet-button:selected {   
-    -fx-background-image: url("images/pagination-dot-selected.png");
+.home-page-cell:Title {
+    -fx-background-color: #f3472f;
+    -fx-background-insets: 10 0 10 0;
 }
-/* style Section Ribbons on the home page */
-.section-ribbon {
-    -fx-border-image-source: url("images/section-ribbon.png");
-    -fx-border-image-slice: 0 38 0 38 fill;
-    -fx-border-image-width: 0 38 0 38;
-    -fx-border-image-repeat: repeat-x;
-}
-/* style Sample Buttons on the home page */
 .sample-button {
-    -fx-font-family: "Arial";
-    -fx-font-weight: bold;
-    -fx-font-size: 15;
-    -fx-text-fill: white;
-    -fx-graphic-text-gap: 8px;
+    -fx-font-family: "Source Sans Pro";
+    -fx-font-size: 14;
+    -fx-padding: 5px;
+    -fx-text-fill: #777777; 
+    -fx-graphic-text-gap: 8px; 
 }
 .sample-large-preview {
-    -fx-border-image-source: url("images/tile-border.png");
-    -fx-border-image-slice: 7 9 10 7;
-    -fx-border-image-width: 7 9 10 7;
-    -fx-border-image-insets: -2 -4 -5 -2;
-    -fx-border-image-repeat: stretch;
-    -fx-padding: 5px;
-}
-.sample-large-preview-label {
-    -fx-font-weight: bold;
-    -fx-font-size: 17;
-    -fx-text-fill: #555;
-}
-.sample-medium-preview {
-    -fx-border-image-source: url("images/tile-border.png");
-    -fx-border-image-slice: 7 9 10 7;
-    -fx-border-image-width: 7 9 10 7;
-    -fx-border-image-insets: -2 -4 -5 -2;
-    -fx-border-image-repeat: stretch;
-}
-.search-box {
-    -fx-font-family: "Arial";
-    -fx-font-size: 16px;
-    -fx-text-fill: #363636;
-}
-.search-clear-button {
-    -fx-shape: "M9.521,0.083c-5.212,0-9.438,4.244-9.438,9.479c0,5.234,4.225,9.479,9.438,9.479c5.212,0,9.437-4.244,9.437-9.479C18.958,4.327,14.733,0.083,9.521,0.083z M13.91,13.981c-0.367,0.369-0.963,0.369-1.329,0l-3.019-3.03l-3.019,3.03c-0.367,0.369-0.962,0.369-1.329,0c-0.367-0.368-0.366-0.965,0.001-1.334l3.018-3.031L5.216,6.585C4.849,6.217,4.849,5.618,5.217,5.25c0.366-0.369,0.961-0.368,1.328,0l3.018,3.031l3.019-3.031c0.366-0.368,0.961-0.369,1.328,0c0.366,0.368,0.366,0.967,0,1.335l-3.019,3.031l3.02,3.031C14.276,13.017,14.276,13.613,13.91,13.981z";
-    -fx-scale-shape: false;
-    -fx-background-color: #aaaaaa;
-    -fx-padding: 9.5px;
+    -fx-background-color: white;
+    -fx-padding: 10px;
 }
 
 /* *****************************************************************************
    * DOCS PAGE
    ****************************************************************************/
 .sidebar-title {
-    -fx-font-family: "Arial";
-    -fx-font-weight: bold;
-    -fx-font-size: 17;
-    -fx-text-fill: white;
+    -fx-font-family: "Source Sans Pro Semibold";
+    -fx-font-size: 16 !important;
+    -fx-text-fill: #e1731c;
 }
 
 /* *****************************************************************************
    * SAMPLE PAGE
    ****************************************************************************/
-/*.sample-page {
-    -fx-background-color: #eeeeee;
-    -fx-background-image: url("images/home-background.png");
-}*/
-.sample-page-iphone {
-    -fx-background-color: #eeeeee;
-    -fx-background-image: url("images/sample-background.png");
-    -fx-background-size: stretch;
-}
-.sample-page-front {
-    -fx-background-image: url("images/sample-page-background.png");
-    -fx-border-image-source: url("images/sample-page-background-shadow.png");
-    -fx-border-image-slice: 160;
-    -fx-border-image-width: 160;
-    -fx-border-image-repeat: stretch;
-}
-.sample-back-page {
-    -fx-background-image: url("images/sample-back-page-background.png"), url("images/sample-source-text.png");
-    -fx-background-position: left top, right bottom;
-    -fx-background-repeat: repeat, no-repeat;
-    -fx-border-image-source: url("images/sample-page-background-shadow.png");
-    -fx-border-image-slice: 160;
-    -fx-border-image-width: 160;
-    -fx-border-image-repeat: stretch;
-    -fx-base: #3d80ba;
-    -fx-shadow-highlight-color: rgba(255,255,255,0.1);
-    -fx-text-background-color: white;
-}
-.sample-back-page .tab:selected > .tab-container > .tab-label {
-    -fx-text-fill: #395d74 !important;
-}
 .sample-page-box {
-/*    -fx-border-image-source: url("images/sample-box.png");
-    -fx-border-image-slice: 7 7 9 7 fill;
-    -fx-border-image-width: 7 7 9 7;
-    -fx-border-image-insets: -1 -2 -3 -2;
-    -fx-border-image-repeat: stretch;*/
-    -fx-border-image-source: url("images/sample-paper-border.png");
-    -fx-border-image-slice: 6;
-    -fx-border-image-width: 6;
-    -fx-border-image-insets: -2 -5 -5 -2;
-    -fx-border-image-repeat: stretch;
-    -fx-padding: 5 10 5 33;
-    
-    -fx-background-image: url("images/sample-paper.png") , url("images/sample-paper-lines.png");
-    
-    -fx-font-family: "Arial";
+    -fx-padding: 8;
     -fx-font-size: 12px;
-    -fx-font-weight: bold;
-    -fx-text-background-color: #395d74;
+    /*-fx-text-background-color: #395d74;*/
 }
 .sample-page-box .hyperlink{
     -fx-font-size: 12px;
     -fx-text-overrun: leading-word-ellipsis;
 }
 .sample-page-box-title {
-    -fx-font-family: "Bree Serif";
-    -fx-font-size: 16;
+    -fx-font-family: "Source Sans Pro Semibold";
+    -fx-font-size: 16 !important;
     -fx-text-fill: #e1731c;
+    -fx-fill: #e1731c;
+    -fx-padding: 0;
+}
+.sample-container {
+    -fx-background-color: -fx-background; /* give sample area a solid color for occlusion culling */
 }
 
 /* *****************************************************************************
    * POPOVERS
    ****************************************************************************/
 .popover {
-    -fx-padding: 44 7 7 7; 
+    -fx-padding: 44 7 7 7;
 }
 .popover-frame {
     -fx-border-image-source: url("images/popover-empty.png");
@@ -305,58 +107,54 @@
     -fx-border-image-width: 78 120 60 50;
 }
 .popover-title {
-    -fx-font-family: "Arial";
+    /*-fx-font-family: "Bree serif"; */
+    -fx-font-family: "Source Sans Pro Light";
     -fx-font-size: 20px;
-    -fx-text-fill: white;
-    -fx-font-weight: bold;
+ /*   -fx-text-fill: white;
+    -fx-font-weight: bold; */
 }
 .popover-tree-list-cell {
     -fx-background-color: white;
-    -fx-border-color: transparent transparent #dfdfdf transparent;
+   /*  -fx-border-color: transparent transparent #dfdfdf transparent; */
     -fx-padding: 0 30 0 12;
-    -fx-font-family: "Arial";
+    /*-fx-font-family: "Bree Serif"; */
     -fx-font-size: 15px;
-    -fx-font-weight: bold;
+ /*   -fx-font-weight: bold; */
     -fx-text-fill: #363636;
 }
-#PopoverBackground {
+/* #PopoverBackground {
     -fx-background-color: grey;
-}
+} */
 .search-result-cell {
     -fx-background-color: white;
     -fx-padding: 4 30 4 45;
 }
 .search-result-cell:selected {
-    -fx-background-color: white, #eeeeee;
+  /*   -fx-background-color: white, #eeeeee; */
     -fx-background-insets: 0, 0 0 0 40;
 }
 .search-result-cell .title {
-    -fx-font-family: "Arial";
+    /*-fx-font-family: "Bree Serif"; */
     -fx-font-size: 15px;
-    -fx-font-weight: bold;
+  /*  -fx-font-weight: bold; */
     -fx-text-fill: #363636;
 }
 .search-result-cell .details {
-    -fx-font-family: "Arial";
     -fx-font-size: 13px;
     -fx-text-fill: #444444;
 }
 .search-icon-pane .label {
-    -fx-font-family: "Arial";
+    -fx-font-family: "Source Sans Pro Light";
     -fx-font-size: 16px;
-    -fx-font-weight: bold;
     -fx-background-color: #515151;
     -fx-background-radius: 3px;
-    -fx-text-fill: white;
     -fx-alignment: center;
 }
 .sample-tree-list-cell {
     -fx-background-color: white;
-    -fx-border-color: transparent transparent #dfdfdf transparent;
+    -fx-border-color: transparent transparent #dfdfdf transparent; 
     -fx-padding: 0 30 0 20;
-    -fx-font-family: "Arial";
     -fx-font-size: 15px;
-    -fx-font-weight: bold;
     -fx-text-fill: #363636;
     -fx-graphic-text-gap: 20px;
 }
@@ -379,3 +177,54 @@
     -fx-scale-shape: false;
     -fx-background-color: #515151;
 }
+
+.ensmeble-tool-bar .title {
+    -fx-font-family: "Source Sans Pro Light";
+    -fx-font-size: 20;
+    -fx-text-fill: #666;
+}
+.ensmeble-tool-bar .button Region, .ensmeble-tool-bar .toggle-button Region {
+    -fx-background-color: #666666;
+    -fx-scale-shape: false;
+}
+.ensmeble-tool-bar #back Region{
+    -fx-shape: "M0,7L11,0L11,14Z";
+}
+.ensmeble-tool-bar #forward Region{
+    -fx-shape: "M0,0L11,7L0,14Z";
+}
+.ensmeble-tool-bar #home Region{
+    -fx-shape: "M1,8.239V14h3.5V7.5h4V14H12V8.239L6.5,3L1,8.239z M11,4.5V1H9.1L9.062,2.448L6.5,0L0,6.5v0.7h0.5l6-5.826l6,5.826H13V6.5L11,4.5z";
+}
+.ensmeble-tool-bar #list Region{
+    -fx-shape: "M1,2h14c0.553,0,1-0.448,1-1s-0.447-1-1-1H1C0.448,0,0,0.448,0,1S0.448,2,1,2zM15,5.875H1c-0.552,0-1,0.448-1,1c0,0.553,0.448,1,1,1h14c0.553,0,1-0.447,1-1C16,6.323,15.553,5.875,15,5.875z M15,11.75H1c-0.552,0-1,0.447-1,1s0.448,1,1,1h14c0.553,0,1-0.447,1-1S15.553,11.75,15,11.75z";
+}
+.search-box-icon {
+    -fx-shape: "M10.728,9.893c0.889-1.081,1.375-2.435,1.375-3.842C12.103,2.714,9.388,0,6.051,0C2.715,0,0,2.714,0,6.051c0,3.338,2.715,6.052,6.051,6.052c0.954,0,1.898-0.227,2.744-0.656l3.479,3.478l1.743-1.742L10.728,9.893z M6.051,2.484c1.966,0,3.566,1.602,3.566,3.566c0,1.968-1.6,3.567-3.566,3.567c-1.967,0-3.566-1.6-3.566-3.567C2.485,4.086,4.084,2.484,6.051,2.484z";
+    -fx-scale-shape: false;
+    -fx-background-color: #aaaaaa;
+}
+.search-box {
+    -fx-font-size: 16px;
+    -fx-text-fill: #363636;
+    -fx-background-radius: 15, 14;
+    -fx-padding: 0 0 0 30;
+}
+.search-box:focused {
+    -fx-background-radius: 15,14,16,0;
+}
+.search-clear-button {
+    -fx-shape: "M9.521,0.083c-5.212,0-9.438,4.244-9.438,9.479c0,5.234,4.225,9.479,9.438,9.479c5.212,0,9.437-4.244,9.437-9.479C18.958,4.327,14.733,0.083,9.521,0.083z M13.91,13.981c-0.367,0.369-0.963,0.369-1.329,0l-3.019-3.03l-3.019,3.03c-0.367,0.369-0.962,0.369-1.329,0c-0.367-0.368-0.366-0.965,0.001-1.334l3.018-3.031L5.216,6.585C4.849,6.217,4.849,5.618,5.217,5.25c0.366-0.369,0.961-0.368,1.328,0l3.018,3.031l3.019-3.031c0.366-0.368,0.961-0.369,1.328,0c0.366,0.368,0.366,0.967,0,1.335l-3.019,3.031l3.02,3.031C14.276,13.017,14.276,13.613,13.91,13.981z";
+    -fx-scale-shape: false;
+    -fx-background-color: #aaaaaa;
+    -fx-padding: 9.5px;
+}
+
+
+/* *****************************************************************************
+   * POPOVERS
+   ****************************************************************************/
+.popover-tree-list-cell {
+    -fx-background-color: white;
+    -fx-font-size: 15px;
+}
--- a/apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesCommonDesktop.css	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2008, 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.
- */
-
-.sample-back-page .scroll-bar > .track,
-.popover .scroll-bar > .track { 
-    -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.2) , 8, 0.5 , 0 , 0 );
-}
-#HomePage .scroll-bar:horizontal {
-    -fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.15) , 0, 0.5 , 0 , 1 );
-}
-#HomePage .scroll-bar:vertical {
-    -fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.15) , 0, 0.5 , 1 , 0 );
-}
-#HomePage .scroll-bar > .track {
-    -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.5) , 8, 0.5 , 0 , 0 );
-}
-.sidebar-title,
-.sample-button > .text {
-    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.8) , 3, 0.5 , 0 , 1 );
-}
-.sample-large-preview-label {
-    -fx-effect: dropshadow( one-pass-box , white , 0, 0 , 0 , 1 );
-}
\ No newline at end of file
--- a/apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesHelvetica.css	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * 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.
- */
-
-.ensmeble-tool-bar .title {
-    -fx-font-family: "Helvetica";
-}
-.sample-button {
-    -fx-font-family: "Helvetica";
-}
-.sidebar-title {
-    -fx-font-family: "Helvetica";
-}
-.sample-page-box {
-    -fx-font-family: "Helvetica";
-}
-.popover-title {
-    -fx-font-family: "Helvetica";
-}
-.popover-tree-list-cell {
-    -fx-font-family: "Helvetica";
-}
-.popover-left-button {
-    -fx-font-family: "Helvetica";
-}
-.popover-right-button {
-    -fx-font-family: "Helvetica";
-}
\ No newline at end of file
--- a/apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesIOS.css	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * 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.
- */
-.ensmeble-tool-bar {
-    -fx-padding: 7 5 7 5;
-    -fx-background-image: url("images-ios/toolbar.png");
-    -fx-background-size: cover;
-    -fx-base: #58636a;
-    -fx-background: #58636a;
-    -fx-shadow-highlight-color: rgba(255,255,255,0.2);
-    -fx-outer-border: linear-gradient(
-        to bottom,
-        derive(-fx-color,-9%) 0%, 
-        derive(-fx-color,-45%) 100%
-    );
-}
-.ensmeble-tool-bar .title {
-    -fx-font-family: "Helvetica";
-    -fx-font-weight: bold;
-    -fx-font-size: 20;
-    -fx-text-fill: white;
-    -fx-padding: 3 0 0 0;
-}
-.ensmeble-tool-bar .button, .ensmeble-tool-bar .toggle-button {
-    -fx-background-size: cover;
-    -fx-background-color: null;
-}
-.ensmeble-tool-bar #back {
-    -fx-background-image: url("images-ios/back-btn.png");
-}
-.ensmeble-tool-bar #forward {
-    -fx-background-image: url("images-ios/forward-btn.png");
-}
-.ensmeble-tool-bar #home {
-    -fx-background-image: url("images-ios/home-btn.png");
-}
-.ensmeble-tool-bar #list {
-    -fx-background-image: url("images-ios/list-btn.png");
-}
-.ensmeble-tool-bar #search {
-    -fx-background-image: url("images-ios/search-btn.png");
-}
-/* ****** SCROLL BARS ******************************************************************************* */
-.scroll-bar, .scroll-bar:focused {
-    -fx-background-color: transparent;
-    -fx-background-insets: 0;
-    -fx-padding: 0 0 0 0;
-}
-.scroll-bar .thumb {
-    -fx-padding: 2;
-    -fx-background-color: rgba(0,0,0,0.3);
-    -fx-background-insets: 0;
-    -fx-background-radius: 10;
-}
-.scroll-bar .track, .scroll-bar:focused .track  {
-    -fx-background-color: null;
-    -fx-background-insets:  0;
-    -fx-background-radius: 0;
-}
-.scroll-bar .increment-button {
-    -fx-background-color: null;
-}
-.scroll-bar:horizontal .increment-button {
-    -fx-padding: -4 0 0 0;
-}
-.scroll-bar:vertical .increment-button {
-    -fx-padding: 0 0 0 -4;
-}
-.scroll-bar .decrement-button, .scroll-bar .increment-arrow, .scroll-bar .decrement-arrow {
-    -fx-background-color: null;
-    -fx-padding: 0;
-}
-.search-box {
-    -fx-border-image-source: url("images-ios/search.png");
-    -fx-border-image-slice: 0 15 0 30 fill;
-    -fx-border-image-width: 0 15 0 30;
-    -fx-padding: 0 50 0 0; 
-    -fx-prompt-text-fill: #b4b3b4;
-    -fx-text-fill: black;
-    -fx-cursor: text;
-    -fx-border-color: null;
-}
-
-/* *****************************************************************************
-   * POPOVERS
-   ****************************************************************************/
-.popover-frame {
-    -fx-border-image-source: url("images-ios/popover-empty.png");
-}
-.popover .button {
-    -fx-background-color: null;
-    -fx-padding: 5 10 5 10;
-    -fx-border-image-slice: 0 5 0 5 fill;
-    -fx-border-image-width: 0 5 0 5;
-    -fx-font-weight: bold;
-    -fx-text-fill: white;
-}   
-.popover-left-button {
-    -fx-border-image-source: url("images-ios/popover-blue-btn.png");
-}
-.popover-right-button {
-    -fx-border-image-source: url("images-ios/popover-light-blue-btn.png");
-}
\ No newline at end of file
--- a/apps/samples/Ensemble8/src/app/resources/ensemble/EnsembleStylesIOSDesktop.css	Thu Oct 31 17:45:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * 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.
- */
-.ensmeble-tool-bar .title {
-    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.8) , 0 , 0 , 0 , -1 );
-}
-.popover-right-button .text,
-.popover-left-button .text {
-    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.9) , 0, 0.0 , 0 , -1 );
-}
\ No newline at end of file
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/back-btn.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/back-btn@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/forward-btn.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/forward-btn@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/home-btn.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/home-btn@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/list-btn.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/list-btn@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-blue-btn.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-blue-btn@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-empty.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-empty@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-light-blue-btn.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/popover-light-blue-btn@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/search-btn.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/search-btn@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/search.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/search@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/toolbar.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images-ios/toolbar@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/Duke-Lego3.jpg has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/corner-bottom.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/corner-top.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/highlights-ribbon.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/highlights-ribbon@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/home-background.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/home-background@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/orange-arrrow.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/orange-arrrow@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/pagination-dot-selected.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/pagination-dot-selected@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/pagination-dot.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/pagination-dot@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/popover-empty.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/popover-empty@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-back-page-background.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-box.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-box@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-page-background-shadow.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-page-background.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-paper-border.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-paper-lines.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-paper.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-source-text.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/sample-source-text@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/section-ribbon.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/section-ribbon@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/tile-border.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/images/tile-border@2x.png has changed
Binary file apps/samples/Ensemble8/src/app/resources/ensemble/sampleproject/SampleProject.zip has changed
--- a/apps/samples/Ensemble8/src/app/resources/ensemble/syntaxhighlighter/shCoreDefault.css	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/app/resources/ensemble/syntaxhighlighter/shCoreDefault.css	Sat Nov 02 06:58:02 2013 -0700
@@ -226,13 +226,13 @@
 }
 
 .syntaxhighlighter {
-  background-color: white !important;
+  background-color: #f4f4f4 !important;
 }
 .syntaxhighlighter .line.alt1 {
-  background-color: white !important;
+  background-color: #f4f4f4 !important;
 }
 .syntaxhighlighter .line.alt2 {
-  background-color: white !important;
+  background-color: #f4f4f4 !important;
 }
 .syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
   background-color: #e0e0e0 !important;
@@ -261,7 +261,7 @@
 }
 .syntaxhighlighter.collapsed .toolbar {
   color: blue !important;
-  background: white !important;
+  background: #f4f4f4 !important;
   border: 1px solid #6ce26c !important;
 }
 .syntaxhighlighter.collapsed .toolbar a {
@@ -271,12 +271,12 @@
   color: red !important;
 }
 .syntaxhighlighter .toolbar {
-  color: white !important;
+  color: #f4f4f4 !important;
   background: #6ce26c !important;
   border: none !important;
 }
 .syntaxhighlighter .toolbar a {
-  color: white !important;
+  color: #f4f4f4 !important;
 }
 .syntaxhighlighter .toolbar a:hover {
   color: black !important;
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/timeline/timelineevents/TimelineEventsApp.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/animation/timeline/timelineevents/TimelineEventsApp.java	Sat Nov 02 06:58:02 2013 -0700
@@ -41,6 +41,7 @@
 import javafx.scene.Parent;
 import javafx.scene.Scene;
 import javafx.scene.effect.Lighting;
+import javafx.scene.layout.Pane;
 import javafx.scene.layout.StackPane;
 import javafx.scene.paint.Color;
 import javafx.scene.shape.Circle;
@@ -103,7 +104,7 @@
         EventHandler<ActionEvent> onFinished = new EventHandler<ActionEvent>() {
             @Override
             public void handle(ActionEvent t) {
-                 stack.setTranslateX(java.lang.Math.random()*200-100);
+                 stack.setTranslateX(java.lang.Math.random() * 200);
                  //reset counter
                  i = 0;
             }
@@ -111,7 +112,10 @@
         KeyFrame keyFrame = new KeyFrame(duration, onFinished , keyValueX, keyValueY);
         //add the keyframe to the timeline
         timeline.getKeyFrames().add(keyFrame);
-        return stack;
+        Pane pane = new Pane(stack);
+        pane.setPrefSize(260, 60);
+        pane.setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE);
+        return pane;
     }
 
      public void play() {
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/canvas/fireworks/FireworksApp.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/canvas/fireworks/FireworksApp.java	Sat Nov 02 06:58:02 2013 -0700
@@ -44,13 +44,17 @@
  * @preview preview.png
  *
  * @see javafx.scene.canvas.Canvas
+ * @see javafx.animation.AnimationTimer
+ * @see javafx.scene.paint.RadialGradient
+ * @see javafx.scene.effect.BlendMode
  * @see javafx.scene.canvas.GraphicsContext
- * @see javafx.scene.effect.BlendMode
- * @see javafx.scene.effect.BoxBlur
- * @see javafx.scene.shape.Circle
- * @see javafx.scene.Group
- * @see javafx.scene.paint.LinearGradient
- * @see javafx.animation.Timeline
+ * @see javafx.scene.effect.Reflection
+ * @see javafx.scene.image.ImageView
+ * @see javafx.scene.layout.Pane
+ * @see javafx.scene.paint.Color
+ * @see javafx.scene.paint.Paint
+ * @see javafx.scene.paint.CycleMethod
+ * @see javafx.scene.paint.Stop
  */
 public class FireworksApp extends Application {
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/charts/custom/candlestick/CandleStickChartApp.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/charts/custom/candlestick/CandleStickChartApp.java	Sat Nov 02 06:58:02 2013 -0700
@@ -156,7 +156,6 @@
         yAxis = new NumberAxis();
         chart = new CandleStickChart(xAxis,yAxis);
         // setup chart
-        chart.setTitle("Custom Candle Stick Chart");
         xAxis.setLabel("Day");
         yAxis.setLabel("Price");
         // add starting data
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/graphics/images/imageproperties/ImagePropertiesApp.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/graphics/images/imageproperties/ImagePropertiesApp.java	Sat Nov 02 06:58:02 2013 -0700
@@ -91,6 +91,9 @@
         VBox vb = new VBox(10);
         vb.setAlignment(Pos.CENTER);
         vb.getChildren().addAll(hBox, sample2);
+        vb.setMinSize(VBox.USE_PREF_SIZE, VBox.USE_PREF_SIZE);
+        vb.setMaxSize(VBox.USE_PREF_SIZE, VBox.USE_PREF_SIZE);
+ 
         return vb;
     }
 
--- a/apps/samples/Ensemble8/src/samples/java/ensemble/samples/scenegraph/events/gestureevent/GestureEventApp.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/apps/samples/Ensemble8/src/samples/java/ensemble/samples/scenegraph/events/gestureevent/GestureEventApp.java	Sat Nov 02 06:58:02 2013 -0700
@@ -89,8 +89,9 @@
     public Parent createContent() {
         //set up the console
         console.setItems(consoleObservableList);
-        //      console.setLayoutY(5);
         console.setPrefSize(CONSOLE_WIDTH, CONSOLE_HEIGHT);
+        console.setMinSize(ListView.USE_PREF_SIZE, ListView.USE_PREF_SIZE);
+        console.setMaxSize(ListView.USE_PREF_SIZE, ListView.USE_PREF_SIZE);
         VBox root = new VBox();
         root.setSpacing(2);
         root.setPrefSize(SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT);
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/interpolator/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/interpolator/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/timeline/timeline/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/timeline/timeline/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/timeline/timelineevents/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/timeline/timelineevents/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/fadetransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/fadetransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/filltransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/filltransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/paralleltransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/paralleltransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/pathtransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/pathtransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/pausetransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/pausetransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/rotatetransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/rotatetransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/scaletransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/scaletransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/sequentialtransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/sequentialtransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/stroketransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/stroketransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/translatetransition/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/animation/transitions/translatetransition/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/canvas/fireworks/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/canvas/fireworks/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/audio/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/audio/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/chart/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/chart/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/curvefitted/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/curvefitted/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/stacked/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/area/stacked/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/audio/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/audio/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/chart/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/chart/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/horizontal/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/horizontal/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/image/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/image/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/stacked/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bar/stacked/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bubble/chart/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/bubble/chart/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/custom/candlestick/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/custom/candlestick/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/line/category/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/line/category/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/line/chart/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/line/chart/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/line/stock/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/line/stock/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/pie/chart/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/pie/chart/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/pie/drilldown/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/pie/drilldown/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/scatter/animated/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/scatter/animated/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/scatter/chart/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/charts/scatter/chart/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/concurrency/service/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/concurrency/service/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/concurrency/task/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/concurrency/task/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/accordion/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/accordion/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/button/colorbutton/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/button/colorbutton/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/button/graphicbutton/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/button/graphicbutton/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/button/pillbutton/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/button/pillbutton/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/checkbox/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/checkbox/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/choicebox/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/choicebox/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/colorpicker/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/colorpicker/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/datepicker/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/datepicker/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/hyperlink/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/hyperlink/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/listview/horizontallistview/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/listview/horizontallistview/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/listview/listviewcellfactory/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/listview/listviewcellfactory/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/listview/simplelistview/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/listview/simplelistview/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/menu/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/menu/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/pagination/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/pagination/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/progressbar/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/progressbar/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/progressindicator/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/progressindicator/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/radiobutton/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/radiobutton/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/scrollbar/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/scrollbar/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/splitpane/hiddensplitpane/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/splitpane/hiddensplitpane/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/tab/tabpane/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/tab/tabpane/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/table/tablecellfactory/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/table/tablecellfactory/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/table/tableview/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/table/tableview/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/advancedlabel/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/advancedlabel/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/insettext/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/insettext/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/searchbox/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/searchbox/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/simplelabel/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/simplelabel/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/textfield/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/textfield/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/textvalidator/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/text/textvalidator/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/togglebutton/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/togglebutton/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/toolbar/styledtoolbar/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/toolbar/styledtoolbar/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/toolbar/toolbar/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/toolbar/toolbar/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/treetableview/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/treetableview/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/treeview/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/controls/treeview/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/fxml/fxmldemo/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/fxml/fxmldemo/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/bouncingballs/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/bouncingballs/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/brickbreaker/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/brickbreaker/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/calc/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/calc/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/colorfulcircles/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/colorfulcircles/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/digitalclock/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/digitalclock/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/displayshelf/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/displayshelf/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/dropshadow/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/dropshadow/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/gaussianblur/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/gaussianblur/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/innershadow/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/innershadow/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/reflection/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/reflection/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/sepiatone/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/effects/sepiatone/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/images/imagecreation/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/images/imagecreation/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/images/imageoperator/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/images/imageoperator/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/images/imageproperties/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/images/imageproperties/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/paints/color/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/paints/color/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/paints/lineargradient/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/paints/lineargradient/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/paints/radialgradient/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/paints/radialgradient/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/puzzle/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/puzzle/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/arc/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/arc/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/circle/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/circle/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/cubiccurve/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/cubiccurve/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/ellipse/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/ellipse/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/line/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/line/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/path/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/path/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/polygon/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/polygon/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/polyline/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/polyline/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/quadcurve/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/quadcurve/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/rectangle/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/shapes/rectangle/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/stopwatch/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics/stopwatch/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics3d/cube/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics3d/cube/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics3d/cubesystem/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics3d/cubesystem/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics3d/simple3dbox/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics3d/simple3dbox/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics3d/xylophone/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/graphics3d/xylophone/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/language/beans/changelistener/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/language/beans/changelistener/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/language/beans/stringbinding/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/language/beans/stringbinding/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/language/collections/observablelist/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/language/collections/observablelist/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/anchorpane/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/anchorpane/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/borderpane/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/borderpane/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/flowpane/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/flowpane/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/gridpane/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/gridpane/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/hbox/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/hbox/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/stackpane/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/stackpane/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/tilepane/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/tilepane/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/vbox/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/layout/vbox/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/advancedmedia/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/advancedmedia/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/alphamediaplayer/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/alphamediaplayer/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/audioclip/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/audioclip/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/overlaymediaplayer/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/overlaymediaplayer/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/streamingmediaplayer/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/media/streamingmediaplayer/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/cursor/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/cursor/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/gestureevent/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/gestureevent/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/keyevent/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/keyevent/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/keystrokemotion/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/keystrokemotion/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/mouseevent/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/mouseevent/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/multitouch/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/events/multitouch/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/node/customnode/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/node/customnode/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/node/nodeproperties/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/node/nodeproperties/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/stage/advancedstage/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/stage/advancedstage/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/stage/stage/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/scenegraph/stage/stage/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/swing/swinginterop/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/swing/swinginterop/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/text/bidi/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/text/bidi/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/text/textflow/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/text/textflow/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/web/htmleditor/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/web/htmleditor/preview@2x.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/web/webview/preview.png has changed
Binary file apps/samples/Ensemble8/src/samples/resources/ensemble/samples/web/webview/preview@2x.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/ParallelNearAndFarClipTest.java	Sat Nov 02 06:58:02 2013 -0700
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package fx83dfeatures;
+
+import javafx.application.Application;
+import javafx.event.EventHandler;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.Stage;
+
+public class ParallelNearAndFarClipTest extends Application {
+
+    private static final double OFFSET_PERCENT = 0.01; // 1 percent tolerance
+    private static final int WIDTH = 500;
+    private static final int HEIGHT = 500;
+    private static final double NEAR = 0.1;
+    private static final double FAR = 100.0;
+
+    private Scene createClipPlanes(Stage stage) {
+        stage.setTitle("Parallel Near and Far Clip Test");
+
+        final double tanOfHalfFOV = Math.tan(Math.toRadians(15));
+        final double halfHeight = HEIGHT / 2;
+        final double focalLength = halfHeight / tanOfHalfFOV;
+        final double eyePositionZ = -1.0 * focalLength;
+        final double nearClipDistance = focalLength * NEAR + eyePositionZ;
+        final double farClipDistance = focalLength * FAR + eyePositionZ;
+        final double nearClipDistanceOffset = Math.abs(nearClipDistance * OFFSET_PERCENT);
+        final double farClipDistanceOffset = Math.abs(farClipDistance * OFFSET_PERCENT);
+
+        System.out.println("In scene coordinate: focalLength = " + focalLength
+                + ", nearClipDistance = " + nearClipDistance
+                + ", nearClipDistanceOffset = " + nearClipDistanceOffset
+                + ", farClipDistance = " + farClipDistance
+                + ", farClipDistanceOffset = " + farClipDistanceOffset);
+
+        Rectangle insideRect = new Rectangle(200, 200, Color.GREEN);
+        insideRect.setLayoutX(150);
+        insideRect.setLayoutY(150);
+        insideRect.setId("Green");
+
+        Rectangle insideNearClip = new Rectangle(50, 50, Color.BLUE);
+        insideNearClip.setLayoutX(225);
+        insideNearClip.setLayoutY(225);
+        insideNearClip.setTranslateZ(nearClipDistance + nearClipDistanceOffset);
+        insideNearClip.setId("Blue");
+
+        Rectangle outsideNearClip = new Rectangle(100, 100, Color.YELLOW);
+        outsideNearClip.setLayoutX(200);
+        outsideNearClip.setLayoutY(200);
+        outsideNearClip.setTranslateZ(nearClipDistance - nearClipDistanceOffset);
+        outsideNearClip.setId("Yellow");
+
+        Rectangle insideFarClip = new Rectangle(300, 300, Color.RED);
+        insideFarClip.setTranslateX(100);
+        insideFarClip.setTranslateY(100);
+        insideFarClip.setTranslateZ(farClipDistance - farClipDistanceOffset);
+        insideFarClip.setId("Red");
+
+        Rectangle outsideFarClip = new Rectangle(400, 400, Color.CYAN);
+        outsideFarClip.setTranslateX(50);
+        outsideFarClip.setTranslateY(50);
+        outsideFarClip.setTranslateZ(farClipDistance + farClipDistanceOffset);
+        outsideFarClip.setId("Cyan");
+
+        Group root = new Group();
+
+        // Render in painter order (far to near)
+        root.getChildren().addAll(outsideFarClip, insideFarClip, insideRect, insideNearClip, outsideNearClip);
+
+        // Intentionally set depth buffer to false to reduce test complexity
+        Scene scene = new Scene(root, WIDTH, HEIGHT, false);
+        scene.setOnMousePressed(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent event) {
+                System.out.println("Clicked: " + event.getTarget());
+            }
+        });
+
+        return scene;
+    }
+
+    @Override public void start(Stage stage) {
+        Scene scene = createClipPlanes(stage);
+        scene.setFill(Color.GRAY);
+        stage.setScene(scene);
+        stage.sizeToScene();
+        stage.setResizable(false);
+        stage.show();
+        System.out.println("You should expect to see 3 overlapping squares in"
+                + " the order of Blue is on top of Green and Green is on top Red.");
+    }
+
+    public static void main(String[] args) {
+        Application.launch(args);
+    }
+
+}
--- a/build.gradle	Thu Oct 31 17:45:18 2013 -0700
+++ b/build.gradle	Sat Nov 02 06:58:02 2013 -0700
@@ -1422,6 +1422,18 @@
     }
 }
 
+project(":jmx") {
+    dependencies {
+        compile project(":base")
+        compile project(":graphics")
+        compile project(":swing")
+        compile project(":media")
+    }
+
+    // Tests are disabled until RT-33926 can be fixed
+    test.enabled = false
+}
+
 // This project is for system tests that need to run with a full SDK.
 // Most of them display a stage or do other things that preclude running
 // them in a shared JVM or as part of the "smoke test" run (which must
@@ -2156,7 +2168,9 @@
         project.sourceSets.main.output
     });
     exclude("com/**/*", "javafx/scene/ParentDesignInfo*", "Compile*", "javafx/builder/**/*");
-    options.windowTitle("JavaFX ${RELEASE_NAME}")
+    options.windowTitle("${javadocTitle}")
+    options.header("${javadocHeader}")
+    options.bottom("${javadocBottom}")
     options.links(JDK_DOCS);
     options.addBooleanOption("XDignore.symbol.file").setValue(true);
     options.addBooleanOption("Xdoclint:none").setValue(!IS_DOC_LINT);
@@ -2377,6 +2391,16 @@
     }
     jfxrt.dependsOn(jfxswtIndexTask)
 
+    def jmxTask = task ("jmx${t.capital}", type: Jar) {
+        group = "Basic"
+        description = "Creates the javafx-mx.jar"
+        archiveName = "build/${t.name}-sdk/lib/javafx-mx.jar";
+        includeEmptyDirs = false
+        from "modules/jmx/build/classes/main"
+        from "modules/jmx/build/resources/main"
+        dependsOn project(":jmx").assemble
+    }
+
     // The 'sdk' task will build the rest of the SDK, and depends on the 'jfxrtTask' task. After
     // executing this task the sdk bundle for the current COMPILE_TARGETS will be fully created.
     def sdkTask = task("sdk$t.capital") {
@@ -2489,6 +2513,7 @@
                 }
             }
         }
+        dependsOn(jmxTask);
         dependsOn(jfxrtTask)
         dependsOn(javadoc)
         dependsOn(src)
--- a/build.properties	Thu Oct 31 17:45:18 2013 -0700
+++ b/build.properties	Sat Nov 02 06:58:02 2013 -0700
@@ -40,6 +40,16 @@
 
 ##############################################################################
 #
+# Build properties for generating javadoc
+#
+##############################################################################
+
+javadoc.bottom=<small><a href="http://docs.oracle.com/javafx/2/api/license.html">Copyright</a> (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.</small>
+javadoc.title=JavaFX 8
+javadoc.header=JavaFX&nbsp;8
+
+##############################################################################
+#
 # Build properties for defining the version of JDK used to build FX
 #
 # jfx.build.jdk.buildnum should be set to the JDK build number used to
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/behavior/TextFieldBehavior.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/behavior/TextFieldBehavior.java	Sat Nov 02 06:58:02 2013 -0700
@@ -92,21 +92,22 @@
             }
         };
 
+        final WeakChangeListener<Node> weakFocusOwnerListener =
+                                new WeakChangeListener<Node>(focusOwnerListener);
         sceneListener = new ChangeListener<Scene>() {
-            private WeakChangeListener<Node> weakListener = new WeakChangeListener<Node>(focusOwnerListener);
             @Override public void changed(ObservableValue<? extends Scene> observable, Scene oldValue, Scene newValue) {
                 if (oldValue != null) {
-                    oldValue.focusOwnerProperty().removeListener(weakListener);
+                    oldValue.focusOwnerProperty().removeListener(weakFocusOwnerListener);
                 }
                 if (newValue != null) {
-                    newValue.focusOwnerProperty().addListener(weakListener);
+                    newValue.focusOwnerProperty().addListener(weakFocusOwnerListener);
                 }
             }
         };
         textField.sceneProperty().addListener(new WeakChangeListener<Scene>(sceneListener));
 
         if (textField.getScene() != null) {
-            textField.getScene().focusOwnerProperty().addListener(focusOwnerListener);
+            textField.getScene().focusOwnerProperty().addListener(weakFocusOwnerListener);
         }
 
         // Only add this if we're on an embedded platform that supports 5-button navigation
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TextFieldSkin.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TextFieldSkin.java	Sat Nov 02 06:58:02 2013 -0700
@@ -693,8 +693,8 @@
 
         Bounds textBounds = textGroup.getBoundsInParent();
 
-        return new Rectangle2D(x + textBounds.getMinX(), y + textBounds.getMinY(),
-                               width, height);
+        return new Rectangle2D(x + textBounds.getMinX() + textTranslateX.get(),
+                               y + textBounds.getMinY(), width, height);
     }
 
     @Override protected PathElement[] getUnderlineShape(int start, int end) {
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TextInputControlSkin.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TextInputControlSkin.java	Sat Nov 02 06:58:02 2013 -0700
@@ -364,7 +364,8 @@
             @Override public Point2D getTextLocation(int offset) {
                 Scene scene = getSkinnable().getScene();
                 Window window = scene.getWindow();
-                Rectangle2D characterBounds = getCharacterBounds(imstart + offset);
+                // Don't use imstart here because it isn't initialized yet.
+                Rectangle2D characterBounds = getCharacterBounds(textInput.getSelection().getStart() + offset);
                 Point2D p = getSkinnable().localToScene(characterBounds.getMinX(), characterBounds.getMaxY());
                 Point2D location = new Point2D(window.getX() + scene.getX() + p.getX(),
                                                window.getY() + scene.getY() + p.getY());
@@ -493,15 +494,15 @@
                 textInput.replaceText(textInput.getSelection(), committed);
             }
 
-            // Insert composed text
+            // Replace composed text
             imstart = textInput.getSelection().getStart();
             StringBuilder composed = new StringBuilder();
             for (InputMethodTextRun run : event.getComposed()) {
                 composed.append(run.getText());
             }
+            textInput.replaceText(textInput.getSelection(), composed.toString());
             imlength = composed.length();
             if (imlength != 0) {
-                textInput.replaceText(textInput.getSelection(), composed.toString());
                 int pos = imstart;
                 for (InputMethodTextRun run : event.getComposed()) {
                     int endPos = pos + run.getText().length();
@@ -531,7 +532,9 @@
         double minY = 0f;
         double maxY = 0f;
 
-        for (PathElement pe: getUnderlineShape(start, end)) {
+        PathElement elements[] = getUnderlineShape(start, end);
+        for (int i = 0; i < elements.length; i++) {
+            PathElement pe = elements[i];
             if (pe instanceof MoveTo) {
                 minX = maxX = ((MoveTo)pe).getX();
                 minY = maxY = ((MoveTo)pe).getY();
@@ -546,7 +549,11 @@
             } else if (pe instanceof VLineTo) {
                 minY = (minY < ((VLineTo)pe).getY() ? minY : ((VLineTo)pe).getY());
                 maxY = (maxY > ((VLineTo)pe).getY() ? maxY : ((VLineTo)pe).getY());
-            } else if (pe instanceof ClosePath) {
+            }
+            // Don't assume that shapes are ended with ClosePath.
+            if (pe instanceof ClosePath ||
+                i == elements.length - 1 ||
+                (i < elements.length - 1 && elements[i+1] instanceof MoveTo)) {
                 // Now, create the attribute.
                 Shape attr = null;
                 if (highlight == InputMethodHighlight.SELECTED_RAW) {
--- a/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TreeTableViewSkin.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/skin/TreeTableViewSkin.java	Sat Nov 02 06:58:02 2013 -0700
@@ -437,7 +437,7 @@
             needCellsRecreated = true;
             forceCellRecreate = false;
         } else if (newCount != oldCount) {
-            needCellsReconfigured = true;
+            needCellsRebuilt = true;
         } else {
             needCellsReconfigured = true;
         }
--- a/modules/controls/src/main/java/javafx/scene/chart/BarChart.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/chart/BarChart.java	Sat Nov 02 06:58:02 2013 -0700
@@ -69,15 +69,16 @@
     private Map<Series, Map<String, Data<X,Y>>> seriesCategoryMap = 
                                 new HashMap<Series, Map<String, Data<X,Y>>>();
     private Legend legend = new Legend();
-    private boolean seriesRemove = false;
     private final Orientation orientation;
     private CategoryAxis categoryAxis;
     private ValueAxis valueAxis;
     private Timeline dataRemoveTimeline;
-    private Data<X,Y> dataItemBeingRemoved = null;
-    private Series<X,Y> seriesOfDataRemoved = null;
     private double bottomPos  = 0;
     private static String NEGATIVE_STYLE = "negative";
+    private ParallelTransition pt;
+    // For storing data values in case removed and added immediately.
+    private Map<Data<X,Y>, Double> XYValueMap = 
+                                new HashMap<Data<X,Y>, Double>();
     // -------------- PUBLIC PROPERTIES ----------------------------------------
 
     /** The gap to leave between bars in the same category */
@@ -217,15 +218,6 @@
         categoryMap.put(category, item);
         Node bar = createBar(series, getData().indexOf(series), item, itemIndex);
         if (shouldAnimate()) {
-            if (dataRemoveTimeline != null && dataRemoveTimeline.getStatus().equals(Animation.Status.RUNNING)) {
-                if (dataItemBeingRemoved != null && dataItemBeingRemoved == item) {
-                    dataRemoveTimeline.stop();
-                    getPlotChildren().remove(bar);
-                    removeDataItemFromDisplay(seriesOfDataRemoved, item);
-                    dataItemBeingRemoved = null;
-                    seriesOfDataRemoved = null;
-                }
-            }
             animateDataAdd(item, bar);
         } else {
             getPlotChildren().add(bar);
@@ -235,24 +227,17 @@
     @Override protected void dataItemRemoved(final Data<X,Y> item, final Series<X,Y> series) {
         final Node bar = item.getNode();
         if (shouldAnimate()) {
+            XYValueMap.clear();
             dataRemoveTimeline = createDataRemoveTimeline(item, bar, series);
-            dataItemBeingRemoved = item;
-            seriesOfDataRemoved = series;
             dataRemoveTimeline.setOnFinished(new EventHandler<ActionEvent>() {
                 public void handle(ActionEvent event) {
                     item.setSeries(null);
-                    getPlotChildren().remove(bar);
                     removeDataItemFromDisplay(series, item);
-                    dataItemBeingRemoved = null;
-                    updateMap(series, item);
                 }
             });
             dataRemoveTimeline.play();
         } else {
-            item.setSeries(null);
-            getPlotChildren().remove(bar);
-            removeDataItemFromDisplay(series, item);
-            updateMap(series, item);
+            processDataRemove(series, item);
         }
     }
 
@@ -277,7 +262,7 @@
              item.getNode().getStyleClass().remove(NEGATIVE_STYLE);
          }
     }
-    
+
     @Override protected void seriesAdded(Series<X,Y> series, int seriesIndex) {
         // handle any data already in series
         // create entry in the map
@@ -311,22 +296,21 @@
         updateDefaultColorIndex(series);
         // remove all symbol nodes
         if (shouldAnimate()) {
-            ParallelTransition pt = new ParallelTransition();
+            pt = new ParallelTransition();
             pt.setOnFinished(new EventHandler<ActionEvent>() {
                 public void handle(ActionEvent event) {
                     removeSeriesFromDisplay(series);
                 }
             });
+            
+            boolean lastSeries = (getSeriesSize() > 1) ? false : true;
+            XYValueMap.clear();
             for (final Data<X,Y> d : series.getData()) {
                 final Node bar = d.getNode();
-                seriesRemove = true;
                 // Animate series deletion
-                if (getSeriesSize() > 1) {
-                    for (int j=0; j< series.getData().size(); j++) {
-                        Data<X,Y> item = series.getData().get(j);
-                        Timeline t = createDataRemoveTimeline(item, bar, series);
+                if (!lastSeries) {
+                        Timeline t = createDataRemoveTimeline(d, bar, series);
                         pt.getChildren().add(t);
-                    }
                 } else {
                     // fade out last series
                     FadeTransition ft = new FadeTransition(Duration.millis(700),bar);
@@ -334,8 +318,7 @@
                     ft.setToValue(0);
                     ft.setOnFinished(new EventHandler<ActionEvent>() {
                          @Override public void handle(ActionEvent actionEvent) {
-                            getPlotChildren().remove(bar);
-                            updateMap(series, d);
+                            processDataRemove(series, d);
                          }
                     });
                     pt.getChildren().add(ft);
@@ -434,6 +417,13 @@
         }
         if (seriesCategoryMap.isEmpty() && categoryAxis.isAutoRanging()) categoryAxis.getCategories().clear();
     }
+    
+    private void processDataRemove(final Series<X,Y> series, final Data<X,Y> item) {
+        Node bar = item.getNode();
+        getPlotChildren().remove(bar);
+        updateMap(series, item);
+    }
+     
     private void animateDataAdd(Data<X,Y> item, Node bar) {
         double barVal;
         if (orientation == Orientation.VERTICAL) {
@@ -471,24 +461,29 @@
         Timeline t = new Timeline();
         if (orientation == Orientation.VERTICAL) {
 //            item.setYValue(getYAxis().toRealValue(getYAxis().getZeroPosition()));
+            
+            // save data values in case the same data item gets added immediately.
+            XYValueMap.put(item, ((Number)item.getYValue()).doubleValue());
             item.setYValue(getYAxis().toRealValue(bottomPos));
             t.getKeyFrames().addAll(new KeyFrame(Duration.ZERO,
                                     new KeyValue(item.currentYProperty(), item.getCurrentY())),
                                     new KeyFrame(Duration.millis(700), new EventHandler<ActionEvent>() {
                                     @Override public void handle(ActionEvent actionEvent) {
-                                        getPlotChildren().remove(bar);
-                                        updateMap(series, item);
+                                        processDataRemove(series, item);
+                                        XYValueMap.clear();
                                     }
                                 },
                                 new KeyValue(item.currentYProperty(), item.getYValue(),
                                 Interpolator.EASE_BOTH) ));
         } else {
+            // save data values in case the same data item gets added immediately.
+             XYValueMap.put(item, ((Number)item.getXValue()).doubleValue());
             item.setXValue(getXAxis().toRealValue(getXAxis().getZeroPosition()));
             t.getKeyFrames().addAll(new KeyFrame(Duration.ZERO, new KeyValue(item.currentXProperty(), item.getCurrentX())),
                 new KeyFrame(Duration.millis(700), new EventHandler<ActionEvent>() {
                         @Override public void handle(ActionEvent actionEvent) {
-                            getPlotChildren().remove(bar);
-                            updateMap(series, item);
+                            processDataRemove(series, item);
+                            XYValueMap.clear();
                         }
                     },
                     new KeyValue(item.currentXProperty(), item.getXValue(),
@@ -497,6 +492,54 @@
         return t;
     }
     
+    @Override void dataBeingRemovedIsAdded(Data item, Series series) {
+        if (dataRemoveTimeline != null) {
+            dataRemoveTimeline.setOnFinished(null);
+            dataRemoveTimeline.stop();
+        }
+        processDataRemove(series, item);
+        item.setSeries(null);
+        removeDataItemFromDisplay(series, item);
+        restoreDataValues(item);
+        XYValueMap.clear();
+    }
+    
+    private void restoreDataValues(Data item) {
+        Double value = XYValueMap.get(item);
+        if (value != null) {
+            // Restoring original X/Y values 
+            if (orientation.equals(Orientation.VERTICAL)) {
+                item.setYValue(value);
+                item.setCurrentY(value);
+            } else {
+                item.setXValue(value);
+                item.setCurrentX(value);
+
+            }
+        }
+    }
+    @Override void seriesBeingRemovedIsAdded(Series<X,Y> series) {
+        boolean lastSeries = (pt.getChildren().size() == 1) ? true : false;
+        if (pt!= null) {
+            if (!pt.getChildren().isEmpty()) {
+                for (Animation a : pt.getChildren()) {
+                    a.setOnFinished(null);
+                }
+            }
+            for (Data item : series.getData()) {
+                processDataRemove(series, item);
+                if (!lastSeries) {
+                    restoreDataValues(item);
+                }
+            }
+            XYValueMap.clear();
+            pt.setOnFinished(null);
+            pt.getChildren().clear();
+            pt.stop();
+            removeSeriesFromDisplay(series);
+        }
+    }
+     
     private void updateDefaultColorIndex(final Series<X,Y> series) {
         int clearIndex = seriesColorMap.get(series);
         colorBits.clear(clearIndex);
@@ -524,7 +567,7 @@
         Map<String, Data<X,Y>> catmap = seriesCategoryMap.get(series);
         return (catmap != null) ? catmap.get(category) : null;
     }
-
+    
     // -------------- STYLESHEET HANDLING ------------------------------------------------------------------------------
 
     /**
--- a/modules/controls/src/main/java/javafx/scene/chart/LineChart.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/chart/LineChart.java	Sat Nov 02 06:58:02 2013 -0700
@@ -77,7 +77,10 @@
     private Timeline dataRemoveTimeline;
     private Series<X,Y> seriesOfDataRemoved = null;
     private Data<X,Y> dataItemBeingRemoved = null;
-
+    private FadeTransition fadeSymbolTransition = null;
+    private Map<Data<X,Y>, Double> XYValueMap = 
+                                new HashMap<Data<X,Y>, Double>();
+    private Timeline seriesRemoveTimeline = null;
     // -------------- PUBLIC PROPERTIES ----------------------------------------
 
     /** When true, CSS styleable symbols are created for any data items that don't have a symbol node specified. */
@@ -230,6 +233,7 @@
         // remove item from sorted list
         int itemIndex = series.getItemIndex(item);
         if (shouldAnimate()) {
+            XYValueMap.clear();
             boolean animate = false;
             if (itemIndex > 0 && itemIndex < series.getDataSize()) {
                 animate = true;
@@ -277,16 +281,16 @@
                 // fade out symbol
                 if (symbol != null) {
                     symbol.setOpacity(0);
-                    FadeTransition ft = new FadeTransition(Duration.millis(500),symbol);
-                    ft.setToValue(0);
-                    ft.setOnFinished(new EventHandler<ActionEvent>() {
+                    fadeSymbolTransition = new FadeTransition(Duration.millis(500),symbol);
+                    fadeSymbolTransition.setToValue(0);
+                    fadeSymbolTransition.setOnFinished(new EventHandler<ActionEvent>() {
                         @Override public void handle(ActionEvent actionEvent) {
                             item.setSeries(null);
                             getPlotChildren().remove(symbol);
                             removeDataItemFromDisplay(series, item);
                         }
                     });
-                    ft.play();
+                    fadeSymbolTransition.play();
                 }
             }
             if (animate) {
@@ -395,8 +399,8 @@
                 startValues[j]   = new KeyValue(nodes.get(j).opacityProperty(),1);
                 endValues[j]       = new KeyValue(nodes.get(j).opacityProperty(),0);
             }
-            Timeline tl = new Timeline();
-            tl.getKeyFrames().addAll(
+            seriesRemoveTimeline = new Timeline();
+            seriesRemoveTimeline.getKeyFrames().addAll(
                 new KeyFrame(Duration.ZERO,startValues),
                 new KeyFrame(Duration.millis(900), new EventHandler<ActionEvent>() {
                     @Override public void handle(ActionEvent actionEvent) {
@@ -405,7 +409,7 @@
                     }
                 },endValues)
             );
-            tl.play();
+            seriesRemoveTimeline.play();
         } else {
             getPlotChildren().remove(series.getNode());
             for (Data d:series.getData()) getPlotChildren().remove(d.getNode());
@@ -442,10 +446,46 @@
             }
         }
     }
+    /** @inheritDoc */
+    @Override void dataBeingRemovedIsAdded(Data item, Series series) {
+        if (fadeSymbolTransition != null) {
+            fadeSymbolTransition.setOnFinished(null);
+            fadeSymbolTransition.stop();
+        }
+        if (dataRemoveTimeline != null) {
+            dataRemoveTimeline.setOnFinished(null);
+            dataRemoveTimeline.stop();
+        }
+        final Node symbol = item.getNode();
+        if (symbol != null) getPlotChildren().remove(symbol);
+        
+        item.setSeries(null);
+        removeDataItemFromDisplay(series, item);
+        
+        // restore values to item
+        Double value = XYValueMap.get(item);
+        if (value != null) {
+            item.setYValue(value);
+            item.setCurrentY(value);
+        }
+        XYValueMap.clear();
+    }
+    /** @inheritDoc */
+    @Override void seriesBeingRemovedIsAdded(Series<X,Y> series) {
+        if (seriesRemoveTimeline != null) {
+            seriesRemoveTimeline.setOnFinished(null);
+            seriesRemoveTimeline.stop();
+            getPlotChildren().remove(series.getNode());
+            for (Data d:series.getData()) getPlotChildren().remove(d.getNode());
+            removeSeriesFromDisplay(series);
+        }
+    }
 
     private Timeline createDataRemoveTimeline(final Data<X,Y> item, final Node symbol, final Series<X,Y> series) {
         Timeline t = new Timeline();
-
+        // save data values in case the same data item gets added immediately.
+        XYValueMap.put(item, ((Number)item.getYValue()).doubleValue());
+            
         t.getKeyFrames().addAll(new KeyFrame(Duration.ZERO, new KeyValue(item.currentYProperty(),
                 item.getCurrentY()), new KeyValue(item.currentXProperty(),
                 item.getCurrentX())),
@@ -453,6 +493,7 @@
                     @Override public void handle(ActionEvent actionEvent) {
                         if (symbol != null) getPlotChildren().remove(symbol);
                         removeDataItemFromDisplay(series, item);
+                        XYValueMap.clear();
                     }
                 },
                 new KeyValue(item.currentYProperty(),
--- a/modules/controls/src/main/java/javafx/scene/chart/XYChart.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/chart/XYChart.java	Sat Nov 02 06:58:02 2013 -0700
@@ -112,6 +112,7 @@
             while (c.next()) {
                 if (c.getRemoved().size() > 0) updateLegend();
                 for (Series<X,Y> series : c.getRemoved()) {
+                    series.setToRemove = true;
                     series.setChart(null);
                     seriesRemoved(series);
 //                    seriesDefaultColorIndex --;
@@ -120,6 +121,10 @@
                     final Series<X,Y> series = c.getList().get(i);
                     // add new listener to data
                     series.setChart(XYChart.this);
+                    if (series.setToRemove) {
+                        series.setToRemove = false;
+                        series.getChart().seriesBeingRemovedIsAdded(series);
+                    }
                     // update linkedList Pointers for series
                     if (XYChart.this.begin == null) {
                         XYChart.this.begin = getData().get(i);
@@ -555,6 +560,19 @@
     protected void updateLegend(){}
 
     /**
+     * This method is called when there is an attempt to add series that was  
+     * set to be removed, and the removal might not have completed. 
+     * @param series 
+     */
+    void seriesBeingRemovedIsAdded(Series<X,Y> series) {}
+    
+    /**
+     * This method is called when there is an attempt to add a Data item that was
+     * set to be removed, and the removal might not have completed.
+     * @param data 
+     */
+    void dataBeingRemovedIsAdded(Data<X,Y> item, Series<X,Y> series) {}
+    /**
      * Called when a data item has been added to a series. This is where implementations of XYChart can create/add new
      * nodes to getPlotChildren to represent this data item. They also may animate that data add with a fade in or
      * similar if animated = true.
@@ -906,6 +924,7 @@
      * @param series The series to remove
      */
     protected final void removeSeriesFromDisplay(Series<X, Y> series) {
+        if (series != null) series.setToRemove = false;
         if (begin == series) {
             begin = series.next;
         } else {
@@ -1447,7 +1466,7 @@
 
         /** the style class for default color for this series */
         String defaultColorStyleClass;
-
+        boolean setToRemove = false;
         Data<X,Y> begin = null; // start pointer of a data linked list.
         /*
          * Next pointer for the next series. We maintain a linkedlist of the
@@ -1485,7 +1504,8 @@
                     if (c.getAddedSize() > 0) {
                         for (Data<X,Y> itemPtr = begin; itemPtr != null; itemPtr = itemPtr.next) {
                             if (itemPtr.setToRemove) {
-                                removeDataItemRef(itemPtr);
+                                getChart().dataBeingRemovedIsAdded(itemPtr, Series.this);
+                                itemPtr.setToRemove = false;
                             }
                         }
                     }
@@ -1696,6 +1716,7 @@
          * when data is deleted.
          */
         private void removeDataItemRef(Data<X,Y> item) {
+            if (item != null) item.setToRemove = false;
             if (begin == item) {
                 begin = item.next;
             } else {
@@ -1724,5 +1745,5 @@
             return count;
         }
     }
-
+    
 }
--- a/modules/controls/src/main/java/javafx/scene/control/Labeled.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/main/java/javafx/scene/control/Labeled.java	Sat Nov 02 06:58:02 2013 -0700
@@ -461,7 +461,7 @@
                     this.origin = origin;
 
                     // Don't want applyStyle to throw an exception which would leave this.origin set to the wrong value
-                    if (graphic.isBound() == false) super.applyStyle(origin, v);
+                    if (graphic == null || graphic.isBound() == false) super.applyStyle(origin, v);
 
                     // Origin is only valid for this invocation of applyStyle, so reset it to USER in case someone calls set.
                     this.origin = StyleOrigin.USER;
--- a/modules/controls/src/test/java/javafx/scene/chart/BarChartTest.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/controls/src/test/java/javafx/scene/chart/BarChartTest.java	Sat Nov 02 06:58:02 2013 -0700
@@ -30,11 +30,9 @@
 import org.junit.Test;
 import static org.junit.Assert.assertEquals;
 import javafx.collections.*;
-import com.sun.javafx.pgstub.StubToolkit;
-import com.sun.javafx.tk.Toolkit;
 
 import javafx.scene.Node;
-import javafx.scene.Scene;
+import javafx.scene.chart.XYChart.Series;
 import javafx.scene.layout.StackPane;
 
 /**
@@ -114,4 +112,22 @@
         assertEquals("0", xAxis.getCategories().get(0));
     }
     
+    @Test
+    public void testRemoveAndAddSameSeriesBeforeAnimationCompletes() {
+        startApp();
+        assertEquals(2, bc.getData().size());
+        // remove and add the same series.
+        bc.getData().add(bc.getData().remove(0));
+        pulse();
+        assertEquals(2, bc.getData().size());
+    }
+    
+    @Test
+    public void testRemoveAndAddSameDataBeforeAnimationCompletes() {
+        startApp();
+        Series s = bc.getData().get(0);
+        assertEquals(3, s.getDataSize());
+        s.getData().add(s.getData().remove(0));
+        assertEquals(3, s.getDataSize());
+    }
 }
--- a/modules/fxml/src/main/java/com/sun/javafx/fxml/BeanAdapter.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/fxml/src/main/java/com/sun/javafx/fxml/BeanAdapter.java	Sat Nov 02 06:58:02 2013 -0700
@@ -36,6 +36,8 @@
 import java.util.*;
 
 import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 import javafx.beans.value.ObservableValue;
 import sun.reflect.misc.FieldUtil;
@@ -111,7 +113,7 @@
         localCache = getClassMethodCache(bean.getClass());
     }
 
-    private static MethodCache getClassMethodCache(Class<?> type) {
+    private static MethodCache getClassMethodCache(final Class<?> type) {
         if (type == Object.class) {
             return null;
         }
@@ -123,21 +125,32 @@
             Map<String, List<Method>> classMethods = new HashMap<>();
 
             ReflectUtil.checkPackageAccess(type);
-            Method[] declaredMethods = type.getDeclaredMethods();
-            for (int i = 0; i < declaredMethods.length; i++) {
-                Method method = declaredMethods[i];
-                int modifiers = method.getModifiers();
+            if (Modifier.isPublic(type.getModifiers())) {
+                // only interested in public methods in public classes in
+                // non-restricted packages
+                final Method[] declaredMethods =
+                        AccessController.doPrivileged(
+                                new PrivilegedAction<Method[]>() {
+                                    @Override
+                                    public Method[] run() {
+                                        return type.getDeclaredMethods();
+                                    }
+                                });
+                for (int i = 0; i < declaredMethods.length; i++) {
+                    Method method = declaredMethods[i];
+                    int modifiers = method.getModifiers();
 
-                if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
-                    String name = method.getName();
-                    List<Method> namedMethods = classMethods.get(name);
+                    if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
+                        String name = method.getName();
+                        List<Method> namedMethods = classMethods.get(name);
 
-                    if (namedMethods == null) {
-                        namedMethods = new ArrayList<>();
-                        classMethods.put(name, namedMethods);
+                        if (namedMethods == null) {
+                            namedMethods = new ArrayList<>();
+                            classMethods.put(name, namedMethods);
+                        }
+
+                        namedMethods.add(method);
                     }
-
-                    namedMethods.add(method);
                 }
             }
             MethodCache cache = new MethodCache(classMethods, getClassMethodCache(type.getSuperclass()));
--- a/modules/fxml/src/main/java/javafx/fxml/FXMLLoader.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/fxml/src/main/java/javafx/fxml/FXMLLoader.java	Sat Nov 02 06:58:02 2013 -0700
@@ -80,13 +80,15 @@
 import com.sun.javafx.fxml.expression.KeyPath;
 import java.net.MalformedURLException;
 import java.security.AccessController;
+import java.security.AllPermission;
 import java.security.PrivilegedAction;
 import java.util.EnumMap;
 import java.util.Locale;
 import java.util.StringTokenizer;
 import javafx.beans.InvalidationListener;
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
 import sun.reflect.misc.ConstructorUtil;
-import sun.reflect.misc.FieldUtil;
 import sun.reflect.misc.MethodUtil;
 import sun.reflect.misc.ReflectUtil;
 
@@ -545,12 +547,18 @@
                     }
 
                     for (SupportedType t : types) {
-                        Method method = getControllerMethods().get(t).get(handlerName);
+                        Method method = controllerAccessor
+                                            .getControllerMethods()
+                                            .get(t)
+                                            .get(handlerName);
                         if (method != null) {
                             return new MethodHandler(controller, method, t);
                         }
                     }
-                    Method method = getControllerMethods().get(SupportedType.PARAMETERLESS).get(handlerName);
+                    Method method = controllerAccessor
+                                        .getControllerMethods()
+                                        .get(SupportedType.PARAMETERLESS)
+                                        .get(handlerName);
                     if (method != null) {
                         return new MethodHandler(controller, method, SupportedType.PARAMETERLESS);
                     }
@@ -683,7 +691,7 @@
                 }
 
                 if (handlerValue.startsWith(CONTROLLER_METHOD_PREFIX)) {
-                    MethodHandler handler = getControllerMethodHandle(handlerValue, SupportedType.PROPERTY_CHANGE_LISTENER, SupportedType.EVENT);
+                    final MethodHandler handler = getControllerMethodHandle(handlerValue, SupportedType.PROPERTY_CHANGE_LISTENER, SupportedType.EVENT);
                     if (handler != null) {
                         if (handler.type == SupportedType.EVENT) {
                             // Note: this part is solely for purpose of 2.2 backward compatibility where an Event object
@@ -836,7 +844,8 @@
 
                 // Set the controller field value
                 if (controller != null) {
-                    Field field = getControllerFields().get(fx_id);
+                    Field field = controllerAccessor.getControllerFields()
+                                                    .get(fx_id);
 
                     if (field != null) {
                         try {
@@ -1126,7 +1135,7 @@
             fxmlLoader.setClassLoader(classLoader);
             fxmlLoader.impl_setStaticLoad(staticLoad);
 
-            Object value = fxmlLoader.load();
+            Object value = fxmlLoader.loadImpl(callerClass);
 
             if (fx_id != null) {
                 String id = this.fx_id + CONTROLLER_SUFFIX;
@@ -1135,7 +1144,8 @@
                 namespace.put(id, controller);
 
                 if (FXMLLoader.this.controller != null) {
-                    Field field = getControllerFields().get(id);
+                    Field field = controllerAccessor.getControllerFields()
+                                                    .get(id);
 
                     if (field != null) {
                         try {
@@ -1764,9 +1774,6 @@
     private List<String> packages = new LinkedList<String>();
     private Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
 
-    private Map<String, Field> controllerFields = null;
-    private Map<SupportedType, Map<String, Method>> controllerMethods = null;
-
     private ScriptEngineManager scriptEngineManager = null;
 
     private static ClassLoader defaultClassLoader;
@@ -2221,8 +2228,7 @@
             namespace.put(CONTROLLER_KEYWORD, controller);
         }
 
-        controllerFields = null;
-        controllerMethods = null;
+        controllerAccessor.setController(controller);
     }
 
     /**
@@ -2370,27 +2376,11 @@
      * The loaded object hierarchy.
      * @since JavaFX 2.1
      */
+    @CallerSensitive
     public <T> T load() throws IOException {
-        if (location == null) {
-            throw new IllegalStateException("Location is not set.");
-        }
-
-        InputStream inputStream = null;
-        T value;
-        try {
-            inputStream = location.openStream();
-            value = load(inputStream);
-        } catch (LoadException exception) {
-            throw exception;
-        } catch (Exception exception) {
-            throw constructLoadException(exception);
-        } finally {
-            if (inputStream != null) {
-                inputStream.close();
-            }
-        }
-
-        return value;
+        return loadImpl((System.getSecurityManager() != null)
+                            ? Reflection.getCallerClass()
+                            : null);
     }
 
     /**
@@ -2402,144 +2392,187 @@
      * @return
      * The loaded object hierarchy.
      */
-    @SuppressWarnings("dep-ann")
+    @CallerSensitive
     public <T> T load(InputStream inputStream) throws IOException {
+        return loadImpl(inputStream, (System.getSecurityManager() != null)
+                                         ? Reflection.getCallerClass()
+                                         : null);
+    }
+
+    private Class<?> callerClass;
+
+    private <T> T loadImpl(final Class<?> callerClass) throws IOException {
+        if (location == null) {
+            throw new IllegalStateException("Location is not set.");
+        }
+
+        InputStream inputStream = null;
+        T value;
+        try {
+            inputStream = location.openStream();
+            value = loadImpl(inputStream, callerClass);
+        } finally {
+            if (inputStream != null) {
+                inputStream.close();
+            }
+        }
+
+        return value;
+    }
+
+    @SuppressWarnings({ "dep-ann", "unchecked" })
+    private <T> T loadImpl(InputStream inputStream,
+                           Class<?> callerClass) throws IOException {
         if (inputStream == null) {
             throw new NullPointerException("inputStream is null.");
         }
 
-        clearImports();
-
-        // Initialize the namespace
-        namespace.put(LOCATION_KEY, location);
-        namespace.put(RESOURCES_KEY, resources);
-
-        // Clear the script engine
-        scriptEngine = null;
-
-        // Create the parser
+        this.callerClass = callerClass;
+        controllerAccessor.setCallerClass(callerClass);
         try {
-            XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
-            xmlInputFactory.setProperty("javax.xml.stream.isCoalescing", true);
-
-            // Some stream readers incorrectly report an empty string as the prefix
-            // for the default namespace; correct this as needed
-            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
-            xmlStreamReader = new StreamReaderDelegate(xmlInputFactory.createXMLStreamReader(inputStreamReader)) {
-                @Override
-                public String getPrefix() {
-                    String prefix = super.getPrefix();
-
-                    if (prefix != null
-                        && prefix.length() == 0) {
-                        prefix = null;
+            clearImports();
+
+            // Initialize the namespace
+            namespace.put(LOCATION_KEY, location);
+            namespace.put(RESOURCES_KEY, resources);
+
+            // Clear the script engine
+            scriptEngine = null;
+
+            // Create the parser
+            try {
+                XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+                xmlInputFactory.setProperty("javax.xml.stream.isCoalescing", true);
+
+                // Some stream readers incorrectly report an empty string as the prefix
+                // for the default namespace; correct this as needed
+                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
+                xmlStreamReader = new StreamReaderDelegate(xmlInputFactory.createXMLStreamReader(inputStreamReader)) {
+                    @Override
+                    public String getPrefix() {
+                        String prefix = super.getPrefix();
+
+                        if (prefix != null
+                            && prefix.length() == 0) {
+                            prefix = null;
+                        }
+
+                        return prefix;
                     }
 
-                    return prefix;
+                    @Override
+                    public String getAttributePrefix(int index) {
+                        String attributePrefix = super.getAttributePrefix(index);
+
+                        if (attributePrefix != null
+                            && attributePrefix.length() == 0) {
+                            attributePrefix = null;
+                        }
+
+                        return attributePrefix;
+                    }
+                };
+            } catch (XMLStreamException exception) {
+                throw constructLoadException(exception);
+            }
+
+            // Push this loader onto the stack
+            loaders.push(this);
+
+            // Parse the XML stream
+            try {
+                while (xmlStreamReader.hasNext()) {
+                    int event = xmlStreamReader.next();
+
+                    switch (event) {
+                        case XMLStreamConstants.PROCESSING_INSTRUCTION: {
+                            processProcessingInstruction();
+                            break;
+                        }
+
+                        case XMLStreamConstants.COMMENT: {
+                            processComment();
+                            break;
+                        }
+
+                        case XMLStreamConstants.START_ELEMENT: {
+                            processStartElement();
+                            break;
+                        }
+
+                        case XMLStreamConstants.END_ELEMENT: {
+                            processEndElement();
+                            break;
+                        }
+
+                        case XMLStreamConstants.CHARACTERS: {
+                            processCharacters();
+                            break;
+                        }
+                    }
                 }
-
-                @Override
-                public String getAttributePrefix(int index) {
-                    String attributePrefix = super.getAttributePrefix(index);
-
-                    if (attributePrefix != null
-                        && attributePrefix.length() == 0) {
-                        attributePrefix = null;
+            } catch (XMLStreamException exception) {
+                throw constructLoadException(exception);
+            }
+
+            if (controller != null) {
+                if (controller instanceof Initializable) {
+                    ((Initializable)controller).initialize(location, resources);
+                } else {
+                    // Inject controller fields
+                    Map<String, Field> controllerFields =
+                            controllerAccessor.getControllerFields();
+
+                    Field locationField = controllerFields.get(LOCATION_KEY);
+                    if (locationField != null) {
+                        try {
+                            locationField.set(controller, location);
+                        } catch (IllegalAccessException exception) {
+                            // TODO Throw when Initializable is deprecated/removed
+                            // throw constructLoadException(exception);
+                        }
                     }
 
-                    return attributePrefix;
-                }
-            };
-        } catch (XMLStreamException exception) {
-            throw constructLoadException(exception);
-        }
-
-        // Push this loader onto the stack
-        loaders.push(this);
-
-        // Parse the XML stream
-        try {
-            while (xmlStreamReader.hasNext()) {
-                int event = xmlStreamReader.next();
-
-                switch (event) {
-                    case XMLStreamConstants.PROCESSING_INSTRUCTION: {
-                        processProcessingInstruction();
-                        break;
+                    Field resourcesField = controllerFields.get(RESOURCES_KEY);
+                    if (resourcesField != null) {
+                        try {
+                            resourcesField.set(controller, resources);
+                        } catch (IllegalAccessException exception) {
+                            // TODO Throw when Initializable is deprecated/removed
+                            // throw constructLoadException(exception);
+                        }
                     }
 
-                    case XMLStreamConstants.COMMENT: {
-                        processComment();
-                        break;
-                    }
-
-                    case XMLStreamConstants.START_ELEMENT: {
-                        processStartElement();
-                        break;
-                    }
-
-                    case XMLStreamConstants.END_ELEMENT: {
-                        processEndElement();
-                        break;
-                    }
-
-                    case XMLStreamConstants.CHARACTERS: {
-                        processCharacters();
-                        break;
+                    // Initialize the controller
+                    Method initializeMethod = controllerAccessor
+                                                  .getControllerMethods()
+                                                  .get(SupportedType.PARAMETERLESS)
+                                                  .get(INITIALIZE_METHOD_NAME);
+
+                    if (initializeMethod != null) {
+                        try {
+                            MethodUtil.invoke(initializeMethod, controller, new Object [] {});
+                        } catch (IllegalAccessException exception) {
+                            // TODO Throw when Initializable is deprecated/removed
+                            // throw constructLoadException(exception);
+                        } catch (InvocationTargetException exception) {
+                            throw constructLoadException(exception);
+                        }
                     }
                 }
             }
-        } catch (XMLStreamException exception) {
+        } catch (final LoadException exception) {
+            throw exception;
+        } catch (final Exception exception) {
             throw constructLoadException(exception);
+        } finally {
+            controllerAccessor.setCallerClass(null);
+            // Clear controller accessor caches
+            controllerAccessor.reset();
+            // Clear the parser
+            xmlStreamReader = null;
         }
 
-        if (controller != null) {
-            if (controller instanceof Initializable) {
-                ((Initializable)controller).initialize(location, resources);
-            } else {
-                // Inject controller fields
-                Map<String, Field> controllerFields = getControllerFields();
-
-                Field locationField = controllerFields.get(LOCATION_KEY);
-                if (locationField != null) {
-                    try {
-                        locationField.set(controller, location);
-                    } catch (IllegalAccessException exception) {
-                        // TODO Throw when Initializable is deprecated/removed
-                        // throw constructLoadException(exception);
-                    }
-                }
-
-                Field resourcesField = controllerFields.get(RESOURCES_KEY);
-                if (resourcesField != null) {
-                    try {
-                        resourcesField.set(controller, resources);
-                    } catch (IllegalAccessException exception) {
-                        // TODO Throw when Initializable is deprecated/removed
-                        // throw constructLoadException(exception);
-                    }
-                }
-
-                // Initialize the controller
-                Method initializeMethod = getControllerMethods().get(SupportedType.PARAMETERLESS).
-                        get(INITIALIZE_METHOD_NAME);
-
-                if (initializeMethod != null) {
-                    try {
-                        MethodUtil.invoke(initializeMethod, controller, new Object [] {});
-                    } catch (IllegalAccessException exception) {
-                        // TODO Throw when Initializable is deprecated/removed
-                        // throw constructLoadException(exception);
-                    } catch (InvocationTargetException exception) {
-                        throw constructLoadException(exception);
-                    }
-                }
-            }
-        }
-
-        // Clear the parser
-        xmlStreamReader = null;
-
         return (T)root;
     }
 
@@ -2871,44 +2904,6 @@
         return classLoader.loadClass(packageName + "." + className.replace('.', '$'));
     }
 
-    private Map<String, Field> getControllerFields() throws LoadException {
-        if (controllerFields == null) {
-            controllerFields = new HashMap<>();
-
-            Class<?> controllerType = controller.getClass();
-            Class<?> type = controllerType;
-
-            while (type != Object.class) {
-                Field[] fields = FieldUtil.getDeclaredFields(type);
-
-                for (int i = 0; i < fields.length; i++) {
-                    Field field = fields[i];
-                    int modifiers = field.getModifiers();
-
-                    // Only add fields that are visible to this controller type
-                    if (type == controllerType
-                        || (modifiers & Modifier.PRIVATE) == 0) {
-                        // Ensure that the field is accessible
-                        if ((modifiers & Modifier.PUBLIC) == 0
-                            && field.getAnnotation(FXML.class) != null) {
-                            try {
-                                field.setAccessible(true);
-                            } catch (SecurityException exception) {
-                                throw constructLoadException(exception);
-                            }
-                        }
-
-                        controllerFields.put(field.getName(), field);
-                    }
-                }
-
-                type = type.getSuperclass();
-            }
-        }
-
-        return controllerFields;
-    }
-
     private static enum SupportedType {
         PARAMETERLESS {
 
@@ -2968,7 +2963,7 @@
         protected abstract boolean methodIsOfType(Method m);
     }
 
-    private SupportedType toSupportedType(Method m) {
+    private static SupportedType toSupportedType(Method m) {
         for (SupportedType t : SupportedType.values()) {
             if (t.methodIsOfType(m)) {
                 return t;
@@ -2977,58 +2972,6 @@
         return null;
     }
 
-    private Map<SupportedType, Map<String, Method>> getControllerMethods() throws LoadException {
-        if (controllerMethods == null) {
-            controllerMethods = new EnumMap<>(SupportedType.class);
-            for (SupportedType t: SupportedType.values()) {
-                controllerMethods.put(t, new HashMap<String, Method>());
-            }
-
-            Class<?> controllerType = controller.getClass();
-            Class<?> type = controllerType;
-
-            while (type != Object.class) {
-                ReflectUtil.checkPackageAccess(type);
-                Method[] methods = type.getDeclaredMethods();
-
-                for (int i = 0; i < methods.length; i++) {
-                    Method method = methods[i];
-                    int modifiers = method.getModifiers();
-
-                    // Only add methods that are visible to this controller type
-                    if (type == controllerType
-                        || (modifiers & Modifier.PRIVATE) == 0) {
-                        // Ensure that the method is accessible
-                        if ((modifiers & Modifier.PUBLIC) == 0
-                            && method.getAnnotation(FXML.class) != null) {
-                            try {
-                                method.setAccessible(true);
-                            } catch (SecurityException exception) {
-                                throw constructLoadException(exception);
-                            }
-                        }
-
-                        // Add this method to the map if:
-                        // a) it is the initialize() method, or
-                        // b) it takes a single event argument, or
-                        // c) it takes no arguments and a handler with this
-                        //    name has not already been defined
-                        String methodName = method.getName();
-                        SupportedType convertedType;
-
-                        if ((convertedType = toSupportedType(method)) != null) {
-                            controllerMethods.get(convertedType).put(methodName, method);
-                        }
-                    }
-                }
-
-                type = type.getSuperclass();
-            }
-        }
-
-        return controllerMethods;
-    }
-
     private ScriptEngineManager getScriptEngineManager() {
         if (scriptEngineManager == null) {
             scriptEngineManager = new javax.script.ScriptEngineManager();
@@ -3092,9 +3035,16 @@
      *
      * @param location
      */
-    @SuppressWarnings("unchecked")
+    @CallerSensitive
     public static <T> T load(URL location) throws IOException {
-        return (T)load(location, null);
+        return loadImpl(location, (System.getSecurityManager() != null)
+                                      ? Reflection.getCallerClass()
+                                      : null);
+    }
+
+    private static <T> T loadImpl(URL location, Class<?> callerClass)
+            throws IOException {
+        return loadImpl(location, null, callerClass);
     }
 
     /**
@@ -3103,9 +3053,19 @@
      * @param location
      * @param resources
      */
-    @SuppressWarnings("unchecked")
-    public static <T> T load(URL location, ResourceBundle resources) throws IOException {
-        return (T)load(location, resources, new JavaFXBuilderFactory());
+    @CallerSensitive
+    public static <T> T load(URL location, ResourceBundle resources)
+                                     throws IOException {
+        return loadImpl(location, resources,
+                        (System.getSecurityManager() != null)
+                            ? Reflection.getCallerClass()
+                            : null);
+    }
+
+    private static <T> T loadImpl(URL location, ResourceBundle resources,
+                                  Class<?> callerClass) throws IOException {
+        return loadImpl(location, resources,  new JavaFXBuilderFactory(),
+                        callerClass);
     }
 
     /**
@@ -3115,10 +3075,20 @@
      * @param resources
      * @param builderFactory
      */
-    @SuppressWarnings("unchecked")
-    public static <T> T load(URL location, ResourceBundle resources, BuilderFactory builderFactory)
-        throws IOException {
-        return (T)load(location, resources, builderFactory, null);
+    @CallerSensitive
+    public static <T> T load(URL location, ResourceBundle resources,
+                             BuilderFactory builderFactory)
+                                     throws IOException {
+        return loadImpl(location, resources, builderFactory,
+                        (System.getSecurityManager() != null)
+                            ? Reflection.getCallerClass()
+                            : null);
+    }
+
+    private static <T> T loadImpl(URL location, ResourceBundle resources,
+                                  BuilderFactory builderFactory,
+                                  Class<?> callerClass) throws IOException {
+        return loadImpl(location, resources, builderFactory, null, callerClass);
     }
 
     /**
@@ -3130,10 +3100,23 @@
      * @param controllerFactory
      * @since JavaFX 2.1
      */
-    @SuppressWarnings("unchecked")
-    public static <T> T load(URL location, ResourceBundle resources, BuilderFactory builderFactory,
-        Callback<Class<?>, Object> controllerFactory) throws IOException {
-        return (T)load(location, resources, builderFactory, controllerFactory, Charset.forName(DEFAULT_CHARSET_NAME));
+    @CallerSensitive
+    public static <T> T load(URL location, ResourceBundle resources,
+                             BuilderFactory builderFactory,
+                             Callback<Class<?>, Object> controllerFactory)
+                                     throws IOException {
+        return loadImpl(location, resources, builderFactory, controllerFactory,
+                        (System.getSecurityManager() != null)
+                            ? Reflection.getCallerClass()
+                            : null);
+    }
+
+    private static <T> T loadImpl(URL location, ResourceBundle resources,
+                                  BuilderFactory builderFactory,
+                                  Callback<Class<?>, Object> controllerFactory,
+                                  Class<?> callerClass) throws IOException {
+        return loadImpl(location, resources, builderFactory, controllerFactory,
+                        Charset.forName(DEFAULT_CHARSET_NAME), callerClass);
     }
 
     /**
@@ -3146,16 +3129,32 @@
      * @param charset
      * @since JavaFX 2.1
      */
-    @SuppressWarnings("unchecked")
-    public static <T> T load(URL location, ResourceBundle resources, BuilderFactory builderFactory,
-        Callback<Class<?>, Object> controllerFactory, Charset charset) throws IOException {
+    @CallerSensitive
+    public static <T> T load(URL location, ResourceBundle resources,
+                             BuilderFactory builderFactory,
+                             Callback<Class<?>, Object> controllerFactory,
+                             Charset charset) throws IOException {
+        return loadImpl(location, resources, builderFactory, controllerFactory,
+                        charset,
+                        (System.getSecurityManager() != null)
+                            ? Reflection.getCallerClass()
+                            : null);
+    }
+
+    private static <T> T loadImpl(URL location, ResourceBundle resources,
+                                  BuilderFactory builderFactory,
+                                  Callback<Class<?>, Object> controllerFactory,
+                                  Charset charset, Class<?> callerClass)
+                                          throws IOException {
         if (location == null) {
             throw new NullPointerException("Location is required.");
         }
 
-        FXMLLoader fxmlLoader = new FXMLLoader(location, resources, builderFactory, controllerFactory, charset);
-
-        return (T)fxmlLoader.load();
+        FXMLLoader fxmlLoader =
+                new FXMLLoader(location, resources, builderFactory,
+                               controllerFactory, charset);
+
+        return fxmlLoader.<T>loadImpl(callerClass);
     }
 
     /**
@@ -3236,4 +3235,249 @@
         return retVal;
     }
 
+    private static void checkAllPermissions() {
+        final SecurityManager securityManager = System.getSecurityManager();
+        if (securityManager != null) {
+            securityManager.checkPermission(new AllPermission());
+        }
+    }
+
+    private final ControllerAccessor controllerAccessor =
+            new ControllerAccessor();
+
+    private static final class ControllerAccessor {
+        private static final int PUBLIC = 1;
+        private static final int PROTECTED = 2;
+        private static final int PACKAGE = 4;
+        private static final int PRIVATE = 8;
+        private static final int INITIAL_CLASS_ACCESS =
+                PUBLIC | PACKAGE;
+        private static final int INITIAL_MEMBER_ACCESS =
+                PUBLIC | PROTECTED | PACKAGE | PRIVATE;
+
+        private static final int METHODS = 0;
+        private static final int FIELDS = 1;
+
+        private Object controller;
+        private ClassLoader callerClassLoader;
+
+        private Map<String, Field> controllerFields;
+        private Map<SupportedType, Map<String, Method>> controllerMethods;
+
+        public void setController(final Object controller) {
+            if (this.controller != controller) {
+                this.controller = controller;
+                reset();
+            }
+        }
+
+        public void setCallerClass(final Class<?> callerClass) {
+            final ClassLoader newCallerClassLoader =
+                    (callerClass != null) ? callerClass.getClassLoader()
+                                          : null;
+            if (callerClassLoader != newCallerClassLoader) {
+                callerClassLoader = newCallerClassLoader;
+                reset();
+            }
+        }
+
+        public void reset() {
+            controllerFields = null;
+            controllerMethods = null;
+        }
+
+        public Map<String, Field> getControllerFields() {
+            if (controllerFields == null) {
+                controllerFields = new HashMap<>();
+
+                if (callerClassLoader == null) {
+                    // allow null class loader only with full permission check
+                    checkAllPermissions();
+                }
+
+                addAccessibleMembers(controller.getClass(),
+                                     INITIAL_CLASS_ACCESS,
+                                     INITIAL_MEMBER_ACCESS,
+                                     FIELDS);
+            }
+
+            return controllerFields;
+        }
+
+        public Map<SupportedType, Map<String, Method>> getControllerMethods() {
+            if (controllerMethods == null) {
+                controllerMethods = new EnumMap<>(SupportedType.class);
+                for (SupportedType t: SupportedType.values()) {
+                    controllerMethods.put(t, new HashMap<String, Method>());
+                }
+
+                if (callerClassLoader == null) {
+                    // allow null class loader only with full permission check
+                    checkAllPermissions();
+                }
+
+                addAccessibleMembers(controller.getClass(),
+                                     INITIAL_CLASS_ACCESS,
+                                     INITIAL_MEMBER_ACCESS,
+                                     METHODS);
+            }
+
+            return controllerMethods;
+        }
+
+        private void addAccessibleMembers(final Class<?> type,
+                                          final int prevAllowedClassAccess,
+                                          final int prevAllowedMemberAccess,
+                                          final int membersType) {
+            if (type == Object.class) {
+                return;
+            }
+
+            int allowedClassAccess = prevAllowedClassAccess;
+            int allowedMemberAccess = prevAllowedMemberAccess;
+            if ((callerClassLoader != null)
+                    && (type.getClassLoader() != callerClassLoader)) {
+                // restrict further access
+                allowedClassAccess &= PUBLIC;
+                allowedMemberAccess &= PUBLIC;
+            }
+
+            final int classAccess = getAccess(type.getModifiers());
+            if ((classAccess & allowedClassAccess) == 0) {
+                // we are done
+                return;
+            }
+
+            ReflectUtil.checkPackageAccess(type);
+
+            addAccessibleMembers(type.getSuperclass(),
+                                 allowedClassAccess,
+                                 allowedMemberAccess & ~PRIVATE,
+                                 membersType);
+
+            final int finalAllowedMemberAccess = allowedMemberAccess;
+            AccessController.doPrivileged(
+                    new PrivilegedAction<Void>() {
+                        @Override
+                        public Void run() {
+                            if (membersType == FIELDS) {
+                                addAccessibleFields(type,
+                                                    finalAllowedMemberAccess);
+                            } else {
+                                addAccessibleMethods(type,
+                                                     finalAllowedMemberAccess);
+                            }
+
+                            return null;
+                        }
+                    });
+        }
+
+        private boolean isAccessibleToController(
+                final Class<?> type, final int memberModifiers) {
+            if (Modifier.isPublic(memberModifiers)
+                    || Modifier.isProtected(memberModifiers)) {
+                return true;
+            }
+
+            return Reflection.verifyMemberAccess(controller.getClass(),
+                                                 type,
+                                                 controller,
+                                                 memberModifiers);
+        }
+
+        private void addAccessibleFields(final Class<?> type,
+                                         final int allowedMemberAccess) {
+            final boolean isPublicType = Modifier.isPublic(type.getModifiers());
+
+            final Field[] fields = type.getDeclaredFields();
+            for (int i = 0; i < fields.length; ++i) {
+                final Field field = fields[i];
+                final int memberModifiers = field.getModifiers();
+
+                if (((memberModifiers & (Modifier.STATIC
+                                             | Modifier.FINAL)) != 0)
+                        || ((getAccess(memberModifiers) & allowedMemberAccess)
+                                == 0)
+                        || !isAccessibleToController(type, memberModifiers)) {
+                    continue;
+                }
+
+                if (!isPublicType || !Modifier.isPublic(memberModifiers)) {
+                    if (field.getAnnotation(FXML.class) == null) {
+                        // no fxml annotation on a non-public field
+                        continue;
+                    }
+
+                    // Ensure that the field is accessible
+                    field.setAccessible(true);
+                }
+
+                controllerFields.put(field.getName(), field);
+            }
+        }
+
+        private void addAccessibleMethods(final Class<?> type,
+                                          final int allowedMemberAccess) {
+            final boolean isPublicType = Modifier.isPublic(type.getModifiers());
+
+            final Method[] methods = type.getDeclaredMethods();
+            for (int i = 0; i < methods.length; ++i) {
+                final Method method = methods[i];
+                final int memberModifiers = method.getModifiers();
+
+                if (((memberModifiers & (Modifier.STATIC
+                                             | Modifier.ABSTRACT
+                                             | Modifier.NATIVE)) != 0)
+                        || ((getAccess(memberModifiers) & allowedMemberAccess)
+                                == 0)
+                        || !isAccessibleToController(type, memberModifiers)) {
+                    continue;
+                }
+
+                if (!isPublicType || !Modifier.isPublic(memberModifiers)) {
+                    if (method.getAnnotation(FXML.class) == null) {
+                        // no fxml annotation on a non-public method
+                        continue;
+                    }
+
+                    // Ensure that the method is accessible
+                    method.setAccessible(true);
+                }
+
+                // Add this method to the map if:
+                // a) it is the initialize() method, or
+                // b) it takes a single event argument, or
+                // c) it takes no arguments and a handler with this
+                //    name has not already been defined
+                final String methodName = method.getName();
+                final SupportedType convertedType;
+
+                if ((convertedType = toSupportedType(method)) != null) {
+                    controllerMethods.get(convertedType)
+                                     .put(methodName, method);
+                }
+            }
+        }
+
+        private static int getAccess(final int fullModifiers) {
+            final int untransformedAccess =
+                    fullModifiers & (Modifier.PRIVATE | Modifier.PROTECTED
+                                                      | Modifier.PUBLIC);
+
+            switch (untransformedAccess) {
+                case Modifier.PUBLIC:
+                    return PUBLIC;
+
+                case Modifier.PROTECTED:
+                    return PROTECTED;
+
+                case Modifier.PRIVATE:
+                    return PRIVATE;
+
+                default:
+                    return PACKAGE;
+            }
+        }
+    }
 }
--- a/modules/graphics/src/main/docs/javafx/scene/doc-files/cssref.html	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/docs/javafx/scene/doc-files/cssref.html	Sat Nov 02 06:58:02 2013 -0700
@@ -3468,7 +3468,7 @@
       </tbody>
     </table>
     <h4><a name="control" id="control">Control</a></h4>
-    <p>The Control class has all the properties of <a href="#parent">Parent</a></p>
+    <p>The Control class has all the properties of <a href="#region">Region</a></p>
     <table summary="property table" class="csspropertytable" cellpadding="2" cellspacing="1">
       <thead>
         <tr>
--- a/modules/graphics/src/main/java/com/sun/glass/ui/Pixels.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/Pixels.java	Sat Nov 02 06:58:02 2013 -0700
@@ -125,17 +125,29 @@
         Application.checkEventThread();
         return this.scale;
     }
+    
+    public final float getScaleUnsafe() {
+        return this.scale;
+    }
 
     public final int getWidth() {
         Application.checkEventThread();
         return this.width;
     }
 
+    public final int getWidthUnsafe() {
+        return this.width;
+    }
+
     public final int getHeight() {
         Application.checkEventThread();
         return this.height;
     }
     
+    public final int getHeightUnsafe() {
+        return this.height;
+    }
+    
     public final int getBytesPerComponent() {
         Application.checkEventThread();
         return this.bytesPerComponent;
--- a/modules/graphics/src/main/java/com/sun/glass/ui/View.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/View.java	Sat Nov 02 06:58:02 2013 -0700
@@ -354,6 +354,9 @@
     }
 
     protected abstract void _enableInputMethodEvents(long ptr, boolean enable);
+    protected void _finishInputMethodComposition(long ptr) {
+        // Action needed only on Windows.
+    }
 
     /*
         Read by the checkNotClosed method which could be called from lock/unlock on render thread
@@ -624,6 +627,12 @@
         _enableInputMethodEvents(this.ptr, enable);
     }
 
+    public void finishInputMethodComposition() {
+        Application.checkEventThread();
+        checkNotClosed();
+        _finishInputMethodComposition(this.ptr);
+    }
+
     private double[] getInputMethodCandidatePos(int offset) {
         if (this.eventHandler != null) {
             return this.eventHandler.getInputMethodCandidatePos(offset);
--- a/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensTouchInputSupport.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/lens/LensTouchInputSupport.java	Sat Nov 02 06:58:02 2013 -0700
@@ -60,6 +60,15 @@
      */    
     private static final int touchMoveSensitivity;
 
+    /**
+     * This property enable/disable multi touch support by the input driver.
+     * When the property is disabled and a multitouch screen is connected, the
+     * input driver will 'downgrade' the screen events to a single touch 
+     * point, as if a single touch screen was connected 
+     * 
+     */
+    private static final boolean useMultiTouch;
+
     static {
         touchTapRadius = AccessController.doPrivileged(
         new PrivilegedAction<Integer>() {
@@ -76,6 +85,14 @@
                 return Integer.getInteger("lens.input.touch.MoveSensitivity", 3);
             }
         });
+
+        useMultiTouch = AccessController.doPrivileged(
+        new PrivilegedAction<Boolean>() {
+            @Override
+            public Boolean run() {
+                return Boolean.getBoolean("com.sun.javafx.experimental.embedded.multiTouch");
+            }
+        });
     }
 
 
--- a/modules/graphics/src/main/java/com/sun/glass/ui/win/WinView.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/win/WinView.java	Sat Nov 02 06:58:02 2013 -0700
@@ -71,6 +71,7 @@
     }
 
     @Override native protected void _enableInputMethodEvents(long ptr, boolean enable);
+    @Override native protected void _finishInputMethodComposition(long ptr);
 
     @Override native protected long _create(Map caps);
     @Override native protected long _getNativeView(long ptr);
--- a/modules/graphics/src/main/java/com/sun/javafx/css/FontFace.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/css/FontFace.java	Sat Nov 02 06:58:02 2013 -0700
@@ -25,8 +25,14 @@
 
 package com.sun.javafx.css;
 
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * A FontFace is a @font-face definition from CSS file
@@ -70,6 +76,53 @@
         return sb.toString();
     }
 
+    final void writeBinary(final DataOutputStream os, final StringStore stringStore) throws IOException
+    {
+        Set<Map.Entry<String,String>> entrySet = getDescriptors() != null ? getDescriptors().entrySet() : null;
+        int nEntries = entrySet != null ? entrySet.size() : 0;
+        os.writeShort(nEntries);
+        if (entrySet != null) {
+            for(Map.Entry<String,String> entry : entrySet) {
+                int index = stringStore.addString(entry.getKey());
+                os.writeInt(index);
+                index = stringStore.addString(entry.getValue());
+                os.writeInt(index);
+            }
+        }
+
+        List<FontFaceSrc> fontFaceSrcs = getSources();
+        nEntries = fontFaceSrcs != null ? fontFaceSrcs.size() : 0;
+        os.writeShort(nEntries);
+        for (int n=0; n<nEntries; n++) {
+            FontFaceSrc fontFaceSrc = fontFaceSrcs.get(n);
+            fontFaceSrc.writeBinary(os, stringStore);
+        }
+
+    }
+
+    final static FontFace readBinary(int bssVersion, DataInputStream is, String[] strings) throws IOException
+    {
+        int nEntries = is.readShort();
+        Map<String,String> descriptors = new HashMap(nEntries);
+        for (int n=0; n<nEntries; n++) {
+            int index = is.readInt();
+            String key = strings[index];
+            index = is.readInt();
+            String value = strings[index];
+            descriptors.put(key, value);
+        }
+
+        nEntries = is.readShort();
+        List<FontFaceSrc> fontFaceSrcs = new ArrayList<>(nEntries);
+        for (int n=0; n<nEntries; n++) {
+            FontFaceSrc fontFaceSrc = FontFaceSrc.readBinary(bssVersion, is, strings);
+            fontFaceSrcs.add(fontFaceSrc);
+        }
+
+        return new FontFace(descriptors, fontFaceSrcs);
+
+    }
+
     public static class FontFaceSrc {
         private final FontFaceSrcType type;
         private final String src;
@@ -98,5 +151,28 @@
         public String getFormat() {
             return format;
         }
+
+        final void writeBinary(final DataOutputStream os, final StringStore stringStore) throws IOException
+        {
+            // ok if type, src or format are null since StringStore allows null
+            os.writeInt(stringStore.addString(type.name()));
+            os.writeInt(stringStore.addString(src));
+            os.writeInt(stringStore.addString(format));
+        }
+
+        final static FontFaceSrc readBinary(int bssVersion, DataInputStream is, String[] strings) throws IOException
+        {
+            int index = is.readInt();
+            FontFaceSrcType type = (strings[index] != null) ? FontFaceSrcType.valueOf(strings[index]) : null;
+
+            index = is.readInt();
+            String src = strings[index];
+
+            index = is.readInt();
+            String format = strings[index];
+
+            return new FontFaceSrc(type, src, format);
+
+        }
     }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/css/ParsedValueImpl.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/css/ParsedValueImpl.java	Sat Nov 02 06:58:02 2013 -0700
@@ -572,7 +572,7 @@
             return new ParsedValueImpl(value, converter, lookup);
 
         } else if (valType == VALUE_ARRAY) {
-            if (bssVersion == 4) {
+            if (bssVersion >= 4) {
                 // This byte was used to denote whether or not array was all nulls.
                 // But really, just need to know nVals
                 is.readByte();
@@ -592,7 +592,7 @@
             return new ParsedValueImpl(values, converter, lookup);
 
         } else if (valType == ARRAY_OF_VALUE_ARRAY) {
-            if (bssVersion == 4) {
+            if (bssVersion >= 4) {
                 // This byte was used to denote whether or not array was all nulls.
                 // But really, just need to know nLayers
                 is.readByte();
@@ -602,7 +602,7 @@
             final ParsedValueImpl[][] layers = nLayers > 0 ? new ParsedValueImpl[nLayers][0] : null;
 
             for (int l=0; l<nLayers; l++) {
-                if (bssVersion == 4) {
+                if (bssVersion >= 4) {
                     // was used to denote whether or not array was all nulls
                     // but really just need to know nVals
                     is.readByte();
@@ -635,6 +635,7 @@
             final int nameIndex = is.readShort();
             final String ename = strings[nameIndex];
 
+            // Note: this block should be entered _only_ if version 2
             if (bssVersion == 2) {
                 // RT-31022
                 // Once upon a time, the enum's class name was added to the
--- a/modules/graphics/src/main/java/com/sun/javafx/css/Stylesheet.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/css/Stylesheet.java	Sat Nov 02 06:58:02 2013 -0700
@@ -60,8 +60,9 @@
     /**
      * Version number of binary CSS format. The value is incremented whenever the format of the
      * binary stream changes. This number does not correlate with JavaFX versions.
+     * Version 5: persist @font-face
      */
-    public final static int BINARY_CSS_VERSION = 4;
+    final static int BINARY_CSS_VERSION = 5;
             
     private final String url;
     /** The URL from which the stylesheet was loaded.
@@ -196,6 +197,16 @@
         os.writeShort(index);
         os.writeShort(rules.size());
         for (Rule r : rules) r.writeBinary(os,stringStore);
+
+        // Version 5 adds persistence of FontFace
+        List<FontFace> fontFaceList = getFontFaces();
+        int nFontFaces = fontFaceList != null ? fontFaceList.size() : 0;
+        os.writeShort(nFontFaces);
+
+        for(int n=0; n<nFontFaces; n++) {
+            FontFace fontFace = fontFaceList.get(n);
+            fontFace.writeBinary(os, stringStore);
+        }
     }
     
     // protected for unit testing 
@@ -211,7 +222,15 @@
             persistedRules.add(Rule.readBinary(bssVersion,is,strings));
         }
         this.rules.addAll(persistedRules);
-        
+
+        if (bssVersion >= 5) {
+            List<FontFace> fontFaceList = this.getFontFaces();
+            int nFontFaces = is.readShort();
+            for (int n=0; n<nFontFaces; n++) {
+                FontFace fontFace = FontFace.readBinary(bssVersion, is, strings);
+                fontFaceList.add(fontFace);
+            }
+        }
     }
 
     private String[] stringStore;
--- a/modules/graphics/src/main/java/com/sun/javafx/css/parser/CSSLexer.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/css/parser/CSSLexer.java	Sat Nov 02 06:58:02 2013 -0700
@@ -75,6 +75,7 @@
     final static int WS = 40;
     final static int NL = 41;
     final static int FONT_FACE = 42;
+    final static int URL = 43;
 
     private final Recognizer A = new SimpleRecognizer('a','A');
     private final Recognizer B = new SimpleRecognizer('b','B');
@@ -199,7 +200,20 @@
     // lparen after ident implies function
     final LexerState lparenState = new LexerState(FUNCTION, "lparenState",
         LPAREN_CHAR
-    );
+    ) {
+        @Override public int getType() {
+
+            if (text.indexOf("url(") == 0) {
+                try {
+                    return consumeUrl();
+                } catch (IOException ioe) {
+                    return Token.INVALID;
+                }
+            }
+            return super.getType();
+        }
+    };
+
 
     // initial digits in a number
     final LexerState leadingDigitsState = new LexerState(NUMBER,"leadingDigitsState",
@@ -283,7 +297,7 @@
         // ident '-'? {nmchar}+
         // nmStartState -- [_a-z0-9-] --> nmCharState
         // nmCharState -- [_a-z0-9-] --> nmCharState
-        // nmCharState -- [)] --> lparenState
+        // nmCharState -- [(] --> lparenState
         //
         map.put(
                 nmStartState,
@@ -354,7 +368,7 @@
                     unitsState
                 }
         );
-    
+
         return map;
     }
 
@@ -446,7 +460,158 @@
             }
         }
     }
-   
+
+    // http://www.ietf.org/rfc/rfc3986
+    // http://www.w3.org/TR/2011/REC-CSS2-20110607/syndata.html#uri
+    // http://www.w3.org/TR/css3-syntax/#consume-a-url-token
+    private int consumeUrl() throws IOException {
+
+        text.delete(0, text.length());
+
+        // skip initial white space
+        while (WS_CHARS.recognize(ch)) {
+            ch = readChar();
+        }
+
+        if (ch == Token.EOF) {
+            return Token.EOF;
+        }
+
+        if (ch == '\'' || ch == '"') {
+
+            int endQuote = ch;
+
+            ch = readChar();
+
+            // consume the string
+            while (ch != endQuote) {
+
+                if (ch == Token.EOF) {
+                    break;
+                }
+
+                // un-escaped newline is an error
+                if (NL_CHARS.recognize(ch)) {
+                    break;
+                }
+
+                // handle escaped char
+                // Note: this block does not handle the algorithm for consuming hex-digits
+                if (ch == '\\') {
+
+                    ch = readChar();
+
+                    if (NL_CHARS.recognize(ch)) {
+
+                        // consume newline
+                        while(NL_CHARS.recognize(ch)) {
+                            ch = readChar();
+                        }
+
+                    } else if (ch != Token.EOF) {
+                        // if EOF, do nothing
+                        text.append((char)ch);
+                        ch = readChar();
+                    }
+
+                    continue;
+                }
+
+                text.append((char)ch);
+                ch = readChar();
+
+            }
+
+            if (ch == endQuote) {
+
+                ch = readChar();
+                while(WS_CHARS.recognize(ch)) {
+                    ch = readChar();
+                }
+
+                // After consuming white-space, the char has to be rparen or EOF. Error otherwise.
+                if (ch == ')') {
+                    // consume the rparen
+                    ch = readChar();
+                    return URL;
+                }
+
+                if(ch == Token.EOF) {
+                    return URL;
+                }
+            }
+
+        } else {
+
+            // TODO: a lot of repeat code from above
+            text.append((char)ch);
+            ch = readChar();
+
+            while (true) {
+
+                while (WS_CHARS.recognize(ch)) {
+                    ch = readChar();
+                }
+
+                if (ch == ')') {
+                    // consume the rparen
+                    ch = readChar();
+                    return URL;
+                }
+
+                if (ch == Token.EOF) {
+                    return URL;
+                }
+
+                // handle escaped char
+                // Note: this block does not handle the algorithm for consuming hex-digits
+                if (ch == '\\') {
+
+                    ch = readChar();
+
+                    if (NL_CHARS.recognize(ch)) {
+
+                        // consume newline
+                        while(NL_CHARS.recognize(ch)) {
+                            ch = readChar();
+                        }
+
+                    } else if (ch != Token.EOF) {
+                        // if EOF, do nothing
+                        text.append((char)ch);
+                        ch = readChar();
+                    }
+
+                    continue;
+                }
+
+                if (ch == '\'' || ch == '"' || ch == '(') {
+                    break;
+                }
+
+                text.append((char)ch);
+                ch = readChar();
+
+            }
+        }
+
+        // if we get to here, then the token is bad
+        // consume up to rparen or eof
+        while(true) {
+            int lastCh = ch;
+            if (ch == Token.EOF) {
+                return Token.EOF;
+            } else if (ch == ')' && lastCh != '\\') {
+                ch = readChar();
+                return Token.INVALID;
+            }
+
+            lastCh = ch;
+            ch = readChar();
+        }
+
+    }
+
     private class UnitsState extends LexerState {
 
         private Recognizer units[][] = {
--- a/modules/graphics/src/main/java/com/sun/javafx/css/parser/CSSParser.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/css/parser/CSSParser.java	Sat Nov 02 06:58:02 2013 -0700
@@ -877,6 +877,8 @@
             break;
         case CSSLexer.FUNCTION:
             return  parseFunction(root);
+        case CSSLexer.URL:
+            return parseURI(root);
         default:
             final String msg = "Unknown token type: \'" + ttype + "\'";
             error(root, msg);
@@ -1383,8 +1385,6 @@
             return parseLadder(root);
         } else if ("region".regionMatches(true, 0, fcn, 0, 6)) {
             return parseRegion(root);
-        } else if ("url".regionMatches(true, 0, fcn, 0, 3)) {
-            return parseURI(root);
         } else {
             error(root, "Unexpected function \'" + fcn + "\'");
         }
@@ -3387,26 +3387,18 @@
         return new ParsedValueImpl<String,String>(styleClassOrId, StringConverter.getInstance());
     }
 
-    // parse a URI value
-    // i.e., url("<uri>")
+    // url("<uri>") is tokenized by the lexer, so the root arg should be a URL token.
     private ParsedValueImpl<ParsedValue[],String> parseURI(Term root)
             throws ParseException {
 
-        // first term in the chain is the function name...
-        final String fn = (root.token != null) ? root.token.getText() : null;
-        if (!"url".regionMatches(true, 0, fn, 0, 3)) {
-            error(root,"Expected \'url\'");
-        }
-
-        Term arg = root.firstArg;
-        if (arg == null) error(root, "Expected \'url(\"<uri-string>\")\'");
-
-        if (arg.token == null ||
-            arg.token.getType() != CSSLexer.STRING ||
-            arg.token.getText() == null ||
-            arg.token.getText().isEmpty()) error(arg, "Expected \'url(\"<uri-string>\")\'");
-
-        final String uri = arg.token.getText();
+        if (root == null) error(root, "Expected \'url(\"<uri-string>\")\'");
+
+        if (root.token == null ||
+            root.token.getType() != CSSLexer.URL ||
+            root.token.getText() == null ||
+            root.token.getText().isEmpty()) error(root, "Expected \'url(\"<uri-string>\")\'");
+
+        final String uri = root.token.getText();
         ParsedValueImpl[] uriValues = new ParsedValueImpl[] {
             new ParsedValueImpl<String,String>(uri, StringConverter.getInstance()),
             null // placeholder for Stylesheet URL
@@ -3763,77 +3755,68 @@
                             if (currentToken.getType() == CSSLexer.IDENT) {
                                 // simple reference to other font-family
                                 sources.add(new FontFace.FontFaceSrc(FontFace.FontFaceSrcType.REFERENCE,currentToken.getText()));
-                            } else if (currentToken.getType() == CSSLexer.FUNCTION) {
-                                if ("url(".equalsIgnoreCase(currentToken.getText())) {
-                                    // consume the function token
-                                    currentToken = nextToken(lexer);
-                                    // parse function contents
-                                    final StringBuilder urlSb = new StringBuilder();
-                                    while(true) {
-                                        if((currentToken != null) && (currentToken.getType() != CSSLexer.RPAREN) &&
-                                                (currentToken.getType() != Token.EOF)) {
-                                            urlSb.append(currentToken.getText());
-                                        } else {
-                                            break;
+
+                            } else if (currentToken.getType() == CSSLexer.URL) {
+
+                                // let URLConverter do the conversion
+                                ParsedValueImpl[] uriValues = new ParsedValueImpl[] {
+                                        new ParsedValueImpl<String,String>(currentToken.getText(), StringConverter.getInstance()),
+                                        new ParsedValueImpl<String,String>(sourceOfStylesheet, null)
+                                };
+                                ParsedValue<ParsedValue[], String> parsedValue =
+                                        new ParsedValueImpl<ParsedValue[], String>(uriValues, URLConverter.getInstance());
+                                String urlStr = parsedValue.convert(null);
+
+                                URL url = null;
+                                try {
+                                    URI fontUri = new URI(urlStr);
+                                    url = fontUri.toURL();
+                                } catch (URISyntaxException |  MalformedURLException malf) {
+
+                                    final int line = currentToken.getLine();
+                                    final int pos = currentToken.getOffset();
+                                    final String msg = MessageFormat.format("Could not resolve @font-face url [{2}] at [{0,number,#},{1,number,#}]",line,pos,urlStr);
+                                    CssError error = createError(msg);
+                                    if (LOGGER.isLoggable(Level.WARNING)) {
+                                        LOGGER.warning(error.toString());
+                                    }
+                                    reportError(error);
+
+                                    // skip the rest.
+                                    while(currentToken != null) {
+                                        int ttype = currentToken.getType();
+                                        if (ttype == CSSLexer.RBRACE ||
+                                                ttype == Token.EOF) {
+                                            return null;
                                         }
                                         currentToken = nextToken(lexer);
                                     }
-                                    int start = 0, end = urlSb.length();
-                                    if (urlSb.charAt(start) == '\'' || urlSb.charAt(start) == '\"') start ++;
-                                    if (urlSb.charAt(start) == '/' || urlSb.charAt(start) == '\\') start ++;
-                                    if (urlSb.charAt(end-1) == '\'' || urlSb.charAt(end-1) == '\"') end --;
-                                    final String urlStr = urlSb.substring(start,end);
-
-                                    URL url = null;
-                                    Exception exception = null;
-                                    try {
-                                        URI stylesheetUri = new URI(sourceOfStylesheet);
-                                        URI fontUri = stylesheetUri.resolve(urlStr);
-                                        url = fontUri.toURL();
-                                    } catch (URISyntaxException |  MalformedURLException malf) {
-
-                                        final int line = currentToken.getLine();
-                                        final int pos = currentToken.getOffset();
-                                        final String msg = MessageFormat.format("Could not resolve @font-face url [{2}] at [{0,number,#},{1,number,#}]",line,pos,urlStr);
-                                        CssError error = createError(msg);
-                                        if (LOGGER.isLoggable(Level.WARNING)) {
-                                            LOGGER.warning(error.toString());
-                                        }
-                                        reportError(error);
-
-                                        // skip the rest.
-                                        while(currentToken != null) {
-                                            int ttype = currentToken.getType();
-                                            if (ttype == CSSLexer.RPAREN ||
-                                                ttype == Token.EOF) {
-                                                return null;
-                                            }
-                                            currentToken = nextToken(lexer);
-                                        }
-                                    }
-                                    String format = null;
-                                    while(true) {
-                                        currentToken = nextToken(lexer);
-                                        final int ttype = (currentToken != null) ? currentToken.getType() : Token.EOF;
-                                        if (ttype == CSSLexer.FUNCTION) {
-                                            if ("format(".equalsIgnoreCase(currentToken.getText())) {
-                                                continue;
-                                            } else {
-                                                break;
-                                            }
-                                        } else if (ttype == CSSLexer.IDENT ||
-                                                ttype == CSSLexer.STRING) {
-
-                                            format = Utils.stripQuotes(currentToken.getText());
-                                        } else if (ttype == CSSLexer.RPAREN) {
+                                }
+
+                                String format = null;
+                                while(true) {
+                                    currentToken = nextToken(lexer);
+                                    final int ttype = (currentToken != null) ? currentToken.getType() : Token.EOF;
+                                    if (ttype == CSSLexer.FUNCTION) {
+                                        if ("format(".equalsIgnoreCase(currentToken.getText())) {
                                             continue;
                                         } else {
                                             break;
                                         }
+                                    } else if (ttype == CSSLexer.IDENT ||
+                                            ttype == CSSLexer.STRING) {
+
+                                        format = Utils.stripQuotes(currentToken.getText());
+                                    } else if (ttype == CSSLexer.RPAREN) {
+                                        continue;
+                                    } else {
+                                        break;
                                     }
-
-                                    sources.add(new FontFace.FontFaceSrc(FontFace.FontFaceSrcType.URL,url.toExternalForm(), format));
-                                } else if ("local(".equalsIgnoreCase(currentToken.getText())) {
+                                }
+                                sources.add(new FontFace.FontFaceSrc(FontFace.FontFaceSrcType.URL,url.toExternalForm(), format));
+
+                            } else if (currentToken.getType() == CSSLexer.FUNCTION) {
+                                if ("local(".equalsIgnoreCase(currentToken.getText())) {
                                     // consume the function token
                                     currentToken = nextToken(lexer);
                                     // parse function contents
@@ -4388,6 +4371,9 @@
 
                 }
 
+            case CSSLexer.URL:
+                break;
+
             default:
                 final int line = currentToken != null ? currentToken.getLine() : -1;
                 final int pos = currentToken != null ? currentToken.getOffset() : -1;
--- a/modules/graphics/src/main/java/com/sun/javafx/embed/EmbeddedSceneInterface.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/embed/EmbeddedSceneInterface.java	Sat Nov 02 06:58:02 2013 -0700
@@ -28,7 +28,6 @@
 import java.nio.IntBuffer;
 
 import com.sun.javafx.scene.traversal.Direction;
-import com.sun.javafx.tk.TKSceneListener;
 import javafx.collections.ObservableList;
 import javafx.event.EventType;
 import javafx.scene.input.InputMethodEvent;
@@ -48,6 +47,11 @@
      * A notification about the embedded container is resized.
      */
     public void setSize(int width, int height);
+    
+    /*
+     * A notification about the scale factor is changed.
+     */
+    public void setPixelScaleFactor(float scale);
 
     /*
      * A request to fetch all the FX scene pixels into a offscreen buffer.
--- a/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java	Sat Nov 02 06:58:02 2013 -0700
@@ -1338,6 +1338,11 @@
         return lcdEnabled;
     }
 
+    public static boolean isJreFont(FontResource fr) {
+        String file = fr.getFileName();
+        return file.startsWith(jreFontDir);
+    }
+
     public static float getLCDContrast() {
         if (lcdContrast == -1) {
             if (isWindows) {
--- a/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyphLayout.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyphLayout.java	Sat Nov 02 06:58:02 2013 -0700
@@ -60,7 +60,7 @@
         return lineRef;
     }
 
-    private int getFontSlot(long runRef, CompositeFontResource fr, String name) {
+    private int getFontSlot(long runRef, CompositeFontResource fr, String name, int slot) {
         long runAttrs = OS.CTRunGetAttributes(runRef);
         if (runAttrs == 0) return -1;
         long actualFont = OS.CFDictionaryGetValue(runAttrs, OS.kCTFontAttributeName());
@@ -70,7 +70,6 @@
          * instead of CTFontCopyDisplayName() to avoid localized names*/
         String fontName = OS.CTFontCopyAttributeDisplayName(actualFont);
         if (fontName == null) return -1;
-        int slot = 0;
         if (!fontName.equalsIgnoreCase(name)) {
             if (fr == null) return -1;
             slot = fr.getSlotForFont(fontName);
@@ -83,10 +82,12 @@
 
     public void layout(TextRun run, PGFont font, FontStrike strike, char[] text) {
 
+        int slot = 0;
         CompositeFontResource composite = null;
         if (strike instanceof CompositeStrike) {
             composite = (CompositeFontResource)strike.getFontResource();
-            strike = ((CompositeStrike)strike).getStrikeSlot(0);
+            slot = getInitialSlot(composite);
+            strike = ((CompositeStrike)strike).getStrikeSlot(slot);
         }
         float size = strike.getSize();
         String fontName = strike.getFontResource().getFullName();
@@ -105,7 +106,7 @@
             for (int i = 0; i < runCount; i++) {
                 long runRef = OS.CFArrayGetValueAtIndex(runs, i);
                 if (runRef == 0) continue;
-                int slot = getFontSlot(runRef, composite, fontName) ;
+                slot = getFontSlot(runRef, composite, fontName, slot);
                 if (slot != -1) {
                     glyphStart += OS.CTRunGetGlyphs(runRef, slot << 24, glyphStart, glyphs);
                 } else {
--- a/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java	Sat Nov 02 06:58:02 2013 -0700
@@ -80,10 +80,12 @@
 
     public void layout(TextRun run, PGFont font, FontStrike strike, char[] text) {
 
+        int slot = 0;
         FontResource fr = font.getFontResource();
         boolean composite = fr instanceof CompositeFontResource;
         if (composite) {
-            fr = ((CompositeFontResource)fr).getSlotResource(0);
+            slot = getInitialSlot(fr);
+            fr = ((CompositeFontResource)fr).getSlotResource(slot);
         }
         IDWriteFontFace face = ((DWFontFile)fr).getFontFace();
         if (face == null) return;
@@ -135,10 +137,11 @@
         int step = rtl ? -1 : 1;
         int i, j;
         int[] iglyphs = new int[glyphCount];
+        int slotMask = slot << 24;
         boolean missingGlyph = false;
         i = 0; j = rtl ? glyphCount - 1 : 0;
         while (i < glyphCount) {
-            iglyphs[i] = glyphs[j];
+            iglyphs[i] = glyphs[j] | slotMask;
             if (iglyphs[i] == 0) {
                 missingGlyph = true;
                 break;
@@ -148,7 +151,7 @@
         }
         if (missingGlyph && composite) {
             analyzer.Release();
-            renderShape(text, run, font);
+            renderShape(text, run, font, slot);
             return;
         }
 
@@ -251,7 +254,7 @@
     }
 
     private int getFontSlot(IDWriteFontFace face, CompositeFontResource composite,
-                            String primaryFont) {
+                            String primaryFont, int slot) {
         if (face == null) return -1;
         IDWriteFontCollection collection = DWFactory.getFontCollection();
         PrismFontFactory prismFactory = PrismFontFactory.getFontFactory();
@@ -306,7 +309,6 @@
         }
 
         String fallbackName = fr.getFullName();
-        int slot = 0;
         if (!primaryFont.equalsIgnoreCase(fallbackName)) {
             slot = composite.getSlotForFont(fallbackName);
         }
@@ -319,9 +321,9 @@
         return slot;
     }
 
-    private void renderShape(char[] text, TextRun run, PGFont font) {
+    private void renderShape(char[] text, TextRun run, PGFont font, int slot) {
         CompositeFontResource composite = (CompositeFontResource)font.getFontResource();
-        FontResource fr = composite.getSlotResource(0);
+        FontResource fr = composite.getSlotResource(slot);
         String family = fr.getFamilyName();
         String fullName = fr.getFullName();
         int weight = fr.isBold() ? OS.DWRITE_FONT_WEIGHT_BOLD :
@@ -371,7 +373,7 @@
                 int textStart = 0;
                 while (renderer.Next()) {
                     IDWriteFontFace fallback = renderer.GetFontFace();
-                    int slot = getFontSlot(fallback, composite, fullName);
+                    slot = getFontSlot(fallback, composite, fullName, slot);
                     if (slot >= 0) {
                         renderer.GetGlyphIndices(glyphs, glyphStart, slot << 24);
                         renderer.GetGlyphOffsets(offsets, glyphStart * 2);
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/PickRay.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/PickRay.java	Sat Nov 02 06:58:02 2013 -0700
@@ -47,8 +47,8 @@
         set(origin, direction, nearClip, farClip);
     }
 
-    public PickRay(double x, double y, double nearClip, double farClip) {
-        set(x, y, nearClip, farClip);
+    public PickRay(double x, double y, double z, double nearClip, double farClip) {
+        set(x, y, z, nearClip, farClip);
     }
 
     public static PickRay computePerspectivePickRay(
@@ -93,7 +93,7 @@
     }
 
     public static PickRay computeParallelPickRay(
-            double x, double y,
+            double x, double y, double viewHeight,
             Affine3D cameraTransform,
             double nearClip, double farClip,
             PickRay pickRay) {
@@ -102,7 +102,12 @@
             pickRay = new PickRay();
         }
 
-        pickRay.set(x, y, nearClip, farClip);
+        // This is the same math as in the perspective case, fixed
+        // for the default 30 degrees vertical field of view.
+        final double distanceZ = (viewHeight / 2.0)
+                / Math.tan(Math.toRadians(15.0));
+
+        pickRay.set(x, y, distanceZ, nearClip * distanceZ, farClip * distanceZ);
 
         if (cameraTransform != null) {
             pickRay.transform(cameraTransform);
@@ -118,17 +123,9 @@
         this.farClip = farClip;
     }
 
-    public final void set(double x, double y, double nearClip, double farClip) {
-        // Right now the parallel camera picks nodes even on negative distances
-        // (behind the camera). Therefore, it doesn't matter
-        // what is the Z coordinate of the origin. Also the reported distance
-        // is always an infinity so it doesn't matter what is the magnitude
-        // of the direction.
-        // Right now we need the (origin+direction) point be in the XY plane
-        // for correct picking of the scene. This requirement will be removed
-        // when the projection plane is properly used for the intersection.
-        setOrigin(x, y, -1);
-        setDirection(0, 0, 1);
+    public final void set(double x, double y, double z, double nearClip, double farClip) {
+        setOrigin(x, y, -z);
+        setDirection(0, 0, z);
         this.nearClip = nearClip;
         this.farClip = farClip;
     }
--- a/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGParallelCamera.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGParallelCamera.java	Sat Nov 02 06:58:02 2013 -0700
@@ -36,7 +36,7 @@
 
     @Override
     public PickRay computePickRay(float x, float y, PickRay pickRay) {
-        return PickRay.computeParallelPickRay(x, y, worldTransform, zNear, zFar,
-                pickRay);
+        return PickRay.computeParallelPickRay(x, y, viewHeight, worldTransform,
+                zNear, zFar, pickRay);
     }
 }
--- a/modules/graphics/src/main/java/com/sun/javafx/text/GlyphLayout.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/text/GlyphLayout.java	Sat Nov 02 06:58:02 2013 -0700
@@ -302,6 +302,30 @@
     public abstract void layout(TextRun run, PGFont font,
                                 FontStrike strike, char[] text);
 
+    protected int getInitialSlot(FontResource fr) {
+        /* For some reason, DirectWrite and CoreText do not work with the JRE
+         * fonts (Lucida Sans). For example, with Arabic text the glyphs
+         * do not have ligatures (as if all glyphs were generated using just
+         * the CMAP table). Possible reasons for this failure is the
+         * presence of a system version of Lucida Sans, which does not include
+         * Arabic, and that causes some internal cache to fail (since both fonts
+         * would have the same postscript name); or possibly the JRE fonts
+         * have some internal settings that causes DirectWrite and
+         * CoreText to fail. Pango and ICU do not present the same problem.
+         * The fix is to use a different font.
+         * This fix relies that a CompositeFontResource has at least one
+         * fallback, and that is not a JRE font, and this method is used
+         * only to process complex text.
+         */
+        if (PrismFontFactory.isJreFont(fr)) {
+            if (PrismFontFactory.debugFonts) {
+                System.err.println("Avoiding JRE Font: " + fr.getFullName());
+            }
+            return 1;
+        }
+        return 0;
+    }
+
     /* This scheme creates a singleton GlyphLayout which is checked out
      * for use. Callers who find its checked out create one that after use
      * is discarded. This means that in a MT-rendering environment,
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/TKScene.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/TKScene.java	Sat Nov 02 06:58:02 2013 -0700
@@ -78,6 +78,8 @@
 
     public void enableInputMethodEvents(boolean enable);
 
+    public void finishInputMethodComposition();
+
     public void entireSceneNeedsRepaint();
 
     public TKClipboard createDragboard(boolean isDragSource);
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedScene.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedScene.java	Sat Nov 02 06:58:02 2013 -0700
@@ -47,6 +47,9 @@
 import com.sun.javafx.sg.prism.NGNode;
 import com.sun.javafx.tk.TKClipboard;
 import com.sun.javafx.tk.Toolkit;
+import com.sun.prism.paint.Color;
+import com.sun.prism.paint.Paint;
+import com.sun.glass.ui.Pixels;
 
 final class EmbeddedScene extends GlassScene implements EmbeddedSceneInterface {
 
@@ -55,12 +58,13 @@
 
     private UploadingPainter        painter;
     private PaintRenderJob          paintRenderJob;
+    
+    private final EmbeddedSceneDnD dndDelegate;    
 
-    volatile IntBuffer textureBits;
-    volatile int bitsLineStride;
-
-    private final EmbeddedSceneDnD dndDelegate;
-
+    volatile IntBuffer  texBits;
+    volatile int        texLineStride; // pre-scaled
+    volatile float      texScaleFactor = 1.0f;
+ 
     public EmbeddedScene(HostInterface host, boolean depthBuffer, boolean antiAliasing) {
         super(depthBuffer, antiAliasing);
         sceneState = new EmbeddedState(this);
@@ -116,10 +120,24 @@
         }
     }
 
+    @Override
+    public void finishInputMethodComposition() {
+        if (QuantumToolkit.verbose) {
+            System.err.println("EmbeddedScene.finishInputMethodComposition");
+        }
+    }
+    
+    @Override
+    public void setPixelScaleFactor(float scale) {
+        painter.setPixelScaleFactor(scale);
+        entireSceneNeedsRepaint();
+    }
+
     // Called by EmbeddedPainter on the render thread under renderLock
-    void uploadPixels(IntBuffer pixels, int stride) {
-        textureBits = pixels;
-        bitsLineStride = stride;
+    void uploadPixels(Pixels pixels) {
+        texBits = (IntBuffer)pixels.getPixels();
+        texLineStride = pixels.getWidthUnsafe();
+        texScaleFactor = pixels.getScaleUnsafe();
         if (host != null) {
             host.repaint();
         }
@@ -161,36 +179,59 @@
         });
     }
 
+    /**
+     * @param dest the destination buffer
+     * @param width the logical width of the buffer
+     * @param height the logical height of the buffer
+     * @param scale the scale factor
+     * @return 
+     */
     @Override
     public boolean getPixels(IntBuffer dest, int width, int height) {
         ViewPainter.renderLock.lock();
         try {
-            if (textureBits == null) return false;
+            // The dest buffer scale factor is expected to match painter.getPixelScaleFactor().
+            if (painter.getPixelScaleFactor() != texScaleFactor || texBits == null) {
+                return false;
+            }
+            width = (int)Math.round(width * texScaleFactor);
+            height = (int)Math.round(height * texScaleFactor);
+        
             dest.rewind();
-            textureBits.rewind();            
-            if (dest.capacity() != textureBits.capacity()) {
+            texBits.rewind();
+            if (dest.capacity() != texBits.capacity()) {
                 // Calculate the intersection of the dest & src images.
-                int w = Math.min(width, bitsLineStride);
-                int h = Math.min(height, textureBits.capacity() / bitsLineStride);
+                int w = Math.min(width, texLineStride);
+                int h = Math.min(height, texBits.capacity() / texLineStride);
 
                 // Copy the intersection to the dest.
                 // The backed array of the textureBits may not be available,
                 // so not relying on it.
                 int[] linebuf = new int[w];
                 for (int i = 0; i < h; i++) {
-                    textureBits.position(i * bitsLineStride);
-                    textureBits.get(linebuf, 0, w);
+                    texBits.position(i * texLineStride);
+                    texBits.get(linebuf, 0, w);
                     dest.position(i * width);
                     dest.put(linebuf);
                 }
                 return true;
             }
-            dest.put(textureBits);
+            dest.put(texBits);
             return true;
         } finally {
             ViewPainter.renderLock.unlock();
         }
     }
+    
+    @Override
+    protected Color getClearColor() {
+        if (fillPaint != null && fillPaint.getType() == Paint.Type.COLOR &&
+            ((Color)fillPaint).getAlpha() == 0f)
+        {
+            return (Color)fillPaint;
+        }
+        return super.getClearColor();
+    }
 
     @Override
     public void mouseEvent(final int type, final int button,
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedState.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedState.java	Sat Nov 02 06:58:02 2013 -0700
@@ -51,7 +51,7 @@
         if (isValid()) {
             EmbeddedScene escene = (EmbeddedScene) scene;
             // Pixels are always stored in an IntBuffer for uploading
-            escene.uploadPixels((IntBuffer)pixels.getPixels(), getWidth());
+            escene.uploadPixels(pixels);
             if (uploadCount != null) {
                 uploadCount.decrementAndGet();
             }
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassScene.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/GlassScene.java	Sat Nov 02 06:58:02 2013 -0700
@@ -69,7 +69,7 @@
 
     private NGNode root;
     private NGCamera camera;
-    private Paint fillPaint;
+    protected Paint fillPaint;
 
     // Write from FX thread, read from render thread
     private volatile boolean entireSceneDirty = true;
@@ -332,7 +332,7 @@
         return doPresent;
     }
 
-    final Color getClearColor() {
+    protected Color getClearColor() {
         WindowStage windowStage = stage instanceof WindowStage ? (WindowStage)stage : null;
         if (windowStage != null && windowStage.getPlatformWindow().isTransparentWindow()) {
             return (Color.TRANSPARENT);
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/PresentingPainter.java	Sat Nov 02 06:58:02 2013 -0700
@@ -68,6 +68,9 @@
                 factory = GraphicsPipeline.getDefaultResourceFactory();
             }
             if (factory == null || !factory.isDeviceReady()) {
+                if (!sceneState.getScene().isEntireSceneDirty()) {
+                    sceneState.getScene().entireSceneNeedsRepaint();
+                }
                 return;
             }
 
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/UploadingPainter.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/UploadingPainter.java	Sat Nov 02 06:58:02 2013 -0700
@@ -36,7 +36,6 @@
 import com.sun.prism.impl.BufferUtil;
 import com.sun.prism.impl.Disposer;
 import com.sun.prism.impl.ManagedResource;
-import com.sun.prism.impl.PrismSettings;
 
 /**
  * UploadingPainter is used when we need to render into an offscreen buffer.
@@ -50,6 +49,8 @@
     private IntBuffer   pixBits; // Users for RTTs that are backed by a SW array
     private final AtomicInteger uploadCount = new AtomicInteger(0);
     private RTTexture   rttexture;
+    
+    private volatile float pixScaleFactor = 1.0f;
 
     UploadingPainter(GlassScene view) {
         super(view);
@@ -61,6 +62,15 @@
             rttexture = null;
         }
     }
+    
+    public void setPixelScaleFactor(float scale) {
+        pixScaleFactor = scale;
+    }
+    
+    @Override
+    public float getPixelScaleFactor() {
+        return pixScaleFactor;
+    }    
 
     @Override public void run() {
         renderLock.lock();
@@ -82,9 +92,13 @@
             if (factory == null || !factory.isDeviceReady()) {
                 return;
             }
-
-            boolean needsReset = (rttexture == null) || (viewWidth != penWidth) || (viewHeight != penHeight);
-
+            
+            float scale = pixScaleFactor;
+            
+            boolean needsReset = (pix == null) ||
+                                 (scale != pix.getScaleUnsafe()) ||
+                                 (viewWidth != penWidth) || (viewHeight != penHeight);
+            
             if (!needsReset) {
                 rttexture.lock();
                 if (rttexture.isSurfaceLost()) {
@@ -92,10 +106,13 @@
                     needsReset = true;
                 }
             }
-
+            
+            int bufWidth = (int)Math.round(viewWidth * scale);
+            int bufHeight = (int)Math.round(viewHeight * scale);
+            
             if (needsReset) {
                 disposeRTTexture();
-                rttexture = factory.createRTTexture(viewWidth, viewHeight, WrapMode.CLAMP_NOT_NEEDED);
+                rttexture = factory.createRTTexture(bufWidth, bufHeight, WrapMode.CLAMP_NOT_NEEDED);
                 if (rttexture == null) {
                     return;
                 }
@@ -110,24 +127,25 @@
                 sceneState.getScene().entireSceneNeedsRepaint();
                 return;
             }
+            g.scale(scale, scale);
             paintImpl(g);
 
             int rawbits[] = rttexture.getPixels();
-
+            
             if (rawbits != null) {
                 if (pixBits == null || uploadCount.get() > 0) {
-                    pixBits = IntBuffer.allocate(viewWidth * viewHeight);
+                    pixBits = IntBuffer.allocate(bufWidth * bufHeight);
                 }
-                System.arraycopy(rawbits, 0, pixBits.array(), 0, viewWidth * viewHeight);
-                pix = app.createPixels(viewWidth, viewHeight, pixBits);
+                System.arraycopy(rawbits, 0, pixBits.array(), 0, bufWidth * bufHeight);
+                pix = app.createPixels(bufWidth, bufHeight, pixBits, scale);
             } else {
                 if (textureBits == null || uploadCount.get() > 0) {
-                    textureBits = BufferUtil.newIntBuffer(viewWidth * viewHeight);
+                    textureBits = BufferUtil.newIntBuffer(bufWidth * bufHeight);
                 }
                 
                 if (textureBits != null) {
                     if (rttexture.readPixels(textureBits)) {
-                        pix = app.createPixels(viewWidth, viewHeight, textureBits);
+                        pix = app.createPixels(bufWidth, bufHeight, textureBits, scale);
                     } else {
                         /* device lost */
                         sceneState.getScene().entireSceneNeedsRepaint();
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewPainter.java	Sat Nov 02 06:58:02 2013 -0700
@@ -176,7 +176,7 @@
         // might be reassigned to the sceneBuffer graphics.
         Graphics g = backBufferGraphics;
         // Take into account the pixel scale factor for retina displays
-        final float pixelScale = presentable == null ? 1.0f : presentable.getPixelScaleFactor();
+        final float pixelScale = getPixelScaleFactor();
         // Initialize renderEverything based on various conditions that will cause us to render
         // the entire scene every time.
         boolean renderEverything = renderOverlay ||
@@ -435,6 +435,10 @@
 
         return sceneState.isWindowVisible() && !sceneState.isWindowMinimized();
     }
+    
+    protected float getPixelScaleFactor() {
+        return presentable == null ? 0.1f : presentable.getPixelScaleFactor();
+    }
 
     private void doPaint(Graphics g, NodePath renderRootPath) {
         // Null path indicates that occlusion culling is not used
--- a/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewScene.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/javafx/tk/quantum/ViewScene.java	Sat Nov 02 06:58:02 2013 -0700
@@ -150,6 +150,11 @@
         platformView.enableInputMethodEvents(enable);
     }
 
+    @Override
+    public void finishInputMethodComposition() {
+        platformView.finishInputMethodComposition();
+    }
+
     @Override public String toString() {
         View view = getPlatformView();
         return (" scene: " + hashCode() + " @ (" + view.getWidth() + "," + view.getHeight() + ")");
--- a/modules/graphics/src/main/java/com/sun/prism/impl/GlyphCache.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/com/sun/prism/impl/GlyphCache.java	Sat Nov 02 06:58:02 2013 -0700
@@ -134,12 +134,12 @@
         Point2D pt = new Point2D();
 
         for (int gi = 0; gi < len; gi++) {
-            int gc = gl.getGlyphCode(gi) & CompositeGlyphMapper.GLYPHMASK;
+            int gc = gl.getGlyphCode(gi);
 
             // If we have a supplementary character, then a special
             // glyph is inserted in the list, which is one we skip
             // over for rendering. It has no advance.
-            if (gc == CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
+            if ((gc & CompositeGlyphMapper.GLYPHMASK) == CharToGlyphMapper.INVISIBLE_GLYPH_ID) {
                 continue;
             }
             pt.setLocation(x + gl.getPosX(gi), y + gl.getPosY(gi));
--- a/modules/graphics/src/main/java/javafx/scene/CssStyleHelper.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/CssStyleHelper.java	Sat Nov 02 06:58:02 2013 -0700
@@ -614,7 +614,7 @@
 
         if (cachedFont == null) {
 
-            cachedFont = lookupFont(node, "-fx-font", styleMap, cachedFont, null);
+            cachedFont = lookupFont(node, "-fx-font", styleMap, cachedFont);
 
             if (cachedFont == SKIP) cachedFont = getCachedFont(node.getStyleableParent());
             if (cachedFont == null) cachedFont = new CalculatedValue(Font.getDefault(), null, false);
@@ -628,9 +628,8 @@
         final StyleCacheEntry.Key cacheEntryKey = new StyleCacheEntry.Key(transitionStates, fontForRelativeSizes);
         StyleCacheEntry cacheEntry = sharedCache.getStyleCacheEntry(cacheEntryKey);
 
-        // if no one is watching for styles and the cacheEntry already exists,
-        // then we can definitely take the fastpath
-        final boolean fastpath = this.observableStyleMap == null && cacheEntry != null;
+        // if the cacheEntry already exists, take the fastpath
+        final boolean fastpath = cacheEntry != null;
 
         if (cacheEntry == null) {
             cacheEntry = new StyleCacheEntry();
@@ -671,12 +670,6 @@
 
             final String property = cssMetaData.getProperty();
 
-            // Create a List to hold the Styles if the node has
-            // a Map<WritableValue, List<Style>>
-            final List<Style> styleList = (observableStyleMap != null)
-                    ? new ArrayList<Style>()
-                    : null;
-
             CalculatedValue calculatedValue = cacheEntry.get(property);
 
             // If there is no calculatedValue and we're on the fast path,
@@ -700,7 +693,7 @@
 
                 // slowpath!
                 calculatedValue = lookup(node, cssMetaData, styleMap, transitionStates[0],
-                        node, cachedFont, styleList);
+                        node, cachedFont);
 
                 // lookup is not supposed to return null.
                 if (calculatedValue == null) {
@@ -806,6 +799,7 @@
                 }
 
                 if (observableStyleMap != null) {
+                    List<Style> styleList = getMatchingStyles(node, cssMetaData);
                     observableStyleMap.put(styleableProperty, styleList);
                 }
 
@@ -886,6 +880,7 @@
      *
      *
      *
+     *
      * @param styleable
      * @param states
      * @param originatingStyleable
@@ -896,13 +891,10 @@
                                    final StyleMap styleMap,
                                    final Set<PseudoClass> states,
                                    final Styleable originatingStyleable,
-                                   final CalculatedValue cachedFont,
-                                   final List<Style> styleList) {
+                                   final CalculatedValue cachedFont) {
 
         if (cssMetaData.getConverter() == FontConverter.getInstance()) {
-
-            if (styleList != null) styleList.addAll(getMatchingStyles(styleable, cssMetaData));
-            return lookupFont(styleable, cssMetaData.getProperty(), styleMap, cachedFont, styleList);
+            return lookupFont(styleable, cssMetaData.getProperty(), styleMap, cachedFont);
         }
 
         final String property = cssMetaData.getProperty();
@@ -921,7 +913,7 @@
             if (numSubProperties == 0) {
 
                 return handleNoStyleFound(styleable, cssMetaData,
-                        styleMap, states, originatingStyleable, cachedFont, styleList);
+                        styleMap, states, originatingStyleable, cachedFont);
 
             } else {
 
@@ -944,7 +936,7 @@
                     CssMetaData subkey = subProperties.get(i);
                     CalculatedValue constituent =
                         lookup(styleable, subkey, styleMap, states,
-                                originatingStyleable, cachedFont, styleList);
+                                originatingStyleable, cachedFont);
                     if (constituent != SKIP) {
                         if (subs == null) {
                             subs = new HashMap<CssMetaData,Object>();
@@ -968,7 +960,7 @@
                 // If there are no subkeys which apply...
                 if (subs == null || subs.isEmpty()) {
                     return handleNoStyleFound(styleable, cssMetaData,
-                            styleMap, states, originatingStyleable, cachedFont, styleList);
+                            styleMap, states, originatingStyleable, cachedFont);
                 }
 
                 try {
@@ -1016,11 +1008,8 @@
             // value was "inherit". If so, then we will simply inherit.
             final ParsedValueImpl cssValue = style.getParsedValueImpl();
             if (cssValue != null && "inherit".equals(cssValue.getValue())) {
-                if (styleList != null) styleList.add(style.getStyle());
                 style = getInheritedStyle(styleable, property);
-
                 if (style == null) return SKIP;
-
             }
         }
 
@@ -1028,12 +1017,8 @@
 //                ", selector = \'" + style.selector.toString() + "\'" +
 //                ", node = " + node.toString());
 
-        if (styleList != null) {
-            styleList.add(style.getStyle());
-        }
-
         return calculateValue(style, styleable, cssMetaData, styleMap, states,
-                originatingStyleable, cachedFont, styleList);
+                originatingStyleable, cachedFont);
     }
 
     /**
@@ -1042,8 +1027,7 @@
     private CalculatedValue handleNoStyleFound(final Styleable styleable,
                                                final CssMetaData cssMetaData,
                                                final StyleMap styleMap, Set<PseudoClass> pseudoClassStates, Styleable originatingStyleable,
-                                               final CalculatedValue cachedFont,
-                                               final List<Style> styleList) {
+                                               final CalculatedValue cachedFont) {
 
         if (cssMetaData.isInherits()) {
 
@@ -1065,7 +1049,7 @@
             CalculatedValue cv =
                     calculateValue(style, styleable, cssMetaData,
                             styleMap, pseudoClassStates, originatingStyleable,
-                                   cachedFont, styleList );
+                                   cachedFont);
 
             return cv;
 
@@ -1169,8 +1153,7 @@
             final ParsedValueImpl parsedValue,
             final StyleMap styleMap, Set<PseudoClass> states,
             final ObjectProperty<StyleOrigin> whence,
-            Set<ParsedValue> resolves,
-            final List<Style> styleList) {
+            Set<ParsedValue> resolves) {
 
         //
         // either the value itself is a lookup, or the value contain a lookup
@@ -1200,14 +1183,6 @@
                         resolves.add(parsedValue);
                     }
 
-
-                    if (styleList != null) {
-                        final Style style = resolved.getStyle();
-                        if (style != null && !styleList.contains(style)) {
-                            styleList.add(style);
-                        }
-                    }
-
                     // The origin of this parsed value is the greatest of
                     // any of the resolved reference. If a resolved reference
                     // comes from an inline style, for example, then the value
@@ -1223,7 +1198,7 @@
                     // the resolved value may itself need to be resolved.
                     // For example, if the value "color" resolves to "base",
                     // then "base" will need to be resolved as well.
-                    ParsedValueImpl pv = resolveLookups(styleable, resolved.getParsedValueImpl(), styleMap, states, whence, resolves, styleList);
+                    ParsedValueImpl pv = resolveLookups(styleable, resolved.getParsedValueImpl(), styleMap, states, whence, resolves);
 
                     if (resolves != null) {
                         resolves.remove(parsedValue);
@@ -1252,7 +1227,7 @@
                 for (int ll=0; ll<layers[l].length; ll++) {
                     if (layers[l][ll] == null) continue;
                     resolved[l][ll] =
-                        resolveLookups(styleable, layers[l][ll], styleMap, states, whence, resolves, styleList);
+                        resolveLookups(styleable, layers[l][ll], styleMap, states, whence, resolves);
                 }
             }
 
@@ -1268,7 +1243,7 @@
             for (int l=0; l<layer.length; l++) {
                 if (layer[l] == null) continue;
                 resolved[l] =
-                    resolveLookups(styleable, layer[l], styleMap, states, whence, resolves, styleList);
+                    resolveLookups(styleable, layer[l], styleMap, states, whence, resolves);
             }
 
             resolves.clear();
@@ -1373,8 +1348,7 @@
             final CssMetaData cssMetaData,
             final StyleMap styleMap, final Set<PseudoClass> states,
             final Styleable originatingStyleable,
-            final CalculatedValue fontFromCacheEntry,
-            final List<Style> styleList) {
+            final CalculatedValue fontFromCacheEntry) {
 
         final ParsedValueImpl cssValue = style.getParsedValueImpl();
         if (cssValue != null && !("null").equals(cssValue.getValue())) {
@@ -1383,7 +1357,7 @@
             try {
 
                 ObjectProperty<StyleOrigin> whence = new SimpleObjectProperty<StyleOrigin>(style.getOrigin());
-                resolved = resolveLookups(styleable, cssValue, styleMap, states, whence, new HashSet<ParsedValue>(), styleList);
+                resolved = resolveLookups(styleable, cssValue, styleMap, states, whence, new HashSet<ParsedValue>());
 
                 final String property = cssMetaData.getProperty();
 
@@ -1558,7 +1532,7 @@
 
                 Set<PseudoClass> pseudoClassState = parent.getPseudoClassStates();
                 StyleMap smap = parentHelper.getStyleMap(parent);
-                cachedFont = parentHelper.lookup(parent, dummyFontProperty, smap, pseudoClassState, parent, null, null);
+                cachedFont = parentHelper.lookup(parent, dummyFontProperty, smap, pseudoClassState, parent, null);
             }
         }
 
@@ -1653,8 +1627,7 @@
             final Styleable styleable,
             final String property,
             final StyleMap styleMap,
-            final CalculatedValue cachedFont,
-            final List<Style> styleList)
+            final CalculatedValue cachedFont)
     {
 
         StyleOrigin origin = null;
@@ -1746,7 +1719,7 @@
 
                 final CalculatedValue cv =
                         calculateValue(fontShorthand, styleable, dummyFontProperty,
-                                styleMap, states, styleable, cvFont, styleList);
+                                styleMap, states, styleable, cvFont);
 
                 // cv could be SKIP
                 if (cv.getValue() instanceof Font) {
@@ -1787,7 +1760,7 @@
             // and, therefore, we can use the fontSize style
             final CalculatedValue cv =
                     calculateValue(fontSize, styleable, dummyFontProperty,
-                            styleMap, states, styleable, cvFont, styleList);
+                            styleMap, states, styleable, cvFont);
 
             if (cv.getValue() instanceof Double) {
                 if (origin == null || origin.compareTo(fontSize.getOrigin()) <= 0) {
@@ -1841,7 +1814,7 @@
 
             final CalculatedValue cv =
                     calculateValue(fontWeight, styleable, dummyFontProperty,
-                            styleMap, states, styleable, null, null);
+                            styleMap, states, styleable, null);
 
             if (cv.getValue() instanceof FontWeight) {
                 if (origin == null || origin.compareTo(fontWeight.getOrigin()) <= 0) {
@@ -1878,7 +1851,7 @@
 
             final CalculatedValue cv =
                     calculateValue(fontStyle, styleable, dummyFontProperty,
-                            styleMap, states, styleable, null, null);
+                            styleMap, states, styleable, null);
 
             if (cv.getValue() instanceof FontPosture) {
                 if (origin == null || origin.compareTo(fontStyle.getOrigin()) <= 0) {
@@ -1915,7 +1888,7 @@
 
             final CalculatedValue cv =
                     calculateValue(fontFamily, styleable, dummyFontProperty,
-                            styleMap, states, styleable, null, null);
+                            styleMap, states, styleable, null);
 
             if (cv.getValue() instanceof String) {
                 if (origin == null || origin.compareTo(fontFamily.getOrigin()) <= 0) {
--- a/modules/graphics/src/main/java/javafx/scene/Node.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Node.java	Sat Nov 02 06:58:02 2013 -0700
@@ -8738,9 +8738,10 @@
      * If required, apply styles to this Node and its children, if any. This method does not normally need to 
      * be invoked directly but may be used in conjunction with {@link Parent#layout()} to size a Node before the
      * next pulse, or if the {@link #getScene() Scene} is not in a {@link javafx.stage.Stage}. 
-     * <p>CSS is applied to this Node only if this Node's CSS state is other than clean, or there is a parent that
-     * needs CSS to be applied. This method is a no-op if the Node is not in a Scene. The Scene does not have
-     * to be in a Stage.</p>
+     * <p>Provided that the Node&#39;s {@link #getScene() Scene} is not null, CSS is applied to this Node regardless
+     * of whether this Node&#39;s CSS state is clean. CSS styles are applied from the top&#8209;most parent
+     * of this Node whose CSS state is other than clean, which may affect the styling of other nodes.
+     * This method is a no-op if the Node is not in a Scene. The Scene does not have to be in a Stage.</p>
      * <p>This method does not invoke the {@link Parent#layout()} method. Typically, the caller will use the 
      * following sequence of operations.</p>
      * <pre><code>
@@ -8780,11 +8781,6 @@
             return;
         }
 
-        // quick check to see if there is any possibility that this node needs CSS applied
-        if(cssFlag == CssFlags.CLEAN && getScene().getRoot().cssFlag == CssFlags.CLEAN) {
-            return;
-        }
-
         // If this flag is clean or dirty_branch, make it update
         if (cssFlag != CssFlags.REAPPLY) {
             cssFlag = CssFlags.UPDATE;
--- a/modules/graphics/src/main/java/javafx/scene/ParallelCamera.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/ParallelCamera.java	Sat Nov 02 06:58:02 2013 -0700
@@ -71,9 +71,9 @@
 
     @Override
     final PickRay computePickRay(double x, double y, PickRay pickRay) {
-        return PickRay.computeParallelPickRay(x, y, getCameraTransform(),
-                //TODO: use actual clips after rendering uses them
-                Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, pickRay);
+        return PickRay.computeParallelPickRay(x, y, getViewHeight(),
+                getCameraTransform(),
+                getNearClip(), getFarClip(), pickRay);
     }
 
     @Override
@@ -97,7 +97,13 @@
             position = new Vec3d();
         }
 
-        position.set(0.0, 0.0, -1.0);
+        // This is the same math as in PerspectiveCamera, fixed for the default
+        // 30 degrees vertical field of view.
+        final double halfViewWidth = getViewWidth() / 2.0;
+        final double halfViewHeight = getViewHeight() / 2.0;
+        final double distanceZ = halfViewHeight / Math.tan(Math.toRadians(15.0));
+        position.set(halfViewWidth, halfViewHeight, -distanceZ);
+
         return position;
     }
 }
--- a/modules/graphics/src/main/java/javafx/scene/Scene.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/Scene.java	Sat Nov 02 06:58:02 2013 -0700
@@ -1794,7 +1794,7 @@
      */
     Node test_pick(double x, double y) {
         inMousePick = true;
-        PickResult result = mouseHandler.pickNode(new PickRay(x, y,
+        PickResult result = mouseHandler.pickNode(new PickRay(x, y, 1,
                 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
         inMousePick = false;
         if (result != null) {
@@ -2328,6 +2328,8 @@
                 PerformanceTracker.logEvent("Scene - first repaint");
             }
 
+            focusCleanup();
+
             if (PULSE_LOGGING_ENABLED) {
                 long start = System.currentTimeMillis();
                 Scene.this.doCSSPass();
@@ -2386,8 +2388,6 @@
             // required for image cursor created from animated image
             Scene.this.mouseHandler.updateCursorFrame();
 
-            focusCleanup();
-
             if (firstPulse) {
                 if (PerformanceTracker.isLoggingEnabled()) {
                     PerformanceTracker.logEvent("Scene - first repaint - layout complete");
@@ -3808,6 +3808,18 @@
 
     class KeyHandler {
         private void setFocusOwner(final Node value) {
+            // Cancel IM composition if there is one in progress.
+            // This needs to be done before the focus owner is switched as it
+            // generates event that needs to be delivered to the old focus owner.
+            if (oldFocusOwner != null) {
+                final Scene s = oldFocusOwner.getScene();
+                if (s != null) {
+                    final TKScene peer = s.impl_getPeer();
+                    if (peer != null) {
+                        peer.finishInputMethodComposition();
+                    }
+                }
+            }
             focusOwner.set(value);
         }
 
--- a/modules/graphics/src/main/java/javafx/scene/image/ImageView.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/image/ImageView.java	Sat Nov 02 06:58:02 2013 -0700
@@ -215,8 +215,8 @@
                                 addListener(platformImageChangeListener.getWeakListener());
                     }
                     if (dimensionChanged) {
+                        invalidateWidthHeight();
                         impl_geomChanged();
-                        invalidateWidthHeight();
                     }
                     impl_markDirty(DirtyBits.NODE_CONTENTS);
                 }
@@ -280,9 +280,9 @@
             new AbstractNotifyListener() {
         @Override
         public void invalidated(Observable valueModel) {
+            invalidateWidthHeight();
             impl_markDirty(DirtyBits.NODE_CONTENTS);
             impl_geomChanged();
-            invalidateWidthHeight();
         }
     };
     /**
@@ -393,9 +393,9 @@
 
                 @Override
                 protected void invalidated() {
+                    invalidateWidthHeight();
                     impl_markDirty(DirtyBits.NODE_VIEWPORT);
-                    impl_geomChanged();
-                    invalidateWidthHeight();
+                    impl_geomChanged();                    
                 }
 
                 @Override
@@ -441,9 +441,9 @@
 
                 @Override
                 protected void invalidated() {
+                    invalidateWidthHeight();
                     impl_markDirty(DirtyBits.NODE_VIEWPORT);
                     impl_geomChanged();
-                    invalidateWidthHeight();
                 }
 
                 @Override
@@ -506,9 +506,9 @@
 
                 @Override
                 protected void invalidated() {
+                    invalidateWidthHeight();
                     impl_markDirty(DirtyBits.NODE_VIEWPORT);
                     impl_geomChanged();
-                    invalidateWidthHeight();
                 }
 
                 @Override
@@ -610,9 +610,9 @@
 
                 @Override
                 protected void invalidated() {
+                    invalidateWidthHeight();
                     impl_markDirty(DirtyBits.NODE_VIEWPORT);
                     impl_geomChanged();
-                    invalidateWidthHeight();
                 }
 
                 @Override
--- a/modules/graphics/src/main/java/javafx/scene/layout/GridPane.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/scene/layout/GridPane.java	Sat Nov 02 06:58:02 2013 -0700
@@ -1980,8 +1980,13 @@
             if (portion != 0) {
                 for (Iterator<Integer> i = adjusting.iterator(); i.hasNext();) {
                     final int index = i.next();
-                    final double limit = snapSpace(limitSize.getProportionalSize(index))
+                    double limit = snapSpace(limitSize.getProportionalMinOrMaxSize(index, shrinking))
                             - heights.getSize(index); // negative in shrinking case
+                    if (shrinking && limit > 0
+                            || !shrinking && limit < 0) { // Limit completely if current size
+                                                 // (originally based on preferred) already passed the computed limit
+                        limit = 0;
+                    }
                     final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
                     heights.addSize(index, change);
                     available -= change;
@@ -2209,8 +2214,13 @@
             if (portion != 0) {
                 for (Iterator<Integer> i = adjusting.iterator(); i.hasNext();) {
                     final int index = i.next();
-                    final double limit = snapSpace(limitSize.getProportionalSize(index))
+                    double limit = snapSpace(limitSize.getProportionalMinOrMaxSize(index, shrinking))
                             - widths.getSize(index); // negative in shrinking case
+                    if (shrinking && limit > 0
+                            || !shrinking && limit < 0) { // Limit completely if current size
+                                                 // (originally based on preferred) already passed the computed limit
+                        limit = 0;
+                    }
                     final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
                     widths.addSize(index, change);
                     available -= change;
@@ -2543,7 +2553,7 @@
             }
         }
 
-        private double getProportionalSize(int position) {
+        private double getProportionalMinOrMaxSize(int position, boolean min) {
             double result = singleSizes[position];
             if (!isPreset(position) && multiSizes != null) {
                 for (Interval i : multiSizes.keySet()) {
@@ -2552,18 +2562,18 @@
                         double propSize = segment;
                         for (int j = i.begin; j < i.end; ++j) {
                             if (j != position) {
-                                if (singleSizes[j] > segment) {
-                                    propSize += singleSizes[j] - segment;
+                                if (min ? singleSizes[j] > segment : singleSizes[j] < segment) {
+                                    propSize += segment - singleSizes[j];
                                 }
                             }
                         }
-                        result = Math.max(result, propSize);
+                        result = min ? Math.max(result, propSize) : Math.min(result, propSize);
                     }
                 }
             }
             return result;
         }
-
+        
         private double computeTotal(final int from, final int to) {
             double total = gap * (to - from - 1);
             for (int i = from; i < to; ++i) {
--- a/modules/graphics/src/main/java/javafx/stage/PopupWindow.java	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/java/javafx/stage/PopupWindow.java	Sat Nov 02 06:58:02 2013 -0700
@@ -432,8 +432,10 @@
         
         // RT-28447
         final Scene ownerScene = getRootWindow(owner).getScene();
-        sceneValue.getStylesheets().setAll(ownerScene.getStylesheets());
-        
+        if (ownerScene != null) {
+            sceneValue.getStylesheets().setAll(ownerScene.getStylesheets());
+        }
+
         // It is required that the root window exist and be visible to show the popup.
         if (getRootWindow(owner).isShowing()) {
             // We do show() first so that the width and height of the
--- a/modules/graphics/src/main/native-glass/gtk/GlassWindow.cpp	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/GlassWindow.cpp	Sat Nov 02 06:58:02 2013 -0700
@@ -176,7 +176,7 @@
 
 /*
  * Class:     com_sun_glass_ui_gtk_GtkWindow
- * Method:    _setBounds
+ * Method:    setBoundsImpl
  * Signature: (JIIZZIIII)V
  */
 JNIEXPORT void JNICALL Java_com_sun_glass_ui_gtk_GtkWindow_setBoundsImpl
--- a/modules/graphics/src/main/native-glass/gtk/glass_window.cpp	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window.cpp	Sat Nov 02 06:58:02 2013 -0700
@@ -627,7 +627,9 @@
             resizable(),
             xshape(),
             frame_extents_initialized(),
-            map_received(false)
+            map_received(false),
+            location_assigned(false),
+            size_assigned(false)
 {
     jwindow = mainEnv->NewGlobalRef(_jwindow);
 
@@ -1032,6 +1034,18 @@
     }
 }
 
+void WindowContextTop::set_visible(bool visible)
+{
+    if (visible) {
+        if (!size_assigned) {
+            set_bounds(0, 0, false, false, 320, 200, -1, -1);
+        }
+        if (!location_assigned) {
+            set_bounds(0, 0, true, true, -1, -1, -1, -1);
+        }
+    }
+    WindowContextBase::set_visible(visible);
+}
 
 void WindowContextTop::set_bounds(int x, int y, bool xSet, bool ySet, int w, int h, int cw, int ch) {
     if (!frame_extents_initialized && frame_type == TITLED) {
@@ -1089,6 +1103,9 @@
         windowChangesMask |= CWY;
     }
 
+    if (xSet || ySet) location_assigned = true;
+    if (w > 0 || h > 0 || cw > 0 || ch > 0) size_assigned = true;
+
     window_configure(&windowChanges, windowChangesMask);
 
 }
@@ -1240,6 +1257,10 @@
 void WindowContextTop::set_minimized(bool minimize) {
     is_iconified = minimize;
     if (minimize) {
+        if (frame_type == TRANSPARENT) {
+            // https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1245571
+            gdk_window_input_shape_combine_mask(gdk_window, NULL, 0, 0);
+        }
         gtk_window_iconify(GTK_WINDOW(gtk_widget));
     } else {
         gtk_window_deiconify(GTK_WINDOW(gtk_widget));
--- a/modules/graphics/src/main/native-glass/gtk/glass_window.h	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window.h	Sat Nov 02 06:58:02 2013 -0700
@@ -376,6 +376,8 @@
 
     bool frame_extents_initialized;
     bool map_received;
+    bool location_assigned;
+    bool size_assigned;
 public:
     WindowContextTop(jobject, WindowContext*, long, WindowFrameType, WindowType);
     void process_map();
@@ -402,6 +404,7 @@
     void set_modal(bool, WindowContext* parent = NULL);
     void set_gravity(float, float);
     void set_level(int);
+    void set_visible(bool);
 
     void enter_fullscreen();
     void exit_fullscreen();
--- a/modules/graphics/src/main/native-glass/lens/input/udev/udevInput.c	Thu Oct 31 17:45:18 2013 -0700
+++ b/modules/graphics/src/main/native-glass/lens/input/udev/udevInput.c	Sat Nov 02 06:58:02 2013 -0700
@@ -107,7 +107,7 @@
     /* multitouch points */
     int                     nextTouchID; // ID used for the next new touch point
     // the ID of the point that mouse events will be synthesize from
-    int                     touchPrimaryPointID; 
+    int                     touchPrimaryPointID;
     /* existing touch points that have already been sent up to Glass */
     int                     touchPointCount;
     int                     touchIDs[LENS_MAX_TOUCH_POINTS];
@@ -236,6 +236,8 @@
 #define LENS_MAX_MOVE_SENSITIVITY 1000
 static int gTouchMoveSensitivity = 3; //pixels
 
+static jboolean gUseMultiTouch = JNI_FALSE;
+
 
 //JNI
 static JNIEnv *gJNIEnv = NULL;
@@ -343,6 +345,10 @@
                                                            "touchMoveSensitivity",
                                                            "I");
 
+        jfieldID useMultiVar = (*env)->GetStaticFieldID(env,
+                                                           lensTouchInputSupport,
+                                                           "useMultiTouch",
+                                                           "Z");
         //try to set tap radius
         if (radiusVar != NULL) {
             int confRadius = (*env)->GetStaticIntField(env,
@@ -390,6 +396,20 @@
                              className);
         }
 
+        //try to set multi-touch enabled property
+        if (useMultiVar != NULL) {
+            gUseMultiTouch = (*env)->GetStaticBooleanField(env,
+                                                           lensTouchInputSupport,
+                                                           useMultiVar);
+            GLASS_LOG_CONFIG("multitouch usage was set to %s",
+                             gUseMultiTouch? "true" : "false");
+        } else {
+            GLASS_LOG_SEVERE("Could not find static useMultiTouch filed in %s, "
+                             "disabling multi touch support",
+                             className);
+            gUseMultiTouch = JNI_FALSE;
+        }
+
     } else {
         GLASS_LOG_SEVERE("Could not find %s", className);
     }
@@ -1760,6 +1780,8 @@
 
 
             int primaryPointIndex = -1;
+            jboolean primaryPointReassigned = JNI_FALSE;
+
             //Find the primary point in this touch event. Mouse events will be
             //synthesized from it
             if (mouseState->touchPrimaryPointID == -1) {
@@ -1798,6 +1820,7 @@
                                          " reassign to point[%d], id = %d ",
                                          i,
                                          (int)ids[i]);
+                            primaryPointReassigned = JNI_TRUE;
                             break;
                         }
                     }
@@ -1810,8 +1833,44 @@
 
             if (primaryPointIndex == -1) {
                  GLASS_LOG_FINEST("primary point not found - release");
+                 mouseState->touchPrimaryPointID = -1; //mark as not set
+
             }
 
+            //check if we can use multi touch events and simulate single touch 
+            //screen event, if not.
+            //follow primaryPointIndex for notifications
+            if (!gUseMultiTouch && 
+                device->isTouch && device->touchProtocolType != TOUCH_PROTOCOL_ST ) {                
+                if (primaryPointIndex > -1) {
+                    GLASS_LOG_FINEST("[multi->single] Using primary point with index"
+                                     " %d for notification",
+                                     primaryPointIndex);
+                    //use index point
+
+                    ids[0] = 1; //always use same point id
+                    count = 1;
+                    if (primaryPointReassigned && 
+                        states[primaryPointIndex] == com_sun_glass_events_TouchEvent_TOUCH_PRESSED) {
+                        //avoid double press
+                        states[0] = com_sun_glass_events_TouchEvent_TOUCH_MOVED;
+                    } else {
+                        states[0] = states[primaryPointIndex];
+                    }
+                    xs[0] = xs[primaryPointIndex];
+                    ys[0] = ys[primaryPointIndex];
+                    
+                    primaryPointIndex = 0;
+                } else {
+                    //all points were released, just drop the count to 1. The 
+                    //coordinates from the first point will be used for the notification
+                    GLASS_LOG_FINEST("[multi->single] All points released, using first "
+                                     " point for notification");
+                    ids[0] = 1;
+                    count = 1;
+                }
+            }//!gUseMultiTouch
+
             GLASS_IF_LOG_FINEST {