/// <summary>
        /// An animation which will apply the derived effect.
        /// </summary>
        /// <param name="animationSet">The animation set.</param>
        /// <param name="value">The value.</param>
        /// <param name="duration">The duration in milliseconds.</param>
        /// <param name="delay">The delay in milliseconds.</param>
        /// <param name="easingType">The easing function to use</param>
        /// <param name="easingMode">The easing mode to use</param>
        /// <returns>An animation set with the effect added to it.</returns>
        public AnimationSet EffectAnimation(
            AnimationSet animationSet,
            double value          = 0d,
            double duration       = 500d,
            double delay          = 0d,
            EasingType easingType = EasingType.Default,
            EasingMode easingMode = EasingMode.EaseOut)
        {
            if (animationSet == null)
            {
                return(null);
            }

            if (!IsSupported)
            {
                return(null);
            }

            var visual           = animationSet.Visual;
            var associatedObject = animationSet.Element as FrameworkElement;

            if (associatedObject == null)
            {
                return(animationSet);
            }

            Compositor = visual?.Compositor;

            if (Compositor == null)
            {
                return(null);
            }

            // check to see if the visual already has an effect applied.
            var spriteVisual = ElementCompositionPreview.GetElementChildVisual(associatedObject) as SpriteVisual;

            EffectBrush = spriteVisual?.Brush as CompositionEffectBrush;

            if (EffectBrush == null || EffectBrush?.Comment != EffectName)
            {
                _effectProperties   = ApplyEffect();
                EffectBrush.Comment = EffectName;

                var sprite = Compositor.CreateSpriteVisual();
                sprite.Brush = EffectBrush;
                ElementCompositionPreview.SetElementChildVisual(associatedObject, sprite);

                sprite.Size = new Vector2((float)associatedObject.ActualWidth, (float)associatedObject.ActualHeight);

                associatedObject.SizeChanged +=
                    (s, e) =>
                {
                    sprite.Size = new Vector2(
                        (float)associatedObject.ActualWidth,
                        (float)associatedObject.ActualHeight);
                };
            }

            if (duration <= 0)
            {
                foreach (var effectProperty in _effectProperties)
                {
                    animationSet.AddEffectDirectPropertyChange(EffectBrush, (float)value, effectProperty);
                }
            }
            else
            {
                foreach (var effectProperty in _effectProperties)
                {
                    var animation = Compositor.CreateScalarKeyFrameAnimation();
                    animation.InsertKeyFrame(1f, (float)value, AnimationExtensions.GetCompositionEasingFunction(easingType, Compositor, easingMode));

                    animation.Duration  = TimeSpan.FromMilliseconds(duration);
                    animation.DelayTime = TimeSpan.FromMilliseconds(delay);

                    animationSet.AddCompositionEffectAnimation(EffectBrush, animation, effectProperty);
                }
            }

            // Saturation starts from 1 to 0, instead of 0 to 1 so this makes sure the
            // the brush isn't removed from the UI element incorrectly. Completing on
            // Saturation as it's reusing the same sprite visual. Removing the Sprite removes the effect.
            if (EffectName != "Saturation" && value == 0)
            {
                animationSet.Completed += AnimationSet_Completed;
            }

            return(animationSet);
        }