private static void Float(Layout layout, DockItem dockItem)
        {
            var sourceOfDockItemsControl =
                dockItem.GetSelfAndLogicalAncestors().OfType <ItemsControl>().FirstOrDefault() as DockItemsControl;

            if (sourceOfDockItemsControl == null)
            {
                throw new ApplicationException("Unable to determine source items control.");
            }
            var sourceDockControl = DockControl.GetOwnerOfHeaderItems(sourceOfDockItemsControl);

            layout._floatTransfer = FloatTransfer.TakeSnapshot(dockItem, sourceDockControl);
            var floatingItemSnapShots = sourceDockControl.GetVisualDescendents().OfType <Layout>()
                                        .SelectMany(l => l.FloatingDockItems().Select(FloatingItemSnapShot.Take))
                                        .ToList();

            if (sourceDockControl == null)
            {
                throw new ApplicationException("Unable to determine source tab control.");
            }
            sourceDockControl.RemoveItem(dockItem);

            ((IList)layout.FloatingItems).Add(layout._floatTransfer.Content);

            Dispatcher.UIThread.InvokeAsync(
                new Action(() => RestoreFloatingItemSnapShots(layout, floatingItemSnapShots)), DispatcherPriority.Loaded);
        }
        private static bool TryGetSourceTabControl(DockItem dockItem, out DockControl dockControl)
        {
            var sourceOfDockItemsControl =
                dockItem.GetSelfAndLogicalAncestors().OfType <ItemsControl>().FirstOrDefault() as DockItemsControl;

            if (sourceOfDockItemsControl == null)
            {
                throw new ApplicationException("Unable to determine source items control.");
            }

            dockControl = DockControl.GetOwnerOfHeaderItems(sourceOfDockItemsControl);

            return(dockControl != null);
        }
        private void Branch(DropZoneLocation location, DockItem sourceDockItem)
        {
            if (InterLayoutClient == null)
            {
                throw new InvalidOperationException("InterLayoutClient is not set.");
            }

            var sourceOfdockItemsControl =
                sourceDockItem.GetSelfAndLogicalAncestors().OfType <ItemsControl>().FirstOrDefault() as DockItemsControl;

            if (sourceOfdockItemsControl == null)
            {
                return;
            }

            var sourceDockControl = DockControl.GetOwnerOfHeaderItems(sourceOfdockItemsControl);

            if (sourceDockControl == null)
            {
                throw new ApplicationException("Unable to determine source dock control ");
            }

            var floatingItemSnapShots = sourceDockControl.GetVisualChildren().OfType <Layout>()
                                        .SelectMany(l => l.FloatingDockItems().Select(FloatingItemSnapShot.Take))
                                        .ToList();

            var sourceItemIndex = sourceOfdockItemsControl.ItemContainerGenerator.IndexFromContainer(sourceDockItem);
            var sourceItem      = (DockItem)((IList)sourceDockControl.Items)[sourceItemIndex];

            sourceDockControl.RemoveItem(sourceItem);

            var branchItem = new Branch
            {
                Orientation = (location == DropZoneLocation.Right || location == DropZoneLocation.Left) ? Orientation.Horizontal : Orientation.Vertical,
            };

            object newContent;

            if (BranchTemplate == null)
            {
                var newTabHost = InterLayoutClient.GetNewHost(Partition, sourceDockControl);
                if (newTabHost == null)
                {
                    throw new ApplicationException("InterLayoutClient did not provide a new tab host.");
                }
                newTabHost.DockControl.AddToSource(sourceItem);
                newTabHost.DockControl.SelectedItem = sourceItem;
                newContent = newTabHost.Container;

                Dispatcher.UIThread.InvokeAsync(new Action(() => RestoreFloatingItemSnapShots(newTabHost.DockControl, floatingItemSnapShots)), DispatcherPriority.Loaded);
            }
            else
            {
                newContent = new ContentControl
                {
                    Content = new object(),
                };

                ((ContentControl)newContent).DataTemplates.Add(BranchTemplate);

                Dispatcher.UIThread.InvokeAsync(new Action(() =>
                {
                    var newDockControl = ((ContentControl)newContent).GetVisualChildren().OfType <DockControl>().FirstOrDefault();
                    if (newDockControl == null)
                    {
                        return;
                    }

                    newDockControl.DataContext = sourceDockControl.DataContext;
                    newDockControl.AddToSource(sourceItem);
                    newDockControl.SelectedItem = sourceItem;
                    Dispatcher.UIThread.InvokeAsync(new Action(() => RestoreFloatingItemSnapShots(newDockControl, floatingItemSnapShots)), DispatcherPriority.Loaded);
                }), DispatcherPriority.Loaded);
            }

            if (location == DropZoneLocation.Right || location == DropZoneLocation.Bottom)
            {
                branchItem.FirstItem  = Content;
                branchItem.SecondItem = newContent;
            }
            else
            {
                branchItem.FirstItem  = newContent;
                branchItem.SecondItem = Content;
            }

            SetValue(ContentProperty, branchItem);
        }