private static Storyboard CreateStoryboard(
            FrameworkElement target,
            DependencyProperty animatingDependencyProperty,
            string propertyPath,
            ref object toValue,
            TimeSpan durationTimeSpan,
            IEasingFunction easingFunction)
        {
            object fromValue = target.GetValue(animatingDependencyProperty);

            double fromDoubleValue;
            double toDoubleValue;

            DateTime fromDateTime;
            DateTime toDateTime;

            var storyBoard = new Storyboard();

            Storyboard.SetTarget(storyBoard, target);
            Storyboard.SetTargetProperty(storyBoard, new PropertyPath(propertyPath));

            if ((fromValue != null && toValue != null))
            {
                if (ValueHelper.TryConvert(fromValue, out fromDoubleValue) &&
                    ValueHelper.TryConvert(toValue, out toDoubleValue))
                {
                    var doubleAnimation = new DoubleAnimation();
                    doubleAnimation.EasingFunction = easingFunction;
                    doubleAnimation.Duration       = durationTimeSpan;
                    doubleAnimation.To             = ValueHelper.ToDouble(toValue);
                    toValue = doubleAnimation.To;

                    storyBoard.Children.Add(doubleAnimation);
                }
                else if (ValueHelper.TryConvert(fromValue, out fromDateTime) &&
                         ValueHelper.TryConvert(toValue, out toDateTime))
                {
                    var keyFrameAnimation = new ObjectAnimationUsingKeyFrames();
                    keyFrameAnimation.Duration = durationTimeSpan;

                    var intervals = (long)(durationTimeSpan.TotalSeconds * KeyFramesPerSecond);
                    if (intervals < 2L)
                    {
                        intervals = 2L;
                    }

                    IEnumerable <TimeSpan> timeSpanIntervals =
                        ValueHelper.GetTimeSpanIntervalsInclusive(durationTimeSpan, intervals);

                    IEnumerable <DateTime> dateTimeIntervals =
                        ValueHelper.GetDateTimesBetweenInclusive(fromDateTime, toDateTime, intervals);

                    IEnumerable <DiscreteObjectKeyFrame> keyFrames =
                        EnumerableFunctions.Zip(
                            dateTimeIntervals,
                            timeSpanIntervals,
                            (dateTime, timeSpan) =>
                            new DiscreteObjectKeyFrame {
                        Value = dateTime, KeyTime = timeSpan
                    });

                    foreach (DiscreteObjectKeyFrame keyFrame in keyFrames)
                    {
                        keyFrameAnimation.KeyFrames.Add(keyFrame);
                        toValue = keyFrame.Value;
                    }

                    storyBoard.Children.Add(keyFrameAnimation);
                }
            }

            if (storyBoard.Children.Count == 0)
            {
                var keyFrameAnimation = new ObjectAnimationUsingKeyFrames();
                var endFrame          = new DiscreteObjectKeyFrame {
                    Value = toValue, KeyTime = new TimeSpan(0, 0, 0)
                };
                keyFrameAnimation.KeyFrames.Add(endFrame);

                storyBoard.Children.Add(keyFrameAnimation);
            }

            return(storyBoard);
        }