private Tuple<Changes, ListBoxItem> GetChanges(SelectionChangedEventArgs selch)
        {
            Changes ch = new Changes(ListBoxOwner);
            selch.AddedItems.Cast<object>().Apply(o => ch.AddSelected(o));
            selch.RemovedItems.Cast<object>().Apply(o => ch.AddRemoved(o));

            ListBoxItem lbi = ch.AddedSelectedListBoxItem
                                .Union(ch.RemovedSelectedListBoxItem)
                                .Union(ListBoxOwner.SelectedItems.Cast<object>().Select(ch.Convert))
                                .Where(lbic => ((lbic != null) && (lbic.IsMouseOver)))
                                .FirstOrDefault();

            return new Tuple<Changes, ListBoxItem>(ch, lbi);
        }
        internal void ApplyChanges(ListBoxItem lbi, Changes ichanges)
        {
            StopCurrentAnimation();

            SynchronizeApplyChanges(lbi, ichanges);
        }
        private void SynchronizeApplyChanges(ListBoxItem lbi, Changes ichanges)
        {
            UpdateDisplay(lbi, ichanges);

            if (ichanges.AddedSelectedListBoxItem.Contains(lbi))
            {
                OnSelect(lbi);
            }
            else if (ichanges.RemovedSelectedListBoxItem.Contains(lbi))
            {
                OnUnSelect(lbi);
            }
        }
        internal void UpdateDisplay(ListBoxItem lbi, Changes ichanges)
        {
            ListBox lb = this.ListBoxOwner;
            if (lb == null)
            {
                RefreshDisplay();
                return;
            }

            var Fact = lb.ItemContainerGenerator;
            int UnchangedObjectIndex = Fact.IndexFromContainer(lbi);

            HashSet<object> Currentselected = lb.SelectedItems.Cast<object>().ToHashSet();
            HashSet<object> OldSelected = Currentselected.Where(o => !ichanges.AddeddSelected.Contains(o)).Union(ichanges.RemovedSelected).ToHashSet();

            int OldIndex = IntIndexDeb(UnchangedObjectIndex, o => OldSelected.Contains(o));
            int NewIndex = IntIndexDeb(UnchangedObjectIndex, o => Currentselected.Contains(o));

            if (NewIndex != OldIndex)
            {
                if (!TrySetHorizontalOffset(HorizontalOffset + NewIndex - OldIndex))
                    RefreshDisplay();
            }
            else
            {
                RefreshDisplay();
            }
        }