public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
		{
			var delegateVisitor = new GetDelgateUsagesVisitor (context);
			context.RootNode.AcceptVisitor (delegateVisitor);

			return new GatherVisitor (context, delegateVisitor).GetIssues ();
		}
		public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
		{
			var unit = context.RootNode as SyntaxTree;
			if (unit == null)
				return Enumerable.Empty<CodeIssue> ();
			return new GatherVisitor (context, unit).GetIssues ();
		}
			public GatherVisitor(BaseRefactoringContext context) : base (context)
			{
				this.context = context;
				rules = new Dictionary<string, Func<int, int, bool>>();
				rules [typeof(ArgumentException).FullName] = (left, right) => left > right;
				rules [typeof(ArgumentNullException).FullName] = (left, right) => left < right;
				rules [typeof(ArgumentOutOfRangeException).FullName] = (left, right) => left < right;
				rules [typeof(DuplicateWaitObjectException).FullName] = (left, right) => left < right;
			}
		public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
		{
//			var sw = new Stopwatch();
//			sw.Start();
			var gatherer = new GatherVisitor(context, tryResolve);
			var issues = gatherer.GetIssues();
//			sw.Stop();
//			Console.WriteLine("Elapsed time in ParameterCanBeDemotedIssue: {0} (Checked types: {3, 4} Qualified for resolution check: {5, 4} Members with issues: {4, 4} Method bodies resolved: {2, 4} File: '{1}')",
//			                  sw.Elapsed, context.UnresolvedFile.FileName, gatherer.MethodResolveCount, gatherer.TypesChecked, gatherer.MembersWithIssues, gatherer.TypeResolveCount);
			return issues;
		}
		protected static bool FindUsage (BaseRefactoringContext context, SyntaxTree unit,
										 ITypeParameter typaParameter, AstNode declaration)
		{
			var found = false;
			refFinder.FindTypeParameterReferences (typaParameter, context.UnresolvedFile, unit, context.Compilation,
				(node, resolveResult) =>
				{
					found = found || node != declaration;
				}, context.CancellationToken);
			return found;
		}
		protected static bool HidesMember(BaseRefactoringContext ctx, AstNode node, string variableName)
		{
			var typeDecl = node.GetParent<TypeDeclaration>();
			if (typeDecl == null)
				return false;
			var entityDecl = node.GetParent<EntityDeclaration>();
			var memberResolveResult = ctx.Resolve(entityDecl) as MemberResolveResult;
			if (memberResolveResult == null)
				return false;
			var typeResolveResult = ctx.Resolve(typeDecl) as TypeResolveResult;
			if (typeResolveResult == null)
				return false;

			var sourceMember = memberResolveResult.Member;

			return typeResolveResult.Type.GetMembers(m => m.Name == variableName).Any(m2 => IsAccessible(sourceMember, m2));
		}
		protected override IEnumerable<CodeAction> GetFixes (BaseRefactoringContext context, Node env,
															 string variableName)
		{
			var containingStatement = env.ContainingStatement;

			// we don't give a fix for these cases since the general fix may not work
			// lambda in while/do-while/for condition
			if (containingStatement is WhileStatement || containingStatement is DoWhileStatement ||
				containingStatement is ForStatement)
				yield break;
			// lambda in for initializer/iterator
			if (containingStatement.Parent is ForStatement &&
				((ForStatement)containingStatement.Parent).EmbeddedStatement != containingStatement)
				yield break;

			Action<Script> action = script =>
			{
				var newName = LocalVariableNamePicker.PickSafeName (
					containingStatement.GetParent<EntityDeclaration> (),
					Enumerable.Range (1, 100).Select (i => variableName + i));

				var variableDecl = new VariableDeclarationStatement (new SimpleType("var"), newName, 
																	 new IdentifierExpression (variableName));
				
				if (containingStatement.Parent is BlockStatement || containingStatement.Parent is SwitchSection) {
					script.InsertBefore (containingStatement, variableDecl);
				} else {
					var offset = script.GetCurrentOffset (containingStatement.StartLocation);
					script.InsertBefore (containingStatement, variableDecl);
					script.InsertText (offset, "{");
					script.InsertText (script.GetCurrentOffset (containingStatement.EndLocation), "}");
					script.FormatText (containingStatement.Parent);
				}

				var textNodes = new List<AstNode> ();
				textNodes.Add (variableDecl.Variables.First ().NameToken);

				foreach (var reference in env.GetAllReferences ()) {
					var identifier = new IdentifierExpression (newName);
					script.Replace (reference.AstNode, identifier);
					textNodes.Add (identifier);
				}
				script.Link (textNodes.ToArray ());
			};
			yield return new CodeAction (context.TranslateString ("Copy to local variable"), action);
		}
			public GatherVisitor(BaseRefactoringContext context) : base (context)
			{
				var type = typeof(ThreadStaticAttribute).ToTypeReference().Resolve(ctx.Compilation.TypeResolveContext);
				threadStaticDefinition = type.GetDefinition();
			}
		internal abstract GatherVisitorBase GetGatherVisitor(BaseRefactoringContext context);
 public GatherVisitor(BaseRefactoringContext ctx)
     : base(ctx)
 {
 }
		public IEnumerable<CodeIssue> GetIssues (BaseRefactoringContext context)
		{
			return new GatherVisitor (context).GetIssues ();
		}
			public GatherVisitor (BaseRefactoringContext ctx)
				: base (ctx)
			{
				unreachableNodes = new HashSet<AstNode> ();
			}
			CodeAction GetAction(BaseRefactoringContext context, Expression targetExpression,
			                                   IMember member)
			{
				var builder = context.CreateTypeSytemAstBuilder(targetExpression);
				var newType = builder.ConvertType(member.DeclaringType);
				string description = string.Format("{0} '{1}'", context.TranslateString("Use base class"), newType.GetText());
				return new CodeAction(description, script => {
					script.Replace(targetExpression, newType);
				});
			}
			public GatherVisitor (BaseRefactoringContext context) : base (context)
			{
				binOpVisitor = new BinaryExpressionVisitor (this);
			}
			public GatherVisitor (BaseRefactoringContext ctx, GetDelgateUsagesVisitor usedDelegates)
				: base (ctx)
			{
				this.usedDelegates = usedDelegates;
			}
		internal override GatherVisitorBase GetGatherVisitor (BaseRefactoringContext context)
		{
			return new GatherVisitor (context);
		}
			public GatherVisitor(BaseRefactoringContext context, VariableDeclaredInWideScopeIssue inspector) : base (context)
			{
				this.context = context;
			}
		public TypeCriteriaCollector(BaseRefactoringContext context)
		{
			this.context = context;
			TypeCriteria = new Dictionary<IVariable, IList<ITypeCriterion>>();
			UsedVariables = new HashSet<IVariable>();
		}
			public GatherVisitor (BaseRefactoringContext ctx)
				: base (ctx)
			{
				this.collectedAstNodes = new HashSet<AstNode> ();
			}
		/// <summary>
		/// Initializes a new instance of the <see cref="ICSharpCode.NRefactory.PlayScript.GatherVisitorBase"/> class.
		/// </summary>
		/// <param name='ctx'>
		/// The refactoring context.
		/// </param>
		public GatherVisitorBase (BaseRefactoringContext ctx)
		{
			this.ctx = ctx;
		}
			public GetDelgateUsagesVisitor(BaseRefactoringContext ctx)
			{
				this.ctx = ctx;
			}
			public GatherVisitor (BaseRefactoringContext ctx, SyntaxTree unit)
				: base (ctx)
			{
				this.unit = unit;
			}
//			readonly ConditionalToNullCoalescingIssue inspector;
			
			public GatherVisitor (BaseRefactoringContext ctx, ConditionalToNullCoalescingIssue inspector) : base (ctx)
			{
//				this.inspector = inspector;
			}
		public IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context)
		{
			var visitor = new GatherVisitor(context);
			context.RootNode.AcceptVisitor(visitor);
			return visitor.FoundIssues;
		}
//			readonly RedundantInternalIssue inspector;
			
			public GatherVisitor (BaseRefactoringContext ctx, RedundantInternalIssue inspector) : base (ctx)
			{
//				this.inspector = inspector;
			}
			public GatherVisitor (BaseRefactoringContext ctx) : base (ctx)
			{
				service = (NamingConventionService)ctx.GetService (typeof (NamingConventionService));
			}
			public GatherVisitor(BaseRefactoringContext context) : base (context)
			{
				this.context = context;
			}
			public GatherVisitor(BaseRefactoringContext context) : base (context)
			{
			}
			public GatherVisitor (BaseRefactoringContext ctx)
				: base (ctx)
			{
			}
		protected override IEnumerable<CodeAction> GetFixes (BaseRefactoringContext context, Node env,
															 string variableName)
		{
			yield break;
		}
			public GatherVisitor (BaseRefactoringContext ctx)
				: base (ctx)
			{
				conversions = CSharpConversions.Get(ctx.Compilation);
			}
 public IEnumerable <CodeIssue> GetIssues(BaseRefactoringContext context)
 {
     return(new GatherVisitor(context).GetIssues());
 }