/// <summary>
        /// Link variable types in the parameter to the common types
        /// </summary>
        /// <param name="p"></param>
        protected void LinkParameterType(AdvanceCompositeBlockParameterDescription p)
        {
            switch (p.Type.Kind)
            {
            case TypeKind.VARIABLE_TYPE:
                AdvanceType t;
                if (this.sharedTypeVariables.TryGetValue(p.Type.TypeVariableName, out t))
                {
                    p.Type = t;
                }
                else
                {
                    this.AddSharedTypeVariable(p.Type.TypeVariableName, p.Type);
                }
                break;

            case TypeKind.PARAMETRIC_TYPE:
                HashSet <AdvanceType>      visited = new HashSet <AdvanceType>();
                List <List <AdvanceType> > queue   = new List <List <AdvanceType> >();
                queue.Add(p.Type.TypeArguments);
                while (queue.Count > 0)
                {
                    List <AdvanceType> args = queue[0];
                    queue.RemoveAt(0);
                    for (int i = 0; i < args.Count; i++)
                    {
                        AdvanceType at = args[i];
                        switch (at.Kind)
                        {
                        case TypeKind.VARIABLE_TYPE:
                            AdvanceType st;
                            if (this.sharedTypeVariables.TryGetValue(at.TypeVariableName, out st))
                            {
                                args[i] = st;
                            }
                            else
                            {
                                this.AddSharedTypeVariable(at.TypeVariableName, at);
                            }
                            break;

                        case TypeKind.PARAMETRIC_TYPE:
                            if (!visited.Contains(at))
                            {
                                visited.Add(at);
                                queue.Add(at.TypeArguments);
                            }
                            break;
                        }
                    }
                }
                break;
            }
        }
 /// <summary>
 /// Add parameter description as an input parameter
 /// </summary>
 /// <param name="p">description</param>
 /// <returns>True if parameter is new</returns>
 public bool AddOutput(AdvanceCompositeBlockParameterDescription p)
 {
     if (this.outputs.ContainsKey(p.Id))
     {
         return(false);
     }
     else
     {
         this.outputs.Add(p.Id, p);
         this.LinkParameterType(p);
         return(true);
     }
 }
        /// <summary>
        /// Fill object data from xml node
        /// </summary>
        /// <param name="source">Source Xml</param>
        protected override void LoadFromXmlNode(XmlNode source)
        {
            this.Id            = GetAttribute(source, "id");
            this.Documentation = GetAttribute(source, "documentation", null);
            this.Keywords      = GetListAttribute(source, "keywords");
            this.Visuals       = CreateFromXml <AdvanceBlockVisuals>(source);
            HashSet <string> usedIds = new HashSet <string>();

            foreach (XmlNode n in GetChildren(source, "*"))
            {
                switch (n.Name)
                {
                case "block":
                    AdvanceBlockReference b = CreateFromXml <AdvanceBlockReference>(n);
                    b.parent = this;
                    if (usedIds.Contains(b.Id))
                    {
                        this.ThrowDuplicatedIdentifierException(n, b.Id);
                    }
                    else
                    {
                        this.Blocks.Add(b.Id, b);
                        usedIds.Add(b.Id);
                    }
                    break;

                case "composite-block":
                    AdvanceCompositeBlock cb = CreateFromXml <AdvanceCompositeBlock>(n);
                    cb.Parent = this;
                    if (usedIds.Contains(cb.Id))
                    {
                        this.ThrowDuplicatedIdentifierException(n, cb.Id);
                    }
                    else
                    {
                        this.Composites.Add(cb.Id, cb);
                        usedIds.Add(cb.Id);
                    }
                    break;

                case "constant":
                    AdvanceConstantBlock c = CreateFromXml <AdvanceConstantBlock>(n);
                    if (usedIds.Contains(c.Id))
                    {
                        this.ThrowDuplicatedIdentifierException(n, c.Id);
                    }
                    else
                    {
                        this.Constants.Add(c.Id, c);
                        usedIds.Add(c.Id);
                    }
                    break;

                case "bind":
                    AdvanceBlockBind bb = CreateFromXml <AdvanceBlockBind>(n);
                    bb.Parent = this;
                    this.Bindings.Add(bb);
                    break;

                case "type-variable":
                    AdvanceTypeVariable tv = CreateFromXml <AdvanceTypeVariable>(n);
                    if (!this.AddTypeVariable(tv))
                    {
                        this.ThrowDuplicatedIdentifierException(n, tv.Name);
                    }
                    break;

                case "input":
                    AdvanceCompositeBlockParameterDescription inp = CreateFromXml <AdvanceCompositeBlockParameterDescription>(n);
                    if (!this.AddInput(inp))
                    {
                        this.ThrowDuplicatedIdentifierException(n, inp.Id);
                    }
                    break;

                case "output":
                    AdvanceCompositeBlockParameterDescription outp = CreateFromXml <AdvanceCompositeBlockParameterDescription>(n);
                    if (!this.AddOutput(outp))
                    {
                        this.ThrowDuplicatedIdentifierException(n, outp.Id);
                    }
                    break;
                }
            }
            this.LinkTypeVariables();
        }