Inheritance: ErrorNode
        private static void OnForInputTypesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d.GetType().FullName == "System.Windows.Documents.CaretElement")
            {
                return;
            }

            var newValue = (InputTypeCollection)e.NewValue;

            if (newValue == null)
            {
                d.SetValue(NodePropertyKey, ValidNode.Default);
                return;
            }

            if (newValue.Contains(d))
            {
                var inputNode = GetNode(d) as InputNode;
                if (inputNode == null)
                {
#pragma warning disable IDISP001, CA2000 // Dispose created. Disposed in SetNode
                    inputNode = new InputNode((FrameworkElement)d);
#pragma warning restore IDISP001, CA2000 // Dispose created.
                    SetNode(d, inputNode);
                }
            }
            else
            {
                // below looks pretty expensive but
                // a) Not expecting scope to change often.
                // b) Not expecting many errors often.
                // optimize if profiler points at it
                // ReSharper disable once UseNullPropagation
                var errorNode = GetNode(d) as ErrorNode;
                if (errorNode == null)
                {
                    return;
                }

                var removedErrors = errorNode.Errors.Where(error => !IsScopeFor(d, error)).ToArray();
                if (removedErrors.Length > 0)
                {
                    errorNode.ErrorCollection.Remove(removedErrors);
                    if (errorNode.Errors.Count == 0)
                    {
                        SetNode(d, ValidNode.Default);
                    }
                    else
                    {
                        var removeChildren = errorNode.Children.Where(c => !errorNode.Errors.Intersect(c.Errors).Any()).ToArray();
                        foreach (var removeChild in removeChildren)
                        {
                            errorNode.ChildCollection.Remove(removeChild);
                        }
                    }
                }
            }
        }
        private static void OnForInputTypesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d.GetType().FullName == "System.Windows.Documents.CaretElement")
            {
                return;
            }

            var newValue = (InputTypeCollection)e.NewValue;
            if (newValue == null)
            {
                d.SetValue(NodePropertyKey, ValidNode.Default);
                return;
            }

            if (newValue.Contains(d))
            {
                var inputNode = GetNode(d) as InputNode;
                if (inputNode == null)
                {
                    inputNode = new InputNode((FrameworkElement)d);
                    SetNode(d, inputNode);
                }
            }
            else
            {
                // below looks pretty expensive but
                // a) Not expecting scope to change often.
                // b) Not expecting many errors often.
                // optimize if profiler points at it
                // ReSharper disable once UseNullPropagation
                var errorNode = GetNode(d) as ErrorNode;
                if (errorNode == null)
                {
                    return;
                }

                var removedErrors = errorNode.Errors.Where(error => !IsScopeFor(d, error)).ToArray();
                if (removedErrors.Length > 0)
                {
                    errorNode.ErrorCollection.Remove(removedErrors);
                    if (errorNode.Errors.Count == 0)
                    {
                        SetNode(d, ValidNode.Default);
                    }
                    else
                    {
                        var removeChildren = errorNode.Children.Where(c => !errorNode.Errors.Intersect(c.Errors).Any()).ToArray();
                        foreach (var removeChild in removeChildren)
                        {
                            errorNode.ChildCollection.Remove(removeChild);
                        }
                    }
                }
            }
        }