         event.newState = _currentState ? _currentState : "";
         dispatchEvent(event);
 
-        if (transition)
+        if (nextTransition)
         {
             // Force a validation before playing the transition effect
             UIComponentGlobals.layoutManager.validateNow();
-            _currentTransitionEffect = transition;
-            transition.addEventListener(EffectEvent.EFFECT_END, transition_effectEndHandler);
-            transition.fromState = oldState;
-            transition.toState = _currentState;
-            transition.play();
-            if (!isNaN(prevTransitionFraction) && transition.duration != 0)
-                transition.seek((1 - prevTransitionFraction) * transition.duration);
-        }
-    }
-
+            _currentTransition = nextTransition;
+            transitionFromState = oldState;
+            transitionToState = _currentState;
+            nextTransition.effect.addEventListener(EffectEvent.EFFECT_END, 
+                transition_effectEndHandler);
+            nextTransition.effect.play();
+            if (!isNaN(prevTransitionFraction) && 
+                nextTransition.effect.duration != 0 &&
+                "seek" in nextTransition.effect)
+                nextTransition.effect["seek"]((1 - prevTransitionFraction) * 
+                    getTotalDuration(nextTransition.effect));
+        }
+    }
+
+    // Used by getTotalDuration() to avoid hard-linking against
+    // CompositeEffect
+    private static var compositeEffectType:Class;
+    private static var compositeEffectLoaded:Boolean = false;
+    
+    /**
+     * @private
+     * returns the 'total' duration of an effect. This value
+     * takes into account any startDelay and repetition data.
+     * For CompositeEffect objects, it also accounts for the
+     * total duration of that effect's children.
+     */
+    private function getTotalDuration(effect:IEffect):Number
+    {
+        // TODO (chaase): we should add timing properties to some
+        // interface to avoid these hacks
+        var duration:Number = 0;
+        var effectObj:Object = Object(effect);
+        if (!compositeEffectLoaded)
+        {
+            compositeEffectLoaded = true;
+            if (ApplicationDomain.currentDomain.hasDefinition("mx.effects.CompositeEffect"))
+                compositeEffectType = Class(ApplicationDomain.currentDomain.
+                getDefinition("mx.effects.CompositeEffect"));
+        }
+        if (compositeEffectType && (effect is compositeEffectType))
+            duration = effectObj.compositeDuration;
+        else
+            duration = effect.duration;
+        var repeatDelay:int = ("repeatDelay" in effect) ?
+            effectObj.repeatDelay : 0;
+        var repeatCount:int = ("repeatCount" in effect) ?
+            effectObj.repeatCount : 0;
+        var startDelay:int = ("startDelay" in effect) ?
+            effectObj.startDelay : 0;
+        // Now add in startDelay/repeat info
+        duration = 
+            duration * repeatCount +
+            (repeatDelay * (repeatCount - 1)) +
+            startDelay;
+        return duration;
+    }
     /**
      *  @private
      */
     private function transition_effectEndHandler(event:EffectEvent):void
     {
-        _currentTransitionEffect = null;
+        _currentTransition = null;
     }
 
     /**

     */
    private var hasFocusRect:Boolean = false;


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

     */
    private function commitCurrentState():void
    {
        var nextTransition:Transition =
            playStateTransition ?
            getTransition(_currentState, requestedCurrentState) :
            null;
