             stateChangeComplete_handler(null); // Call directly
     }
     
+    /**
+     *  @private
+     */
+    private function playEffect(yTo:Number, heightTo:Number):void
+    {
+        // stop the current effect
+        if (effect && effect.isPlaying)
+            effect.stop();
+        
+        var duration:Number = getStyle("softKeyboardEffectDuration");
+        
+        if (duration > 0)
+            effect = createSoftKeyboardEffect(yTo, heightTo);
+        
+        if (effect)
+        {
+            effect.duration = duration;
+            effect.play();
+        }
+        else
+        {
+            this.y = yTo;
+            this.height = heightTo;
+        }
+    }
+    
+    /**
+     *  Called by the soft keyboard activate and deactive event handlers, this
+     *  method is responsible for creating the Spark effect played on the pop-up.
+     * 
+     *  This method may be overridden by subclasses. By default, it
+     *  creates a parellel move and resize effect on the pop-up.
+     * 
+     *  @return An IEffect instance serving as the move and/or resize transition
+     *  for the pop-up. This effect is played after the soft keyboard is
+     *  activated or deactivated.
+     * 
+     *  @langversion 3.0
+     *  @playerversion AIR 3
+     *  @productversion Flex 4.5.2
+     */
+    protected function createSoftKeyboardEffect(yTo:Number, heightTo:Number):IEffect
+    {
+        var move:Move;
+        var resize:Resize;
+        var easer:IEaser = new Power(0, 5);
+        
+        if (yTo != this.y)
+        {
+            move = new Move();
+            move.target = this;
+            move.yTo = yTo;
+            move.disableLayout = true;
+            move.easer = easer;
+        }
+        
+        if (heightTo != this.height)
+        {
+            resize = new Resize();
+            resize.target = this;
+            resize.heightTo = heightTo;
+            resize.disableLayout = true;
+            resize.easer = easer;
+        }
+        
+        if (move && resize)
+        {
+            var parallel:Parallel = new Parallel();
+            parallel.addChild(move);
+            parallel.addChild(resize);
+            
+            return parallel;
+        }
+        else if (move || resize)
+        {
+            return (move) ? move : resize;
+        }
+        
+        return null;
+    }
+    
+    //--------------------------------------------------------------------------
+    //
+    //  mx_internal properties
+    //
+    //--------------------------------------------------------------------------
+    
+    //----------------------------------
+    //  isSoftKeyboardEffectActive
+    //----------------------------------
+    
+    private var _isSoftKeyboardEffectActive:Boolean;
+    
+    /**
+     *  @private
+     *  Returns true if the soft keyboard is active and the pop-up is moved
+     *  and/or resized.
+     */
+    mx_internal function get isSoftKeyboardEffectActive():Boolean
+    {
+        return _isSoftKeyboardEffectActive;
+    }
+    
+    //----------------------------------
+    //  marginTop
+    //----------------------------------
+    
+    private var _marginTop:Number = 0;
+    
+    /**
+     *  @private
+     *  Defines a margin at the top of the screen where the pop-up cannot be 
+     *  resized or moved to.
+     */
+    mx_internal function get softKeyboardEffectMarginTop():Number
+    {
+        return _marginTop;
+    }
+    
+    /**
+     *  @private
+     */
+    mx_internal function set softKeyboardEffectMarginTop(value:Number):void
+    {
+        _marginTop = value;
+    }
+    
+    //----------------------------------
+    //  marginBottom
+    //----------------------------------
+    
+    private var _marginBottom:Number = 0;
+    
+    /**
+     *  @private
+     *  Defines a margin at the bottom of the screen where the pop-up cannot be 
+     *  resized or moved to.
+     */
+    mx_internal function get softKeyboardEffectMarginBottom():Number
+    {
+        return _marginBottom;
+    }
+    
+    /**
+     *  @private
+     */
+    mx_internal function set softKeyboardEffectMarginBottom(value:Number):void
+    {
+        _marginBottom = value;
+    }
+    
     //--------------------------------------------------------------------------
     //
     //  Overridden Methods

     */
    public function set moveForSoftKeyboard(value:Boolean):void
    {
        if (!popUpTransition)
            return;
        
        popUpTransition.moveForSoftKeyboard = value;
    }
    
    //----------------------------------
    //  resizeApplication
    //----------------------------------
    
    private var _resizeApplication:Boolean = false;
    
    /**
     *  @copy spark.transitions.SoftKeyboardPopUpTransition#resizeApplication
     */
    public function get resizeApplication():Boolean
    {
        if (!popUpTransition)
            return false;
        
        return popUpTransition.resizeApplication;
    }
    
    /**
     *  @private
     */
    public function set resizeApplication(value:Boolean):void
    {
        popUpTransition.resizeApplication = value;
    }

    //--------------------------------------------------------------------------

        if (event)
            event.target.removeEventListener(FlexEvent.STATE_CHANGE_COMPLETE, stateChangeComplete_handler);
        
        var topLevelApp:Application = FlexGlobals.topLevelApplication as Application;
        var softKeyboardEffectEnabled:Boolean = (topLevelApp && Application.softKeyboardBehavior == "none");
        
        if (isOpen)
        {
            dispatchEvent(new PopUpEvent(PopUpEvent.OPEN, false, false));
            
            if (softKeyboardEffectEnabled)
            {
                // Install soft keyboard event handling on the stage
                stage.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATING, softKeyboardActivatingHandler);
                stage.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, softKeyboardActivateHandler);
                stage.addEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE, softKeyboardDeactivateHandler);
                
                // move and resize immediately if the soft keyboard is active
                if (stage.softKeyboardRect.height > 0)
                {
                    softKeyboardActivatingHandler();
                    softKeyboardActivateHandler();
                }
            }
        }
        else
        {
            // Dispatch the close event before removing from the PopUpManager.
            dispatchEvent(closeEvent);
            closeEvent = null;
            
            if (softKeyboardEffectEnabled)
            {
                // Uninstall soft keyboard event handling
                stage.removeEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATING, softKeyboardActivatingHandler);
                stage.removeEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_ACTIVATE, softKeyboardActivateHandler);
                stage.removeEventListener(SoftKeyboardEvent.SOFT_KEYBOARD_DEACTIVATE, softKeyboardDeactivateHandler);
                
                _isSoftKeyboardEffectActive = false;
            }

            // We just finished closing, remove from the PopUpManager.
            PopUpManager.removePopUp(this);
