             
             var currentTime:Number = intervalTime - cycleStartTime;
             _playheadTime = intervalTime - startTime;
-            if (currentTime >= duration && 
-                (repeatCount == 0 || numRepeats < repeatCount))
-            {
-                // FIXME (chaase): this assumes we've only gone through one cycle since
-                // last time...
-                if (repeatCount != 0)
-                    if (!_doSeek)
-                        numRepeats++;
-                    else
-                        numRepeats = 1 + currentTime / (duration + repeatDelay);
-                if (repeatDelay == 0) {
-                    cycleStartTime += duration;
-                    currentTime = intervalTime - cycleStartTime;
-                    if (repeatBehavior == RepeatBehavior.REVERSE)
-                        _invertValues = !_invertValues;
-                    repeated = true;
-                }
-                else
+            if (currentTime >= duration)
+            { 
+                // numRepeats reflects the current repetition cycle that we're going to
+                // be in, once we repeat.
+                var numRepeats:int = 2 + (_playheadTime - duration) / (duration + repeatDelay);
+                if (repeatCount == 0 || numRepeats <= repeatCount)
                 {
-                    if (_doSeek)
+                    if (repeatDelay == 0)
                     {
-                        _cycleTime = currentTime % (duration + repeatDelay);
-                        if (_cycleTime > duration)
-                            _cycleTime = duration; // must be in repeatDelay phase
-                        calculateValue(_cycleTime);
-                        sendUpdateEvent();
-                        return false;
+                        _cycleTime = currentTime % duration;
+                        cycleStartTime = intervalTime - _cycleTime;
+                        currentTime = _cycleTime;                        
+                        if (repeatBehavior == RepeatBehavior.REVERSE)
+                            _invertValues = !_invertValues;
+                        repeated = true;
                     }
                     else
                     {
-                        // repeatDelay: send out a final update for this cycle with the
-                        // end value, then schedule a timer to wake up and
-                        // start the next cycle
-                        _cycleTime = duration;
-                        calculateValue(_cycleTime);
-                        sendUpdateEvent();
-                        removeAnimation(this);
-                        var delayTimer:Timer = new Timer(repeatDelay, 1);
-                        delayTimer.addEventListener(TimerEvent.TIMER, repeat);
-                        delayTimer.start();
-                        return false;
+                        if (_doSeek)
+                        {
+                            _cycleTime = currentTime % (duration + repeatDelay);
+                            if (_cycleTime > duration)
+                                _cycleTime = duration; // must be in repeatDelay phase
+                            calculateValue(_cycleTime);
+                            sendUpdateEvent();
+                            return false;
+                        }
+                        else
+                        {
+                            // repeatDelay: send out a final update for this cycle with the
+                            // end value, then schedule a timer to wake up and
+                            // start the next cycle
+                            _cycleTime = duration;
+                            calculateValue(_cycleTime);
+                            sendUpdateEvent();
+                            removeAnimation(this);
+                            var delayTimer:Timer = new Timer(repeatDelay, 1);
+                            delayTimer.addEventListener(TimerEvent.TIMER, repeat);
+                            delayTimer.start();
+                            return false;
+                        }
                     }
                 }
             }

            // UPDATE event with this start value
            sendUpdateEvent();
            Animation.addAnimation(this);
            _isPlaying = true;
            if (actualStartTime > 0)
                seek(actualStartTime);

                break;
            }
        }
        sendAnimationEvent(EffectEvent.EFFECT_START);
        
        // start/end values may be changed by Animate (set dynamically),
