/// <summary>
        /// Loads an event which is attached to a node.
        /// </summary>
        /// <param name="node">The node the event is created for.</param>
        /// <param name="xml">The XML node the event retrieves its name and attributes from.</param>
        /// <returns>Returns the created SubItems.Event.</returns>
        protected Events.Event CreateEvent(Node node, XmlNode xml)
        {
            // get the type of the event and create it

            // maintain compatibility with version 1
            //string clss= GetAttribute(xml, "Class");
            string clss;

            if (!GetAttribute(xml, "Class", out clss))
            {
                string find  = ".Events." + GetAttribute(xml, "name");
                Type   found = Plugin.FindType(find);
                if (found != null)
                {
                    clss = found.FullName;
                }
            }

            Type t = Plugin.GetType(clss);

            if (t == null)
            {
                throw new Exception(string.Format(Resources.ExceptionUnknownEventType, clss));
            }

            Events.Event evnt = Events.Event.Create(t, node);

            // initialise the events properties
            IList <DesignerPropertyInfo> properties = evnt.GetDesignerProperties();

            for (int p = 0; p < properties.Count; ++p)
            {
                if (properties[p].Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave))
                {
                    continue;
                }

                InitProperty(xml, evnt, properties[p]);
            }

            // update event with attributes
            evnt.OnPropertyValueChanged(false);

            return(evnt);
        }
        /// <summary>
        /// Saves a node to the XML file.
        /// </summary>
        /// <param name="root">The XML node we want to attach the node to.</param>
        /// <param name="node">The node we want to save.</param>
        protected void SaveNode(XmlElement root, Node node)
        {
            // allow the node to process its attributes in preparation of the save
            node.PreSave(_node);

            // store the class we have to create when loading
            XmlElement elem = _xmlfile.CreateElement("Node");

            elem.SetAttribute("Class", node.GetType().FullName);

            // save attributes
            IList <DesignerPropertyInfo> properties = node.GetDesignerProperties();

            for (int p = 0; p < properties.Count; ++p)
            {
                if (!properties[p].Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave))
                {
                    elem.SetAttribute(properties[p].Property.Name, properties[p].GetStringValue(node));
                }
            }

            // append node to root
            root.AppendChild(elem);

            // save comment
            if (node.CommentObject != null)
            {
                XmlElement comment = _xmlfile.CreateElement("Comment");

                properties = node.CommentObject.GetDesignerProperties();
                for (int p = 0; p < properties.Count; ++p)
                {
                    if (!properties[p].Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave))
                    {
                        comment.SetAttribute(properties[p].Property.Name, properties[p].GetStringValue(node.CommentObject));
                    }
                }

                elem.AppendChild(comment);
            }

            // save events
            foreach (Nodes.Node.SubItem sub in node.SubItems)
            {
                if (sub is Nodes.Node.SubItemEvent)
                {
                    Events.Event ne = ((Nodes.Node.SubItemEvent)sub).Event;

                    XmlElement evnt = _xmlfile.CreateElement("Event");
                    evnt.SetAttribute("Class", ne.GetType().FullName);

                    // save attributes
                    properties = ne.GetDesignerProperties();
                    for (int p = 0; p < properties.Count; ++p)
                    {
                        if (!properties[p].Attribute.HasFlags(DesignerProperty.DesignerFlags.NoSave))
                        {
                            elem.SetAttribute(properties[p].Property.Name, properties[p].GetStringValue(ne));
                        }
                    }

                    elem.AppendChild(evnt);
                }
            }

            // save children if allowed. Disallowed for referenced behaviours.
            if (node.SaveChildren)
            {
                // save connectors
                foreach (Nodes.Node.Connector connector in node.Connectors)
                {
                    // if we have no children to store we can skip the connector
                    if (connector.ChildCount < 1)
                    {
                        continue;
                    }

                    XmlElement conn = _xmlfile.CreateElement("Connector");
                    conn.SetAttribute("Identifier", connector.Identifier);
                    elem.AppendChild(conn);

                    // save their children
                    for (int i = 0; i < connector.ChildCount; ++i)
                    {
                        SaveNode(conn, connector.GetChild(i));
                    }
                }
            }
        }