private static void OnShowStoryboardChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue == e.OldValue)
            {
                return;
            }

            var element = d as FrameworkElement;

            if (element == null)
            {
                throw new ArgumentException("d");
            }

            var entry = s_entries.GetOrCreate(element, () => new EntryInfo());

            if (entry.ShowStoryboard != null)
            {
                ShowHideAnimation.UnhandleShowStoryboardCompletedEvent(element);
            }

            if (e.NewValue == null)
            {
                entry.ShowStoryboard = null;
            }
            else
            {
                entry.ShowStoryboard = (Storyboard)((Freezable)e.NewValue).Clone();
            }
        }
        static void ShowStoryboard_Completed(FrameworkElement element, object sender, EventArgs e)
        {
            EntryInfo entry;

            if (s_entries.TryGetValue(element, out entry))
            {
                ShowHideAnimation.UnhandleShowStoryboardCompletedEvent(element);
                if (entry.ContentHolder != null)
                {
                    entry.ContentHolder.Visibility = Visibility.Visible;
                }
                if (entry.SnapshotHolder != null)
                {
                    entry.SnapshotHolder.Visibility = Visibility.Hidden;
                }
            }
        }
        private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue == e.OldValue)
            {
                return;
            }

            var element = d as FrameworkElement;

            if (element == null)
            {
                throw new ArgumentException("d");
            }

            var entry      = s_entries.GetOrCreate(element, () => new EntryInfo());
            var visibility = (Visibility)e.NewValue;

            if (visibility == Visibility.Visible)
            {
                if (entry.ShowStoryboard == null)
                {
                    element.Visibility = Visibility.Visible;
                }
                else
                {
                    if (entry.SnapshotHolder != null)
                    {
                        ShowHideAnimation.TakeSnapshot(element);
                    }

                    entry.ShowStoryboardCompletedEventHander = (_, __) => ShowHideAnimation.ShowStoryboard_Completed(element, _, __);
                    entry.ShowStoryboard.Completed          += entry.ShowStoryboardCompletedEventHander;
                    element.Visibility = Visibility.Visible;

                    if (element.IsLoaded)
                    {
                        entry.ShowStoryboard.Begin(element);
                    }
                    else
                    {
                        entry.ShowStoryboard.Begin(element, true);
                        entry.ShowStoryboard.SkipToFill(element);
                    }
                }
            }
            else if (visibility != Visibility.Visible)
            {
                if (entry.HideStoryboard == null)
                {
                    element.Visibility = visibility;
                }
                else
                {
                    if (entry.SnapshotHolder != null)
                    {
                        ShowHideAnimation.TakeSnapshot(element);
                    }

                    entry.HideStoryboardCompletedEventHander = (_, __) => ShowHideAnimation.HideStoryboard_Completed(element, _, __);
                    entry.HideStoryboard.Completed          += entry.HideStoryboardCompletedEventHander;
                    element.Visibility = Visibility.Visible;

                    if (element.IsLoaded)
                    {
                        entry.HideStoryboard.Begin(element);
                    }
                    else
                    {
                        entry.HideStoryboard.Begin(element, true);
                        entry.HideStoryboard.SkipToFill(element);
                    }
                }
            }
        }