private bool IsValidDrop(DragEventArgs e, out DropInfo dropInfo)
        {
            dropInfo = null;
            IDataSourceViewModel viewModel = e.Data.GetData(typeof (SingleDataSourceViewModel)) as IDataSourceViewModel ??
                                             e.Data.GetData(typeof (MergedDataSourceViewModel)) as IDataSourceViewModel;
            var source = new TreeItem
                {
                    ViewModel = viewModel
                };
            if (source.ViewModel == null)
                return false;

            TreeItem dropTarget = GetDataSourceFromPosition(e.GetPosition(_partDataSources));
            if (dropTarget == null)
                return false;

            DataSourceDropType dropType = GetDropType(e, dropTarget, viewModel);
            var model = (MainWindowViewModel) DataContext;
            IDataSourceViewModel group;
            if (!model.CanBeDropped(source.ViewModel, dropTarget.ViewModel, dropType, out group))
                return false;

            dropInfo = new DropInfo
                {
                    Source = source,
                    Type = dropType,
                    Target = dropTarget,
                    TargetGroup = new TreeItem
                        {
                            ViewModel = group,
                            TreeViewItem = GetTreeViewItem(group)
                        }
                };
            return true;
        }
        private DataSourceDropType GetDropType(DragEventArgs e,
		                                       TreeItem destination,
		                                       IDataSourceViewModel source)
        {
            if (destination == null)
                return DataSourceDropType.None;

            Point pos = e.GetPosition(destination.TreeViewItem);

            var dropType = DataSourceDropType.None;
            double height = destination.TreeViewItem.ActualHeight;
            if (source is SingleDataSourceViewModel)
            {
                // Let's distribute it as follows:
                // 20% top => arrange
                // 60% middle => group
                // 20% bottom => arrange
                //
                // This way 60% of the height is used for grouping and 40% is used for arranging.
                if (pos.Y < height*0.2)
                    dropType |= DataSourceDropType.ArrangeTop;
                else if (pos.Y < height*0.8)
                    dropType |= DataSourceDropType.Group;
                else
                    dropType |= DataSourceDropType.ArrangeBottom;

                if (destination.ViewModel.Parent != null)
                    dropType |= DataSourceDropType.Group;
            }
            else
            {
                // Groups can't be grouped any further, thus we
                // simply arrange it above or beneath the drop source
                // at a 50/50 split.
                if (pos.Y < height*0.5)
                    dropType |= DataSourceDropType.ArrangeTop;
                else
                    dropType |= DataSourceDropType.ArrangeBottom;
            }

            return dropType;
        }