/// <summary>
        /// Checks the Xml header block of the given class for consistency with the class.
        /// </summary>
        /// <param name="classElement">The element to parse.</param>
        /// <param name="settings">The analyzer settings.</param>
        private void CheckClassElementHeader(ClassBase classElement, AnalyzerSettings settings)
        {
            Param.AssertNotNull(classElement, "classElement");
            Param.Ignore(settings);

            AnalyzerSettings adjustedSettings = settings;
            adjustedSettings.RequireFields = false;

            if (classElement.Declaration.ContainsModifier(CsTokenType.Partial))
            {
                // This is a partial element. Check for the possible partial element header types.
                this.CheckHeader(classElement, adjustedSettings, true);
            }
            else
            {
                // Just perform the regular set of checks on the header.
                this.CheckHeader(classElement, adjustedSettings, false);
            }
        }
        /*
        /// <summary>
        /// Determines whether to reference the set accessor within the property's summary documentation.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="setAccessor">The set accessor.</param>
        /// <returns>Returns true to reference the set accessor in the summary documentation, or false to omit it.</returns>
        private static bool IncludeSetAccessorInDocumentation(Property property, Accessor setAccessor)
        {
            Param.AssertNotNull(property, "property");
            Param.AssertNotNull(setAccessor, "setAccessor");

            // If the set accessor has the same access modifier as the property, always include it in the documentation.
            // Accessors get 'private' access modifiers by default if no access modifier is defined, in which case they
            // default to having the access of their parent property. Also include documentation for the set accessor
            // if it appears to be private but it does not actually define the 'private' keyword.
            if (setAccessor.AccessModifier == property.AccessModifier ||
                (setAccessor.AccessModifier == AccessModifierType.Private && !setAccessor.Declaration.ContainsModifier(CsTokenType.Private)))
            {
                return true;
            }

            // If the property is visible externally, then only include the set accessor in the documentation if
            // it is marked as public or protected.
            if (property.ActualAccess == AccessModifierType.Public ||
                property.ActualAccess == AccessModifierType.Protected ||
                property.ActualAccess == AccessModifierType.ProtectedInternal)
            {
                if (setAccessor.AccessModifier == AccessModifierType.Public ||
                    setAccessor.AccessModifier == AccessModifierType.Protected ||
                    setAccessor.AccessModifier == AccessModifierType.ProtectedInternal)
                {
                    return true;
                }
            }

            // If the property is internal, the include the set accessor in the docs unless it contains the private keyword.
            if (property.ActualAccess == AccessModifierType.Internal || property.ActualAccess == AccessModifierType.ProtectedAndInternal)
            {
                if (!setAccessor.Declaration.ContainsModifier(CsTokenType.Private))
                {
                    return true;
                }
            }

            // If the property is private, always include the set accessor in the docs.
            if (property.ActualAccess == AccessModifierType.Private)
            {
                return true;
            }

            // Otherwise, do not include the set accessor in the docs.
            return false;
        }
        */
        /// <summary>
        /// Builds a regular expression that can be used to validate the name of the given type when 
        /// used within a documentation cref attribute.
        /// </summary>
        /// <param name="type">The type to match against.</param>
        /// <returns>Returns the regular expression object.</returns>
        private static string BuildCrefValidationStringForType(ClassBase type)
        {
            Param.AssertNotNull(type, "type");

            // Determine whether the type is generic.
            string typeName = type.Declaration.Name;
            string[] genericParams = null;
            string genericParametersRegex = null;

            int index = typeName.IndexOf('<');
            if (index > 0)
            {
                // Get the generic types from the type name.
                genericParams = ExtractGenericParametersFromType(typeName, index);
                if (genericParams != null && genericParams.Length > 0)
                {
                    genericParametersRegex = BuildGenericParametersRegex(genericParams);
                }

                // Remove the generic brackets from the type name.
                typeName = typeName.Substring(0, index);
            }

            // Also capture the fully qualified name of the type, without generic parameters included.
            string namespaceRegex = BuildNamespaceRegex(type);

            // Build the regex string to match all possible formats for the type name.
            return string.Format(
                CultureInfo.InvariantCulture,
                CrefRegex,
                namespaceRegex,
                typeName,
                genericParametersRegex == null ? string.Empty : genericParametersRegex,
                genericParams == null ? string.Empty : "`" + genericParams.Length.ToString(CultureInfo.InvariantCulture));
        }
        /// <summary>
        /// Gets a string to match the namespace of the type in a format that can be inserted into a regular expression for matching.
        /// </summary>
        /// <param name="type">The type to match.</param>
        /// <returns>Returns the namespace string.</returns>
        private static string BuildNamespaceRegex(ClassBase type)
        {
            Param.AssertNotNull(type, "type");

            // The fully-qualified name of a type should always begin with Root. This part should be ignored.
            string fullyQualifiedName = type.FullyQualifiedName;
            Debug.Assert(fullyQualifiedName.StartsWith("Root.", StringComparison.Ordinal), "The fully qualified name of a type should start with Root.");

            StringBuilder namespaceRegex = new StringBuilder();

            int start = 5;

            // Start at position 5 to skip past the 'Root.' prefix.
            for (int i = start; i < fullyQualifiedName.Length; ++i)
            {
                if (fullyQualifiedName[i] == '.')
                {
                    // Since a dot is a special character in regex syntax, we need to escape this character.
                    if (namespaceRegex.Length > 0)
                    {
                        namespaceRegex.Append("\\.");
                    }

                    namespaceRegex.Append(fullyQualifiedName.Substring(start, i - start));

                    start = i + 1;
                }
                else if (fullyQualifiedName[i] == '<')
                {
                    // Stop if we get to an opening generic bracket.
                    break;
                }
            }

            if (namespaceRegex.Length > 0)
            {
                namespaceRegex.Append("\\.");
            }

            return namespaceRegex.ToString();
        }
        /// <summary>
        /// Checks a word to see if it should start with this. or base.
        /// </summary>
        /// <param name="word">The word text to check.</param>
        /// <param name="item">The word being checked.</param>
        /// <param name="line">The line that the word appears on.</param>
        /// <param name="expression">The expression the word appears within.</param>
        /// <param name="parentElement">The element that contains the word.</param>
        /// <param name="parentClass">The parent class that this element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckWordUsageAgainstClassMemberRules(
            string word,
            CsToken item,
            int line,
            Expression expression,
            CsElement parentElement,
            ClassBase parentClass,
            Dictionary<string, List<CsElement>> members)
        {
            Param.AssertValidString(word, "word");
            Param.AssertNotNull(item, "item");
            Param.AssertGreaterThanZero(line, "line");
            Param.AssertNotNull(expression, "expression");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // If there is a local variable with the same name, or if the item we're checking is within the left-hand side
            // of an object initializer expression, then ignore it.
            if (!IsLocalMember(word, item, expression) && !IsObjectInitializerLeftHandSideExpression(expression))
            {
                // Determine if this is a member of our class.
                CsElement foundMember = null;
                ICollection<CsElement> classMembers = ReadabilityRules.FindClassMember(word, parentClass, members, false);
                if (classMembers != null)
                {
                    if (classMembers != null)
                    {
                        foreach (CsElement classMember in classMembers)
                        {
                            if (classMember.Declaration.ContainsModifier(CsTokenType.Static) ||
                                (classMember.ElementType == ElementType.Field && ((Field)classMember).Const))
                            {
                                // There is a member with a matching name that is static or is a const field. In this case,
                                // ignore the issue and quit.
                                foundMember = null;
                                break;
                            }
                            else if (classMember.ElementType != ElementType.Class &&
                                classMember.ElementType != ElementType.Struct &&
                                classMember.ElementType != ElementType.Delegate &&
                                classMember.ElementType != ElementType.Enum)
                            {
                                // Found a matching member.
                                if (foundMember == null)
                                {
                                    foundMember = classMember;
                                }
                            }
                        }
                    }

                    if (foundMember != null)
                    {
                        if (foundMember.ElementType == ElementType.Property)
                        {
                            // If the property's name and type are the same, then this is not a violation.
                            // In this case, the type is being accessed, not the property.
                            Property property = (Property)foundMember;
                            if (property.ReturnType.Text != property.Declaration.Name)
                            {
                                this.AddViolation(parentElement, line, Rules.PrefixLocalCallsWithThis, word);
                            }
                        }
                        else
                        {
                            this.AddViolation(parentElement, line, Rules.PrefixLocalCallsWithThis, word);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Adds all members of a class to a dictionary, taking into account partial classes.
        /// </summary>
        /// <param name="parentClass">The class to collect.</param>
        /// <returns>Returns the dictionary of class members.</returns>
        private static Dictionary<string, List<CsElement>> CollectClassMembers(ClassBase parentClass)
        {
            Param.AssertNotNull(parentClass, "parentClass");

            Dictionary<string, List<CsElement>> members = new Dictionary<string, List<CsElement>>();

            if (parentClass.Declaration.ContainsModifier(CsTokenType.Partial))
            {
                foreach (ClassBase @class in parentClass.PartialElementList)
                {
                    CollectClassMembersAux(@class, members);
                }
            }
            else
            {
                CollectClassMembersAux(parentClass, members);
            }

            return members;
        }
        ////private void CheckClassMemberRulesForChildExpressions(
        ////    Expression expression,
        ////    Expression parentExpression,
        ////    CsElement parentElement,
        ////    ClassBase parentClass,
        ////    Dictionary<string, List<CsElement>> members)
        ////{
        ////    Param.AssertNotNull(expression, "expression");
        ////    Param.Ignore(parentExpression);
        ////    Param.AssertNotNull(parentElement, "parentElement");
        ////    Param.AssertNotNull(parentClass, "parentClass");
        ////    Param.AssertNotNull(members, "members");
        ////    foreach (Expression childExpression in expression.ChildExpressions)
        ////    {
        ////        ExpressionWithParameters expressionWithParameters = childExpression as ExpressionWithParameters;
        ////        if (expressionWithParameters != null)
        ////        {
        ////            foreach (Parameter parameter in expressionWithParameters.Parameters)
        ////            {
        ////                if (parameter.Type == null && parameter.Name != null)
        ////                {
        ////                    //todo
        ////                }
        ////            }
        ////        }
        ////        else if (childExpression.ExpressionType == ExpressionType.MethodInvocation)
        ////        {
        ////            MethodInvocationExpression methodInvocation = childExpression as MethodInvocationExpression;
        ////            foreach (Expression argument in methodInvocation.Arguments)
        ////            {
        ////                // Check each expression within this child expression.
        ////                this.CheckClassMemberRulesForExpressions(
        ////                    argument.ChildExpressions,
        ////                    argument,
        ////                    parentElement,
        ////                    parentClass,
        ////                    members);
        ////            }
        ////        }
        ////        this.CheckClassMemberRulesForChildExpressions(childExpression, expression, parentElement, parentClass, members);
        ////    }
        ////}
        /// <summary>
        /// Parses the given literal token.
        /// </summary>
        /// <param name="tokenNode">The literal token node.</param>
        /// <param name="expression">The expression that contains the token.</param>
        /// <param name="parentExpression">The parent of the expression that contains the token.</param>
        /// <param name="parentElement">The element that contains the expression.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForLiteralToken(
            Node<CsToken> tokenNode,
            Expression expression,
            Expression parentExpression,
            CsElement parentElement,
            ClassBase parentClass,
            Dictionary<string, List<CsElement>> members)
        {
            Param.AssertNotNull(tokenNode, "token");
            Param.AssertNotNull(expression, "expression");
            Param.Ignore(parentExpression);
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Skip types. We only care about named members.
            if (!(tokenNode.Value is TypeToken))
            {
                // If the name starts with a dot, ignore it.
                if (!tokenNode.Value.Text.StartsWith(".", StringComparison.Ordinal))
                {
                    if (tokenNode.Value.Text == "base" && parentExpression != null)
                    {
                        // An item is only allowed to start with base if there is an implementation of the
                        // item in the local class and the caller is trying to explicitly call the base
                        // class implementation instead of the local class implementation. Extract the name
                        // of the item being accessed.
                        CsToken name = ReadabilityRules.ExtractBaseClassMemberName(parentExpression, tokenNode);
                        if (name != null)
                        {
                            ICollection<CsElement> matches = ReadabilityRules.FindClassMember(name.Text, parentClass, members, true);

                            // Check to see if there is a non-static match.
                            bool found = false;
                            if (matches != null)
                            {
                                foreach (CsElement match in matches)
                                {
                                    if (!match.Declaration.ContainsModifier(CsTokenType.Static))
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                            }

                            if (!found)
                            {
                                this.AddViolation(parentElement, name.LineNumber, Rules.DoNotPrefixCallsWithBaseUnlessLocalImplementationExists, name);
                            }
                        }
                    }
                    else if (tokenNode.Value.Text != "this")
                    {
                        // Check whether this word should really start with this.
                        this.CheckWordUsageAgainstClassMemberRules(
                            tokenNode.Value.Text,
                            tokenNode.Value,
                            tokenNode.Value.LineNumber,
                            expression,
                            parentElement,
                            parentClass,
                            members);
                    }
                }
            }
        }
        /// <summary>
        /// Parses the given statement list.
        /// </summary>
        /// <param name="statements">The list of statements to parse.</param>
        /// <param name="parentElement">The element that contains the statements.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForStatements(
            ICollection<Statement> statements,
            CsElement parentElement,
            ClassBase parentClass,
            Dictionary<string, List<CsElement>> members)
        {
            Param.AssertNotNull(statements, "statements");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Loop through each of the statements.
            foreach (Statement statement in statements)
            {
                if (statement.ChildStatements.Count > 0)
                {
                    // Parse the sub-statements.
                    this.CheckClassMemberRulesForStatements(statement.ChildStatements, parentElement, parentClass, members);
                }

                // Parse the expressions in the statement.
                this.CheckClassMemberRulesForExpressions(statement.ChildExpressions, null, parentElement, parentClass, members);
            }
        }
        /// <summary>
        /// Parses the given expression.
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <param name="parentExpression">The parent expression, if there is one.</param>
        /// <param name="parentElement">The element that contains the expressions.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForExpression(
            Expression expression,
            Expression parentExpression,
            CsElement parentElement,
            ClassBase parentClass,
            Dictionary<string, List<CsElement>> members)
        {
            Param.AssertNotNull(expression, "expression");
            Param.Ignore(parentExpression);
            Param.AssertNotNull(parentElement, "parentElement");
            Param.AssertNotNull(parentClass, "parentClass");
            Param.AssertNotNull(members, "members");

            if (expression.ExpressionType == ExpressionType.Literal)
            {
                LiteralExpression literalExpression = (LiteralExpression)expression;

                // Check to see whether this literal is preceded by a member access symbol. If not
                // then we want to check whether this is a reference to one of our class members.
                if (!IsLiteralTokenPrecededByMemberAccessSymbol(literalExpression.TokenNode, expression.Tokens.MasterList))
                {
                    // Process the literal.
                    this.CheckClassMemberRulesForLiteralToken(
                        literalExpression.TokenNode,
                        expression,
                        parentExpression,
                        parentElement,
                        parentClass,
                        members);
                }
            }
            else
            {
                if (expression.ExpressionType == ExpressionType.Assignment &&
                    parentExpression != null &&
                    parentExpression.ExpressionType == ExpressionType.CollectionInitializer)
                {
                    // When we encounter assignment expressions within collection initializer expressions, we ignore the expression
                    // on the left-hand side of the assignment. This is because we know that the left-hand side refers to a property on
                    // the type being initialized, not a property on the local class. Thus, it does not ever need to be prefixed by this.
                    // Without this check we can get name collisions, such as:
                    // public sealed class Person
                    // {
                    //     public string FirstName { get; }
                    //     public void CreateAnonymousType()
                    //     {
                    //         var anonymousType = new { FirstName = this.FirstName };
                    //     }
                    // }
                    this.CheckClassMemberRulesForExpression(((AssignmentExpression)expression).RightHandSide, expression, parentElement, parentClass, members);
                }
                else if (expression.ChildExpressions.Count > 0)
                {
                    // Check each child expression within this expression.
                    this.CheckClassMemberRulesForExpressions(
                        expression.ChildExpressions,
                        expression,
                        parentElement,
                        parentClass,
                        members);
                }

                // Check if this is an anonymous method expression, which contains a child statement list.
                if (expression.ExpressionType == ExpressionType.AnonymousMethod)
                {
                    // Check the statements under this anonymous method.
                    this.CheckClassMemberRulesForStatements(
                        expression.ChildStatements,
                        parentElement,
                        parentClass,
                        members);
                }
                else if (expression.ExpressionType == ExpressionType.MethodInvocation)
                {
                    // Check each of the arguments passed into the method call.
                    MethodInvocationExpression methodInvocation = (MethodInvocationExpression)expression;
                    foreach (Argument argument in methodInvocation.Arguments)
                    {
                        // Check each expression within this child expression.
                        this.CheckClassMemberRulesForExpression(
                            argument.Expression,
                            null,
                            parentElement,
                            parentClass,
                            members);
                    }
                }
                ////else if (expression.ExpressionType == ExpressionType.MemberAccess)
                ////{
                ////    MemberAccessExpression memberAccess = (MemberAccessExpression)expression;
                ////    if (memberAccess.OperatorType != MemberAccessExpression.Operator.QualifiedAlias)
                ////    {
                ////        this.CheckClassMemberRulesForLiteralToken(
                ////            memberAccess.Tokens.First,
                ////            expression,
                ////            parentElement,
                ////            parentClass,
                ////            members);
                ////    }
                ////}
            }
        }
        /// <summary>
        /// Parses the list of expressions.
        /// </summary>
        /// <param name="expressions">The list of expressions.</param>
        /// <param name="parentExpression">The parent expression, if there is one.</param>
        /// <param name="parentElement">The element that contains the expressions.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForExpressions(
            ICollection<Expression> expressions,
            Expression parentExpression,
            CsElement parentElement,
            ClassBase parentClass,
            Dictionary<string, List<CsElement>> members)
        {
            Param.AssertNotNull(expressions, "expressions");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentExpression);
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Loop through each of the expressions in the list.
            foreach (Expression expression in expressions)
            {
                // If the expression is a variable declarator expression, we don't
                // want to match against the identifier tokens.
                if (expression.ExpressionType == ExpressionType.VariableDeclarator)
                {
                    VariableDeclaratorExpression declarator = expression as VariableDeclaratorExpression;
                    if (declarator.Initializer != null)
                    {
                        this.CheckClassMemberRulesForExpression(declarator.Initializer, parentExpression, parentElement, parentClass, members);
                    }
                }
                else
                {
                    this.CheckClassMemberRulesForExpression(expression, parentExpression, parentElement, parentClass, members);
                }
            }
        }
        /// <summary>
        /// Finds the given class member in the given class.
        /// </summary>
        /// <param name="word">The word to check.</param>
        /// <param name="parentClass">The class the word appears in.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        /// <param name="interfaces">True if interface implementations should be included.</param>
        /// <returns>Returns the class members that match against the given name.</returns>
        private static ICollection<CsElement> FindClassMember(
            string word, ClassBase parentClass, Dictionary<string, List<CsElement>> members, bool interfaces)
        {
            Param.AssertNotNull(word, "word");
            Param.AssertNotNull(parentClass, "parentClass");
            Param.AssertNotNull(members, "members");
            Param.Ignore(interfaces);

            // If the word is the same as the class name, then this is a constructor and we
            // don't want to match against it.
            if (word != parentClass.Declaration.Name)
            {
                ICollection<CsElement> matches = ReadabilityRules.MatchClassMember(word, members, interfaces);
                if (matches != null && matches.Count > 0)
                {
                    return matches;
                }
            }

            return null;
        }
        /// <summary>
        /// Checks the items within the given element.
        /// </summary>
        /// <param name="element">The element to check.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        /// <returns>Returns false if the analyzer should quit.</returns>
        private bool CheckClassMemberRulesForElements(CsElement element, ClassBase parentClass, Dictionary<string, List<CsElement>> members)
        {
            Param.AssertNotNull(element, "element");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Check whether processing has been cancelled by the user.
            if (this.Cancel)
            {
                return false;
            }

            if (element.ElementType == ElementType.Class ||
                element.ElementType == ElementType.Struct ||
                element.ElementType == ElementType.Interface)
            {
                parentClass = element as ClassBase;
                members = CollectClassMembers(parentClass);
            }

            foreach (CsElement child in element.ChildElements)
            {
                if (!child.Generated)
                {
                    if (child.ElementType == ElementType.Method ||
                        child.ElementType == ElementType.Constructor ||
                        child.ElementType == ElementType.Destructor ||
                        child.ElementType == ElementType.Accessor)
                    {
                        // If the parent class is null, then this element is sitting outside of a class.
                        // This is illegal in C# so the code will not compile, but we still attempt to
                        // parse it. In this case there is no use of this prefixes since there is no class.
                        if (parentClass != null)
                        {
                            this.CheckClassMemberRulesForStatements(child.ChildStatements, child, parentClass, members);
                        }
                    }
                    else
                    {
                        if (child.ElementType == ElementType.Class || child.ElementType == ElementType.Struct)
                        {
                            ClassBase elementContainer = child as ClassBase;
                            Debug.Assert(elementContainer != null, "The element is not a class.");

                            this.CheckClassMemberRulesForElements(child, elementContainer, members);
                        }
                        else if (!this.CheckClassMemberRulesForElements(child, parentClass, members))
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
        /// <summary>
        /// Adds all members of a class to a dictionary.
        /// </summary>
        /// <param name="class">The class to collect.</param>
        /// <param name="members">Adds all members of the class to the given dictionary.</param>
        private static void CollectClassMembersAux(ClassBase @class, Dictionary<string, List<CsElement>> members)
        {
            Param.AssertNotNull(@class, "class");
            Param.AssertNotNull(members, "members");

            foreach (CsElement child in @class.ChildElements)
            {
                if (child.ElementType == ElementType.Field)
                {
                    // Look through each of the declarators in the field.
                    foreach (VariableDeclaratorExpression declarator in ((Field)child).VariableDeclarationStatement.Declarators)
                    {
                        AddClassMember(members, child, declarator.Identifier.Text);
                    }
                }
                else if (child.ElementType == ElementType.Event)
                {
                    // Look through each of the declarators in the event.
                    foreach (EventDeclaratorExpression declarator in ((Event)child).Declarators)
                    {
                        AddClassMember(members, child, declarator.Identifier.Text);
                    }
                }
                else if (child.ElementType != ElementType.EmptyElement)
                {
                    AddClassMember(members, child, child.Declaration.Name);
                }
            }
        }
        /// <summary>
        /// Gets the actual qualified namespace of the class. For nested types where A.B.C.D exists and C.D is the type it returns A.B rather than A.B.C.
        /// </summary>
        /// <param name="type">The type to get the namespace for.</param>
        /// <returns>A string of the actual namespace.</returns>
        private static string GetActualQualifiedNamespace(ClassBase type)
        {
            Param.AssertNotNull(type, "type");

            CsElement localType = type;
            while (localType.Parent is ClassBase)
            {
                localType = (CsElement)localType.Parent;
            }

            string fullyQualifiedNameOfParentClass = localType.FullyQualifiedName;
            int lastIndexOfDot = fullyQualifiedNameOfParentClass.LastIndexOf('.');

            return lastIndexOfDot == -1 ? string.Empty : fullyQualifiedNameOfParentClass.Substring(0, lastIndexOfDot + 1);
        }
        /// <summary>
        /// Gets the actual name of the class. If nested type returns A+B rather than only B.
        /// </summary>
        /// <param name="type">The type to get the correct class name for.</param>
        /// <param name="showPlusInTypeName">True to show a '+' sign in a nested type.</param>
        /// <returns>A string of the actual class name.</returns>
        private static string GetActualClassName(ClassBase type, bool showPlusInTypeName)
        {
            Param.AssertNotNull(type, "type");
            Param.Ignore(showPlusInTypeName);

            CsElement localType = type;

            while (localType.Parent is ClassBase)
            {
                localType = (CsElement)localType.Parent;
            }

            int lastIndexOfDot = localType.FullyQualifiedName.LastIndexOf('.');
            if (lastIndexOfDot == -1)
            {
                return type.Name;
            }
            else
            {
                Debug.Assert(type.FullNamespaceName.Length > lastIndexOfDot + 1, "The fully qualified name is corrupted.");
                string remainder = type.FullyQualifiedName.Substring(lastIndexOfDot + 1);
                return showPlusInTypeName ? remainder.Replace('.', '+') : remainder;
            }
        }
        /// <summary>
        /// Gets a string to match the namespace of the type in a format that can be inserted into a regular expression for matching.
        /// </summary>
        /// <param name="type">The type to match.</param>
        /// <returns>Returns the namespace string.</returns>
        private static string BuildNamespaceRegex(ClassBase type)
        {
            Param.AssertNotNull(type, "type");

            // The fully-qualified name of a type should always begin with Root. This part should be ignored.
            string actualQualifiedClassName = GetActualQualifiedNamespace(type);
            Debug.Assert(actualQualifiedClassName.StartsWith("Root.", StringComparison.Ordinal), "The fully qualified name of a type should start with Root.");

            return actualQualifiedClassName.Substring(5).Replace(".", "\\.");
        }
        /*
        /// <summary>
        /// Determines whether to reference the set accessor within the property's summary documentation.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="setAccessor">The set accessor.</param>
        /// <returns>Returns true to reference the set accessor in the summary documentation, or false to omit it.</returns>
        private static bool IncludeSetAccessorInDocumentation(Property property, Accessor setAccessor)
        {
            Param.AssertNotNull(property, "property");
            Param.AssertNotNull(setAccessor, "setAccessor");

            // If the set accessor has the same access modifier as the property, always include it in the documentation.
            // Accessors get 'private' access modifiers by default if no access modifier is defined, in which case they
            // default to having the access of their parent property. Also include documentation for the set accessor
            // if it appears to be private but it does not actually define the 'private' keyword.
            if (setAccessor.AccessModifier == property.AccessModifier ||
                (setAccessor.AccessModifier == AccessModifierType.Private && !setAccessor.Declaration.ContainsModifier(CsTokenType.Private)))
            {
                return true;
            }

            // If the property is visible externally, then only include the set accessor in the documentation if
            // it is marked as public or protected.
            if (property.ActualAccess == AccessModifierType.Public ||
                property.ActualAccess == AccessModifierType.Protected ||
                property.ActualAccess == AccessModifierType.ProtectedInternal)
            {
                if (setAccessor.AccessModifier == AccessModifierType.Public ||
                    setAccessor.AccessModifier == AccessModifierType.Protected ||
                    setAccessor.AccessModifier == AccessModifierType.ProtectedInternal)
                {
                    return true;
                }
            }

            // If the property is internal, the include the set accessor in the docs unless it contains the private keyword.
            if (property.ActualAccess == AccessModifierType.Internal || property.ActualAccess == AccessModifierType.ProtectedAndInternal)
            {
                if (!setAccessor.Declaration.ContainsModifier(CsTokenType.Private))
                {
                    return true;
                }
            }

            // If the property is private, always include the set accessor in the docs.
            if (property.ActualAccess == AccessModifierType.Private)
            {
                return true;
            }

            // Otherwise, do not include the set accessor in the docs.
            return false;
        }
        */
        /// <summary>
        /// Builds a regular expression that can be used to validate the name of the given type when 
        /// used within a documentation cref attribute.
        /// </summary>
        /// <param name="type">The type to match against.</param>
        /// <returns>Returns the regular expression object.</returns>
        private static string BuildCrefValidationStringForType(ClassBase type)
        {
            Param.AssertNotNull(type, "type");

            // We get the actual type name. For nested types this is A.B rather than just B.
            string actualTypeName = GetActualClassName(type, false);
            string[] typeNameParts = actualTypeName.Split('.');

            StringBuilder actualTypeNameWithoutGenerics = new StringBuilder();
            StringBuilder typeNameWithGenerics = new StringBuilder();

            for (int i = 0; i < typeNameParts.Length; ++i)
            {
                typeNameWithGenerics.Append(BuildTypeNameStringWithGenerics(typeNameParts[i]));
                actualTypeNameWithoutGenerics.Append(RemoveGenericsFromTypeName(typeNameParts[i]));

                if (i < typeNameParts.Length - 1)
                {
                    typeNameWithGenerics.Append(@"\.");
                    actualTypeNameWithoutGenerics.Append(@"\.");
                }
            }

            StringBuilder typeNameWithParamsNumber = new StringBuilder();
            for (int i = 0; i < typeNameParts.Length; i++)
            {
                typeNameWithParamsNumber.Append(BuildTypeNameStringWithParamsNumber(typeNameParts[i]));

                if (i < typeNameParts.Length - 1)
                {
                    typeNameWithParamsNumber.Append(@"\.");
                }
            }

            // Also capture the fully qualified name of the type, without generic parameters included.
            string namespaceRegex = BuildNamespaceRegex(type);

            // Build the regex string to match all possible formats for the type name.
            return string.Format(CultureInfo.InvariantCulture, CrefRegex, namespaceRegex, actualTypeNameWithoutGenerics, typeNameWithGenerics, typeNameWithParamsNumber);
        }