bool AnalyzeTargetExpression (RefactoringOptions options, MonoDevelop.CSharp.Ast.CompilationUnit unit)
		{
			var data = options.GetTextEditorData ();
			var target = unit.GetNodeAt (data.Caret.Line, data.Caret.Column);
			if (target == null)
				return false;
			if (target.Parent is MemberReferenceExpression && ((MemberReferenceExpression)target.Parent).GetChildByRole (MemberReferenceExpression.Roles.Identifier) == target) {
				var memberReference = (MemberReferenceExpression)target.Parent;
				target = memberReference.Target;
				var targetResult = options.GetResolver ().Resolve (new ExpressionResult (data.GetTextBetween (target.StartLocation.Line, target.StartLocation.Column, target.EndLocation.Line, target.EndLocation.Column)), resolvePosition);
				if (targetResult.StaticResolve)
					modifiers = MonoDevelop.Projects.Dom.Modifiers.Static;
				declaringType = options.Dom.GetType (targetResult.ResolvedType);
				methodName = memberReference.MemberName;
			} else if (target is Identifier) {
				declaringType = options.ResolveResult.CallingType;
				methodName = data.GetTextBetween (target.StartLocation.Line, target.StartLocation.Column, target.EndLocation.Line, target.EndLocation.Column);
			}
			
			if (declaringType != null && !HasCompatibleMethod (declaringType, methodName, invocation)) {
				if (declaringType.HasParts)
					declaringType = declaringType.Parts.FirstOrDefault (t => t.CompilationUnit.FileName == options.Document.FileName) ?? declaringType;
				var doc = ProjectDomService.GetParsedDocument (declaringType.SourceProjectDom, declaringType.CompilationUnit.FileName);
				declaringType = doc.CompilationUnit.GetTypeAt (declaringType.Location) ?? declaringType;
				return true;
			}
			return false;
		}
		bool AnalyzeTargetExpression (RefactoringOptions options, MonoDevelop.CSharp.Dom.CompilationUnit unit)
		{
			var data = options.GetTextEditorData ();
			var target = unit.GetNodeAt (data.Caret.Line, data.Caret.Column);
			if (target == null)
				return false;
			if (target.Parent is MemberReferenceExpression && ((MemberReferenceExpression)target.Parent).Identifier == target) {
				var memberReference = (MemberReferenceExpression)target.Parent;
				target = memberReference.Target;
				var targetResult = options.GetResolver ().Resolve (new ExpressionResult (data.GetTextBetween (target.StartLocation.Line, target.StartLocation.Column, target.EndLocation.Line, target.EndLocation.Column)), resolvePosition);
				if (targetResult.StaticResolve)
					modifiers = MonoDevelop.Projects.Dom.Modifiers.Static;
				declaringType = options.Dom.GetType (targetResult.ResolvedType);
				methodName = memberReference.Identifier.Name;
			} else if (target is Identifier) {
				declaringType = options.ResolveResult.CallingType;
				methodName = data.GetTextBetween (target.StartLocation.Line, target.StartLocation.Column, target.EndLocation.Line, target.EndLocation.Column);
			}
			return declaringType != null && !HasCompatibleMethod (declaringType, methodName, invocation);
		}
		IMethod ConstructMethodFromInvocation (RefactoringOptions options)
		{
			var resolver = options.GetResolver ();
			var data = options.GetTextEditorData ();
			
			DomMethod result = new DomMethod (methodName, modifiers, MethodModifier.None, DomLocation.Empty, DomRegion.Empty, returnType);
			result.DeclaringType = new DomType ("GeneratedType") { ClassType = declaringType.ClassType };
			int i = 1;
			foreach (var curArg in invocation.Arguments) {
				var argument = curArg;
				DomParameter arg = new DomParameter ();
				if (argument is DirectionExpression) {
					var de = (DirectionExpression)argument;
					arg.ParameterModifiers = de.FieldDirection == FieldDirection.Out ? ParameterModifiers.Out : ParameterModifiers.Ref; 
					argument = de.Expression;
				}
				
				string argExpression = data.GetTextBetween (argument.StartLocation.Line, argument.StartLocation.Column, argument.EndLocation.Line, argument.EndLocation.Column);
				var resolveResult = resolver.Resolve (new ExpressionResult (argExpression), resolvePosition);
				
				if (argument is MemberReferenceExpression) {
					arg.Name = ((MemberReferenceExpression)argument).Identifier.Name;
				} else if (argument is IdentifierExpression) {
					arg.Name = ((IdentifierExpression)argument).Identifier;
					int idx = arg.Name.LastIndexOf ('.');
					if (idx >= 0)
						arg.Name = arg.Name.Substring (idx + 1);
				} else {
					arg.Name = "par" + i++;
				}
				
				arg.Name = char.ToLower (arg.Name[0]) + arg.Name.Substring (1);
				
				if (resolveResult != null) {
					arg.ReturnType = resolveResult.ResolvedType;
				} else {
					arg.ReturnType = DomReturnType.Object;
				}
				
				result.Add (arg);
			}
			return result;
		}
		IReturnType GuessReturnType (RefactoringOptions options)
		{
			var resolver = options.GetResolver ();
			var data = options.GetTextEditorData ();
			DomNode node = invocation;
			while (node != null) {
				if (node.Parent is VariableInitializer) {
					var initializer = (VariableInitializer)node.Parent;
					var resolveResult = resolver.Resolve (new ExpressionResult (initializer.Name), resolvePosition);
					return resolveResult.ResolvedType;
				}
				if (node.Parent is AssignmentExpression) {
					var resolveResult = ResolveAssignment (options, (AssignmentExpression)node.Parent);
					if (resolveResult != null)
						return resolveResult.ResolvedType;
				}
				if (node.Parent is InvocationExpression) {
					var parentInvocation = (InvocationExpression)node.Parent;
					int idx = 0;
					foreach (var arg in parentInvocation.Arguments) {
						if (arg == node)
							break;
						idx++;
					}
					var resolveResult = resolver.Resolve (new ExpressionResult (data.GetTextBetween (parentInvocation.StartLocation.Line, parentInvocation.StartLocation.Column, parentInvocation.EndLocation.Line, parentInvocation.EndLocation.Column)), resolvePosition) as MethodResolveResult;
					if (resolveResult != null) {
						if (idx < resolveResult.MostLikelyMethod.Parameters.Count)
							return resolveResult.MostLikelyMethod.Parameters[idx].ReturnType;
					}
					return DomReturnType.Object;
				}
				
				node = node.Parent;
			}
			return DomReturnType.Void;
		}
		ResolveResult ResolveAssignment (RefactoringOptions options, AssignmentExpression assignment)
		{
			var resolver = options.GetResolver ();
			var data = options.GetTextEditorData ();
			string expression;
			if (assignment.Left is IdentifierExpression) {
				expression = ((IdentifierExpression)assignment.Left).Identifier;
			} else {
				var left = assignment.Left;
				expression = data.GetTextBetween (left.StartLocation.Line, left.StartLocation.Column, left.EndLocation.Line, left.EndLocation.Column);
			}
			return resolver.Resolve (new ExpressionResult (expression), resolvePosition);
		}
		bool Analyze (RefactoringOptions options, ExtractMethodParameters param, bool fillParameter)
		{
			var data = options.GetTextEditorData ();
			var parser = new CSharpParser ();
			var unit = parser.Parse (data);
			var resolver = options.GetResolver ();
			if (unit == null)
				return false;
			var selectionRange = data.SelectionRange;
			var startOffset = selectionRange.Offset;
			while (startOffset + 1 < data.Length && char.IsWhiteSpace (data.GetCharAt (startOffset + 1)))
				startOffset++;
			var endOffset = selectionRange.EndOffset;
			while (startOffset < endOffset && endOffset - 1 > 0 && char.IsWhiteSpace (data.GetCharAt (endOffset - 1)))
				endOffset--;
			if (startOffset >= endOffset)
				return false;
			
			var endLocation = data.OffsetToLocation (endOffset);
			var startLocation = data.OffsetToLocation (startOffset);
			param.StartOffset = startOffset;
			param.EndOffset = endOffset;
			param.Nodes = new List<AstNode> (unit.GetNodesBetween (startLocation.Line, startLocation.Column, endLocation.Line, endLocation.Column));
			string text = options.Document.Editor.GetTextBetween (startLocation, endLocation);
			
			param.Text = RemoveIndent (text, GetIndent (data.GetTextBetween (data.GetLine (startLocation.Line).Offset, data.GetLine (endLocation.Line).EndOffset))).TrimEnd ('\n', '\r');
			VariableLookupVisitor visitor = new VariableLookupVisitor (resolver, param.Location);
			visitor.MemberLocation = param.DeclaringMember.Location;
			visitor.CutRegion = new DomRegion (startLocation.Line, startLocation.Column, endLocation.Line, endLocation.Column);
			if (fillParameter) {
				unit.AcceptVisitor (visitor, null);
				if (param.Nodes != null && (param.Nodes.Count == 1 && param.Nodes [0].NodeType == NodeType.Expression)) {
					ResolveResult resolveResult = resolver.Resolve (new ExpressionResult ("(" + text + ")"), param.Location);
					if (resolveResult != null && resolveResult.ResolvedType != null)
						param.ExpressionType = resolveResult.ResolvedType;
				}
				
				foreach (VariableDescriptor varDescr in visitor.VariableList.Where (v => !v.IsDefinedInsideCutRegion && (v.UsedInCutRegion || v.IsChangedInsideCutRegion || v.UsedAfterCutRegion && v.IsDefinedInsideCutRegion))) {
					param.Parameters.Add (varDescr);
				}
			
				param.Variables = new List<VariableDescriptor> (visitor.Variables.Values);
				param.ReferencesMember = visitor.ReferencesMember;
				
				param.OneChangedVariable = param.Variables.Count (p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion) == 1;
				if (param.OneChangedVariable)
					param.ExpressionType = param.Variables.First (p => p.IsDefinedInsideCutRegion && p.UsedAfterCutRegion).ReturnType;
				/*
					foreach (VariableDescriptor varDescr in visitor.VariableList.Where (v => !v.IsDefined && param.Variables.Contains (v))) {
					if (param.Parameters.Contains (varDescr))
						continue;
					if (startLocation <= varDescr.Location && varDescr.Location < endLocation)
						continue;
					param.Parameters.Add (varDescr);
				}
				
				
				param.ChangedVariables = new HashSet<string> (visitor.Variables.Values.Where (v => v.GetsChanged).Select (v => v.Name));
				*/
				// analyze the variables outside of the selected text
				IMember member = param.DeclaringMember;
			
				int bodyStartOffset = data.Document.LocationToOffset (member.BodyRegion.Start.Line, member.BodyRegion.Start.Column);
				int bodyEndOffset = data.Document.LocationToOffset (member.BodyRegion.End.Line, member.BodyRegion.End.Column);
				if (startOffset < bodyStartOffset || bodyEndOffset < endOffset)
					return false;
				text = data.Document.GetTextBetween (bodyStartOffset, startOffset) + data.Document.GetTextBetween (endOffset, bodyEndOffset);
				//				ICSharpCode.OldNRefactory.Ast.INode parsedNode = provider.ParseText (text);
				//				visitor = new VariableLookupVisitor (resolver, param.Location);
				//				visitor.CutRegion = new DomRegion (data.MainSelection.MinLine, data.MainSelection.MaxLine);
				//				visitor.MemberLocation = new Location (param.DeclaringMember.Location.Column, param.DeclaringMember.Location.Line);
				//				if (parsedNode != null)
				//					parsedNode.AcceptVisitor (visitor, null);
				
				
				/*	
				param.VariablesOutside = new Dictionary<string, VariableDescriptor> ();
				foreach (var pair in visitor.Variables) {
					if (startLocation < pair.Value.Location || endLocation >= pair.Value.Location) {
						param.VariablesOutside.Add (pair.Key, pair.Value);
					}
				}
				param.OutsideVariableList = new List<VariableDescriptor> ();
				foreach (var v in visitor.VariableList) {
					if (startLocation < v.Location || endLocation >= v.Location)
						param.OutsideVariableList.Add (v);
				}
				
				param.ChangedVariablesUsedOutside = new List<VariableDescriptor> (param.Variables.Where (v => v.GetsChanged && param.VariablesOutside.ContainsKey (v.Name)));
				param.OneChangedVariable = param.Nodes.Count == 1 && param.Nodes[0] is BlockStatement;
				if (param.OneChangedVariable) 
					param.OneChangedVariable = param.ChangedVariablesUsedOutside.Count == 1;
				
				param.VariablesToGenerate = new List<VariableDescriptor> (param.ChangedVariablesUsedOutside.Where (v => v.IsDefined));
				foreach (VariableDescriptor var in param.VariablesToGenerate) {
					param.Parameters.Add (var);
				}
				if (param.OneChangedVariable) {
					param.VariablesToDefine = new List<VariableDescriptor> (param.Parameters.Where (var => !var.InitialValueUsed));
					param.VariablesToDefine.ForEach (var => param.Parameters.Remove (var));
				} else {
					param.VariablesToDefine = new List<VariableDescriptor> ();
				}*/
			}
			
			return true;
		}