//**//

        protected override void OnValidateInternal()
        {
            HandleDuplication();

            if (!ValidNodes)
            {
                ChiselNodeHierarchyManager.RebuildTreeNodes(this);
                return;
            }

            UpdateGenerator();
            UpdateBrushMeshInstances();

            ChiselNodeHierarchyManager.NotifyContentsModified(this);
            base.OnValidateInternal();
        }
        bool InitializeBrushMeshInstances()
        {
            var instances = brushContainerAsset ? brushContainerAsset.Instances : null;

            // TODO: figure out why this can happen (mess around with spiral stairs)
            // TODO: does this have anything to do with spiral stairs not updating all submeshes when being modified?
            if (instances != null &&
                instances.Length !=
                brushContainerAsset.SubMeshCount)
            {
                brushContainerAsset.UpdateInstances();
                instances = brushContainerAsset ? brushContainerAsset.Instances : null;
            }

            if (instances == null)
            {
                if (Nodes != null && Nodes.Length > 0)
                {
                    ChiselNodeHierarchyManager.RebuildTreeNodes(this);
                }
                return(false);
            }

            var requiredNodeLength = RequiredNodeLength(instances);

            if (requiredNodeLength == 0 &&
                Nodes != null && Nodes.Length > 0)
            {
                ChiselNodeHierarchyManager.RebuildTreeNodes(this);
                return(false);
            }

            if (Nodes != null && Nodes.Length == requiredNodeLength)
            {
                if (Nodes.Length == 1)
                {
                    var brush = (CSGTreeBrush)TopNode;
                    brush.BrushMesh = brushContainerAsset.Instances[0];
                    brush.Operation = brushContainerAsset.Operations[0];
                }
                else
                {
                    for (int i = 0; i < instances.Length; i++)
                    {
                        var brush = (CSGTreeBrush)Nodes[i + 1];
                        brush.BrushMesh = brushContainerAsset.Instances[i];
                        brush.Operation = brushContainerAsset.Operations[i];
                    }
                }
                return(true);
            }
            else
            {
                bool needRebuild = (Nodes != null && instances != null && instances.Length > 0) && Nodes.Length != requiredNodeLength;
                if (Nodes.Length == 1)
                {
                    var brush = (CSGTreeBrush)TopNode;
                    if (brush.BrushMesh != BrushMeshInstance.InvalidInstance)
                    {
                        brush.BrushMesh = BrushMeshInstance.InvalidInstance;
                        brush.Operation = CSGOperationType.Additive;
                    }
                }
                else
                {
                    for (int i = 1; i < Nodes.Length; i++)
                    {
                        var brush = (CSGTreeBrush)Nodes[i];
                        if (brush.BrushMesh != BrushMeshInstance.InvalidInstance)
                        {
                            brush.BrushMesh = BrushMeshInstance.InvalidInstance;
                            brush.Operation = CSGOperationType.Additive;
                        }
                    }
                }
                if (needRebuild) // if we don't do this, we'll end up creating nodes infinitely, when the node can't make a valid brushMesh
                {
                    ChiselNodeHierarchyManager.RebuildTreeNodes(this);
                }
                return(false);
            }
        }