/// <summary>
        /// Called when the user releases a drag. Moves the item within the source list and then resets everything.
        /// </summary>
        private void dragInterceptor_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            if (ItemsSource is ScriptBrickCollection)
              {
            if (dragItem is Script)
              foreach (DataObject dataObject in ItemsSource)
              {
            if (dataObject is Brick)
            {
              var container = this.ItemContainerGenerator.ContainerFromItem(dataObject);

              if(container != null)
                ((UIElement)container).Visibility = Visibility.Visible;
            }
              }
              }

              if (this.dragItem == null)
              {
            return;
              }

              if (this.dropTargetIndex >= 0)
              {
            this.MoveItem(this.dragItem, this.dropTargetIndex);
              }

              if (this.dragItemContainer != null)
              {
            this.dragItemContainer.Visibility = Visibility.Visible;
            this.dragItemContainer.Opacity = 0;
            this.AnimateDrop(this.dragItemContainer);
            this.dragItemContainer = null;
              }

              this.dragScrollDelta = 0;
              this.dropTargetIndex = -1;
              this.ClearDropTarget();
        }
        /// <summary>
        /// Called when the user presses down on the transparent drag-interceptor. Identifies the targed
        /// drag handle and list item and prepares for a drag operation.
        /// </summary>
        private void dragInterceptor_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            isDraging = true;

              if (this.dragItem != null)
              {
            return;
              }

              if (this.itemsPanel == null)
              {
            ItemsPresenter scrollItemsPresenter = (ItemsPresenter)this.scrollViewer.Content;
            this.itemsPanel = (Panel)VisualTreeHelper.GetChild(scrollItemsPresenter, 0);
              }

              GeneralTransform interceptorTransform = this.dragInterceptor.TransformToVisual(
              Application.Current.RootVisual);
              Point targetPoint = interceptorTransform.Transform(e.ManipulationOrigin);
              targetPoint = ReorderListBox.GetHostCoordinates(targetPoint);

              List<UIElement> targetElements = VisualTreeHelper.FindElementsInHostCoordinates(
              targetPoint, this.itemsPanel).ToList();
              ReorderListBoxItem targetItemContainer = targetElements.OfType<ReorderListBoxItem>().FirstOrDefault();
              if (targetItemContainer != null && targetElements.Contains(targetItemContainer.DragHandle))
              {
            VisualStateManager.GoToState(targetItemContainer, ReorderListBoxItem.DraggingState, true);

            GeneralTransform targetItemTransform = targetItemContainer.TransformToVisual(this.dragInterceptor);
            Point targetItemOrigin = targetItemTransform.Transform(new Point(0, 0));
            Canvas.SetLeft(this.dragIndicator, targetItemOrigin.X);
            Canvas.SetTop(this.dragIndicator, targetItemOrigin.Y);
            this.dragIndicator.Width = targetItemContainer.RenderSize.Width;
            this.dragIndicator.Height = targetItemContainer.RenderSize.Height;

            this.dragItemContainer = targetItemContainer;
            this.dragItem = this.dragItemContainer.Content;

            this.isDragItemSelected = this.dragItemContainer.IsSelected;

            this.dragInterceptorRect = interceptorTransform.TransformBounds(
            new Rect(new Point(0, 0), this.dragInterceptor.RenderSize));

            this.dropTargetIndex = -1;
              }

              // Added by valentin
              if (ItemsSource is ScriptBrickCollection)
              {
            if (dragItem is Script)
            {
              bool failed = false;
              foreach (DataObject dataObject in ItemsSource)
              {
            if (dataObject is Brick)
            {
              var container = this.ItemContainerGenerator.ContainerFromItem(dataObject);

              if (container != null)
              {
                ((UIElement)container).Visibility = Visibility.Collapsed;
                failed = true;
              }
            }
              }

              if (failed)
              {
            foreach (DataObject dataObject in ItemsSource)
            {
              if (dataObject is Brick)
              {
                var container = this.ItemContainerGenerator.ContainerFromItem(dataObject);

                if (container != null)
                  ((UIElement)container).Visibility = Visibility.Visible;
              }
            }
            e.Complete();
              }
            }
              }
        }
        /// <summary>
        /// Creates a storyboard to animate the visible moves of a rearrange.
        /// </summary>
        private Storyboard CreateRearrangeStoryboard(IEnumerable<RearrangeItemInfo> visibleMoves,
            Duration animationDuration)
        {
            Storyboard storyboard = new Storyboard();

              ReorderListBoxItem temporaryItemContainer = null;

              foreach (RearrangeItemInfo move in visibleMoves)
              {
            Size itemSize = new Size(this.rearrangeCanvas.RenderSize.Width, move.Height);

            ReorderListBoxItem itemContainer = null;
            if (move.ToIndex >= 0)
            {
              itemContainer = (ReorderListBoxItem)this.ItemContainerGenerator.ContainerFromIndex(move.ToIndex);
            }
            if (itemContainer == null)
            {
              if (temporaryItemContainer == null)
              {
            temporaryItemContainer = new ReorderListBoxItem();
              }

              itemContainer = temporaryItemContainer;
              itemContainer.Width = itemSize.Width;
              itemContainer.Height = itemSize.Height;
              this.rearrangeCanvas.Children.Add(itemContainer);
              this.PrepareContainerForItemOverride(itemContainer, move.Item);
              itemContainer.UpdateLayout();
            }

            WriteableBitmap itemSnapshot = new WriteableBitmap((int)itemSize.Width, (int)itemSize.Height);
            itemSnapshot.Render(itemContainer, null);
            itemSnapshot.Invalidate();

            Image itemImage = new Image();
            itemImage.Width = itemSize.Width;
            itemImage.Height = itemSize.Height;
            itemImage.Source = itemSnapshot;
            itemImage.RenderTransform = new TranslateTransform();
            this.rearrangeCanvas.Children.Add(itemImage);

            if (itemContainer == temporaryItemContainer)
            {
              this.rearrangeCanvas.Children.Remove(itemContainer);
            }

            if (!Double.IsNaN(move.FromY) && !Double.IsNaN(move.ToY))
            {
              Canvas.SetTop(itemImage, move.FromY);
              if (move.FromY != move.ToY)
              {
            DoubleAnimation moveAnimation = new DoubleAnimation();
            moveAnimation.Duration = animationDuration;
            Storyboard.SetTarget(moveAnimation, itemImage.RenderTransform);
            Storyboard.SetTargetProperty(moveAnimation, new PropertyPath(TranslateTransform.YProperty));
            moveAnimation.To = move.ToY - move.FromY;
            storyboard.Children.Add(moveAnimation);
              }
            }
            else if (Double.IsNaN(move.FromY) != Double.IsNaN(move.ToY))
            {
              if (move.FromIndex >= 0 && move.ToIndex >= 0)
              {
            DoubleAnimation moveAnimation = new DoubleAnimation();
            moveAnimation.Duration = animationDuration;
            Storyboard.SetTarget(moveAnimation, itemImage.RenderTransform);
            Storyboard.SetTargetProperty(moveAnimation, new PropertyPath(TranslateTransform.YProperty));

            const double animationDistance = 200;
            if (!Double.IsNaN(move.FromY))
            {
              Canvas.SetTop(itemImage, move.FromY);
              if (move.FromIndex < move.ToIndex)
              {
                moveAnimation.To = animationDistance;
              }
              else if (move.FromIndex > move.ToIndex)
              {
                moveAnimation.To = -animationDistance;
              }
            }
            else
            {
              Canvas.SetTop(itemImage, move.ToY);
              if (move.FromIndex < move.ToIndex)
              {
                moveAnimation.From = -animationDistance;
              }
              else if (move.FromIndex > move.ToIndex)
              {
                moveAnimation.From = animationDistance;
              }
            }

            storyboard.Children.Add(moveAnimation);
              }

              DoubleAnimation fadeAnimation = new DoubleAnimation();
              fadeAnimation.Duration = animationDuration;
              Storyboard.SetTarget(fadeAnimation, itemImage);
              Storyboard.SetTargetProperty(fadeAnimation, new PropertyPath(UIElement.OpacityProperty));

              if (Double.IsNaN(move.FromY))
              {
            itemImage.Opacity = 0.0;
            fadeAnimation.To = 1.0;
            Canvas.SetTop(itemImage, move.ToY);
              }
              else
              {
            itemImage.Opacity = 1.0;
            fadeAnimation.To = 0.0;
            Canvas.SetTop(itemImage, move.FromY);
              }

              storyboard.Children.Add(fadeAnimation);
            }
              }

              return storyboard;
        }
        /// <summary>
        /// Slides the drag indicator (item snapshot) to the location of the dropped item,
        /// then performs the visibility swap and removes the dragging visual state.
        /// </summary>
        private void AnimateDrop(ReorderListBoxItem itemContainer)
        {
            GeneralTransform itemTransform = itemContainer.TransformToVisual(this.dragInterceptor);
              Rect itemRect = itemTransform.TransformBounds(new Rect(new Point(0, 0), itemContainer.RenderSize));
              double delta = Math.Abs(itemRect.Y - Canvas.GetTop(this.dragIndicator) -
              ((TranslateTransform)this.dragIndicator.RenderTransform).Y);

              if (delta > 0 && !(dragItem is Script))
              {
            // Adjust the duration based on the distance, so the speed will be constant.
            TimeSpan duration = TimeSpan.FromSeconds(0.25 * delta / itemRect.Height);

            Storyboard dropStoryboard = new Storyboard();
            DoubleAnimation moveToDropAnimation = new DoubleAnimation();
            Storyboard.SetTarget(moveToDropAnimation, this.dragIndicator.RenderTransform);
            Storyboard.SetTargetProperty(moveToDropAnimation, new PropertyPath(TranslateTransform.YProperty));
            moveToDropAnimation.To = itemRect.Y - Canvas.GetTop(this.dragIndicator);
            moveToDropAnimation.Duration = duration;
            dropStoryboard.Children.Add(moveToDropAnimation);

            dropStoryboard.Completed += delegate
            {
              this.dragItem = null;
              itemContainer.Opacity = 1;
              this.dragIndicator.Visibility = Visibility.Collapsed;
              this.dragIndicator.Source = null;
              ((TranslateTransform)this.dragIndicator.RenderTransform).Y = 0;
              VisualStateManager.GoToState(itemContainer, ReorderListBoxItem.NotDraggingState, true);

            };
            dropStoryboard.Begin();
              }
              else
              {
            // There was no need for an animation, so do the visibility swap right now.
            this.dragItem = null;
            itemContainer.Opacity = 1;
            this.dragIndicator.Visibility = Visibility.Collapsed;
            this.dragIndicator.Source = null;
            VisualStateManager.GoToState(itemContainer, ReorderListBoxItem.NotDraggingState, true);
              }
        }
        /// <summary>
        /// Ensures that a possibly-recycled item container (ReorderListBoxItem) is ready to display a list item.
        /// </summary>
        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);

              ReorderListBoxItem itemContainer = (ReorderListBoxItem)element;
              itemContainer.ApplyTemplate();  // Loads visual states.

              // BEGIN Added by Valentin

              if(item is Script)
              {
            itemContainer.DragHandleTemplate = (DataTemplate) App.Current.Resources["DragItemTemplateScript"];

              }
              else if(item is Brick)
              {
            itemContainer.DragHandleTemplate = (DataTemplate)App.Current.Resources["DragItemTemplateBrick"];
              }

              // END added

              // Set this state before binding to avoid showing the visual transition in this case.
              string reorderState = this.IsReorderEnabled ?
              ReorderListBoxItem.ReorderEnabledState : ReorderListBoxItem.ReorderDisabledState;
              VisualStateManager.GoToState(itemContainer, reorderState, false);

              itemContainer.SetBinding(ReorderListBoxItem.IsReorderEnabledProperty,
              new Binding(ReorderListBox.IsReorderEnabledPropertyName) { Source = this });

              if (item == this.dragItem)
              {
            itemContainer.IsSelected = this.isDragItemSelected;
            VisualStateManager.GoToState(itemContainer, ReorderListBoxItem.DraggingState, false);

            if (this.dropTargetIndex >= 0)
            {
              // The item's dragIndicator is currently being moved, so the item itself is hidden.
              itemContainer.Visibility = Visibility.Collapsed;
              this.dragItemContainer = itemContainer;
            }
            else
            {
              itemContainer.Opacity = 0;
              this.Dispatcher.BeginInvoke(() => this.AnimateDrop(itemContainer));
            }
              }
              else
              {
            VisualStateManager.GoToState(itemContainer, ReorderListBoxItem.NotDraggingState, false);
              }
        }
        /// <summary>
        /// Called when an item container (ReorderListBoxItem) is being removed from the list panel.
        /// This may be because the item was removed from the list or because the item is now outside
        /// the virtualization region (because ListBox uses a VirtualizingStackPanel as its items panel).
        /// </summary>
        protected override void ClearContainerForItemOverride(DependencyObject element, object item)
        {
            base.ClearContainerForItemOverride(element, item);

              ReorderListBoxItem itemContainer = (ReorderListBoxItem)element;
              if (itemContainer == this.dragItemContainer)
              {
            this.dragItemContainer.Visibility = Visibility.Visible;
            this.dragItemContainer = null;
              }
        }
        /// <summary>
        /// Updates the targeted index -- that is the index where the item will be moved to if dropped at this point.
        /// </summary>
        private void UpdateDropTargetIndex(ReorderListBoxItem targetItemContainer, bool after)
        {
            int dragItemIndex = this.Items.IndexOf(this.dragItem);
              int targetItemIndex = this.Items.IndexOf(targetItemContainer.Content);

              int newDropTargetIndex;
              if (targetItemIndex == dragItemIndex)
              {
            newDropTargetIndex = dragItemIndex;
              }
              else
              {
            newDropTargetIndex = targetItemIndex + (after ? 1 : 0) - (targetItemIndex >= dragItemIndex ? 1 : 0);
              }

              if (newDropTargetIndex != this.dropTargetIndex)
              {
            this.dropTargetIndex = newDropTargetIndex;
              }
        }