/// <summary>
        /// Initializes a new instance of the DropInfo class.
        /// </summary>
        ///
        /// <param name="sender">
        /// The sender of the drag event.
        /// </param>
        ///
        /// <param name="e">
        /// The drag event.
        /// </param>
        ///
        /// <param name="dragInfo">
        /// Information about the source of the drag, if the drag came from within the framework.
        /// </param>
        public DropInfo(object sender, DragEventArgs e, DragInfo dragInfo)
        {
            var dataFormat = DragDrop.DataFormat.Name;

            this.Data      = (e.Data.GetDataPresent(dataFormat)) ? e.Data.GetData(dataFormat) : e.Data;
            this.DragInfo  = dragInfo;
            this.KeyStates = e.KeyStates;

            this.VisualTarget = sender as UIElement;
            // if drop target isn't a ItemsControl
            if (!(this.VisualTarget is ItemsControl))
            {
                // try to find next ItemsControl
                var itemsControl = VisualTreeExtensions.GetVisualAncestor <ItemsControl>(this.VisualTarget);
                if (itemsControl != null)
                {
                    // now check if this ItemsControl is a drop target
                    if (DragDrop.GetIsDropTarget(itemsControl))
                    {
                        this.VisualTarget = itemsControl;
                    }
                }
            }
            // visual target can be null, so give us a point...
            this.DropPosition = this.VisualTarget != null?e.GetPosition(this.VisualTarget) : new Point();

            if (this.VisualTarget is ItemsControl)
            {
                var itemsControl     = (ItemsControl)this.VisualTarget;
                var item             = itemsControl.GetItemContainerAt(this.DropPosition);
                var directlyOverItem = item != null;

                this.TargetGroup               = this.FindGroup(itemsControl, this.DropPosition);
                this.VisualTargetOrientation   = itemsControl.GetItemsPanelOrientation();
                this.VisualTargetFlowDirection = itemsControl.GetItemsPanelFlowDirection();

                if (item == null)
                {
                    item             = itemsControl.GetItemContainerAt(this.DropPosition, this.VisualTargetOrientation);
                    directlyOverItem = false;
                }

                if (item != null)
                {
                    var itemParent = ItemsControl.ItemsControlFromItemContainer(item);

                    this.InsertIndex      = itemParent.ItemContainerGenerator.IndexFromContainer(item);
                    this.TargetCollection = itemParent.ItemsSource ?? itemParent.Items;

                    if (directlyOverItem || typeof(TreeViewItem).IsAssignableFrom(item.GetType()))
                    {
                        this.TargetItem       = itemParent.ItemContainerGenerator.ItemFromContainer(item);
                        this.VisualTargetItem = item;
                    }

                    var itemRenderSize = item.RenderSize;

                    if (this.VisualTargetOrientation == Orientation.Vertical)
                    {
                        var currentYPos  = e.GetPosition(item).Y;
                        var targetHeight = itemRenderSize.Height;

                        if (currentYPos > targetHeight / 2)
                        {
                            this.InsertIndex++;
                            this.InsertPosition = RelativeInsertPosition.AfterTargetItem;
                        }
                        else
                        {
                            this.InsertPosition = RelativeInsertPosition.BeforeTargetItem;
                        }

                        if (currentYPos > targetHeight * 0.25 && currentYPos < targetHeight * 0.75)
                        {
                            this.InsertPosition |= RelativeInsertPosition.TargetItemCenter;
                        }
                    }
                    else
                    {
                        var currentXPos = e.GetPosition(item).X;
                        var targetWidth = itemRenderSize.Width;

                        if ((this.VisualTargetFlowDirection == FlowDirection.RightToLeft && currentXPos < targetWidth / 2) ||
                            (this.VisualTargetFlowDirection == FlowDirection.LeftToRight && currentXPos > targetWidth / 2))
                        {
                            this.InsertIndex++;
                            this.InsertPosition = RelativeInsertPosition.AfterTargetItem;
                        }
                        else
                        {
                            this.InsertPosition = RelativeInsertPosition.BeforeTargetItem;
                        }

                        if (currentXPos > targetWidth * 0.25 && currentXPos < targetWidth * 0.75)
                        {
                            this.InsertPosition |= RelativeInsertPosition.TargetItemCenter;
                        }
#if DEBUG
                        Console.WriteLine("==> DropInfo: {0}, {1}, {2}, X={3}", this.InsertPosition, item, this.InsertIndex, currentXPos);
#endif
                    }
                }
                else
                {
                    this.TargetCollection = itemsControl.ItemsSource ?? itemsControl.Items;
                    this.InsertIndex      = itemsControl.Items.Count;
                }
            }
        }