private void OnCurrentTimeInvalidated(object sender, EventArgs args)
        {
            object target = _dependencyObject.Target;

            if (target == null)
            {
                // If the target has been garbage collected, remove this handler
                // from the AnimationClock so that this collection can be
                // released also.
                DetachAnimationClock((AnimationClock)sender, _removeRequestedHandler);
            }
            else
            {
                // recompute animated value
                try
                {
                    DependencyObject targetDO = ((DependencyObject)target);

                    // fetch the existing entry
                    EffectiveValueEntry oldEntry = targetDO.GetValueEntry(
                            targetDO.LookupEntry(_dependencyProperty.GlobalIndex),
                            _dependencyProperty,
                            null,
                            RequestFlags.RawEntry);

                    EffectiveValueEntry newEntry;
                    object value;

                    // create a copy of that entry, removing animated & coerced values

                    if (!oldEntry.HasModifiers)
                    {
                        // no modifiers; just use it, removing deferred references
                        newEntry = oldEntry;
                        value = newEntry.Value;
                        if (newEntry.IsDeferredReference)
                        {
                            value = ((DeferredReference) value).GetValue(newEntry.BaseValueSourceInternal);
                            newEntry.Value = value;
                        }
                    }
                    else
                    {
                        // else entry has modifiers; preserve expression but throw away
                        // coerced & animated values, since we'll be recomputing an animated value
                        newEntry = new EffectiveValueEntry();
                        newEntry.BaseValueSourceInternal = oldEntry.BaseValueSourceInternal;
                        newEntry.PropertyIndex = oldEntry.PropertyIndex;
                        newEntry.HasExpressionMarker = oldEntry.HasExpressionMarker;

                        value = oldEntry.ModifiedValue.BaseValue;
                        if (oldEntry.IsDeferredReference)
                        {
                            DeferredReference dr = value as DeferredReference;
                            if (dr != null)
                            {
                                value = dr.GetValue(newEntry.BaseValueSourceInternal);
                            }
                        }

                        newEntry.Value = value;

                        if (oldEntry.IsExpression)
                        {
                            value = oldEntry.ModifiedValue.ExpressionValue;
                            if (oldEntry.IsDeferredReference)
                            {
                                DeferredReference dr = value as DeferredReference;
                                if (dr != null)
                                {
                                    value = dr.GetValue(newEntry.BaseValueSourceInternal);
                                }
                            }
                            newEntry.SetExpressionValue(value, newEntry.Value);
                        }
                    }

                    // compute the new value for the property

                    PropertyMetadata metadata = _dependencyProperty.GetMetadata(targetDO.DependencyObjectType);
                    object animatedValue = AnimationStorage.GetCurrentPropertyValue(this, targetDO, _dependencyProperty, metadata, value);

                    if (_dependencyProperty.IsValidValueInternal(animatedValue))
                    {
                        // update the new entry to contain the new animated value
                        newEntry.SetAnimatedValue(animatedValue, value);

                        // call UpdateEffectiveValue to put the new entry in targetDO's effective values table
                        targetDO.UpdateEffectiveValue(
                                targetDO.LookupEntry(_dependencyProperty.GlobalIndex),
                                _dependencyProperty,
                                metadata,
                                oldEntry,
                                ref newEntry,
                                false /* coerceWithDeferredReference */,
                                false /* coerceWithCurrentValue */,
                                OperationType.Unknown);

                        if (_hadValidationError)
                        {
                            if (TraceAnimation.IsEnabled)
                            {
                                TraceAnimation.TraceActivityItem(
                                    TraceAnimation.AnimateStorageValidationNoLongerFailing,
                                    this,
                                    animatedValue,
                                    target,
                                    _dependencyProperty);

                                _hadValidationError = false;
                            }
                        }
                    }
                    else if(!_hadValidationError)
                    {
                        if (TraceAnimation.IsEnabled)
                        {
                            TraceAnimation.TraceActivityItem(
                                TraceAnimation.AnimateStorageValidationFailed,
                                this,
                                animatedValue,
                                target,
                                _dependencyProperty);
                        }

                        _hadValidationError = true;
                    }
                }
                catch (Exception e)
                {
                    // Catch all exceptions thrown during the InvalidateProperty callstack
                    // and wrap them in an AnimationException

                    throw new AnimationException(
                        (AnimationClock)sender,
                        _dependencyProperty,
                        (IAnimatable)target,
                        SR.Get(
                            SRID.Animation_Exception,
                            _dependencyProperty.Name,
                            target.GetType().FullName,
                            ((AnimationClock)sender).Timeline.GetType().FullName),
                        e);
                }
            }
        }
        private void OnCurrentTimeInvalidated(object sender, EventArgs args)
        {
            object target = _dependencyObject.Target;

            if (target == null)
            {
                // If the target has been garbage collected, remove this handler
                // from the AnimationClock so that this collection can be
                // released also.
                DetachAnimationClock((AnimationClock)sender, _removeRequestedHandler);
            }
            else
            {
                // recompute animated value
                try
                {
                    DependencyObject targetDO = ((DependencyObject)target);

                    // fetch the existing entry
                    EffectiveValueEntry oldEntry = targetDO.GetValueEntry(
                        targetDO.LookupEntry(_dependencyProperty.GlobalIndex),
                        _dependencyProperty,
                        null,
                        RequestFlags.RawEntry);

                    EffectiveValueEntry newEntry;
                    object value;

                    // create a copy of that entry, removing animated & coerced values

                    if (!oldEntry.HasModifiers)
                    {
                        // no modifiers; just use it, removing deferred references
                        newEntry = oldEntry;
                        value    = newEntry.Value;
                        if (newEntry.IsDeferredReference)
                        {
                            value          = ((DeferredReference)value).GetValue(newEntry.BaseValueSourceInternal);
                            newEntry.Value = value;
                        }
                    }
                    else
                    {
                        // else entry has modifiers; preserve expression but throw away
                        // coerced & animated values, since we'll be recomputing an animated value
                        newEntry = new EffectiveValueEntry();
                        newEntry.BaseValueSourceInternal = oldEntry.BaseValueSourceInternal;
                        newEntry.PropertyIndex           = oldEntry.PropertyIndex;
                        newEntry.HasExpressionMarker     = oldEntry.HasExpressionMarker;

                        value = oldEntry.ModifiedValue.BaseValue;
                        if (oldEntry.IsDeferredReference)
                        {
                            DeferredReference dr = value as DeferredReference;
                            if (dr != null)
                            {
                                value = dr.GetValue(newEntry.BaseValueSourceInternal);
                            }
                        }

                        newEntry.Value = value;

                        if (oldEntry.IsExpression)
                        {
                            value = oldEntry.ModifiedValue.ExpressionValue;
                            if (oldEntry.IsDeferredReference)
                            {
                                DeferredReference dr = value as DeferredReference;
                                if (dr != null)
                                {
                                    value = dr.GetValue(newEntry.BaseValueSourceInternal);
                                }
                            }
                            newEntry.SetExpressionValue(value, newEntry.Value);
                        }
                    }

                    // compute the new value for the property

                    PropertyMetadata metadata      = _dependencyProperty.GetMetadata(targetDO.DependencyObjectType);
                    object           animatedValue = AnimationStorage.GetCurrentPropertyValue(this, targetDO, _dependencyProperty, metadata, value);

                    if (_dependencyProperty.IsValidValueInternal(animatedValue))
                    {
                        // update the new entry to contain the new animated value
                        newEntry.SetAnimatedValue(animatedValue, value);

                        // call UpdateEffectiveValue to put the new entry in targetDO's effective values table
                        targetDO.UpdateEffectiveValue(
                            targetDO.LookupEntry(_dependencyProperty.GlobalIndex),
                            _dependencyProperty,
                            metadata,
                            oldEntry,
                            ref newEntry,
                            false /* coerceWithDeferredReference */,
                            false /* coerceWithCurrentValue */,
                            OperationType.Unknown);

                        if (_hadValidationError)
                        {
                            if (TraceAnimation.IsEnabled)
                            {
                                TraceAnimation.TraceActivityItem(
                                    TraceAnimation.AnimateStorageValidationNoLongerFailing,
                                    this,
                                    animatedValue,
                                    target,
                                    _dependencyProperty);

                                _hadValidationError = false;
                            }
                        }
                    }
                    else if (!_hadValidationError)
                    {
                        if (TraceAnimation.IsEnabled)
                        {
                            TraceAnimation.TraceActivityItem(
                                TraceAnimation.AnimateStorageValidationFailed,
                                this,
                                animatedValue,
                                target,
                                _dependencyProperty);
                        }

                        _hadValidationError = true;
                    }
                }
                catch (Exception e)
                {
                    // Catch all exceptions thrown during the InvalidateProperty callstack
                    // and wrap them in an AnimationException

                    throw new AnimationException(
                              (AnimationClock)sender,
                              _dependencyProperty,
                              (IAnimatable)target,
                              SR.Get(
                                  SRID.Animation_Exception,
                                  _dependencyProperty.Name,
                                  target.GetType().FullName,
                                  ((AnimationClock)sender).Timeline.GetType().FullName),
                              e);
                }
            }
        }