/// <summary>
        /// This function adapts the children of the view that they represent the children of the node this view is for.
        /// Children are added and removed.
        /// </summary>
        /// <param name="processedBehaviors">A list of previously processed behaviours to deal with circular references.</param>
        public override void SynchronizeWithNode(ProcessedBehaviors processedBehaviors)
        {
            // if we have a circular reference, we must skip it
            if (!processedBehaviors.MayProcessCheckOnly(_node))
            {
                _children.ClearChildren();
                return;
            }

            base.SynchronizeWithNode(processedBehaviors);
        }
        public override void DoSynchronizeWithNode(ProcessedBehaviors processedBehaviors)
        {
            // make all connectors changable
            for (int i = 0; i < _children.Connectors.Count; ++i)
            {
                _children.Connectors[i].IsReadOnly = false;
            }

            if (_isExpanded)
            {
                base.DoSynchronizeWithNode(processedBehaviors);
            }
            else
            {
                _subGraphNeedsToBeRebuilt = false;

                _children.ClearConnectors();
                RemoveAllConnectorSubItems();

                //foreach(Connector connector in _node.Connectors)
                //	connector.Clone(_children);

                new ConnectorMultiple(_children, string.Empty, "GenericChildren", 1, int.MaxValue);

                // generate the dummy nodes for the sub-referenced behaviours
                foreach (Node child in ((Node)((ReferencedBehaviorNode)_node).Reference).Children)
                {
                    GenerateReferencedBehaviorsTree(processedBehaviors, this, child);
                }

                // make all connectors readonly
                for (int i = 0; i < _children.Connectors.Count; ++i)
                {
                    _children.Connectors[i].IsReadOnly = true;
                }

                GenerateNewLabel();
            }
        }
        /// <summary>
        /// Recalculates the layout if necessary.
        /// </summary>
        /// <param name="graphics">The graphics object which is used to measure the strings.</param>
        internal void UpdateLayout(Graphics graphics)
        {
            if (_layoutChanged)
            {
                _layoutChanged = false;

                // synchronize layout
                ProcessedBehaviors processedBehaviors = new ProcessedBehaviors();
                _rootNodeLayout.SynchronizeWithNode(processedBehaviors);

                // calculate the size of each node
                _rootNodeLayout.UpdateFinalSize(graphics, _rootNodeLayout.RootBehavior);
                _rootNodeLayout.UpdateExtent();

                // calculate the total size of the branches
                _rootNodeLayout.CalculateLayoutSize(_padding);

                // align the branches
                _rootNodeLayout.Layout(_padding);

                // align the parents at the centre of their children
                _rootNodeLayout.UpdateLocation();
            }
        }
        /// <summary>
        /// Adds nodes to the referenced behaviour which represent sub-referenced behaviours.
        /// </summary>
        /// <param name="processedBehaviors">A list of processed behaviours to handle circular references.</param>
        /// <param name="parent">The node the sub-referenced behaviours will be added to.</param>
        /// <param name="node">The current node we are checking.</param>
        protected void GenerateReferencedBehaviorsTree(ProcessedBehaviors processedBehaviors, NodeViewData parent, Node node)
        {
            if (!processedBehaviors.MayProcess(node))
            {
                return;
            }

            // check if this is a referenced behaviour
            if (node is ReferencedBehaviorNode)
            {
                // create the dummy node and add it without marking the behaviour as being modified as these are no REAL nodes.
                NodeViewData rb = node.CreateNodeViewData(parent, _rootBehavior);

#if DEBUG
                rb.IsSubreferencedGraphNode();
#endif
                rb.DoSynchronizeWithNode(processedBehaviors);

                Connector conn = parent.GetConnector("GenericChildren");
                Debug.Check(conn != null);

                Connector rbconn = parent.GetConnector("GenericChildren");
                Debug.Check(rbconn != null);

                bool parentReadOnly = conn.IsReadOnly;

                conn.IsReadOnly = false;

                parent.AddChildNotModified(conn, rb);

                conn.IsReadOnly = parentReadOnly;

                // we have a circular reference here. Skip the children
                if (((ReferencedBehaviorNode)node).Reference == _rootBehavior)
                {
                    rbconn.IsReadOnly = true;
                    return;
                }

                // do the same for all the children
                foreach (Node child in node.Children)
                {
                    GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), rb, child);
                }

                rbconn.IsReadOnly = true;
            }
            else if (node is Impulse)
            {
                // create the dummy node and add it without marking the behaviour as being modified as these are no REAL nodes.
                NodeViewData ip = node.CreateNodeViewData(parent, _rootBehavior);

                ip.DoSynchronizeWithNode(processedBehaviors);

                // do the same for all the children
                foreach (Node child in node.Children)
                {
                    GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), ip, child);
                }

                if (ip.Children.Count > 0)
                {
                    Connector conn = parent.GetConnector("GenericChildren");
                    Debug.Check(conn != null);

                    Connector ipconn = ip.GetConnector("GenericChildren");
                    Debug.Check(ipconn != null);

                    parent.AddChildNotModified(conn, ip);

                    ipconn.IsReadOnly = true;
                }
            }
            else
            {
                // do the same for all the children
                foreach (Node child in node.Children)
                {
                    GenerateReferencedBehaviorsTree(processedBehaviors.Branch(child), parent, child);
                }
            }
        }
 /// <summary>
 /// Used to branch a new list for its children.
 /// </summary>
 /// <param name="previous">The list of processed behaviours the parent used.</param>
 protected ProcessedBehaviors(ProcessedBehaviors previous)
 {
     _processedBehaviors.AddRange(previous._processedBehaviors);
 }