public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
            {
                methodDeclaration.Attributes.AcceptVisitor(this);
                if (HasEntryPointSignature(methodDeclaration) || methodDeclaration.HasModifier(Modifiers.Public) || methodDeclaration.HasModifier(Modifiers.Protected))
                {
                    return;
                }
                var eligibleParameters = methodDeclaration.Parameters
                                         .Where(p => p.ParameterModifier != ParameterModifier.Out && p.ParameterModifier != ParameterModifier.Ref)
                                         .ToList();

                if (eligibleParameters.Count == 0)
                {
                    return;
                }
                var declarationResolveResult = ctx.Resolve(methodDeclaration) as MemberResolveResult;

                if (declarationResolveResult == null)
                {
                    return;
                }
                var member = declarationResolveResult.Member;

                if (member.IsOverride || member.IsOverridable || member.ImplementedInterfaceMembers.Any())
                {
                    return;
                }

                var collector = new TypeCriteriaCollector(ctx);

                methodDeclaration.AcceptVisitor(collector);

                foreach (var parameter in eligibleParameters)
                {
                    ProcessParameter(parameter, methodDeclaration.Body, collector);
                }
            }
            void ProcessParameter(ParameterDeclaration parameter, AstNode rootResolutionNode, TypeCriteriaCollector collector)
            {
                var localResolveResult = ctx.Resolve(parameter) as LocalResolveResult;

                if (localResolveResult == null)
                {
                    return;
                }
                var variable = localResolveResult.Variable;
                var typeKind = variable.Type.Kind;

                if (!(typeKind == TypeKind.Class ||
                      typeKind == TypeKind.Struct ||
                      typeKind == TypeKind.Interface ||
                      typeKind == TypeKind.Array) ||
                    parameter.Type is PrimitiveType ||
                    !collector.UsedVariables.Contains(variable))
                {
                    return;
                }

                var candidateTypes = localResolveResult.Type.GetAllBaseTypes().ToList();

                TypesChecked += candidateTypes.Count;
                var criterion = collector.GetCriterion(variable);

                var possibleTypes =
                    (from type in candidateTypes
                     where !type.Equals(localResolveResult.Type) && criterion.SatisfiedBy(type)
                     select type).ToList();

                TypeResolveCount += possibleTypes.Count;
                var validTypes =
                    (from type in possibleTypes
                     where (!tryResolve || TypeChangeResolvesCorrectly(ctx, parameter, rootResolutionNode, type)) && !FilterOut(variable.Type, type)
                     select type).ToList();

                if (validTypes.Any())
                {
                    AddIssue(new CodeIssue(parameter.Type, ctx.TranslateString("Parameter can be declared with base type"), GetActions(parameter, validTypes))
                    {
                        IssueMarker = IssueMarker.DottedLine
                    });
                    MembersWithIssues++;
                }
            }
            void ProcessParameter(ParameterDeclaration parameter, AstNode rootResolutionNode, TypeCriteriaCollector collector)
            {
                var localResolveResult = ctx.Resolve(parameter) as LocalResolveResult;

                if (localResolveResult == null)
                {
                    return;
                }
                var variable = localResolveResult.Variable;
                var typeKind = variable.Type.Kind;

                if (!(typeKind == TypeKind.Class ||
                      typeKind == TypeKind.Struct ||
                      typeKind == TypeKind.Interface ||
                      typeKind == TypeKind.Array) ||
                    !collector.UsedVariables.Contains(variable))
                {
                    return;
                }

                var candidateTypes = localResolveResult.Type.GetAllBaseTypes()
                                     .Where(t => t.IsParameterized)
                                     .ToList();

                var validTypes =
                    (from type in candidateTypes
                     where !tryResolve || ParameterCanBeDeclaredWithBaseTypeIssue.TypeChangeResolvesCorrectly(ctx, parameter, rootResolutionNode, type)
                     select type).ToList();

                if (!validTypes.Any())
                {
                    return;
                }

                var foundType = validTypes.FirstOrDefault();

                if (foundType == null)
                {
                    return;
                }

                AddIssue(new CodeIssue(parameter.NameToken, string.Format(ctx.TranslateString("Parameter can be {0}"),
                                                                          foundType.Name), string.Format(ctx.TranslateString("Parameter can be {0}"),
                                                                                                         foundType.Name),
                                       script => script.Replace(parameter.Type, CreateShortType(ctx, foundType, parameter))));
            }