private List <BaseEntity> ExtractConstants(XElement constantElement, String name, String summary, String declaration)
        {
            List <BaseEntity> constants = new List <BaseEntity> ();

            // Extract types and names
            string[] declarations = declaration.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string part in declarations)
            {
                //this.Logger.WriteLine("Parsing constant '{0}'...", part.Trim());

                String stripped = part.Trim();
                stripped = stripped.Replace("extern", String.Empty);
                stripped = stripped.Replace("const", String.Empty);
                stripped = stripped.TrimAll();

                Match r = CONSTANT_REGEX.Match(stripped);
                if (r.Success)
                {
                    String type = r.Groups [1].Value.Trim(' ', '*', ' ');

                    bool isOut;
                    bool isByRef;
                    bool isBlock;
                    type = this.TypeManager.ConvertType(type, out isOut, out isByRef, out isBlock, this.Logger);

                    ConstantEntity constantEntity = new ConstantEntity();
                    constantEntity.Type = type;
                    constantEntity.Name = r.Groups [2].Value.Trim();
                    constants.Add(constantEntity);

                    //this.Logger.WriteLine("Constant found '{0}' of type '{1}'", constantEntity.Name, constantEntity.Type);
                }
                else
                {
                    this.Logger.WriteLine("FAILED to parse constant '{0}'", stripped);
                    return(null);
                }
            }

            // Get the definitions
            XElement termDefinitions = (from el in constantElement.ElementsAfterSelf("dl")
                                        where (String)el.Attribute("class") == "termdef"
                                        select el).FirstOrDefault();

            if (termDefinitions == null)
            {
                this.Logger.WriteLine("MISSING terms");
                return(null);
            }

            IEnumerable <XElement> termName       = termDefinitions.Elements("dt");
            IEnumerable <XElement> termDefinition = termDefinitions.Elements("dd");

            if (termName.Count() == termDefinition.Count())
            {
                // Iterate over definitions
                for (int i = 0; i < termName.Count(); i++)
                {
                    String term = termName.ElementAt(i).Value.TrimAll();
                    IEnumerable <String> summaries = termDefinition.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll());

                    // Find the enumeration value
                    BaseEntity baseEntity = constants.Find(c => c.Name == term);
                    if (baseEntity != null)
                    {
                        foreach (string sum in summaries)
                        {
                            if (CommentHelper.IsAvailability(sum))
                            {
                                baseEntity.MinAvailability = CommentHelper.ExtractAvailability(sum);
                                break;
                            }
                            baseEntity.Summary.Add(sum);
                        }
                    }
                    else
                    {
                        this.Logger.WriteLine("Term with no match '" + term + "'");
                    }
                }
            }
            else
            {
                this.Logger.WriteLine("MISMATCH in terms");
                return(null);
            }

            return(constants);
        }
        public ConstantEntity Parse(TypedEntity typedEntity, string constantElement, IEnumerable <XElement> elements)
        {
            ConstantEntity constantEntity = new ConstantEntity();

            XElement declarationElement = (from el in elements
                                           where el.Name == "div" &&
                                           el.Attribute("class") != null &&
                                           el.Attribute("class").Value == "declaration_indent"
                                           select el).FirstOrDefault();

            //XElement discussionElement = (from el in elements
            //                              where el.Name == "h5" && el.Value.Trim() == "Discussion"
            //                              select el).FirstOrDefault();

            XElement availabilityElement = (from el in elements
                                            let term = el.Descendants("dt").FirstOrDefault()
                                                       let definition = el.Descendants("dd").FirstOrDefault()
                                                                        where el.Name == "dl" &&
                                                                        term != null &&
                                                                        term.Value.Trim() == "Availability"
                                                                        select definition).FirstOrDefault();

            String stripped = declarationElement.TrimAll();

            stripped = stripped.Trim(';');
            while (stripped.Contains("  "))
            {
                stripped = stripped.Replace("  ", " ");
            }
            stripped = stripped.Replace("extern", String.Empty);
            stripped = stripped.Replace("const", String.Empty);
            stripped = stripped.TrimAll();

            Match r = CONSTANT_REGEX.Match(stripped);

            if (r.Success)
            {
                String type = r.Groups[1].Value.Trim(' ', '*', ' ');

                bool isOut;
                bool isByRef;
                bool isBlock;
                type = this.TypeManager.ConvertType(type, out isOut, out isByRef, out isBlock, this.Logger);

                constantEntity.Type = type;
                constantEntity.Name = r.Groups[2].Value.Trim();
            }
            else
            {
                this.Logger.WriteLine("FAILED to parse constant '{0}'", stripped);
                return(constantEntity);
            }

            // Extract abstract
            IEnumerable <XElement> abstractElements = elements.SkipWhile(el => el.Name != "p").TakeWhile(el => el.Name == "p");

            foreach (XElement element in abstractElements)
            {
                String line = element.TrimAll();
                if (!String.IsNullOrEmpty(line))
                {
                    constantEntity.Summary.Add(line);
                }
            }

            //// Extract discussion
            //if (discussionElement != null)
            //{
            //    IEnumerable<XElement> discussionElements = discussionElement.ElementsAfterSelf().TakeWhile(el => el.Name == "p");
            //    foreach (XElement element in discussionElements)
            //    {
            //        String line = element.TrimAll();
            //        if (!String.IsNullOrEmpty(line))
            //        {
            //            constantEntity.Summary.Add(line);
            //        }
            //    }
            //}

            // Get the availability
            if (availabilityElement != null)
            {
                constantEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll());
            }

            return(constantEntity);
        }