/// <summary>
        /// Adds an adorner to the adorner layer.
        /// </summary>
        /// <param name="adorner">The adorner to add to the adorner layer.</param>
        public void Add(Adorner adorner)
        {
            Contract.Require(adorner, nameof(adorner));

            // NOTE: In WPF this doesn't work but it also doesn't produce an error, so we just fail silently here
            var adornerLayerParent = VisualTreeHelper.GetParent(this);

            if (!adorner.AdornedElement.IsDescendantOf(adornerLayerParent))
            {
                return;
            }

            var state = new AdornerState(adorner);

            state.LastAbsoluteX    = adorner.AdornedElement.UntransformedAbsolutePosition.X;
            state.LastAbsoluteY    = adorner.AdornedElement.UntransformedAbsolutePosition.Y;
            state.LastRenderWidth  = adorner.AdornedElement.RenderSize.Width;
            state.LastRenderHeight = adorner.AdornedElement.RenderSize.Height;

            adorners.Add(adorner);
            adornersStates.Add(state);

            adorner.InvalidateMeasure();
            adorner.ChangeLogicalParent(this);

            InvalidateMeasure();
            InvalidateArrange(true);
        }
        /// <summary>
        /// Removes an adorner from the adorner layer.
        /// </summary>
        /// <param name="adorner">The adorner to remove from the adorner layer.</param>
        public void Remove(Adorner adorner)
        {
            Contract.Require(adorner, nameof(adorner));

            var index = adorners.IndexOf(adorner);

            if (index >= 0)
            {
                adorners.RemoveAt(index);
                adornersStates.RemoveAt(index);

                adorner.ChangeLogicalParent(null);
            }
        }
        /// <summary>
        /// Adds an adorner to the adorner layer.
        /// </summary>
        /// <param name="adorner">The adorner to add to the adorner layer.</param>
        public void Add(Adorner adorner)
        {
            Contract.Require(adorner, "adorner");

            // NOTE: In WPF this doesn't work but it also doesn't produce an error, so we just fail silently here
            var adornerLayerParent = VisualTreeHelper.GetParent(this);
            if (!adorner.AdornedElement.IsDescendantOf(adornerLayerParent))
                return;

            var state = new AdornerState(adorner);
            state.LastAbsoluteX = adorner.AdornedElement.UntransformedAbsolutePosition.X;
            state.LastAbsoluteY = adorner.AdornedElement.UntransformedAbsolutePosition.Y;
            state.LastRenderWidth = adorner.AdornedElement.RenderSize.Width;
            state.LastRenderHeight = adorner.AdornedElement.RenderSize.Height;

            adorners.Add(adorner);
            adornersStates.Add(state);
            
            adorner.InvalidateMeasure();
            adorner.ChangeLogicalParent(this);

            InvalidateMeasure();
            InvalidateArrange(true);
        }
        /// <summary>
        /// Removes an adorner from the adorner layer.
        /// </summary>
        /// <param name="adorner">The adorner to remove from the adorner layer.</param>
        public void Remove(Adorner adorner)
        {
            Contract.Require(adorner, "adorner");

            var index = adorners.IndexOf(adorner);
            if (index >= 0)
            {
                adorners.RemoveAt(index);
                adornersStates.RemoveAt(index);

                adorner.ChangeLogicalParent(null);
            }
        }