diff -r 07c0a2cbf8f3 javafx-ui-common/src/javafx/scene/Node.java
--- a/javafx-ui-common/src/javafx/scene/Node.java	Thu Sep 27 15:47:20 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/Node.java	Tue Oct 02 17:25:29 2012 -0700
@@ -137,6 +137,7 @@
 import com.sun.javafx.scene.traversal.Direction;
 import com.sun.javafx.sg.PGNode;
 import com.sun.javafx.tk.Toolkit;
+import javafx.geometry.NodeOrientation;
 
 /**
  * Base class for scene graph nodes. A scene graph is a set of tree data structures
@@ -3043,7 +3044,7 @@
             return;
         }
         layoutBounds.invalidate();
-        if (nodeTransformation != null && nodeTransformation.hasScaleOrRotate()) {
+        if (nodeTransformation != null && nodeTransformation.hasScaleOrRotate() && computeNodeOrientation()) {
             // if either the scale or rotate convenience variables are used,
             // then we need a valid pivot point. Since the layoutBounds
             // affects the pivot we need to invalidate the transform
@@ -3888,7 +3889,7 @@
      * This helper function will update the transform matrix on the peer based
      * on the "complete" transform for this node.
      */
-    void updateLocalToParentTransform() {
+    void updateLocalToParentTransform() {               
         if (transformDirty) {
             localToParentTx.setToIdentity();
             if (getScaleX() != 1 || getScaleY() != 1 || getScaleZ() != 1 || getRotate() != 0) {
@@ -3903,13 +3904,21 @@
             } else {
                 localToParentTx.translate(getTranslateX() + getLayoutX(), getTranslateY() + getLayoutY(), getTranslateZ());
             }
-
+           
             if (impl_hasTransforms()) {
                 for (Transform t : getTransforms()) {
                     t.impl_apply(localToParentTx);
                 }
             }
 
+            if (computeNodeOrientation()) {   
+                // Mirror the node.
+                double xOffset = impl_getPivotX();                
+                localToParentTx.translate(xOffset, 0, 0);
+                localToParentTx.scale(-1, 1);
+                localToParentTx.translate(-xOffset, 0, 0);
+            }
+            
             transformDirty = false;
         }
     }
@@ -4971,6 +4980,104 @@
 
     /***************************************************************************
      *                                                                         *
+     *                       Component Orientation Properties                  *
+     *                                                                         *
+     **************************************************************************/
+    
+    private ObjectProperty<NodeOrientation> nodeOrientation;
+    private static final NodeOrientation DEFAULT_NODE_ORIENTATION = NodeOrientation.INHERIT;
+    
+    public final void setNodeOrientation(NodeOrientation orientation) {
+        nodeOrientationProperty().set(orientation);
+    }
+    
+    public final NodeOrientation getNodeOrientation() {        
+        return nodeOrientation == null ? DEFAULT_NODE_ORIENTATION : nodeOrientation.get();
+    }
+    
+    public final ObjectProperty<NodeOrientation> nodeOrientationProperty() {
+        if (nodeOrientation == null) {           
+            nodeOrientation = new StyleableObjectProperty<NodeOrientation>(DEFAULT_NODE_ORIENTATION) {       
+                @Override
+                protected void invalidated() {
+                    impl_transformsChanged();
+                    // Apply the transform to all the children of this Node.  If we do not do this
+                    // the children's orientation will not get updated.
+                    if (Node.this instanceof Parent) {
+                        Parent p = (Parent)Node.this;
+                        List<Node> children = p.getChildren();
+                        for (int i = 0, max = children.size(); i < max; i++) {
+                            Node n = p.getChildren().get(i);
+                            n.impl_transformsChanged();
+                        }
+                    }
+                }
+                
+                @Override
+                public Object getBean() {
+                    return Node.this;
+                }
+
+                @Override
+                public String getName() {
+                    return "nodeOrientation";
+                }
+
+                @Override
+                public StyleableProperty getStyleableProperty() {
+                    throw new UnsupportedOperationException("Not supported yet.");
+                }
+                
+            };
+        }
+        return nodeOrientation;
+    }
+    
+    public final NodeOrientation getEffectiveNodeOrientation() {
+        return computeNodeOrientation(this);
+    }
+        
+    private NodeOrientation computeNodeOrientation(Node node) {
+        if (NodeOrientation.INHERIT.equals(node.getNodeOrientation())) {
+            // Orientation is inherited walk up the tree to find its orientation.
+            Parent p = getParent();            
+            while (p != null) {
+                if (NodeOrientation.INHERIT.equals(p.getNodeOrientation())) {
+                    p = p.getParent();
+                } else {
+                    return p.getNodeOrientation();
+                }
+            }                    
+        }        
+        return node.getNodeOrientation();
+    }
+    
+    // Return true if the node needs to be mirrored.
+    private boolean computeNodeOrientation() {        
+        NodeOrientation orientation = getNodeOrientation();     
+        // By default we assume LTR.  If it is RTL we want to return true
+        // so we can mirror the scene.
+        if (getScene() != null && getScene().getRoot() != null && getScene().getRoot().equals(this) && NodeOrientation.RIGHT_TO_LEFT.equals(orientation)) {
+            return true;
+        }
+        // We don't need to do anything if the node is inherited.
+        if (NodeOrientation.INHERIT.equals(orientation)) {
+            return false;
+        }
+        
+        NodeOrientation parentOrientation = orientation;        
+        Parent p = getParent();        
+        if (p != null) {
+            parentOrientation = p.getNodeOrientation();
+            if (NodeOrientation.INHERIT.equals(p.getNodeOrientation())) {
+                parentOrientation = computeNodeOrientation(p);
+            }             
+        }        
+        return !parentOrientation.equals(orientation);
+    }
+    
+    /***************************************************************************
+     *                                                                         *
      *                       Misc Seldom Used Properties                       *
      *                                                                         *
      **************************************************************************/
diff -r 07c0a2cbf8f3 javafx-ui-common/src/javafx/scene/Scene.java
--- a/javafx-ui-common/src/javafx/scene/Scene.java	Thu Sep 27 15:47:20 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/Scene.java	Tue Oct 02 17:25:29 2012 -0700
@@ -128,6 +128,7 @@
 
 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGING_ENABLED;
 import static com.sun.javafx.logging.PulseLogger.PULSE_LOGGER;
+import javafx.geometry.NodeOrientation;
 
 /**
  * The JavaFX {@code Scene} class is the container for all content in a scene graph.
@@ -949,7 +950,7 @@
      */
     private ObjectProperty<Parent> root;
 
-    public final void setRoot(Parent value) {
+    public final void setRoot(Parent value) {        
         rootProperty().set(value);
     }
 
@@ -1000,6 +1001,9 @@
                     if (_value.getImpl_traversalEngine() == null) {
                         _value.setImpl_traversalEngine(new TraversalEngine(_value, true));
                     }
+                    if (_value.getNodeOrientation() == null || NodeOrientation.INHERIT.equals(_value.getNodeOrientation())) {
+                        _value.setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
+                    }
                     _value.getStyleClass().add(0, "root");
                     _value.setScene(Scene.this);
                     markDirty(DirtyBits.ROOT_DIRTY);
@@ -1017,7 +1021,7 @@
                     return "root";
                 }
             };
-        }
+        }         
         return root;
     }
 
diff -r 07c0a2cbf8f3 javafx-ui-common/src/javafx/scene/text/Text.java
--- a/javafx-ui-common/src/javafx/scene/text/Text.java	Thu Sep 27 15:47:20 2012 -0700
+++ b/javafx-ui-common/src/javafx/scene/text/Text.java	Tue Oct 02 17:25:29 2012 -0700
@@ -73,6 +73,7 @@
 import com.sun.javafx.sg.PGTextHelper;
 import com.sun.javafx.tk.FontLoader;
 import com.sun.javafx.tk.Toolkit;
+import javafx.geometry.NodeOrientation;
 
 /**
  * The {@code Text} class defines a node that displays a text.
@@ -147,10 +148,11 @@
         if (fontLoader == null) {
             fontLoader = Toolkit.getToolkit().getFontLoader();
         }
+        setNodeOrientation(NodeOrientation.LEFT_TO_RIGHT);
         setPickOnBounds(true);
         getDecorationShapes();
         setBaselineOffset(
-             fontLoader.getFontMetrics(getFontInternal()).getAscent());
+             fontLoader.getFontMetrics(getFontInternal()).getAscent());        
     }
 
     /**
diff -r 07c0a2cbf8f3 javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/PaginationBehavior.java
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/PaginationBehavior.java	Thu Sep 27 15:47:20 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/PaginationBehavior.java	Tue Oct 02 17:25:29 2012 -0700
@@ -48,6 +48,7 @@
 import com.sun.javafx.scene.control.skin.PaginationSkin;
 import java.util.ArrayList;
 import java.util.List;
+import javafx.geometry.NodeOrientation;
 import javafx.scene.input.KeyCode;
 import javafx.scene.input.MouseEvent;
 
@@ -73,10 +74,18 @@
     @Override protected void callAction(String name) {
         if (LEFT.equals(name)) {
             PaginationSkin ps = (PaginationSkin)getControl().getSkin();
-            ps.selectPrevious();
+            if (NodeOrientation.RIGHT_TO_LEFT.equals(getControl().getNodeOrientation())) {
+                ps.selectNext();
+            } else {
+                ps.selectPrevious();
+            }
         } else if (RIGHT.equals(name)) {
             PaginationSkin ps = (PaginationSkin)getControl().getSkin();
-            ps.selectNext();
+            if (NodeOrientation.RIGHT_TO_LEFT.equals(getControl().getNodeOrientation())) {
+                ps.selectPrevious();
+            } else {
+                ps.selectNext();
+            }
         } else {
             super.callAction(name);
         }
diff -r 07c0a2cbf8f3 javafx-ui-controls/src/com/sun/javafx/scene/control/skin/SplitPaneSkin.java
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/SplitPaneSkin.java	Thu Sep 27 15:47:20 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/SplitPaneSkin.java	Tue Oct 02 17:25:29 2012 -0700
@@ -48,6 +48,7 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import javafx.geometry.NodeOrientation;
 import javafx.scene.Group;
 
 public class SplitPaneSkin extends SkinBase<SplitPane, BehaviorBase<SplitPane>>  {
@@ -237,6 +238,8 @@
                 if (horizontal) {
                     divider.setInitialPos(divider.getDividerPos());
                     divider.setPressPos(e.getSceneX());
+                    divider.setPressPos(NodeOrientation.RIGHT_TO_LEFT.equals(getSkinnable().getNodeOrientation())
+                            ? getWidth() - e.getSceneX() : e.getSceneX());
                 } else {
                     divider.setInitialPos(divider.getDividerPos());
                     divider.setPressPos(e.getSceneY());
@@ -247,7 +250,13 @@
 
         divider.setOnMouseDragged(new EventHandler<MouseEvent>() {
             @Override public void handle(MouseEvent e) {                
-                double delta = (horizontal ? e.getSceneX() : e.getSceneY()) - divider.getPressPos();                
+                double delta = 0; 
+                if (horizontal) {
+                    delta = NodeOrientation.RIGHT_TO_LEFT.equals(getSkinnable().getNodeOrientation()) ? getWidth() - e.getSceneX() : e.getSceneX();
+                } else {
+                    delta = e.getSceneY();
+                }
+                delta -= divider.getPressPos();
                 double newPos = Math.ceil(divider.getInitialPos() + delta);    
                 checkDividerPos = true;
                 setAbsoluteDividerPos(divider, newPos);
diff -r 07c0a2cbf8f3 javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TabPaneSkin.java
--- a/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TabPaneSkin.java	Thu Sep 27 15:47:20 2012 -0700
+++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/TabPaneSkin.java	Tue Oct 02 17:25:29 2012 -0700
@@ -296,7 +296,7 @@
         }
     }
 
-    private void removeTab(Tab tab) {
+    private void removeTab(Tab tab) {        
         final TabHeaderSkin tabRegion = tabHeaderArea.getTabHeaderSkin(tab);
         tabHeaderArea.removeTab(tab);
         removeTabContent(tab);
@@ -700,8 +700,8 @@
                     // we need its width to compute the scroll offset.
                     removeTab.add(tabHeaderSkin);
                     tabHeaderSkin.removeListeners(tab);
-                }
-            }
+                }                                
+            }            
         }
 
         private TabHeaderSkin getTabHeaderSkin(Tab tab) {
@@ -1617,6 +1617,10 @@
                 popup = new ContextMenu();
 //                popup.setManaged(false);
             }
+            for (MenuItem mi: popup.getItems()) {
+                TabMenuItem tmi = (TabMenuItem)mi;
+                tmi.getToggleGroup().getToggles().clear();
+            }
             popup.getItems().clear();
             ToggleGroup group = new ToggleGroup();
             ObservableList<RadioMenuItem> menuitems = FXCollections.<RadioMenuItem>observableArrayList();
