void FindDerivedThread (object state)
		{
			monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true);
			using (monitor) {
				IType cls = (IType) item;
				if (cls == null) return;
				
				CodeRefactorer cr = IdeApp.Workspace.GetCodeRefactorer (IdeApp.ProjectOperations.CurrentSelectedSolution);
				foreach (IType sub in cr.FindDerivedClasses (cls)) {
					if (!sub.Location.IsEmpty) {
						IEditableTextFile textFile = cr.TextFileProvider.GetEditableTextFile (sub.CompilationUnit.FileName);
						if (textFile == null) 
							textFile = new TextFile (sub.CompilationUnit.FileName);
						int position = textFile.GetPositionFromLineColumn (sub.Location.Line, sub.Location.Column);
						monitor.ReportResult (new MonoDevelop.Ide.FindInFiles.SearchResult (new FileProvider (sub.CompilationUnit.FileName, sub.SourceProject as Project), position, 0));
					}
				}
			}
		}
		public void GoToDeclaration ()
		{
			if (item is CompoundType) {
				CompoundType compoundType = (CompoundType)item;
				monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true);
				using (monitor) {
					foreach (IType part in compoundType.Parts) {
						FileProvider provider = new FileProvider (part.CompilationUnit.FileName);
						Mono.TextEditor.Document doc = new Mono.TextEditor.Document ();
						System.IO.TextReader textReader = provider.Open ();
						doc.Text = textReader.ReadToEnd ();
						textReader.Close ();
						int position = doc.LocationToOffset (part.Location.Line, part.Location.Column);
						while (position + part.Name.Length < doc.Length) {
							if (doc.GetTextAt (position, part.Name.Length) == part.Name)
								break;
							position++;
						}
						monitor.ReportResult (new MonoDevelop.Ide.FindInFiles.SearchResult (provider, position, part.Name.Length));
					}
					
				}
				
				return;
			}
			IdeApp.ProjectOperations.JumpToDeclaration (item);
		}
		public void FindReferences ()
		{
			monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true);
			ThreadPool.QueueUserWorkItem (FindReferencesThread);
		}
		public void FindReferences ()
		{
			monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true);
			Thread t = new Thread (new ThreadStart (FindReferencesThread));
			t.Name = "Find references";
			t.IsBackground = true;
			t.Start ();
		}
		public void FindDerivedClasses ()
		{
			monitor = IdeApp.Workbench.ProgressMonitors.GetSearchProgressMonitor (true, true);
			Thread t = new Thread (new ThreadStart (FindDerivedThread));
			t.Name = "Find subclasses";
			t.IsBackground = true;
			t.Start ();
		}
        static bool InitializeSearchInFiles()
        {
            Debug.Assert(searchOptions != null);
            cancelled = false;

            searchMonitor = Runtime.TaskService.GetSearchProgressMonitor (true);
            searchMonitor.CancelRequested += (MonitorHandler) Runtime.DispatchService.GuiDispatch (new MonitorHandler (OnCancelRequested));

            InitializeDocumentIterator(null, null);
            InitializeSearchStrategy(null, null);
            find.Reset();

            try {
                find.SearchStrategy.CompilePattern(searchOptions);
            } catch {
                Runtime.MessageService.ShowMessage (GettextCatalog.GetString ("Search pattern is invalid"), DialogPointer);
                return false;
            }
            return true;
        }
		public static IEnumerable<MemberReference> FindReferences (Solution solution, INode member, ISearchProgressMonitor monitor = null)
		{
			var scope = GetScope (member);
			ReferenceFinder finder;
			ProjectDom dom = null;
			ICompilationUnit unit = null;
			IEnumerable<INode> searchNodes = new INode[] { member };
			 if (member is LocalVariable) {
				dom = ((LocalVariable)member).DeclaringMember.DeclaringType.SourceProjectDom;
				unit = ((LocalVariable)member).CompilationUnit;
			} else if (member is IParameter) {
				dom = ((IParameter)member).DeclaringMember.DeclaringType.SourceProjectDom;
				unit = ((IParameter)member).DeclaringMember.DeclaringType.CompilationUnit;
			} else if (member is IType) {
				dom = ((IType)member).SourceProjectDom;
				unit = ((IType)member).CompilationUnit;
			} else if (member is IMember) {
				dom = ((IMember)member).DeclaringType.SourceProjectDom;
				unit = ((IMember)member).DeclaringType.CompilationUnit;
				searchNodes = CollectMembers (dom, (IMember)member);
			}
			
			switch (scope) {
			case RefactoryScope.File:
			case RefactoryScope.DeclaringType:
				if (dom == null || unit == null)
					yield break;
				finder = GetReferenceFinder (DesktopService.GetMimeTypeForUri (unit.FileName));
				if (finder == null)
					yield break;
				foreach (var searchNode in searchNodes) {
					foreach (var foundReference in finder.FindReferences (dom, unit.FileName, searchNode)) {
						yield return foundReference;
					}
				}
				break;
			case RefactoryScope.Project:
				if (dom == null)
					yield break;
				if (monitor != null)
					monitor.BeginTask (GettextCatalog.GetString ("Search reference in project..."), dom.Project.Files.Count);
				int counter = 0;
				foreach (var file in dom.Project.Files) {
					finder = GetReferenceFinder (DesktopService.GetMimeTypeForUri (file.FilePath));
					if (finder == null)
						continue;
					foreach (var searchNode in searchNodes) {
						foreach (var foundReference in finder.FindReferences (dom, file.FilePath, searchNode)) {
							yield return foundReference;
						}
					}
					if (monitor != null) {
						if (counter % 10 == 0)
							monitor.Step (10);
						counter++;
					}
				}
				if (monitor != null)
					monitor.EndTask ();
				break;
				
			case RefactoryScope.Solution:
				if (monitor != null)
					monitor.BeginTask (GettextCatalog.GetString ("Search reference in solution..."), solution.GetAllProjects ().Count);
				foreach (var project in solution.GetAllProjects ()) {
					var currentDom = ProjectDomService.GetProjectDom (project);
					foreach (var file in project.Files) {
						finder = GetReferenceFinder (DesktopService.GetMimeTypeForUri (file.FilePath));
						if (finder == null)
							continue;
						foreach (var searchNode in searchNodes) {
							foreach (var foundReference in finder.FindReferences (currentDom, file.FilePath, searchNode)) {
								yield return foundReference;
							}
						}
					}
					if (monitor != null)
						monitor.Step (1);
				}
				if (monitor != null)
					monitor.EndTask ();
				break;
			}
		}
		public static IEnumerable<MemberReference> FindReferences (INode member, ISearchProgressMonitor monitor = null)
		{
			return FindReferences (IdeApp.ProjectOperations.CurrentSelectedSolution, member, monitor);
		}
		static void SearchCompilation (ISearchProgressMonitor monitor, ICompilation comp, ITypeDefinition cls, IMember member)
		{
			var importedType = comp.Import (cls);
			if (importedType == null) {
				return;
			}

			IMember impMember = null;
			if (member != null) {
				impMember = comp.Import (member);
				if (impMember == null) {
					return;
				}
			}

			foreach (var derivedType in comp.MainAssembly.GetAllTypeDefinitions ()) {
				if (!derivedType.IsDerivedFrom (importedType))
					continue;
				IEntity result;
				if (member != null) {
					result = FindDerivedMember (impMember, derivedType);
					if (result == null)
						continue;
				}
				else {
					result = derivedType;
				}
				ReportResult (monitor, result);
			}
		}
		static void ReportResult (ISearchProgressMonitor monitor, IEntity result)
		{
			string filename = result.Region.FileName;
			if (string.IsNullOrEmpty (filename))
				return;

			var textFile = TextFileProvider.Instance.GetTextEditorData (filename);
			var start = textFile.LocationToOffset (result.Region.Begin);
			textFile.SearchRequest.SearchPattern = result.Name;
			var sr = textFile.SearchForward (start);
			if (sr != null)
				start = sr.Offset;

			if (textFile.Parent == null)
				textFile.Dispose ();

			monitor.ReportResult (new MemberReference (result, result.Region, start, result.Name.Length));
		}