/// <summary>
        /// Determines whether the given word is the name of a local variable.
        /// </summary>
        /// <param name="word">The name to check.</param>
        /// <param name="item">The token containing the word.</param>
        /// <param name="parent">The expression that the word appears in.</param>
        /// <returns>True if the word is the name of a local variable, false if not.</returns>
        private static bool IsLocalMember(string word, Token item, Expression parent)
        {
            Param.AssertValidString(word, "word");
            Param.AssertNotNull(item, "item");
            Param.AssertNotNull(parent, "parent");

            CodeUnit p = parent;

            while (p != null)
            {
                // Check to see if the name matches a local variable.
                if (ReadabilityRules.ContainsVariable(p.Variables, word, item))
                {
                    return(true);
                }

                // If the parent is an element (other than an accessor), do not look any higher up the stack than this.
                if (p.CodeUnitType == CodeUnitType.Element && !p.Is(ElementType.Accessor))
                {
                    break;
                }

                // Check to see whether the variable is defined within the parent.
                p = p.Parent;
            }

            return(false);
        }
        /// <summary>
        /// Determines whether the given token is preceded by a member access symbol.
        /// </summary>
        /// <param name="literalToken">The token to check.</param>
        /// <returns>Returns true if the token is preceded by a member access symbol.</returns>
        private static bool IsLiteralTokenPrecededByMemberAccessSymbol(Token literalToken)
        {
            Param.AssertNotNull(literalToken, "literalToken");

            // Get the previous non-whitespace item.
            LexicalElement previousItem = ReadabilityRules.GetPreviousNonWhitespaceItem(literalToken);

            if (previousItem != null)
            {
                if (previousItem.Is(OperatorType.MemberAccess) ||
                    previousItem.Is(OperatorType.Pointer) ||
                    previousItem.Is(OperatorType.QualifiedAlias))
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <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 <Element> FindClassMember(
            string word, ClassBase parentClass, Dictionary <string, List <Element> > 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.Name)
            {
                ICollection <Element> matches = ReadabilityRules.MatchClassMember(word, members, interfaces);
                if (matches != null && matches.Count > 0)
                {
                    return(matches);
                }
            }

            return(null);
        }
        /// <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,
            Token item,
            int line,
            Expression expression,
            Element parentElement,
            ClassBase parentClass,
            Dictionary <string, List <Element> > 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.
                Element foundMember = null;
                ICollection <Element> classMembers = ReadabilityRules.FindClassMember(word, parentClass, members, false);
                if (classMembers != null)
                {
                    foreach (Element classMember in classMembers)
                    {
                        if (classMember.ContainsModifier(TokenType.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.Name)
                            {
                                this.Violation <Token>(
                                    Rules.PrefixLocalCallsWithThis,
                                    new ViolationContext(parentElement, line, word),
                                    this.FixPrefixLocalCallsWithThisViolation,
                                    item);
                            }
                        }
                        else
                        {
                            this.Violation <Token>(
                                Rules.PrefixLocalCallsWithThis,
                                new ViolationContext(parentElement, line, word),
                                this.FixPrefixLocalCallsWithThisViolation,
                                item);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Parses the given literal token.
        /// </summary>
        /// <param name="token">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(
            Token token,
            Expression expression,
            Expression parentExpression,
            Element parentElement,
            ClassBase parentClass,
            Dictionary <string, List <Element> > members)
        {
            Param.AssertNotNull(token, "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 (token.TokenType != TokenType.Type)
            {
                // If the name starts with a dot, ignore it.
                if (!token.Text.StartsWith(".", StringComparison.Ordinal))
                {
                    if (token.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.
                        Token name = ReadabilityRules.ExtractBaseClassMemberName(parentExpression, token);
                        if (name != null)
                        {
                            ICollection <Element> 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 (Element match in matches)
                                {
                                    if (!match.ContainsModifier(TokenType.Static))
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                            }

                            if (!found)
                            {
                                this.AddViolation(parentElement, name.LineNumber, Rules.DoNotPrefixCallsWithBaseUnlessLocalImplementationExists, name);
                            }
                        }
                    }
                    else if (token.Text != "this")
                    {
                        // Check whether this word should really start with this.
                        this.CheckWordUsageAgainstClassMemberRules(
                            token.Text,
                            token,
                            token.LineNumber,
                            expression,
                            parentElement,
                            parentClass,
                            members);
                    }
                }
            }
        }