private void doMoveSlides(int index, List <SlideInfo> sortedSlides)
        {
            int actualInsertIndex = index;

            foreach (SlideInfo slideInfo in sortedSlides)
            {
                if (slideInfo.Index <= index && actualInsertIndex > 0)
                {
                    --actualInsertIndex;
                }
                slideshow.removeSlide(slideInfo.Slide);
                if (SlideRemoved != null)
                {
                    SlideRemoved.Invoke(slideInfo.Slide);
                }

                slideshow.insertSlide(actualInsertIndex, slideInfo.Slide);
                if (SlideAdded != null)
                {
                    SlideAdded.Invoke(slideInfo.Slide, actualInsertIndex);
                }
                ++actualInsertIndex;
            }
            if (SlideSelected != null)
            {
                Slide primarySelection = lastEditSlide;
                if (primarySelection == null)
                {
                    //Double check the last edit slide if the user moved a slide without actually clicking and releasing that slide will be null,
                    //in this case use the slide that was moved.
                    primarySelection = sortedSlides[0].Slide;
                }
                SlideSelected.Invoke(primarySelection, secondarySlideSelections(sortedSlides, primarySelection));
            }
        }
        public void moveSlides(IEnumerable <Slide> slides, int index)
        {
            List <SlideInfo> sortedSlides = new List <SlideInfo>(from slide in slides select new SlideInfo(slide, slideshow.indexOf(slide)));

            sortedSlides.Sort(SlideInfo.Sort);

            bool wasAllowingUndo = allowUndoCreation;

            allowUndoCreation = false;
            doMoveSlides(index, sortedSlides);
            allowUndoCreation = wasAllowingUndo;

            if (allowUndoCreation)
            {
                undoBuffer.pushAndSkip(new TwoWayDelegateCommand(
                                           new TwoWayDelegateCommand.Funcs()
                {
                    ExecuteFunc = () =>     //Execute
                    {
                        allowUndoCreation = false;
                        doMoveSlides(index, sortedSlides);
                        allowUndoCreation = true;
                    },
                    UndoFunc = () =>     //Undo
                    {
                        allowUndoCreation = false;
                        foreach (SlideInfo info in sortedSlides)
                        {
                            int formerIndex = slideshow.indexOf(info.Slide);
                            slideshow.removeAt(formerIndex);
                            if (SlideRemoved != null)
                            {
                                SlideRemoved.Invoke(info.Slide);
                            }
                        }
                        //Can't think of how to do this without two loops, have to compensate for other things
                        //that need to be undone or else this won't put things back, two loops makes sure
                        //all items are removed and we can just insert back to original indices.
                        foreach (SlideInfo info in sortedSlides)
                        {
                            slideshow.insertSlide(info.Index, info.Slide);
                            if (SlideAdded != null)
                            {
                                SlideAdded.Invoke(info.Slide, info.Index);
                            }
                        }
                        if (SlideSelected != null)
                        {
                            SlideSelected.Invoke(lastEditSlide, secondarySlideSelections(sortedSlides, lastEditSlide));
                        }
                        allowUndoCreation = true;
                    }
                }));
            }
        }
        private void doRemoveSlides(List <SlideInfo> removedSlides)
        {
            bool wasAllowingUndo = allowUndoCreation;

            allowUndoCreation = false;
            foreach (SlideInfo slideInfo in removedSlides)
            {
                slideshow.removeSlide(slideInfo.Slide);
                if (SlideRemoved != null)
                {
                    SlideRemoved.Invoke(slideInfo.Slide);
                }
            }
            allowUndoCreation = wasAllowingUndo;
        }
        public void removeSlide(Slide slide)
        {
            int slideIndex = slideshow.indexOf(slide);

            if (slideIndex != -1)
            {
                slideshow.removeAt(slideIndex);
                if (SlideRemoved != null)
                {
                    SlideRemoved.Invoke(slide);
                }

                Slide changeToSlide = null;
                if (slide == lastEditSlide)
                {
                    if (slideIndex < slideshow.Count)
                    {
                        changeToSlide = slideshow.get(slideIndex);
                    }
                    else if (slideIndex - 1 >= 0)
                    {
                        changeToSlide = slideshow.get(slideIndex - 1);
                    }
                }

                if (changeToSlide != null)
                {
                    bool wasAllowingUndo = allowUndoCreation;
                    allowUndoCreation = false;
                    if (SlideSelected != null)
                    {
                        SlideSelected.Invoke(changeToSlide, IEnumerableUtil <Slide> .EmptyIterator);
                    }
                    allowUndoCreation = wasAllowingUndo;
                }

                if (allowUndoCreation)
                {
                    if (changeToSlide == null)
                    {
                        undoBuffer.pushAndSkip(new TwoWayDelegateCommand <SlideInfo>(new SlideInfo(slide, slideIndex),
                                                                                     new TwoWayDelegateCommand <SlideInfo> .Funcs()
                        {
                            ExecuteFunc = (executeSlide) =>
                            {
                                allowUndoCreation = false;
                                removeSlide(executeSlide.Slide);
                                allowUndoCreation = true;
                            },
                            UndoFunc = (undoSlide) =>
                            {
                                allowUndoCreation = false;
                                addSlide(undoSlide.Slide, undoSlide.Index);
                                allowUndoCreation = true;
                            },
                        }
                                                                                     ));
                    }
                    else
                    {
                        undoBuffer.pushAndSkip(new TwoWayDelegateCommand <RemoveSlideInfo>(new RemoveSlideInfo(slide, slideIndex, changeToSlide),
                                                                                           new TwoWayDelegateCommand <RemoveSlideInfo> .Funcs()
                        {
                            ExecuteFunc = (executeSlide) =>
                            {
                                //Hacky, but we cannot modify the active slide without messing up the classes that triggered this.
                                ThreadManager.invoke(new Action(delegate()
                                {
                                    allowUndoCreation = false;
                                    removeSlide(executeSlide.Slide);
                                    if (SlideSelected != null)
                                    {
                                        SlideSelected.Invoke(executeSlide.ChangeToSlide, IEnumerableUtil <Slide> .EmptyIterator);
                                    }
                                    allowUndoCreation = true;
                                }));
                            },
                            UndoFunc = (undoSlide) =>
                            {
                                //Hacky, but we cannot modify the active slide without messing up the classes that triggered this.
                                ThreadManager.invoke(new Action(delegate()
                                {
                                    allowUndoCreation = false;
                                    addSlide(undoSlide.Slide, undoSlide.Index);
                                    if (SlideSelected != null)
                                    {
                                        SlideSelected.Invoke(undoSlide.Slide, IEnumerableUtil <Slide> .EmptyIterator);
                                    }
                                    allowUndoCreation = true;
                                }));
                            },
                            PoppedFrontFunc = cleanupThumbnail
                        }));
                    }
                }
            }
        }