private CodeDocMethod ConvertToModel(MethodBase methodBase, CodeDocMemberDetailLevel detailLevel, ICodeDocMemberDataProvider extraMemberDataProvider = null)
            {
                Contract.Requires(methodBase != null);
                Contract.Ensures(Contract.Result<CodeDocMethod>() != null);
                Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<CodeDocMethod>().ShortName));
                Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<CodeDocMethod>().FullName));
                Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<CodeDocMethod>().Title));
                Contract.Ensures(Contract.Result<CodeDocMethod>().Title == Contract.Result<CodeDocMethod>().ShortName);
                Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<CodeDocMethod>().SubTitle));

                var includeExceptions = detailLevel != CodeDocMemberDetailLevel.Minimum;
                var appendXmlDoc = detailLevel.HasFlag(CodeDocMemberDetailLevel.Summary) || detailLevel.HasFlag(CodeDocMemberDetailLevel.AdditionalContents);
                var provideXmlDoc = includeExceptions || detailLevel != CodeDocMemberDetailLevel.Minimum;
                var includeInheritance = detailLevel.HasFlag(CodeDocMemberDetailLevel.Inheritance);
                var includeParameters = detailLevel != CodeDocMemberDetailLevel.Minimum;

                var methodInfo = methodBase as MethodInfo;
                var methodCRef = GetCRefIdentifier(methodBase);
                var model = new CodeDocMethod(methodCRef);
                model.Uri = GetUri(methodBase);

                var memberDataProvider = new CodeDocMemberInfoProvider<MethodBase>(methodBase);

                if (provideXmlDoc) {
                    var xmlDocs = XmlDocs.GetMember(methodCRef.FullCRef);
                    if (xmlDocs != null)
                        memberDataProvider.Add(new CodeDocMemberXmlDataProvider(xmlDocs));
                }

                if (extraMemberDataProvider != null)
                    memberDataProvider.Add(extraMemberDataProvider);

                if (includeInheritance && methodInfo != null) {
                    var baseDefinition = methodInfo.FindNextAncestor();
                    if (baseDefinition != null) {
                        var baseDefinitionModel = GetOnly(GetCRefIdentifier(baseDefinition), detailLevel);
                        if (baseDefinitionModel != null)
                            memberDataProvider.Add(new CodeDocMemberDataProvider(baseDefinitionModel));
                    }
                }

                if (appendXmlDoc)
                    ApplyContentXmlDocs(model, memberDataProvider);

                model.ExternalVisibility = memberDataProvider.ExternalVisibility ?? ExternalVisibilityKind.Public;
                model.ShortName = RegularTypeDisplayNameOverlay.GetDisplayName(methodBase);
                model.FullName = FullTypeDisplayNameOverlay.GetDisplayName(methodBase);
                model.Title = model.ShortName;
                Contract.Assume(methodBase.DeclaringType != null);
                model.NamespaceName = methodBase.DeclaringType.Namespace;

                if (includeParameters) {
                    model.Parameters = Array.ConvertAll(
                        methodBase.GetParameters(),
                        p => CreateArgument(p, memberDataProvider));

                    if (methodInfo != null && methodInfo.ReturnParameter != null &&
                        methodInfo.ReturnType != typeof (void))
                        model.Return = CreateReturn(methodInfo.ReturnParameter, memberDataProvider);
                }

                if (methodBase.IsConstructor)
                    model.SubTitle = "Constructor";
                else if (model.Parameters != null && model.Parameters.Count == 1 && model.HasReturn && CSharpOperatorNameSymbolMap.IsConversionOperatorMethodName(methodBase.Name)) {
                    model.SubTitle = "Conversion";

                    string conversionOperationName;
                    if (methodBase.Name.EndsWith("Explicit", StringComparison.OrdinalIgnoreCase))
                        conversionOperationName = "Explicit";
                    else if (methodBase.Name.EndsWith("Implicit", StringComparison.OrdinalIgnoreCase))
                        conversionOperationName = "Implicit";
                    else
                        conversionOperationName = String.Empty;

                    var conversionParameterPart = String.Concat(
                        model.Parameters[0].ParameterType.ShortName,
                        " to ",
                        model.Return.ParameterType.ShortName);

                    model.ShortName = String.IsNullOrEmpty(conversionOperationName)
                        ? conversionParameterPart
                        : String.Concat(conversionOperationName, ' ', conversionParameterPart);
                    model.Title = model.ShortName;
                }
                else if (methodBase.IsOperatorOverload())
                    model.SubTitle = "Operator";
                else
                    model.SubTitle = "Method";

                Contract.Assume(methodBase.DeclaringType != null);
                model.Namespace = GetOrCreateNamespaceByName(methodBase.DeclaringType.Namespace);
                model.Assembly = GetCodeDocAssembly(methodBase.DeclaringType.Assembly);
                model.DeclaringType = GetOrConvert(methodBase.DeclaringType, CodeDocMemberDetailLevel.Minimum);
                model.IsOperatorOverload = methodBase.IsOperatorOverload();
                model.IsExtensionMethod = methodBase.IsExtensionMethod();
                model.IsSealed = methodBase.IsSealed();
                model.IsStatic = memberDataProvider.IsStatic.GetValueOrDefault();
                model.IsObsolete = memberDataProvider.IsObsolete.GetValueOrDefault();
                model.IsPure = memberDataProvider.IsPure.GetValueOrDefault();

                if (methodBase.DeclaringType != null && !methodBase.DeclaringType.IsInterface) {
                    if (methodBase.IsAbstract)
                        model.IsAbstract = true;
                    else if (methodBase.IsVirtual && !methodBase.IsFinal && methodBase.Attributes.HasFlag(MethodAttributes.NewSlot))
                        model.IsVirtual = true;
                }

                if (includeExceptions){
                    if (memberDataProvider.HasExceptions)
                        model.Exceptions = CreateExceptionModels(memberDataProvider.GetExceptions()).ToArray();
                    if (memberDataProvider.HasEnsures)
                        model.Ensures = memberDataProvider.GetEnsures().ToArray();
                    if (memberDataProvider.HasRequires)
                        model.Requires = memberDataProvider.GetRequires().ToArray();
                }

                if (includeParameters && methodBase.IsGenericMethod) {
                    var genericDefinition = methodBase.IsGenericMethodDefinition
                        ? methodBase
                        : methodInfo == null ? null : methodInfo.GetGenericMethodDefinition();
                    if (genericDefinition != null) {
                        var genericArguments = genericDefinition.GetGenericArguments();
                        if (genericArguments.Length > 0) {
                            model.GenericParameters = CreateGenericTypeParameters(
                                genericArguments,
                                memberDataProvider);
                        }
                    }
                }

                return model;
            }