void ScanNodeType(AddinDescription config, ExtensionNodeType nt, ArrayList assemblies, Hashtable internalNodeSets)
        {
            if (nt.TypeName.Length == 0)
            {
                nt.TypeName = "Mono.Addins.TypeExtensionNode";
            }

            Type ntype = FindAddinType(nt.TypeName, assemblies);

            if (ntype == null)
            {
                return;
            }

            // Add type information declared with attributes in the code
            ExtensionNodeAttribute nodeAtt = (ExtensionNodeAttribute)Attribute.GetCustomAttribute(ntype, typeof(ExtensionNodeAttribute), true);

            if (nodeAtt != null)
            {
                if (nt.Id.Length == 0 && nodeAtt.NodeName.Length > 0)
                {
                    nt.Id = nodeAtt.NodeName;
                }
                if (nt.Description.Length == 0 && nodeAtt.Description.Length > 0)
                {
                    nt.Description = nodeAtt.Description;
                }
            }
            else
            {
                // Use the node type name as default name
                if (nt.Id.Length == 0)
                {
                    nt.Id = ntype.Name;
                }
            }

            // Add information about attributes
            object[] fieldAtts = ntype.GetCustomAttributes(typeof(NodeAttributeAttribute), true);
            foreach (NodeAttributeAttribute fatt in fieldAtts)
            {
                NodeTypeAttribute natt = new NodeTypeAttribute();
                natt.Name     = fatt.Name;
                natt.Required = fatt.Required;
                if (fatt.Type != null)
                {
                    natt.Type = fatt.Type.FullName;
                }
                if (fatt.Description.Length > 0)
                {
                    natt.Description = fatt.Description;
                }
                nt.Attributes.Add(natt);
            }

            // Check if the type has NodeAttribute attributes applied to fields.
            foreach (FieldInfo field in ntype.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                NodeAttributeAttribute fatt = (NodeAttributeAttribute)Attribute.GetCustomAttribute(field, typeof(NodeAttributeAttribute));
                if (fatt != null)
                {
                    NodeTypeAttribute natt = new NodeTypeAttribute();
                    if (fatt.Name.Length > 0)
                    {
                        natt.Name = fatt.Name;
                    }
                    else
                    {
                        natt.Name = field.Name;
                    }
                    if (fatt.Description.Length > 0)
                    {
                        natt.Description = fatt.Description;
                    }
                    natt.Type     = field.FieldType.FullName;
                    natt.Required = fatt.Required;
                    nt.Attributes.Add(natt);
                }
            }

            // Check if the extension type allows children by looking for [ExtensionNodeChild] attributes.
            // First of all, look in the internalNodeSets hashtable, which is being used as cache

            string childSet = (string)internalNodeSets [nt.TypeName];

            if (childSet == null)
            {
                object[] ats = ntype.GetCustomAttributes(typeof(ExtensionNodeChildAttribute), true);
                if (ats.Length > 0)
                {
                    // Create a new node set for this type. It is necessary to create a new node set
                    // instead of just adding child ExtensionNodeType objects to the this node type
                    // because child types references can be recursive.
                    ExtensionNodeSet internalSet = new ExtensionNodeSet();
                    internalSet.Id = ntype.Name + "_" + Guid.NewGuid().ToString();
                    foreach (ExtensionNodeChildAttribute at in ats)
                    {
                        ExtensionNodeType internalType = new ExtensionNodeType();
                        internalType.Id       = at.NodeName;
                        internalType.TypeName = at.ExtensionNodeType.FullName;
                        internalSet.NodeTypes.Add(internalType);
                    }
                    config.ExtensionNodeSets.Add(internalSet);
                    nt.NodeSets.Add(internalSet.Id);

                    // Register the new set in a hashtable, to allow recursive references to the
                    // same internal set.
                    internalNodeSets [nt.TypeName] = internalSet.Id;
                    internalNodeSets [ntype.AssemblyQualifiedName] = internalSet.Id;
                    ScanNodeSet(config, internalSet, assemblies, internalNodeSets);
                }
            }
            else
            {
                if (childSet.Length == 0)
                {
                    // The extension type does not declare children.
                    return;
                }
                // The extension type can have children. The allowed children are
                // defined in this extension set.
                nt.NodeSets.Add(childSet);
                return;
            }

            ScanNodeSet(config, nt, assemblies, internalNodeSets);
        }
 public NodeTypeAttributeCompletionData(NodeTypeAttribute att)
 {
     this.att = att;
 }