public static async Task AnimateItems(
            this Selector itemsControl,
            AnimationDefinition animationDefinition,
            double itemDelay = 0.05,
            object selectedObject = null,
            AnimationDefinition selectedItemAnimationDefinition = null)
        {
            if (itemsControl == null) return;
            if (animationDefinition == null) return;
            if (itemDelay <= 0.0)
                itemDelay = 0.05;

            itemsControl.UpdateLayout();

            var animations = new List<Task>();

            double baseDelay = animationDefinition.Delay;
            for (int index = 0; index < itemsControl.Items.Count; index++)
            {
                var container = (FrameworkElement)itemsControl.ContainerFromItem(itemsControl.Items[index]);
                //var container = (FrameworkElement)itemsControl.ItemContainerGenerator.ContainerFromIndex(index);
                if (container == null) continue;

                bool found = false;
                if (selectedItemAnimationDefinition != null)
                {
                    if ((index == itemsControl.SelectedIndex) ||
                        ((selectedObject != null) && (itemsControl.Items != null) && (selectedObject == itemsControl.Items[index]))
                        )
                    {
                        found = true;

                        animationDefinition.Delay = baseDelay;
                        AnimationManager.ClearAnimationProperties(container);
                        animations.Add(
                            container.AnimateAsync(selectedItemAnimationDefinition));
                    }
                }
                if (!found)
                {
                    animationDefinition.Delay = baseDelay + (itemDelay * index);
                    AnimationManager.ClearAnimationProperties(container);
                    animations.Add(
                        container.AnimateAsync(animationDefinition));
                }
            }

            animationDefinition.Delay = baseDelay;

            await Task.WhenAll(animations.ToArray());
        }
        public async static Task ScrollToItem(this ListViewBase listViewBase, object item)
        {
            bool isVirtualizing = default(bool);
            double previousHorizontalOffset = default(double), previousVerticalOffset = default(double);

            // get the ScrollViewer withtin the ListView/GridView
            var scrollViewer = listViewBase.GetScrollViewer();
            // get the SelectorItem to scroll to
            var selectorItem = listViewBase.ContainerFromItem(item) as SelectorItem;

            // when it's null, means virtualization is on and the item hasn't been realized yet
            if (selectorItem == null)
            {
                isVirtualizing = true;

                previousHorizontalOffset = scrollViewer.HorizontalOffset;
                previousVerticalOffset = scrollViewer.VerticalOffset;

                // call task-based ScrollIntoViewAsync to realize the item
                await listViewBase.ScrollIntoViewAsync(item);

                // this time the item shouldn't be null again
                selectorItem = (SelectorItem)listViewBase.ContainerFromItem(item);
            }

            // calculate the position object in order to know how much to scroll to
            var transform = selectorItem.TransformToVisual((UIElement)scrollViewer.Content);
            var position = transform.TransformPoint(new Point(0, 0));

            // when virtualized, scroll back to previous position without animation
            if (isVirtualizing)
            {
                await scrollViewer.ChangeViewAsync(previousHorizontalOffset, previousVerticalOffset, true);
            }

            // scroll to desired position with animation!
            scrollViewer.ChangeView(position.X, position.Y, null);
        }