ExtensionNodeTypeCollection GetAllowedChildTypes(TreeIter it)
        {
            ExtensionNodeTypeCollection types = null;

            Extension ext = (Extension)store.GetValue(it, ColExtension);

            if (ext != null)
            {
                if (ext.Parent == null)
                {
                    ExtensionPoint ep = (ExtensionPoint)store.GetValue(it, ColExtensionPoint);
                    types = ep.NodeSet.GetAllowedNodeTypes();
                }
                else
                {
                    types = ext.GetAllowedNodeTypes();
                }
            }

            ExtensionNodeDescription node = (ExtensionNodeDescription)store.GetValue(it, ColNode);

            if (node != null)
            {
                ExtensionNodeType tn = node.GetNodeType();
                if (tn != null)
                {
                    types = tn.GetAllowedNodeTypes();
                }
            }
            return(types);
        }
        void FillNodes(TreeIter iter, ExtensionNodeSet ns, ExtensionNodeDescriptionCollection nodes)
        {
            ExtensionNodeTypeCollection ntypes = ns.GetAllowedNodeTypes();

            foreach (ExtensionNodeDescription node in nodes)
            {
                if (node.IsCondition)
                {
                    FillNodes(iter, ns, nodes);
                    continue;
                }

                string            id = node.Id;
                ExtensionNodeType nt = ntypes [node.NodeName];

                // The node can only be extended if it has an ID and if it accepts child nodes
                if (id.Length > 0 && (nt.NodeTypes.Count > 0 || nt.NodeSets.Count > 0))
                {
                    TreeIter citer = GetBranch(iter, id + " (" + nt.NodeName + ")", null);
                    store.SetValue(citer, ColObject, node);
                    store.SetValue(citer, ColShowCheck, true);
                    store.SetValue(citer, ColChecked, false);
                    FillExtensionNodeSet(citer, nt);
                    FillNodes(citer, nt, node.ChildNodes);
                }
            }
        }
        void UpdateButtons()
        {
            TreeIter iter;

            if (!tree.Selection.GetSelected(out iter))
            {
                addNodeButton.Sensitive = false;
                buttonRemove.Sensitive  = false;
                DisposeEditor();
                return;
            }

            DisposeEditor();

            ExtensionNodeDescription node = store.GetValue(iter, ColNode) as ExtensionNodeDescription;

            if (node == null)
            {
                ExtensionPoint ep = (ExtensionPoint)store.GetValue(iter, ColExtensionPoint);
                if (ep != null)
                {
                    addNodeButton.Sensitive = true;
                    buttonRemove.Sensitive  = false;
                }
                else
                {
                    addNodeButton.Sensitive = false;
                    buttonRemove.Sensitive  = false;
                }
                return;
            }

            ExtensionNodeType nt = node.GetNodeType();

            if (nt == null)
            {
                return;
            }

            NodeEditorWidget editor = new NodeEditorWidget(data.Project, data.AddinRegistry, nt, adesc, node.GetParentPath(), node);

            editorBox.AddWithViewport(editor);
            editor.Show();
            editor.BorderWidth = 3;
            currentEditor      = editor;

            ExtensionNodeTypeCollection types = GetAllowedChildTypes(iter);

            addNodeButton.Sensitive = types != null && types.Count > 0;
            buttonRemove.Sensitive  = true;
        }
        void PopulateNodeTypes(Gtk.Menu menu, TreeIter it)
        {
            ExtensionNodeTypeCollection types = GetAllowedChildTypes(it);
            Extension ext = (Extension)store.GetValue(it, ColExtension);
            ExtensionNodeDescription node = (ExtensionNodeDescription)store.GetValue(it, ColNode);

            if (types != null && types.Count > 0)
            {
                if (menu.Children.Length > 0)
                {
                    menu.Insert(new Gtk.SeparatorMenuItem(), -1);
                }
                foreach (ExtensionNodeType nt in types)
                {
                    Gtk.ImageMenuItem mi = new Gtk.ImageMenuItem(AddinManager.CurrentLocalizer.GetString("Add node '{0}'", nt.NodeName));
                    menu.Insert(mi, -1);
                    ExtensionNodeType ntc = nt;
                    mi.Activated += delegate {
                        CreateNode(it, ext, node, ntc);
                    };
                }
            }
        }