     //  height
     //----------------------------------
     
-    /**
-     *  @private
-     *  We must override height as well because setting
-     *  height will force scaleX to be positive in the transform
-     *  matrix.
+    private var _height:Number;
+    
+    /**
+     *  @private
+     */
+    override public function get height():Number
+    {
+        return (layoutFeatures == null) ? super.height : _height;
+    }
+    
+    /**
+     *  @private
      */
     override public function set height(value:Number):void  
     {
-        if (mirror)
-        {
-            transform.matrix = origMatrix;
+        if (height == value)
+            return;
+        
+        if (layoutFeatures == null)
+        {
             super.height = value;
-            // Store new scaleX/Y since setting height may modify them
-            _scaleX = super.scaleX;
-            _scaleY = super.scaleY;
-            validateTransformMatrix();
-        }
-        else
-        {
-            super.height = value;
-        }
+        }
+        else
+        {
+            _height = value;
+            // Calculate scaleY based on initial height. We set scaleY
+            // here because resizing a BitmapAsset normally would adjust
+            // the scale to match.
+            layoutFeatures.layoutScaleY = measuredHeight != 0 ? value / measuredHeight : 0;
+            validateTransformMatrix();
+        }
+    }
+    
+    //----------------------------------
+    //  rotation
+    //----------------------------------
+    
+    /**
+     *  @private
+     */
+    override public function get rotationX():Number
+    {
+        return (layoutFeatures == null) ? super.rotationX : layoutFeatures.layoutRotationX;
+    }
+    
+    /**
+     *  @private
+     */
+    override public function set rotationX(value:Number):void
+    {
+        if (rotationX == value)
+            return;
+        
+        if (layoutFeatures == null)
+        {
+            super.rotationX = value;
+        }
+        else
+        {
+            layoutFeatures.layoutRotationX = value;
+            validateTransformMatrix();
+        }
+    }
+    /**
+     *  @private
+     */
+    override public function get rotationY():Number
+    {
+        return (layoutFeatures == null) ? super.rotationY : layoutFeatures.layoutRotationY;
+    }
+    
+    /**
+     *  @private
+     */
+    override public function set rotationY(value:Number):void
+    {
+        if (rotationY == value)
+            return;
+        
+        if (layoutFeatures == null)
+        {
+            super.rotationY = value;
+        }
+        else
+        {
+            layoutFeatures.layoutRotationY = value;
+            validateTransformMatrix();
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    override public function get rotationZ():Number
+    {
+        return (layoutFeatures == null) ? super.rotationZ : layoutFeatures.layoutRotationZ;
+    }
+    
+    /**
+     *  @private
+     */
+    override public function set rotationZ(value:Number):void
+    {
+        if (rotationZ == value)
+            return;
+        
+        if (layoutFeatures == null)
+        {
+            super.rotationZ = value;
+        }
+        else
+        {
+            layoutFeatures.layoutRotationZ = value;
+            validateTransformMatrix();
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    override public function get rotation():Number
+    {
+        return (layoutFeatures == null) ? super.rotation : layoutFeatures.layoutRotationZ;
+    }
+    
+    /**
+     *  @private
+     */
+    override public function set rotation(value:Number):void
+    {
+        rotationZ = value;
     }
     
     //----------------------------------
     //  scaleX
     //----------------------------------
     
-    private var _scaleX:Number;
+    /**
+     *  @private
+     */
+    override public function get scaleX():Number
+    {
+        return (layoutFeatures == null) ? super.scaleX : layoutFeatures.layoutScaleX;
+    }
     
     /**
      *  @private
      */
     override public function set scaleX(value:Number):void
     {
-        if (mirror)
-        {
-            transform.matrix = origMatrix;
+        if (scaleX == value)
+            return;
+        
+        if (layoutFeatures == null)
+        {
             super.scaleX = value;
-            _scaleX = value;
-            validateTransformMatrix();
-        }
-        else
-        {
-            super.scaleX = value;
-        }
-    }
-    
-    override public function get scaleX():Number
-    {
-        return (mirror) ? _scaleX : super.scaleX;
+        }
+        else
+        {
+            layoutFeatures.layoutScaleX = value;
+            layoutFeatures.layoutWidth = value * measuredWidth;
+            validateTransformMatrix();
+        }
     }
     
     //----------------------------------
     //  scaleY
     //----------------------------------
     
-    private var _scaleY:Number;
+    /**
+     *  @private
+     */
+    override public function get scaleY():Number
+    {
+        return (layoutFeatures == null) ? super.scaleY : layoutFeatures.layoutScaleY;
+    }
     
     /**
      *  @private
      */
     override public function set scaleY(value:Number):void
     {
-        if (mirror)
-        {
-            transform.matrix = origMatrix;
+        if (scaleY == value)
+            return;
+        
+        if (layoutFeatures == null)
+        {
             super.scaleY = value;
-            _scaleY = value;
-            validateTransformMatrix();
-        }
-        else
-        {
-            super.scaleY = value;
-        }
-    }
-    
-    override public function get scaleY():Number
-    {
-        return (mirror) ? _scaleY : super.scaleY;
+        }
+        else
+        {
+            layoutFeatures.layoutScaleY = value;
+            _height = value * measuredHeight;
+            validateTransformMatrix();
+        }
+    }
+    
+    //----------------------------------
+    //  scaleZ
+    //----------------------------------
+    
+    /**
+     *  @private
+     */
+    override public function get scaleZ():Number
+    {
+        return (layoutFeatures == null) ? super.scaleZ : layoutFeatures.layoutScaleZ;
+    }
+    
+    /**
+     *  @private
+     */
+    override public function set scaleZ(value:Number):void
+    {
+        if (scaleZ == value)
+            return;
+        
+        if (layoutFeatures == null)
+        {
+            super.scaleZ = value;
+        }
+        else
+        {
+            layoutFeatures.layoutScaleZ = value;
+            validateTransformMatrix();
+        }
     }
 
     //--------------------------------------------------------------------------

     */
    public function invalidateLayoutDirection():void
    {
        // We check the closest parent's layoutDirection property
        // set our mirror property and update our transform matrix
        // accordingly.
        var p:DisplayObjectContainer = parent;
        
        while (p)
        {
            if (p is ILayoutDirectionElement)
            {
                // If this element's layoutDirection doesn't match its parent's, then
                // set the mirror flag.
                const oldMirror:Boolean = mirror;
                mirror = (_layoutDirection != null) &&
                    (_layoutDirection != ILayoutDirectionElement(p).layoutDirection);
                
                if (mirror != oldMirror)
                {
                    if (mirror)
                    {
                        // Set backing variables to current state
                        _scaleX = super.scaleX;
                        _scaleY = super.scaleY;
                        _x = super.x;
                        validateTransformMatrix();
                    }
                    else
                    {
                        // origMatrix has been initialized in validateTransformMatrix
                        // because we weren't matching our parent's layoutDirection before.
                        transform.matrix = origMatrix;
                    }
                }
                break;
            }
            

    
    /**
     *  @private
     *  Initializes AdvancedLayoutFeatures for this asset when mirroring.
     */
    private function initAdvancedLayoutFeatures():void
    {
        var features:AdvancedLayoutFeatures = new AdvancedLayoutFeatures();
        
        features.layoutScaleX = scaleX;
        features.layoutScaleY = scaleY;
        features.layoutScaleZ = scaleZ;
        features.layoutRotationX = rotationX;
        features.layoutRotationY = rotationY;
        features.layoutRotationZ = rotation;
        features.layoutX = x;
        features.layoutY = y;
        features.layoutZ = z;
        features.layoutWidth = width;  // for the mirror transform
        _height = height;  // for backing storage
        layoutFeatures = features;
    }
    
    /**
     *  @private
     *  Applies the transform matrix calculated by AdvancedLayoutFeatures 
     *  so that this bitmap will not be mirrored if a parent is mirrored.
     */
    private function validateTransformMatrix():void
    {
        if (layoutFeatures != null)
        {
            if (layoutFeatures.is3D)
                super.transform.matrix3D = layoutFeatures.computedMatrix3D;
            else
                super.transform.matrix = layoutFeatures.computedMatrix;
        }
    }
}

