/// <summary>
 /// Creates the core code doc generator using the given search context.
 /// </summary>
 /// <param name="searchContext">The search context to use when locating other models.</param>
 /// <returns>A member generator.</returns>
 protected abstract MemberGeneratorBase CreateGenerator(CodeDocRepositorySearchContext searchContext);
 /// <inheritdoc/>
 public abstract ICodeDocMember GetMemberModel(CRef.CRefIdentifier cRef, CodeDocRepositorySearchContext searchContext = null, CodeDocMemberDetailLevel detailLevel = CodeDocMemberDetailLevel.Full);
 /// <inheritdoc/>
 public ICodeDocMember GetMemberModel(string cRef, CodeDocRepositorySearchContext searchContext = null, CodeDocMemberDetailLevel detailLevel = CodeDocMemberDetailLevel.Full)
 {
     if (String.IsNullOrEmpty(cRef)) throw new ArgumentException("Code reference is not valid.", "cRef");
     Contract.EndContractBlock();
     return GetMemberModel(new CRefIdentifier(cRef), searchContext, detailLevel);
 }
 /// <summary>
 /// Creates a member model for the given code reference.
 /// </summary>
 /// <param name="cRef">The code reference to generate a model for.</param>
 /// <param name="searchContext">The serach context to use when locating related members.</param>
 /// <param name="detailLevel">Indicates the desired detail level of the generated model.</param>
 /// <returns>The generated member if possible.</returns>
 public virtual ICodeDocMember GetMemberModel(CRefIdentifier cRef, CodeDocRepositorySearchContext searchContext = null, CodeDocMemberDetailLevel detailLevel = CodeDocMemberDetailLevel.Full)
 {
     return CreateGenerator(searchContext).GetMemberModel(cRef, detailLevel);
 }
 /// <summary>
 /// Creates a new member generator using the given repository and search context.
 /// </summary>
 /// <param name="repository">The repository that is used to generate the models.</param>
 /// <param name="searchContext">The search context used to get other models from.</param>
 public MemberGenerator(ReflectionCodeDocMemberRepository repository, CodeDocRepositorySearchContext searchContext)
     : base(repository, searchContext)
 {
     Contract.Requires(repository != null);
 }
 protected MemberGeneratorBase(CodeDocMemberRepositoryBase repository, CodeDocRepositorySearchContext searchContext)
 {
     if(repository == null) throw new ArgumentNullException("repository");
     Contract.EndContractBlock();
     Repository = repository;
     SearchContext = searchContext;
 }
 /// <summary>
 /// Creates a member generator that uses the given search context.
 /// </summary>
 /// <param name="searchContext">The search context that is to be used by the member generator.</param>
 /// <returns>A member generator that is used to create member models.</returns>
 protected override MemberGeneratorBase CreateGenerator(CodeDocRepositorySearchContext searchContext)
 {
     return new MemberGenerator(this, searchContext);
 }
        /// <summary>
        /// Generates a model that is extracted from MTPS data.
        /// </summary>
        /// <param name="cRef">The code reference to search for.</param>
        /// <param name="searchContext">The search context for locating related items.</param>
        /// <param name="detailLevel">The desired detail level of the generated model.</param>
        /// <returns>A code doc member model if found.</returns>
        public ICodeDocMember GetMemberModel(CRefIdentifier cRef, CodeDocRepositorySearchContext searchContext = null, CodeDocMemberDetailLevel detailLevel = CodeDocMemberDetailLevel.Full)
        {
            if(cRef == null) throw new ArgumentNullException("cRef");
            Contract.EndContractBlock();

            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var tocResults = SearchToc(cRef.FullCRef);
            var bestTocResult = tocResults.FirstOrDefault();
            stopwatch.Stop();
            Debug.WriteLine("Search for {0} returned in {1}", cRef, stopwatch.Elapsed);

            if (bestTocResult == null)
                return null;

            Uri uri;
            if (!Uri.TryCreate(GetUrl(bestTocResult), UriKind.Absolute, out uri))
                uri = cRef.ToUri();

            CodeDocSimpleMember model = null;

            if (detailLevel != CodeDocMemberDetailLevel.Minimum) {
                var contentXml = GetContent(bestTocResult.ContentId);
                if (contentXml != null) {

                    bool? isSealed = null;
                    bool? isValueType = null;
                    bool? isReferenceType = null;
                    bool? isEnum = null;
                    bool? isVirtual = null;
                    bool? isAbstract = null;
                    bool? isMethod = null;
                    ExternalVisibilityKind? visibility = null;

                    var titleDiv = contentXml.GetElementsByTagName("div")
                        .OfType<XmlElement>()
                        .FirstOrDefault(x => "TITLE".Equals(x.GetAttribute("class"), StringComparison.OrdinalIgnoreCase));

                    if (titleDiv != null) {
                        var innerTitleText = titleDiv.InnerText.Trim();
                        if (innerTitleText.EndsWith("Method", StringComparison.OrdinalIgnoreCase)) {
                            isMethod = true;
                        }
                    }

                    var syntaxElement = contentXml.GetElementsByTagName("mtps:CollapsibleArea")
                        .OfType<XmlElement>()
                        .FirstOrDefault(x => "SYNTAX".Equals(x.GetAttribute("Title"), StringComparison.OrdinalIgnoreCase));
                    var codeSnippets = syntaxElement.GetElementsByTagName("mtps:CodeSnippet").OfType<XmlElement>().ToList();

                    foreach (var snippet in codeSnippets) {
                        var inputSpans = snippet.GetElementsByTagName("span")
                            .OfType<XmlElement>()
                            .Where(e => e.GetAttribute("class") == "input")
                            .ToList();
                        if (snippet.GetAttribute("Language") == "CSharp") {
                            foreach (var inputSpan in inputSpans) {
                                var innerText = inputSpan.InnerText;
                                if ("PUBLIC".Equals(innerText, StringComparison.OrdinalIgnoreCase))
                                    visibility = ExternalVisibilityKind.Public;
                                else if ("PROTECTED".Equals(innerText, StringComparison.OrdinalIgnoreCase))
                                    visibility = ExternalVisibilityKind.Protected;
                                else if ("SEALED".Equals(innerText, StringComparison.OrdinalIgnoreCase))
                                    isSealed = true;
                                else if ("CLASS".Equals(innerText, StringComparison.OrdinalIgnoreCase))
                                    isReferenceType = true;
                                else if ("STRUCT".Equals(innerText, StringComparison.OrdinalIgnoreCase))
                                    isValueType = true;
                                else if ("ENUM".Equals(innerText, StringComparison.OrdinalIgnoreCase))
                                    isEnum = true;
                                else if ("VIRTUAL".Equals(innerText, StringComparison.OrdinalIgnoreCase))
                                    isVirtual = true;
                                else if ("ABSTRACT".Equals(innerText, StringComparison.OrdinalIgnoreCase))
                                    isAbstract = true;
                            }
                        }
                    }

                    if (model == null) {
                        if (isReferenceType ?? isValueType ?? isEnum ?? false) {
                            var typeModel = new CodeDocType(cRef);
                            typeModel.IsSealed = isSealed;
                            typeModel.IsValueType = isValueType;
                            typeModel.IsEnum = isEnum;
                            model = typeModel;
                        }
                        else if (isMethod ?? false) {
                            var methodModel = new CodeDocMethod(cRef);
                            methodModel.IsSealed = isSealed;
                            methodModel.IsVirtual = isVirtual;
                            methodModel.IsAbstract = isAbstract;
                            model = methodModel;
                        }
                        else {
                            model = new CodeDocSimpleMember(cRef);
                        }
                        model.ExternalVisibility = visibility ?? ExternalVisibilityKind.Hidden;
                    }

                    XmlNode summaryElement = contentXml.GetElementsByTagName("div")
                        .OfType<XmlElement>()
                        .FirstOrDefault(x => String.Equals(x.GetAttribute("class"), "summary", StringComparison.OrdinalIgnoreCase));
                    if (summaryElement != null) {
                        if (summaryElement.ChildNodes.Count == 1 && summaryElement.ChildNodes[0].Name == "p") {
                            // unwrap the lone p tag.
                            summaryElement = summaryElement.ChildNodes[0];
                        }
                        var summaryXmlDoc = XmlDocParser.Default.Parse(summaryElement);
                        model.SummaryContents = summaryXmlDoc.Children;
                    }

                }

            }

            if (model == null)
                model = new CodeDocSimpleMember(cRef);

            if(model.ExternalVisibility == ExternalVisibilityKind.Hidden)
                model.ExternalVisibility = ExternalVisibilityKind.Public;

            model.Uri = uri;
            model.FullName = bestTocResult.GetFullName();

            int lastTitleSpaceIndex = bestTocResult.Title.LastIndexOf(' ');
            if (lastTitleSpaceIndex >= 0) {
                model.Title = bestTocResult.Title.Substring(0, lastTitleSpaceIndex);
                model.SubTitle = bestTocResult.Title.Substring(lastTitleSpaceIndex + 1);
            }
            else {
                model.Title = bestTocResult.Title;
                model.SubTitle = String.Empty;
            }
            model.ShortName = model.Title;

            if (String.IsNullOrEmpty(model.NamespaceName)) {
                MtpsNodeCore namespaceNode = bestTocResult;
                while (namespaceNode != null && !namespaceNode.IsNamespace) {
                    namespaceNode = namespaceNode.Parent;
                }
                if (namespaceNode != null) {
                    model.NamespaceName = namespaceNode.GetNamespaceName();
                    model.Namespace = GetNamespaceByName(model.NamespaceName);
                }
            }

            return model;
        }
 /// <summary>
 /// Generates a model that is extracted from MTPS data.
 /// </summary>
 /// <param name="cRef">The code reference to search for.</param>
 /// <param name="searchContext">The search context for locating related items.</param>
 /// <param name="detailLevel">The desired detail level of the generated model.</param>
 /// <returns>A code doc member model if found.</returns>
 public ICodeDocMember GetMemberModel(string cRef, CodeDocRepositorySearchContext searchContext = null, CodeDocMemberDetailLevel detailLevel = CodeDocMemberDetailLevel.Full)
 {
     Contract.Requires(!String.IsNullOrEmpty(cRef));
     return GetMemberModel(new CRefIdentifier(cRef), searchContext, detailLevel);
 }
        /// <inheritdoc/>
        public override ICodeDocMember GetMemberModel(CRef.CRefIdentifier cRef, CodeDocRepositorySearchContext searchContext = null, CodeDocMemberDetailLevel detailLevel = CodeDocMemberDetailLevel.Full)
        {
            if (!ActivatedCheck())
                return null;

            try {
                return Repository.GetMemberModel(cRef, searchContext, detailLevel);
            }
            catch (Exception ex) {
                Deactivate(ex);
                return null;
            }
        }
 /// <summary>
 /// A locked request to the wrapped repository for a member model.
 /// </summary>
 /// <param name="cRef">The code reference.</param>
 /// <param name="searchContext">The search context to use when locating other models.</param>
 /// <param name="detailLevel">Indicates the desired detail level of the generated model.</param>
 /// <returns>The member model.</returns>
 public override ICodeDocMember GetMemberModel(CRefIdentifier cRef, CodeDocRepositorySearchContext searchContext = null, CodeDocMemberDetailLevel detailLevel = CodeDocMemberDetailLevel.Full)
 {
     lock (_mutex) {
         return Repository.GetMemberModel(cRef, searchContext, detailLevel);
     }
 }