private void MonitorBreach(DragablzDragDeltaEventArgs e)
        {
            var mousePositionOnHeaderItemsControl = Mouse.GetPosition(_dragablzItemsControl);

            Orientation? breachOrientation = null;
            if (mousePositionOnHeaderItemsControl.X < -InterTabController.HorizontalPopoutGrace
                || (mousePositionOnHeaderItemsControl.X - _dragablzItemsControl.ActualWidth) > InterTabController.HorizontalPopoutGrace)
                breachOrientation = Orientation.Horizontal;
            else if (mousePositionOnHeaderItemsControl.Y < -InterTabController.VerticalPopoutGrace
                     || (mousePositionOnHeaderItemsControl.Y - _dragablzItemsControl.ActualHeight) > InterTabController.VerticalPopoutGrace)
                breachOrientation = Orientation.Vertical;

            if (!breachOrientation.HasValue) return;

            var newTabHost = InterTabController.InterTabClient.GetNewHost(InterTabController.InterTabClient,
                InterTabController.Partition, this);
            if (newTabHost == null || newTabHost.TabablzControl == null || newTabHost.Container == null)
                throw new ApplicationException("New tab host was not correctly provided");

            var item = _dragablzItemsControl.ItemContainerGenerator.ItemFromContainer(e.DragablzItem);

            var myWindow = Window.GetWindow(this);
            if (myWindow == null) throw new ApplicationException("Unable to find owning window.");
            var dragStartWindowOffset = ConfigureNewHostSizeAndGetDragStartWindowOffset(myWindow, newTabHost, e.DragablzItem);

            var dragableItemHeaderPoint = e.DragablzItem.TranslatePoint(new Point(), _dragablzItemsControl);
            var dragableItemSize = new Size(e.DragablzItem.ActualWidth, e.DragablzItem.ActualHeight);
            var floatingItemSnapShots = this.VisualTreeDepthFirstTraversal()
                .OfType<Layout>()
                .SelectMany(l => l.FloatingDragablzItems().Select(FloatingItemSnapShot.Take))
                .ToList();

            var interTabTransfer = new InterTabTransfer(item, e.DragablzItem, breachOrientation.Value, dragStartWindowOffset, e.DragablzItem.MouseAtDragStart, dragableItemHeaderPoint, dragableItemSize, floatingItemSnapShots);

            if (myWindow.WindowState == WindowState.Maximized)
            {
                var desktopMousePosition = Native.GetCursorPos().ToWpf();
                newTabHost.Container.Left = desktopMousePosition.X - dragStartWindowOffset.X;
                newTabHost.Container.Top = desktopMousePosition.Y - dragStartWindowOffset.Y;
            }
            else
            {
                newTabHost.Container.Left = myWindow.Left;
                newTabHost.Container.Top = myWindow.Top;
            }
            newTabHost.Container.Show();
            var contentPresenter = FindChildContentPresenter(item);
            RemoveFromSource(item);
            _itemsHolder.Children.Remove(contentPresenter);
            if (Items.Count == 0)
                Layout.ConsolidateBranch(this);

            RestorePreviousSelection();

            foreach (var dragablzItem in _dragablzItemsControl.DragablzItems())
            {
                dragablzItem.IsDragging = false;
                dragablzItem.IsSiblingDragging = false;
            }

            newTabHost.TabablzControl.ReceiveDrag(interTabTransfer);
            interTabTransfer.OriginatorContainer.IsDropTargetFound = true;
            e.Cancel = true;
        }
        internal void ReceiveDrag(InterTabTransfer interTabTransfer)
        {
            var myWindow = Window.GetWindow(this);
            if (myWindow == null) throw new ApplicationException("Unable to find owning window.");
            myWindow.Activate();

            _interTabTransfer = interTabTransfer;

            if (Items.Count == 0)
            {
                _dragablzItemsControl.LockedMeasure = new Size(
                    interTabTransfer.ItemPositionWithinHeader.X + interTabTransfer.ItemSize.Width,
                    interTabTransfer.ItemPositionWithinHeader.Y + interTabTransfer.ItemSize.Height);
            }

            var lastFixedItem = _dragablzItemsControl.DragablzItems()
                .OrderBy(i => i.LogicalIndex)
                .Take(_dragablzItemsControl.FixedItemCount)
                .LastOrDefault();

            AddToSource(interTabTransfer.Item);
            SelectedItem = interTabTransfer.Item;

            Dispatcher.BeginInvoke(new Action(() => Layout.RestoreFloatingItemSnapShots(this, interTabTransfer.FloatingItemSnapShots)), DispatcherPriority.Loaded);
            _dragablzItemsControl.InstigateDrag(interTabTransfer.Item, newContainer =>
            {
                newContainer.PartitionAtDragStart = interTabTransfer.OriginatorContainer.PartitionAtDragStart;
                newContainer.IsDropTargetFound = true;
                if (interTabTransfer.TransferReason == InterTabTransferReason.Breach)
                {
                    if (interTabTransfer.BreachOrientation == Orientation.Horizontal)
                        newContainer.Y = interTabTransfer.OriginatorContainer.Y;
                    else
                        newContainer.X = interTabTransfer.OriginatorContainer.X;
                }
                else
                {
                    //TODO sort for vert tabs
                    var mouseXOnItemsControl = Native.GetCursorPos().X - _dragablzItemsControl.PointToScreen(new Point()).X;
                    var newX = mouseXOnItemsControl - interTabTransfer.DragStartItemOffset.X;
                    if (lastFixedItem != null)
                    {
                        newX = Math.Max(newX, lastFixedItem.X + lastFixedItem.ActualWidth);
                    }
                    newContainer.X = newX;
                    newContainer.Y = 0;
                }
                newContainer.MouseAtDragStart = interTabTransfer.DragStartItemOffset;
            });
        }
        private void ItemDragCompleted(object sender, DragablzDragCompletedEventArgs e)
        {
            if (!IsMyItem(e.DragablzItem)) return;

            _interTabTransfer = null;
            _dragablzItemsControl.LockedMeasure = null;
            IsDraggingWindow = false;
        }
        private bool MonitorReentry(DragablzDragDeltaEventArgs e)
        {
            var screenMousePosition = _dragablzItemsControl.PointToScreen(Mouse.GetPosition(_dragablzItemsControl));

            var sourceTabablzControl = (TabablzControl) e.Source;
            if (sourceTabablzControl.Items.Count > 1 && e.DragablzItem.LogicalIndex < sourceTabablzControl.FixedHeaderCount)
            {
                return false;
            }

            var otherTabablzControls = LoadedInstances
                .Where(
                    tc =>
                        tc != this && tc.InterTabController != null && InterTabController != null
                        && Equals(tc.InterTabController.Partition, InterTabController.Partition))
                .Select(tc =>
                {
                    var topLeft = tc._dragablzItemsControl.PointToScreen(new Point());
                    var lastFixedItem = tc._dragablzItemsControl.DragablzItems()
                        .OrderBy(di=> di.LogicalIndex)
                        .Take(tc._dragablzItemsControl.FixedItemCount)
                        .LastOrDefault();
                    //TODO work this for vert tabs
                    if (lastFixedItem != null)
                        topLeft.Offset(lastFixedItem.X + lastFixedItem.ActualWidth, 0);
                    var bottomRight =
                        tc._dragablzItemsControl.PointToScreen(new Point(tc._dragablzItemsControl.ActualWidth,
                            tc._dragablzItemsControl.ActualHeight));

                    return new {tc, topLeft, bottomRight};
                });

            var target = Native.SortWindowsTopToBottom(Application.Current.Windows.OfType<Window>())
                .Join(otherTabablzControls, w => w, a => Window.GetWindow(a.tc), (w, a) => a)
                .FirstOrDefault(a => new Rect(a.topLeft, a.bottomRight).Contains(screenMousePosition));

            if (target != null)
            {
                var mousePositionOnItem = Mouse.GetPosition(e.DragablzItem);

                var floatingItemSnapShots = this.VisualTreeDepthFirstTraversal()
                    .OfType<Layout>()
                    .SelectMany(l => l.FloatingDragablzItems().Select(FloatingItemSnapShot.Take))
                    .ToList();

                e.DragablzItem.IsDropTargetFound = true;
                var item = RemoveItem(e.DragablzItem);

                var interTabTransfer = new InterTabTransfer(item, e.DragablzItem, mousePositionOnItem, floatingItemSnapShots);
                e.DragablzItem.IsDragging = false;

                target.tc.ReceiveDrag(interTabTransfer);
                e.Cancel = true;

                return true;
            }

            return false;
        }