void OnHostDetached(object sender, DetachedArgs a)
        {
            // skip sticky objects
            if (sticky)
            {
                return;
            }

            // go up in the hierarchy
            DockObject newHost = host.ParentObject;

            while (newHost != null)
            {
                DockPlacement pos = DockPlacement.None;

                // get a placement hint from the new host
                if (newHost.ChildPlacement(host, ref pos))
                {
                    NextPlacement = pos;
                }
                else
                {
                    Console.WriteLine("Something weird happened while getting the child placement for {0} from parent {1}", host, newHost);
                }

                // we found a "stable" dock object
                if (newHost.InDetach)
                {
                    break;
                }

                newHost = newHost.ParentObject;
            }

            // disconnect host
            DisconnectHost();

            // the toplevel was detached: we attach ourselves to the
            // controller with an initial placement of floating
            if (newHost == null)
            {
                newHost       = this.Master.Controller;
                NextPlacement = DockPlacement.Floating;
            }

            if (newHost != null)
            {
                ConnectHost(newHost);
            }

            PrintPlacementStack();
        }
        void OnHostDocked(object sender, DockedArgs a)
        {
            DockObject obj = sender as DockObject;

            // see if the given position is compatible for the stack's top element
            if (!sticky && placementStack != null)
            {
                DockPlacement pos = NextPlacement;
                if (obj.ChildPlacement(a.Requestor, ref pos))
                {
                    DoExcursion();
                }
            }

            PrintPlacementStack();
        }
        /*
         * Tries to shrink the placement stack by examining the host's
         * children and see if any of them matches the placement which is at
         * the top of the stack.  If this is the case, it tries again with the
         * new host.
         */
        public void DoExcursion()
        {
            if (host != null && !Sticky && placementStack != null && placementStack.Count > 0 && host.IsCompound)
            {
                DockPlacement pos;
                DockPlacement stack_pos = NextPlacement;
                foreach (Widget child in host.Children)
                {
                    DockObject item = child as DockObject;
                    if (item == null)
                    {
                        continue;
                    }
                    pos = stack_pos;

                    host.ChildPlacement(item, ref pos);
                    if (pos == stack_pos)
                    {
                        // remove the stack position
                        if (placementStack.Count > 1)
                        {
                            placementStack.Pop();
                        }
                        DisconnectHost();

                        // connect to the new host
                        ConnectHost(item);

                        // recurse ...
                        if (!item.InReflow)
                        {
                            DoExcursion();
                        }
                        break;
                    }
                }
            }
        }