Initial release for merge
diff --git a/org.eclipse.search/.classpath b/org.eclipse.search/.classpath
index 944dc2e..a9ba8cb 100644
--- a/org.eclipse.search/.classpath
+++ b/org.eclipse.search/.classpath
@@ -1,14 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="search"/>
-	<classpathentry kind="src" path="/org.eclipse.core.resources"/>
-	<classpathentry kind="src" path="/org.eclipse.ui"/>
-	<classpathentry kind="src" path="/org.eclipse.ui.ide"/>
-	<classpathentry kind="src" path="/org.eclipse.ui.workbench.texteditor"/>
-	<classpathentry kind="src" path="/org.eclipse.jface.text"/>
-	<classpathentry kind="src" path="/org.eclipse.ui.editors"/>
-	<classpathentry kind="src" path="/org.eclipse.core.boot"/>
-	<classpathentry kind="src" path="/org.eclipse.core.runtime"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/org.eclipse.search/.project b/org.eclipse.search/.project
index 62b1918..6f15dc6 100644
--- a/org.eclipse.search/.project
+++ b/org.eclipse.search/.project
@@ -4,9 +4,12 @@
 	<comment></comment>
 	<projects>
 		<project>org.eclipse.core.boot</project>
+		<project>org.eclipse.core.filebuffers</project>
 		<project>org.eclipse.core.resources</project>
 		<project>org.eclipse.core.runtime</project>
+		<project>org.eclipse.core.runtime.compatibility</project>
 		<project>org.eclipse.jface.text</project>
+		<project>org.eclipse.search.ui</project>
 		<project>org.eclipse.swt</project>
 		<project>org.eclipse.ui</project>
 		<project>org.eclipse.ui.editors</project>
diff --git a/org.eclipse.search/buildnotes_search.html b/org.eclipse.search/buildnotes_search.html
index 6267ccc..82ce5bb 100644
--- a/org.eclipse.search/buildnotes_search.html
+++ b/org.eclipse.search/buildnotes_search.html
@@ -19,6 +19,25 @@
 <br>
 <br>
 <br>
+========== Eclipse Build Input December 16th 2003 ==========<br>
+
+<!-- Add what's new below and end each line with br tag -->
+<pre>
+- bug fixing
+</pre>
+<br>
+<br>
+========== Eclipse Build Input November 18th 2003 ==========<br>
+
+<!-- Add what's new below and end each line with br tag -->
+<pre>
+- Added a new interface IReplacePage. If an ISearchPage implements IReplacePage,
+  a "Replace" button will be shown in the search dialog (when the page is active).
+  The text search page implements that interface.
+- Extended the text replace dialog to support "Replace in File" and "Replace All" actions.
+</pre>
+<br>
+<br>
 ========== Eclipse Build Input November 11th 2003 ==========<br>
 <!-- Add what's new below and end each line with br tag -->
 <pre>
diff --git a/org.eclipse.search/plugin.properties b/org.eclipse.search/plugin.properties
index f8e4c8b..1c8064b 100644
--- a/org.eclipse.search/plugin.properties
+++ b/org.eclipse.search/plugin.properties
@@ -34,6 +34,7 @@
 ResourcePathSorter.tooltip= Sort by Resource Path
 
 SearchPreferencePage.label= Search
+WorkInProgressPreferencePage.label= Work in Progress
 
 ActionDefinition.openSearchDialog.name= Open Search Dialog
 ActionDefinition.openSearchDialog.description= Open the Search dialog
diff --git a/org.eclipse.search/plugin.xml b/org.eclipse.search/plugin.xml
index 048f82d..5542822 100644
--- a/org.eclipse.search/plugin.xml
+++ b/org.eclipse.search/plugin.xml
@@ -14,11 +14,14 @@
 
 	<requires>
 	  <import plugin="org.eclipse.core.resources"/>
+	  <import plugin="org.eclipse.core.filebuffers"/>
 	  <import plugin="org.eclipse.ui"/>
       <import plugin="org.eclipse.ui.ide"/>
       <import plugin="org.eclipse.ui.workbench.texteditor"/>
       <import plugin="org.eclipse.jface.text"/>
       <import plugin="org.eclipse.ui.editors"/>
+      <import plugin="org.eclipse.core.runtime.compatibility" optional="true"/>
+	  <import plugin="org.eclipse.search.ui"/>
 	</requires>
 	
 	<runtime>
@@ -178,6 +181,11 @@
 			class="org.eclipse.search.internal.ui.SearchPreferencePage"
 			category="org.eclipse.ui.preferencePages.Workbench">
 		</page>
+		<page name="%WorkInProgressPreferencePage.label"
+			id="org.eclipse.search.preferences.WorkInProgressPreferencePage"
+			class="org.eclipse.search.internal.ui.WorkInProgressPreferencePage"
+			category="org.eclipse.search.preferences.SearchPreferencePage">
+		</page>
 	</extension>
 	
 	<extension
@@ -185,6 +193,7 @@
 	     <specification
 	      		annotationType="org.eclipse.search.results"
 	            label="%SearchMarkerPreference.label"
+	            icon="icons/full/obj16/searchm_obj.gif"
 	            markerType="org.eclipse.search.searchmarker"
 	            textPreferenceKey="searchResultIndication"
 	            textPreferenceValue="true"
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/MatchLocator.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/MatchLocator.java
index 9d77f53..5238160 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/core/text/MatchLocator.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/MatchLocator.java
@@ -43,7 +43,6 @@
 		fIsRegEx= options.indexOf('r') != -1;
 		if (!isRegExSearch())
 			pattern= asRegEx(pattern);
-		
 		if (options.indexOf('i') != -1)
 			regExPattern= Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
 		else
@@ -181,9 +180,9 @@
 		}
 		return -1;
 	}
-
+	
 	public boolean isRegExSearch() {
 		return fIsRegEx;
-	}
+}
 	
 }
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchEngine.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchEngine.java
index 93cc3a0..55a3a5f 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchEngine.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchEngine.java
@@ -32,12 +32,11 @@
 	/**
 	 * Search for the given pattern.
 	 */
-	public IStatus search(IWorkspace workspace, String pattern, String options, ISearchScope scope, ITextSearchResultCollector collector) {
+	public IStatus search(IWorkspace workspace, ISearchScope scope, ITextSearchResultCollector collector, MatchLocator matchLocator) {
 		Assert.isNotNull(workspace);
-		Assert.isNotNull(pattern);
 		Assert.isNotNull(scope);
 		Assert.isNotNull(collector);
-		
+		Assert.isNotNull(matchLocator);
 		IProgressMonitor monitor= collector.getProgressMonitor();
 		
 		IProject[] projects= workspace.getRoot().getProjects();
@@ -58,7 +57,7 @@
 					monitor.setTaskName(SearchMessages.getFormattedString("TextSearchEngine.scanning", args)); //$NON-NLS-1$
 				}				
 				collector.aboutToStart();
-				TextSearchVisitor visitor= new TextSearchVisitor(pattern, options, scope, collector, status, amountOfWork);
+				TextSearchVisitor visitor= new TextSearchVisitor(matchLocator, scope, collector, status, amountOfWork);
 				visitor.process(openProjects);	
 			} catch (CoreException ex) {
 				status.add(ex.getStatus());
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchJob.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchJob.java
new file mode 100644
index 0000000..bb77fd2
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchJob.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search.internal.core.text;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search2.ui.ISearchJob;
+import org.eclipse.search2.ui.text.ITextSearchResult;
+import org.eclipse.search2.ui.text.Match;
+
+
+/**
+ * @author Thomas Mäder */
+public class TextSearchJob implements ISearchJob {
+	private ITextSearchResult fSearch;
+	private String fSearchString;
+	private String fSearchOptions;
+	private TextSearchScope fScope;
+	private String fName;
+
+	public TextSearchJob(ITextSearchResult search, TextSearchScope scope, String options, String searchString, String description) {
+		
+		fName= description;
+		fSearch= search;
+		fScope= scope;
+		fSearchOptions= options;
+		fSearchString= searchString;
+	}
+
+	public boolean canRunInBackground() {
+		return true;
+	}
+
+	public IStatus run(final IProgressMonitor pm) {
+		fSearch.removeAll();
+		ITextSearchResultCollector collector= new ITextSearchResultCollector() {
+			public IProgressMonitor getProgressMonitor() {
+				return pm;
+			}
+
+			public void aboutToStart() {
+				fSearch.jobStarted();
+			}
+
+			public void accept(IResourceProxy proxy, String line, int start, int length, int lineNumber) {
+				IResource resource= proxy.requestResource();
+				if (start < 0)
+					start= 0;
+				if (length < 0)
+					length= 0;
+				fSearch.addMatch(new Match(resource, start, length));
+			}
+
+			public void done() {
+				fSearch.jobFinished();
+			}
+		};
+		new TextSearchEngine().search(SearchPlugin.getWorkspace(), fScope, collector, new MatchLocator(fSearchString, fSearchOptions));
+		return new Status(IStatus.OK, "some plugin", 0, "Dummy message", null);
+	}
+
+	public String getName() {
+		return fName;
+	}
+
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java
index 2050df5..a5f9cef 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/core/text/TextSearchVisitor.java
@@ -21,8 +21,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
@@ -36,7 +34,10 @@
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
-
+import org.eclipse.search.internal.core.ISearchScope;
+import org.eclipse.search.internal.ui.SearchMessages;
+import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search.ui.SearchUI;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
@@ -46,12 +47,6 @@
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.texteditor.ITextEditor;
 
-import org.eclipse.search.ui.SearchUI;
-
-import org.eclipse.search.internal.core.ISearchScope;
-import org.eclipse.search.internal.ui.SearchMessages;
-import org.eclipse.search.internal.ui.SearchPlugin;
-
 /**
  * The visitor that does the actual work.
  */
@@ -59,106 +54,32 @@
 	protected static final int fgLF= '\n';
 	protected static final int fgCR= '\r';
 
-	private String fPatternStr;
 	private ISearchScope fScope;
 	private ITextSearchResultCollector fCollector;
 	private IEditorPart[] fEditors;
+	private MatchLocator fLocator;
 		
 	private IProgressMonitor fProgressMonitor;
-	private Matcher fMatcher;
 	private Integer[] fMessageFormatArgs;
 
 	private int fNumberOfScannedFiles;
 	private int fNumberOfFilesToScan;
-	private long fLastUpdateTime;
+	private long fLastUpdateTime;	
 	
-	protected int fPushbackChar;
-	protected boolean fPushback;
-	
-	
-	public TextSearchVisitor(String pattern, String options, ISearchScope scope, ITextSearchResultCollector collector, MultiStatus status, int fileCount) {
+	public TextSearchVisitor(MatchLocator locator, ISearchScope scope, ITextSearchResultCollector collector, MultiStatus status, int fileCount) {
 		super(status);
-		fPatternStr= pattern;
 		fScope= scope;
 		fCollector= collector;
-		fPushback= false;
 
 		fProgressMonitor= collector.getProgressMonitor();
-		Pattern regExPattern;
-		if (options.indexOf('r') == -1)
-			pattern= asRegEx(pattern);
-		if (options.indexOf('i') != -1)
-			regExPattern= Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
-		else
-			regExPattern= Pattern.compile(pattern);
 
-		fMatcher= regExPattern.matcher(""); //$NON-NLS-1$
-			
+		fLocator= locator;
+		
 		fNumberOfScannedFiles= 0;
 		fNumberOfFilesToScan= fileCount;
 		fMessageFormatArgs= new Integer[] { new Integer(0), new Integer(fileCount) };
 	}
 	
-	/*
-	 * Converts '*' and '?' to regEx variables.
-	 */
-	private String asRegEx(String pattern) {
-		
-		StringBuffer out= new StringBuffer(pattern.length());
-		
-		boolean escaped= false;
-		boolean quoting= false;
-	
-		int i= 0;
-		while (i < pattern.length()) {
-			char ch= pattern.charAt(i++);
-	
-			if (ch == '*' && !escaped) {
-				if (quoting) {
-					out.append("\\E"); //$NON-NLS-1$
-					quoting= false;
-				}
-				out.append(".*"); //$NON-NLS-1$
-				escaped= false;
-				continue;
-			} else if (ch == '?' && !escaped) {
-				if (quoting) {
-					out.append("\\E"); //$NON-NLS-1$
-					quoting= false;
-				}
-				out.append("."); //$NON-NLS-1$
-				escaped= false;
-				continue;
-			} else if (ch == '\\' && !escaped) {
-				escaped= true;
-				continue;								
-	
-			} else if (ch == '\\' && escaped) {
-				escaped= false;
-				if (quoting) {
-					out.append("\\E"); //$NON-NLS-1$
-					quoting= false;
-				}
-				out.append("\\\\"); //$NON-NLS-1$
-				continue;								
-			}
-	
-			if (!quoting) {
-				out.append("\\Q"); //$NON-NLS-1$
-				quoting= true;
-			}
-			if (escaped && ch != '*' && ch != '?' && ch != '\\')
-				out.append('\\');
-			out.append(ch);
-			escaped= ch == '\\';
-	
-		}
-		if (quoting)
-			out.append("\\E"); //$NON-NLS-1$
-		
-		return out.toString();
-	}
-	
 	public void process(Collection projects) {
 		Iterator i= projects.iterator();
 		while(i.hasNext()) {
@@ -210,7 +131,7 @@
 		if (proxy.isDerived())
 			return false;
 
-		if (fPatternStr.length() == 0) {
+		if (fLocator.isEmtpy()) {
 			fCollector.accept(proxy, "", -1, 0, -1); //$NON-NLS-1$
 			updateProgressMonitor();
 			return true;
@@ -226,37 +147,7 @@
 				InputStream stream= file.getContents(false);
 				reader= new BufferedReader(new InputStreamReader(stream, ResourcesPlugin.getEncoding()));
 			}
-			int lineCounter= 1;
-			int charCounter=0;
-			boolean eof= false;
-			try {
-				while (!eof) {
-					StringBuffer sb= new StringBuffer(200);
-					int eolStrLength= readLine(reader, sb);
-					int lineLength= sb.length();
-					int start= 0;
-					eof= eolStrLength == -1;
-					String line= sb.toString();
-					while (start < lineLength) {
-						fMatcher.reset(line);
-						if (fMatcher.find(start)) {
-							start= charCounter + fMatcher.start();
-							int length= fMatcher.end() - fMatcher.start();
-							fCollector.accept(proxy, line.trim(), start, length, lineCounter);
-							start= fMatcher.end();
-						}
-						else	// no match in this line
-							start= lineLength;
-					}
-					charCounter+= lineLength + eolStrLength;
-					lineCounter++;
-					if (fProgressMonitor.isCanceled())
-						throw new OperationCanceledException(SearchMessages.getString("TextSearchVisitor.canceled")); //$NON-NLS-1$
-				}
-			} finally {
-				if (reader != null)
-					reader.close();
-			}
+			fLocator.locateMatches(fProgressMonitor, proxy, reader, fCollector);
 		} catch (IOException e) {
 			String message= SearchMessages.getFormattedString("TextSearchVisitor.error", file.getFullPath()); //$NON-NLS-1$
 			throw new CoreException(new Status(IStatus.ERROR, SearchUI.PLUGIN_ID, Platform.PLUGIN_ERROR, message, e));
@@ -294,33 +185,6 @@
 		return null;
 	}
 	
-	protected int readLine(BufferedReader reader, StringBuffer sb) throws IOException {
-		int ch= -1;
-		if (fPushback) {
-			ch= fPushbackChar;
-			fPushback= false;
-		}
-		else
-			ch= reader.read();
-		while (ch >= 0) {
-			if (ch == fgLF)
-				return 1;
-			if (ch == fgCR) {
-				ch= reader.read();
-				if (ch == fgLF)
-					return 2;
-				else {
-					fPushbackChar= ch;
-					fPushback= true;
-					return 1;
-				}
-			}
-			sb.append((char)ch);
-			ch= reader.read();
-		}
-		return -1;
-	}
-	
 	/*
 	 * @see IResourceProxyVisitor#visit(IResourceProxy)
 	 */
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/ScopePart.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/ScopePart.java
index 4bf732d..187cebc 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/ScopePart.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/ScopePart.java
@@ -16,7 +16,15 @@
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.search.internal.ui.util.PixelConverter;
+import org.eclipse.search.internal.ui.util.SWTUtil;
+import org.eclipse.search.ui.ISearchPageContainer;
+import org.eclipse.search.ui.SearchUI;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
@@ -26,23 +34,12 @@
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Text;
-
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.util.Assert;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.window.Window;
-
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkingSet;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;
 
-import org.eclipse.search.ui.ISearchPageContainer;
-import org.eclipse.search.ui.SearchUI;
-
-import org.eclipse.search.internal.ui.util.PixelConverter;
-import org.eclipse.search.internal.ui.util.SWTUtil;
-
 public class ScopePart {
 
 	// Settings store
@@ -280,9 +277,9 @@
 		fUseSelection.setData(new Integer(ISearchPageContainer.SELECTION_SCOPE));
 		fUseSelection.setText(SearchMessages.getString("ScopePart.selectedResourcesScope.text")); //$NON-NLS-1$
 		ISelection selection= fSearchPageContainer.getSelection();
-		fUseSelection.setEnabled(
-			selection instanceof IStructuredSelection && !fSearchPageContainer.getSelection().isEmpty());
-
+		fUseSelection.setEnabled((selection instanceof IStructuredSelection && 
+				!fSearchPageContainer.getSelection().isEmpty()));
+		
 		GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
 		gd.horizontalIndent= 8;
 		fUseSelection.setLayoutData(gd);
@@ -290,8 +287,9 @@
 		fUseProject= new Button(fPart, SWT.RADIO);
 		fUseProject.setData(new Integer(ISearchPageContainer.SELECTED_PROJECTS_SCOPE));
 		fUseProject.setText(SearchMessages.getString("ScopePart.enclosingProjectsScope.text")); //$NON-NLS-1$
-		fUseProject.setEnabled(
-			selection instanceof IStructuredSelection && !fSearchPageContainer.getSelection().isEmpty());
+		fUseProject.setEnabled((selection instanceof IStructuredSelection && 
+								!fSearchPageContainer.getSelection().isEmpty()) ||
+								hasFocusEditor());
 
 		gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
 		gd.horizontalSpan= 2;
@@ -342,6 +340,18 @@
 		return fPart;
 	}
 
+	/**
+	 * @return Whether an editor has the focus
+	 */
+	private boolean hasFocusEditor() {
+		IWorkbenchPage activePage= SearchPlugin.getActivePage();
+		if (activePage == null)
+			return false;
+		if (activePage.getActivePart() instanceof IEditorPart)
+			return true;
+		return false;
+	}
+
 	private void handleScopeChanged(SelectionEvent e) {
 		Object source= e.getSource();
 		if (source instanceof Button) {
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java
index d6c6561..eae98ba 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDialog.java
@@ -26,6 +26,7 @@
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -38,6 +39,7 @@
 import org.eclipse.swt.widgets.TabFolder;
 import org.eclipse.swt.widgets.TabItem;
 
+import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.operation.IRunnableContext;
 import org.eclipse.jface.resource.ImageDescriptor;
@@ -57,6 +59,7 @@
 import org.eclipse.ui.dialogs.ListSelectionDialog;
 import org.eclipse.ui.help.WorkbenchHelp;
 
+import org.eclipse.search.ui.IReplacePage;
 import org.eclipse.search.ui.ISearchPage;
 import org.eclipse.search.ui.ISearchPageContainer;
 import org.eclipse.search.ui.ISearchPageScoreComputer;
@@ -67,7 +70,6 @@
 
 class SearchDialog extends ExtendedDialogWindow implements ISearchPageContainer {
 
-	
 	private class TabFolderLayout extends Layout {
 		protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
 			if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT)
@@ -103,6 +105,9 @@
 	}
 	
 	
+	private static final int SEARCH_ID= IDialogConstants.CLIENT_ID+1;
+	private static final int REPLACE_ID= SEARCH_ID+1;
+	
 	private IWorkspace fWorkspace;
 	private ISearchPage fCurrentPage;
 	private String fInitialPageId;
@@ -113,13 +118,13 @@
 	private Point fMinSize;
 	private ScopePart[] fScopeParts;
 	private boolean fPageStateIgnoringScopePart;
-	Button fCustomizeButton;
+	private Button fCustomizeButton;
+	private Button fReplaceButton;
 
 	public SearchDialog(Shell shell, IWorkspace workspace, ISelection selection, IEditorPart editor, String pageId) {
 		super(shell);
 		Assert.isNotNull(workspace);
 		fWorkspace= workspace;
-		setPerformActionLabel(SearchMessages.getString("SearchDialog.performAction")); //$NON-NLS-1$
 		fSelection= selection;
 		fEditorPart= editor;
 		fDescriptors= SearchPlugin.getDefault().getEnabledSearchPageDescriptors(pageId);
@@ -264,13 +269,12 @@
 			return getControl(fCurrentPage, parent, 0);
 		else {
 			Composite border= new Composite(parent, SWT.NONE);
-			GridLayout layout= new GridLayout();
+			FillLayout layout= new FillLayout();
 			layout.marginWidth= 7;
 			layout.marginHeight= 7;
 			border.setLayout(layout);
 			
 			TabFolder folder= new TabFolder(border, SWT.NONE);
-			folder.setLayoutData(new GridData(GridData.FILL_BOTH));
 			folder.setLayout(new TabFolderLayout());
 
 			for (int i= 0; i < numPages; i++) {			
@@ -306,6 +310,13 @@
 			return border;
 		}	
 	}
+	
+	protected void createButtonsForButtonBar(Composite parent) {
+		fReplaceButton= createActionButton(parent, REPLACE_ID, SearchMessages.getString("SearchDialog.replaceAction"), true); //$NON-NLS-1$
+		fReplaceButton.setVisible(fCurrentPage instanceof IReplacePage);
+		createActionButton(parent, SEARCH_ID, SearchMessages.getString("SearchDialog.searchAction"), true); //$NON-NLS-1$
+		super.createButtonsForButtonBar(parent);
+	}
 
 	protected Control createButtonBar(Composite parent) {
 		Composite composite= new Composite(parent, SWT.NULL);
@@ -333,12 +344,12 @@
 		filler.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
 		
 		Control result= super.createButtonBar(composite);
-		getButton(IDialogConstants.FINISH_ID).setEnabled(fDescriptors.size() > 0);
-		applyDialogFont(result);
+		getButton(SEARCH_ID).setEnabled(fDescriptors.size() > 0);
+		applyDialogFont(composite);
 		return result;
 	}
 
-	protected boolean performAction() {
+	protected boolean performAction(int actionID) {
 		if (fCurrentPage == null)
 			return true;
 		
@@ -348,7 +359,12 @@
 			SearchPlugin.setAutoBuilding(false);
 		try {
 			fCustomizeButton.setEnabled(false);
-			return fCurrentPage.performAction();
+			if (actionID == SEARCH_ID)
+				return fCurrentPage.performAction();
+			else
+				// safe cast, replace button is only visible when the curren page is 
+				// a replace page.
+				return ((IReplacePage)fCurrentPage).performReplace();
 		} finally {
 			fCustomizeButton.setEnabled(true);
 			if (isAutoBuilding)
@@ -356,7 +372,7 @@
 				SearchPlugin.setAutoBuilding(true);				
 		}
 	}
-	
+
 	private SearchPageDescriptor getDescriptorAt(int index) {
 		return (SearchPageDescriptor)fDescriptors.get(index);
 	}
@@ -382,6 +398,9 @@
 	
 	private void turnToPage(SelectionEvent event) {
 		final TabItem item= (TabItem)event.item;
+		TabFolder folder= item.getParent();
+		Control oldControl= folder.getItem(fCurrentIndex).getControl();
+		Point oldSize= oldControl.getSize();
 		if (item.getControl() == null) {
 			final SearchPageDescriptor descriptor= (SearchPageDescriptor)item.getData();
 
@@ -399,10 +418,12 @@
 		}
 		if (item.getData() instanceof ISearchPage) {
 			fCurrentPage= (ISearchPage)item.getData();
+			fReplaceButton.setVisible(fCurrentPage instanceof IReplacePage);
 			fCurrentIndex= item.getParent().getSelectionIndex();
-			resizeDialogIfNeeded(item.getControl());
 			fCurrentPage.setVisible(true);
 		}
+		Control newControl= item.getControl();
+		resizeDialogIfNeeded(oldSize, newControl.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
 	}
 	
 	private int getPreferredPageIndex() {
@@ -504,15 +525,17 @@
 	} 
 
 	private Control getControl(ISearchPage page, Composite parent, int index) {
-		if (page.getControl() == null) {
+		Control control= page.getControl();
+		if (control != null)
+			return control;
 			// Page wrapper
 			Composite pageWrapper= new Composite(parent, SWT.NONE);
 			GridLayout layout= new GridLayout();
-			pageWrapper.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
 			layout.marginWidth= 0;
 			layout.marginHeight= 0;
 			pageWrapper.setLayout(layout);
 			
+		Dialog.applyDialogFont(pageWrapper);
 			// The page itself
 			page.createControl(pageWrapper);
 
@@ -529,16 +552,21 @@
 				applyDialogFont(part);
 				fScopeParts[index].setVisible(true);
 			}
+		return pageWrapper;
 		}
-		return page.getControl().getParent();
-	}
 	
-	private void resizeDialogIfNeeded(Control newControl) {
-		Point currentSize= fCurrentPage.getControl().getSize();
-		Point newSize= newControl.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
-		if (mustResize(currentSize, newSize)) {
+	private void resizeDialogIfNeeded(Point oldSize, Point newSize) {
+		if (oldSize == null || newSize == null)
+			return;
 			Shell shell= getShell();
-			shell.setSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
+		Point shellSize= shell.getSize();
+		if (mustResize(oldSize, newSize)) {
+			if (newSize.x > oldSize.x)
+				shellSize.x+= (newSize.x-oldSize.x);
+			if (newSize.y > oldSize.y)
+				shellSize.y+= (newSize.y-oldSize.y);
+			shell.setSize(shellSize);
+					shell.layout(true);
 		}
 	}
 	
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDropDownAction.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDropDownAction.java
index 8302142..bb6db83 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDropDownAction.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchDropDownAction.java
@@ -28,7 +28,7 @@
 
 	private Menu fMenu;
 	
-	public SearchDropDownAction(SearchResultViewer viewer) {
+	public SearchDropDownAction() {
 		setText(SearchMessages.getString("SearchResultView.previousSearches.text")); //$NON-NLS-1$
 		setToolTipText(SearchMessages.getString("SearchResultView.previousSearches.tooltip")); //$NON-NLS-1$
 		SearchPluginImages.setImageDescriptors(this, SearchPluginImages.T_LCL, SearchPluginImages.IMG_LCL_SEARCH_HISTORY);
@@ -36,8 +36,10 @@
 	}
 
 	public void dispose() {
-		if (fMenu != null)
+		if (fMenu != null)  {
 			fMenu.dispose();
+			fMenu= null;
+		}
 	}
 
 	public Menu getMenu(Menu parent) {
@@ -79,4 +81,12 @@
 	public void run() {
 			new ShowSearchesAction().run(true);
 	}
+
+	/**
+	 * Get's rid of the menu, because the menu hangs on to 
+	 * the searches, etc.
+	 */
+	void clear() {
+		dispose();
+	}
 }
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchManager.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchManager.java
index 0419dc4..6e31023 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchManager.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchManager.java
@@ -57,7 +57,6 @@
 	
 	private HashSet fListeners= new HashSet();
 	private LinkedList fPreviousSearches= new LinkedList();
-	private boolean fIsNewSearch= false;
 	private boolean fIsRemoveAll= false;
 	
 	public static SearchManager getDefault() {
@@ -86,7 +85,7 @@
 
 	void removeAllSearches() {
 		SearchPlugin.getWorkspace().removeResourceChangeListener(this);
-		WorkspaceModifyOperation op= new WorkspaceModifyOperation() {
+		WorkspaceModifyOperation op= new WorkspaceModifyOperation(null) {
 			protected void execute(IProgressMonitor monitor) throws CoreException {
 				monitor.beginTask(SearchMessages.getString("SearchManager.updating"), 100); //$NON-NLS-1$
 				SearchPlugin.getWorkspace().getRoot().deleteMarkers(SearchUI.SEARCH_MARKER, true, IResource.DEPTH_INFINITE);
@@ -120,18 +119,20 @@
 		Iterator iter= fListeners.iterator();
 		while (iter.hasNext()) {
 			SearchResultViewer viewer= (SearchResultViewer)iter.next();
-			viewer.setContextMenuTarget(null);
-			viewer.setActionGroupFactory(null);
-			viewer.setInput(null);
+			handleAllSearchesRemoved(viewer);
 		}
 	}
 
+	private void handleAllSearchesRemoved(SearchResultViewer viewer) {
+		viewer.handleAllSearchesRemoved();
+	}
+
 	void setCurrentSearch(final Search search) {
 		if (fCurrentSearch == search)
 			return;
 			
 		SearchPlugin.getWorkspace().removeResourceChangeListener(this);
-		WorkspaceModifyOperation op= new WorkspaceModifyOperation() {
+		WorkspaceModifyOperation op= new WorkspaceModifyOperation(null) {
 			protected void execute(IProgressMonitor monitor) throws CoreException {
 				internalSetCurrentSearch(search, monitor);
 			}
@@ -287,7 +288,10 @@
 		}
 	}
 
-	void addNewSearch(Search newSearch) {
+	void addNewSearch(final Search newSearch) {
+		
+		SearchPlugin.getWorkspace().removeResourceChangeListener(this);
+		
 		// Clear the viewers
 		Iterator iter= fListeners.iterator();
 		Display display= getDisplay();
@@ -299,9 +303,7 @@
 					public void run() {
 						if (fCurrentSearch != null && viewer == visibleViewer)
 							fCurrentSearch.setSelection(viewer.getSelection());
-						viewer.handleRemoveAll();
-						viewer.clearTitle();
-
+						setNewSearch(viewer, newSearch);
 					}
 				});
 			}
@@ -324,22 +326,24 @@
 		}
 	}
 
-	void setCurrentResults(ArrayList results) {
+	void searchFinished(ArrayList results) {
 		Assert.isNotNull(results);
 		getCurrentSearch().setResults(results);
-		if (results.isEmpty()) {
-			// directly update because there will be no delta
-				Display display= getDisplay();
-				if (display == null || display.isDisposed())
-					return;
-				display.syncExec(new Runnable() {
-					public void run() {
-						handleNewSearchResult();
-					}
-				});
+
+		Display display= getDisplay();
+		if (display == null || display.isDisposed())
+			return;
+		
+		if (Thread.currentThread() == display.getThread())
+			handleNewSearchResult();
+		else {
+			display.syncExec(new Runnable() {
+				public void run() {
+					handleNewSearchResult();
+				}
+			});
 		}
-		else
-			fIsNewSearch= true;
+		SearchPlugin.getWorkspace().addResourceChangeListener(this);
 	}
 	
 	//--- Change event handling -------------------------------------------------
@@ -353,12 +357,7 @@
 		fListeners.remove(viewer);
 	}
 
-	private final void handleSearchMarkersChanged(final IResourceChangeEvent event, IMarkerDelta[] markerDeltas) {
-		if (fIsNewSearch) {
-			fIsNewSearch= false;
-			handleNewSearchResult();
-			return;
-		}
+	private final void handleSearchMarkersChanged(IMarkerDelta[] markerDeltas) {
 		if (fIsRemoveAll) {
 			handleRemoveAll();
 			fIsRemoveAll= false;
@@ -369,8 +368,9 @@
 		while (iter.hasNext())
 			((SearchResultViewer)iter.next()).getControl().setRedraw(false);
 	
-		for (int i=0; i < markerDeltas.length; i++)
+		for (int i=0; i < markerDeltas.length; i++) {
 			handleSearchMarkerChanged(markerDeltas[i]);
+		}
 
 		iter= fListeners.iterator();
 		while (iter.hasNext())
@@ -380,9 +380,8 @@
 
 	private void handleSearchMarkerChanged(IMarkerDelta markerDelta) {
 		int kind= markerDelta.getKind();
-		if ((kind & IResourceDelta.ADDED) != 0)
-			handleAddMatch(markerDelta.getMarker());
-		else if (((kind & IResourceDelta.REMOVED) != 0))
+		// don't listen for adds will be done by ISearchResultView.addMatch(...)
+		if (((kind & IResourceDelta.REMOVED) != 0))
 			handleRemoveMatch(markerDelta.getMarker());
 		else if ((kind & IResourceDelta.CHANGED) != 0)
 			handleUpdateMatch(markerDelta.getMarker());
@@ -395,40 +394,24 @@
 		while (iter.hasNext())
 			((SearchResultViewer)iter.next()).handleRemoveAll();
 	}
-
-	private void handleAddMatch(IMarker marker) {
-		Object groupByKey= getCurrentSearch().getGroupByKeyComputer().computeGroupByKey(marker);
-		SearchResultViewEntry entry= findEntry(groupByKey);
-		if (entry == null) {
-			entry= new SearchResultViewEntry(groupByKey, marker.getResource());
-			getCurrentResults().add(entry);
-			entry.add(marker);
-			Iterator iter= fListeners.iterator();
-			while (iter.hasNext())
-				((SearchResultViewer)iter.next()).handleAddMatch(entry);
-		}
-		else {
-			entry.add(marker);
-			Iterator iter= fListeners.iterator();
-			while (iter.hasNext())
-				((SearchResultViewer)iter.next()).handleUpdateMatch(entry, false);
-		}
-	}
 	
 	private void handleNewSearchResult() {
 		Iterator iter= fListeners.iterator();
-		final Search search= getCurrentSearch();
 		while (iter.hasNext()) {
 			SearchResultViewer viewer= (SearchResultViewer)iter.next();
-			viewer.setPageId(search.getPageId());
-			viewer.setGotoMarkerAction(search.getGotoMarkerAction());
-			viewer.setContextMenuTarget(search.getContextMenuContributor());
-			viewer.setActionGroupFactory(null);
 			viewer.setInput(getCurrentResults());
-			viewer.setActionGroupFactory(search.getActionGroupFactory());
 		}
 	}
 	
+	private void setNewSearch(SearchResultViewer viewer, Search search) {
+		viewer.setInput(null);
+		viewer.clearTitle();
+		viewer.setPageId(search.getPageId());
+		viewer.setGotoMarkerAction(search.getGotoMarkerAction());
+		viewer.setContextMenuTarget(search.getContextMenuContributor());
+		viewer.setActionGroupFactory(search.getActionGroupFactory());
+	}
+	
 	private void handleRemoveMatch(IMarker marker) {
 		SearchResultViewEntry entry= findEntry(marker);
 		if (entry != null) {
@@ -466,17 +449,6 @@
 		return null;
 	}
 
-	private SearchResultViewEntry findEntry(Object key) {
-		if (key == null)
-			return null;
-		Iterator entries= getCurrentResults().iterator();
-		while (entries.hasNext()) {
-			SearchResultViewEntry entry= (SearchResultViewEntry)entries.next();
-			if (key.equals(entry.getGroupByKey()))
-				return entry;
-		}
-		return null;
-	}
 	/**
 	 * Received a resource event. Since the delta could be created in a 
 	 * separate thread this methods post the event into the viewer's 
@@ -489,7 +461,7 @@
 		final IMarkerDelta[] markerDeltas= event.findMarkerDeltas(SearchUI.SEARCH_MARKER, true);
 		if (markerDeltas == null || markerDeltas.length < 1)
 			return;
-		
+
 		Display display= getDisplay();
 		if (display == null || display.isDisposed())
 			return;
@@ -497,7 +469,7 @@
 		Runnable runnable= new Runnable() {
 			public void run() {
 				if (getCurrentSearch() != null) {
-					handleSearchMarkersChanged(event, markerDeltas);
+					handleSearchMarkersChanged(markerDeltas);
 					// update title and actions
 					Iterator iter= fListeners.iterator();
 					while (iter.hasNext()) {
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties
index 8c62da4..b00feec 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchMessages.properties
@@ -10,7 +10,8 @@
 ###############################################################################
 
 SearchDialog.title= Search
-SearchDialog.performAction= &Search
+SearchDialog.searchAction= &Search
+SearchDialog.replaceAction= R&eplace...
 SearchDialog.customize= Customi&ze...
 SearchDialog.noSearchExtension= No Search Extensions plugged into workbench or all search pages disabled.
 
@@ -180,30 +181,19 @@
 ReplaceAction.label_all= Re&place...
 ReplaceAction.label_selected= Rep&lace Selected...
 ReplaceAction.error.only_on_text_search= Replace is only available on text search.
-ReplaceAction.error.unable_to_perform= Replace operation can\'t be performed.
-ReplaceAction.error.changed_file= The content of the following file has changed. Please redo the search to ensure that all matches are correct.
-ReplaceAction.error.changed_files= The content of the following files have changed. Please redo the search to ensure that all matches are correct.
-ReplaceAction.error.opened_file= The following file is open in an editor that the replace operation cannot handle. Please close the editor.
-ReplaceAction.error.opened_files= The following files are open in editors that the replace operation cannot handle. Please close the editors.
-ReplaceAction.error.not_file= The following resource is not a file and cannot be handled. Please exclude it from the replace operation.
-ReplaceAction.error.not_files= The following resources are not files and cannot be handled. Please exclude them from the replace operation.
 ReplaceAction.dialog.title= Replace
 
 ReplaceDialog.replace_label= Replace:
 ReplaceDialog.with_label= &With:
-ReplaceDialog.replace_next= Re&place/Next
 ReplaceDialog.replace= &Replace
-ReplaceDialog.next= &Next
-ReplaceDialog.close= &Close
-ReplaceDialog.save_changes=Automatically &save changes
+ReplaceDialog.replaceAllInFile= Replace All in &File
+ReplaceDialog.replaceAll= Replace &All
+ReplaceDialog.skip= &Skip
+ReplaceDialog.skipFile= S&kip File
 ReplaceDialog.dialog.title= Replace
-ReplaceDialog.error.unexpected_exception=Unexpected exception during replace operation.
-ReplaceDialog.error.different_content= File content differs from search result.
-ReplaceDialog.error.reenable_auto_build_failed=Couldn\'t reactivate auto building.
-ReplaceDialog.error.auto_building= Couldn\'t disable auto building.
-ReplaceDialog.error.no_matches= Couldn\'t find first match.
-ReplaceDialog.error.no_file_for_marker=Current match is not associated with a file. It is not possible to open an editor.
 ReplaceDialog.error.unable_to_open_text_editor=It is not possible to open the built-in text editor for file ''{0}''.
+ReplaceDialog.error.unable_to_replace=An error occurred while replacing in file ''{0}''.
+ReplaceDialog.progress.message=File: {0} ({1} of {2})
 
 SelectAllAction.label= Select A&ll
 SelectAllAction.tooltip= Select All
@@ -216,3 +206,19 @@
 RemovePotentialMatchesAction.dialog.message= The current search result does not contain inexact matches.
 
 OpenWithMenu.label= Open Wit&h
+
+ReadOnlyDialog.skipFile=Skip File
+ReadOnlyDialog.skipAll=Skip All
+ReadOnlyDialog.message=The file {0} is read-only
+ReplaceDialog.task.replace=Replacing Match
+ReplaceDialog.task.replaceInFile=Replacing Matches in File {0}
+ReplaceDialog.task.replace.replaceAll=Replacing Matches
+ReplaceAction.label=Replace
+ReplaceAction.research.error=An error occurred while updating the matches
+SearchAgainConfirmationDialog.outofsync.message=Some resources are out of sync with the file system or may contain stale matches. Do you want to refresh those files and search again?
+SearchAgainConfirmationDialog.outofsync.label=Files out of sync:
+SearchAgainConfirmationDialog.stale.message=Some resources may contain stale matches. Do you want to search again?
+SearchAgainConfirmationDialog.stale.label=Files with stale matches:
+SearchAgainConfirmationDialog.title=Replace
+
+WorkInProgressPreferencePage.newsearch.label=Use new search view
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchResultView.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchResultView.java
index 5decb32..8fc92a4 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchResultView.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchResultView.java
@@ -35,8 +35,8 @@
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IMemento;
 import org.eclipse.ui.IViewSite;
-import org.eclipse.ui.IWorkbenchActionConstants;
 import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.actions.ActionFactory;
 import org.eclipse.ui.help.WorkbenchHelp;
 import org.eclipse.ui.part.CellEditorActionHandler;
 import org.eclipse.ui.part.ViewPart;
@@ -156,7 +156,7 @@
 		actionBars.updateActionBars();
 		
 		// Add selectAll action handlers.
-		actionBars.setGlobalActionHandler(IWorkbenchActionConstants.SELECT_ALL, fSelectAllAction);
+		actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), fSelectAllAction);
 	}
 
 	private void fillToolBar(IToolBarManager tbm) {
@@ -319,7 +319,7 @@
 	 * Implements method from ISearchResultView
 	 */
 	public void searchFinished() {
-		SearchManager.getDefault().setCurrentResults(new ArrayList(fResponse.values()));
+		SearchManager.getDefault().searchFinished(new ArrayList(fResponse.values()));
 		fResponse= null;
 	}
 }
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchResultViewer.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchResultViewer.java
index 1b3cfca..d9e07df 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchResultViewer.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/SearchResultViewer.java
@@ -53,8 +53,8 @@
 
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IMemento;
-import org.eclipse.ui.IWorkbenchActionConstants;
 import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
 import org.eclipse.ui.actions.ActionGroup;
 import org.eclipse.ui.help.WorkbenchHelp;
 
@@ -133,7 +133,7 @@
 		fSearchAgainAction.setEnabled(hasSearchOperation);
 		fSortDropDownAction = new SortDropDownAction(this);
 		fSortDropDownAction.setEnabled(getItemCount() > 0);
-		fSearchDropDownAction= new SearchDropDownAction(this);
+		fSearchDropDownAction= new SearchDropDownAction();
 		fSearchDropDownAction.setEnabled(hasSearch);
 		fCopyToClipboardAction= new CopyToClipboardAction(this);
 
@@ -171,8 +171,8 @@
 		
 		IActionBars actionBars= fOuterPart.getViewSite().getActionBars();
 		if (actionBars != null) {
-			actionBars.setGlobalActionHandler(IWorkbenchActionConstants.NEXT, fShowNextResultAction);
-			actionBars.setGlobalActionHandler(IWorkbenchActionConstants.PREVIOUS, fShowPreviousResultAction);
+			actionBars.setGlobalActionHandler(ActionFactory.NEXT.getId(), fShowNextResultAction);
+			actionBars.setGlobalActionHandler(ActionFactory.PREVIOUS.getId(), fShowPreviousResultAction);
 		}
 
 		fOuterPart.getSite().setSelectionProvider(this);
@@ -270,7 +270,7 @@
 		updateTitle();
 		enableActions();
 		if (getItemCount() > 0)
-			selectResult(getTable(), 0);
+			selectResult(0);
 
 		WorkbenchHelp.setHelp(getControl(), SearchPlugin.getDefault().getSearchViewHelpContextId());
 	}
@@ -483,7 +483,7 @@
 			}
 			fMarkerToShow= 0;
 			entry= (SearchResultViewEntry)getTable().getItem(index).getData();
-			selectResult(table, index);
+			selectResult(index);
 		}
 		entry.setSelectedMarkerIndex(fMarkerToShow);
 		openCurrentSelection();
@@ -520,7 +520,7 @@
 			}
 			entry= (SearchResultViewEntry)getTable().getItem(index).getData();
 			fMarkerToShow= entry.getMatchCount() - 1;
-			selectResult(table, index);
+			selectResult(index);
 		}
 		entry.setSelectedMarkerIndex(fMarkerToShow);
 		openCurrentSelection();
@@ -533,7 +533,7 @@
 		return true;			
 	}
 		
-	private void selectResult(Table table, int index) {
+	private void selectResult(int index) {
 		fHandleSelectionChangedEvents= false;
 		Object element= getElementAt(index);
 		if (element != null)
@@ -580,7 +580,7 @@
 	 */
 	protected void clearTitle() {
 		String title= SearchMessages.getString("SearchResultView.title"); //$NON-NLS-1$
-		if (title == null || !title.equals(fOuterPart.getTitle()))
+		if (!title.equals(fOuterPart.getTitle()))
 			fOuterPart.setTitle(title);
 	}
 
@@ -718,4 +718,11 @@
 		getTable().setRedraw(true);
 	}
 
+	void handleAllSearchesRemoved() {
+		setContextMenuTarget(null);
+		setActionGroupFactory(null);
+		setInput(null);
+		fSearchDropDownAction.clear();
+	}
+
 }
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/WorkInProgressPreferencePage.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/WorkInProgressPreferencePage.java
new file mode 100644
index 0000000..c12e6ae
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/WorkInProgressPreferencePage.java
@@ -0,0 +1,51 @@
+/*
+ * Created on 18.11.2003
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+package org.eclipse.search.internal.ui;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * @author Administrator
+ *
+ * To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+public class WorkInProgressPreferencePage extends FieldEditorPreferencePage	implements IWorkbenchPreferencePage {
+
+	public WorkInProgressPreferencePage() {
+		super(GRID);
+		setPreferenceStore(SearchPlugin.getDefault().getPreferenceStore());
+	}
+	public static final String SEARCH_IN_BACKGROUND= "org.eclipse.search.newsearch"; //$NON-NLS-1$
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors()
+	 */
+	protected void createFieldEditors() {
+		BooleanFieldEditor boolEditor= new BooleanFieldEditor(
+				SEARCH_IN_BACKGROUND,
+				SearchMessages.getString("WorkInProgressPreferencePage.newsearch.label"),  //$NON-NLS-1$
+				getFieldEditorParent()
+				);
+		addField(boolEditor);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+	 */
+	public void init(IWorkbench workbench) {
+		// do nothing
+	}
+	public static boolean useNewSearch() {
+		IPreferenceStore store= SearchPlugin.getDefault().getPreferenceStore();
+		return store.getBoolean(SEARCH_IN_BACKGROUND);
+	}
+	
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileLabelProvider.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileLabelProvider.java
new file mode 100644
index 0000000..764e740
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileLabelProvider.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search.internal.ui.text;
+
+import java.text.MessageFormat;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.LabelProvider;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+
+
+public class FileLabelProvider extends LabelProvider {
+		
+	public static final int SHOW_LABEL= 1;
+	public static final int SHOW_LABEL_PATH= 2;
+	public static final int SHOW_PATH_LABEL= 3;
+	public static final int SHOW_PATH= 4;
+	
+	private static final String fgSeparatorFormat= "{0} - {1}";
+	
+	private WorkbenchLabelProvider fLabelProvider;
+	private ILabelDecorator fDecorator;
+		
+	private int fOrder;
+	private String[] fArgs= new String[2];
+
+	public FileLabelProvider(int orderFlag) {
+		fDecorator= PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator();
+		fLabelProvider= new WorkbenchLabelProvider();
+		fOrder= orderFlag;
+	}
+
+	public void setOrder(int orderFlag) {
+		fOrder= orderFlag;
+	}
+	
+	public String getText(Object element) {
+		if (!(element instanceof IResource))
+			return null; //$NON-NLS-1$
+
+		IResource resource= (IResource)element;
+		String text= null;
+
+		if (resource == null || !resource.exists())
+			text= "<removed resource>";
+		
+		else {
+			IPath path= resource.getFullPath().removeLastSegments(1);
+			if (path.getDevice() == null)
+				path= path.makeRelative();
+			if (fOrder == SHOW_LABEL || fOrder == SHOW_LABEL_PATH) {
+				text= fLabelProvider.getText(resource);
+				if (path != null && fOrder == SHOW_LABEL_PATH) {
+					fArgs[0]= text;
+					fArgs[1]= path.toString();
+					text= MessageFormat.format(fgSeparatorFormat, fArgs);
+				}
+			} else {
+				if (path != null)
+					text= path.toString();
+				else
+					text= ""; //$NON-NLS-1$
+				if (fOrder == SHOW_PATH_LABEL) {
+					fArgs[0]= text;
+					fArgs[1]= fLabelProvider.getText(resource);
+					text= MessageFormat.format(fgSeparatorFormat, fArgs);
+				}
+			}
+		}
+		
+		// Do the decoration
+		if (fDecorator != null) {
+			String decoratedText= fDecorator.decorateText(text, resource);
+		if (decoratedText != null)
+			return decoratedText;
+		}
+		return text;
+	}
+
+	public Image getImage(Object element) {
+		if (!(element instanceof IResource))
+			return null; //$NON-NLS-1$
+
+		IResource resource= (IResource)element;
+		Image image= fLabelProvider.getImage(resource);
+		if (fDecorator != null) {
+			Image decoratedImage= fDecorator.decorateImage(image, resource);
+			if (decoratedImage != null)
+				return decoratedImage;
+		}
+		return image;
+	}
+
+	public void dispose() {
+		super.dispose();
+		fLabelProvider.dispose();
+	}
+
+	public boolean isLabelProperty(Object element, String property) {
+		return fLabelProvider.isLabelProperty(element, property);
+	}
+
+	public void removeListener(ILabelProviderListener listener) {
+		super.removeListener(listener);
+		fLabelProvider.removeListener(listener);
+	}
+
+	public void addListener(ILabelProviderListener listener) {
+		super.addListener(listener);
+		fLabelProvider.addListener(listener);
+	}
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FilePresentationFactory.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FilePresentationFactory.java
new file mode 100644
index 0000000..3178667
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FilePresentationFactory.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search.internal.ui.text;
+
+import org.eclipse.ui.IViewPart;
+
+import org.eclipse.search2.ui.ISearchResultPresentation;
+import org.eclipse.search2.ui.text.IPresentationFactory;
+import org.eclipse.search2.ui.text.ISearchElementPresentation;
+
+/**
+ * @author Thomas Mäder
+ *
+ */
+public class FilePresentationFactory implements IPresentationFactory {
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search.ui.model.text.IPresentationFactory#createSearchResultPresentation(org.eclipse.search.ui.ISearchView)
+	 */
+	public ISearchResultPresentation createSearchResultPresentation(IViewPart view) {
+		return new FileSearchCategory();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search.ui.model.text.IPresentationFactory#createElementPresentation(org.eclipse.search.ui.ISearchView)
+	 */
+	public ISearchElementPresentation createElementPresentation(IViewPart view) {
+		return new FileUIAdapter(view);
+	}
+
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchCategory.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchCategory.java
new file mode 100644
index 0000000..c93087a
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchCategory.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search.internal.ui.text;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import org.eclipse.search2.ui.ISearchResult;
+import org.eclipse.search2.ui.ISearchResultPresentation;
+import org.eclipse.search2.ui.text.ITextSearchResult;
+
+/**
+ * @author Thomas Mäder
+ *
+ */
+public class FileSearchCategory implements ISearchResultPresentation {
+
+	public FileSearchCategory() {
+	}
+
+	public String getText(ISearchResult search) {
+		FileSearchDesription desc= (FileSearchDesription) search.getUserData();
+		return desc.getSearchString()+ " ( "+((ITextSearchResult)search).getMatchCount()+" Occurrences in "+desc.getScopeDescription() + " )";
+	}
+
+	public ImageDescriptor getImageDescriptor(ISearchResult search) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void dispose() {
+	}
+
+	public String getTooltip(ISearchResult search) {
+		return getText(search);
+	}
+
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchDesription.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchDesription.java
new file mode 100644
index 0000000..d48ff11
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileSearchDesription.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search.internal.ui.text;
+
+/**
+ * @author Thomas Mäder
+ *
+ */
+public class FileSearchDesription {
+	private String fSearchString;
+	private String fScopeDescription;
+
+	public FileSearchDesription(String searchString, String scopeDescription) {
+		super();
+		fSearchString= searchString;
+		fScopeDescription= scopeDescription;
+	}
+
+	public String getScopeDescription() {
+		return fScopeDescription;
+	}
+
+	public String getSearchString() {
+		return fSearchString;
+	}
+
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileUIAdapter.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileUIAdapter.java
new file mode 100644
index 0000000..57d4919
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/FileUIAdapter.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search.internal.ui.text;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search2.ui.text.ISearchElementPresentation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * @author Thomas Mäder
+ *
+ */
+public class FileUIAdapter implements ISearchElementPresentation {
+	private static final String PATH_ATTRIBUTE= "Path";
+	private static final String NAME_ATTRIBUTE= "Name";
+	private static final String[] FLAT_ATTRIBUTES= { PATH_ATTRIBUTE, NAME_ATTRIBUTE};
+	private static final String[] STRUCTURED_ATTRIBUTES= { NAME_ATTRIBUTE};
+	
+	private FileLabelProvider fLabelProvider;
+	private ActionGroup fActionGroup;
+
+	public FileUIAdapter(IViewPart view) {
+		fLabelProvider= new FileLabelProvider(FileLabelProvider.SHOW_PATH_LABEL);
+		fActionGroup= new NewTextSearchActionGroup(view);
+	}
+
+	public String getName() {
+		return "Files";
+	}
+
+	public void showMatch(Object element, int offset, int length) throws PartInitException {
+		IFile file= (IFile) element;
+		IWorkbenchPage page= SearchPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage();
+		IEditorPart editor= IDE.openEditor(page, file, true);
+		if (!(editor instanceof ITextEditor))
+			return;
+		ITextEditor textEditor= (ITextEditor) editor;
+		textEditor.selectAndReveal(offset, length);
+	}
+
+	public String[] getSortingAtributes(boolean flatMode) {
+		if (flatMode)
+			return FLAT_ATTRIBUTES;
+		else
+			return STRUCTURED_ATTRIBUTES;
+	}
+
+	public void setSortOrder(String[] attributeNames, boolean flatMode) {
+		if (!flatMode) {
+			fLabelProvider.setOrder(FileLabelProvider.SHOW_LABEL);
+		} else {
+			for (int i= 0; i < attributeNames.length; i++) {
+				if (attributeNames[i].equals(NAME_ATTRIBUTE)) {
+					fLabelProvider.setOrder(FileLabelProvider.SHOW_LABEL_PATH);
+					return;
+				} else if (attributeNames[i].equals(PATH_ATTRIBUTE)) {
+					fLabelProvider.setOrder(FileLabelProvider.SHOW_PATH_LABEL);
+					return;
+				}
+			}
+		}
+	}
+
+	public String getAttribute(Object underlyingElement, String attributeName) {
+		IResource resource= (IResource)underlyingElement;
+		if (PATH_ATTRIBUTE.equals(attributeName))
+			return resource.getFullPath().toString();
+		else if (NAME_ATTRIBUTE.equals(attributeName))
+			return resource.getName();
+		return "";
+	}
+
+	public void dispose() {
+		fLabelProvider.dispose();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search2.ui.text.ISearchElementPresentation#getImage(java.lang.Object)
+	 */
+	public Image getImage(Object element) {
+		return fLabelProvider.getImage(element);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search2.ui.text.ISearchElementPresentation#getText(java.lang.Object)
+	 */
+	public String getText(Object element) {
+		return fLabelProvider.getText(element);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search.ui.ISearchCategory#createActionGroup()
+	 */
+	public ActionGroup getActionGroup() {
+		return fActionGroup;
+	}
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/GotoMarkerAction.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/GotoMarkerAction.java
index 542bd34..5c7b954 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/GotoMarkerAction.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/GotoMarkerAction.java
@@ -22,6 +22,7 @@
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorRegistry;
 import org.eclipse.ui.IReusableEditor;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.PartInitException;
@@ -69,7 +70,7 @@
 		String editorId= null;
 		IEditorDescriptor desc= IDE.getDefaultEditor((IFile)resource);
 		if (desc == null)
-			editorId= SearchPlugin.getDefault().getWorkbench().getEditorRegistry().getDefaultEditor().getId();
+			editorId= SearchPlugin.getDefault().getWorkbench().getEditorRegistry().findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID).getId();
 		else
 			editorId= desc.getId();
 
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/NewTextSearchActionGroup.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/NewTextSearchActionGroup.java
new file mode 100644
index 0000000..056b04b
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/NewTextSearchActionGroup.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search.internal.ui.text;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.actions.OpenWithMenu;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
+
+import org.eclipse.search.ui.IContextMenuConstants;
+
+import org.eclipse.search.internal.ui.SearchMessages;
+
+/**
+ * Action group that adds the Text search actions to a context menu and
+ * the global menu bar.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 2.1
+ */
+class NewTextSearchActionGroup extends ActionGroup {
+
+	private ISelectionProvider fSelectionProvider;		
+	private IWorkbenchPage fPage;
+	private PropertyDialogAction fOpenPropertiesDialog;
+
+	public NewTextSearchActionGroup(IViewPart part) {
+		Assert.isNotNull(part);
+		IWorkbenchPartSite site= part.getSite();
+		fSelectionProvider= site.getSelectionProvider();
+		fPage= site.getPage();
+		fOpenPropertiesDialog= new PropertyDialogAction(site.getShell(), fSelectionProvider);
+
+		ISelection selection= fSelectionProvider.getSelection();
+
+		if (selection instanceof IStructuredSelection)
+			fOpenPropertiesDialog.selectionChanged((IStructuredSelection)selection);
+		else
+			fOpenPropertiesDialog.selectionChanged(selection);
+	}
+	
+	public void fillContextMenu(IMenuManager menu) {
+		// view must exist if we create a context menu for it.
+		
+		ISelection selection= getContext().getSelection();
+		if (selection instanceof IStructuredSelection) {
+			addOpenWithMenu(menu, (IStructuredSelection) selection);
+			if (fOpenPropertiesDialog != null && fOpenPropertiesDialog.isEnabled() && selection != null &&fOpenPropertiesDialog.isApplicableForSelection((IStructuredSelection) selection))
+				menu.appendToGroup(IContextMenuConstants.GROUP_PROPERTIES, fOpenPropertiesDialog);
+		}
+			
+	}
+	
+	private void addOpenWithMenu(IMenuManager menu, IStructuredSelection selection) {
+		if (selection == null || selection.size() != 1)
+			return;
+	
+		Object o= selection.getFirstElement();
+	
+		if (!(o instanceof IAdaptable))
+			return; 
+	
+		// Create menu
+		IMenuManager submenu= new MenuManager(SearchMessages.getString("OpenWithMenu.label")); //$NON-NLS-1$
+		submenu.add(new OpenWithMenu(fPage, (IAdaptable)o));
+	
+		// Add the submenu.
+		menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, submenu);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared in ActionGroup
+	 */
+	public void fillActionBars(IActionBars actionBar) {
+		super.fillActionBars(actionBar);
+		setGlobalActionHandlers(actionBar);
+	}
+	
+	private void setGlobalActionHandlers(IActionBars actionBars) {
+		actionBars.setGlobalActionHandler(IWorkbenchActionConstants.PROPERTIES, fOpenPropertiesDialog);		
+	}
+}	
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceAction.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceAction.java
index b0855cd..8bd9767 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceAction.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceAction.java
@@ -10,38 +10,38 @@
  *******************************************************************************/
 package org.eclipse.search.internal.ui.text;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.util.Assert;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.viewers.IStructuredContentProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.Viewer;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IStatus;
-
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchSite;
-import org.eclipse.ui.model.WorkbenchLabelProvider;
-import org.eclipse.ui.part.FileEditorInput;
-import org.eclipse.ui.texteditor.ITextEditor;
-
+import org.eclipse.search.internal.core.text.ITextSearchResultCollector;
 import org.eclipse.search.internal.ui.Search;
 import org.eclipse.search.internal.ui.SearchManager;
 import org.eclipse.search.internal.ui.SearchMessages;
 import org.eclipse.search.internal.ui.SearchResultViewEntry;
-import org.eclipse.search.internal.ui.util.ListDialog;
+import org.eclipse.search.internal.ui.util.ExceptionHandler;
+import org.eclipse.search.ui.SearchUI;
+import org.eclipse.ui.IWorkbenchSite;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
 
 /* package */ class ReplaceAction extends Action {
 	
@@ -68,157 +68,126 @@
 	}
 	
 	public void run() {
-		if (validateResources()) {
-			Search search= SearchManager.getDefault().getCurrentSearch();
-			IRunnableWithProgress operation= search.getOperation();
-			if (operation instanceof TextSearchOperation) {
-				ReplaceDialog dialog= new ReplaceDialog(fSite.getShell(), fElements, fSite.getWorkbenchWindow(), ((TextSearchOperation)operation).getPattern());
+		Search search= SearchManager.getDefault().getCurrentSearch();
+		IRunnableWithProgress operation= search.getOperation();
+		if (operation instanceof TextSearchOperation) {
+			if (validateResources((TextSearchOperation) operation)) {
+				ReplaceDialog dialog= new ReplaceDialog(fSite.getShell(), fElements, (TextSearchOperation)operation);
 				dialog.open();
-			} else {
-				MessageDialog.openError(fSite.getShell(), getDialogTitle(), SearchMessages.getString("ReplaceAction.error.only_on_text_search")); //$NON-NLS-1$
 			}
+		} else {
+			MessageDialog.openError(fSite.getShell(), getDialogTitle(), SearchMessages.getString("ReplaceAction.error.only_on_text_search")); //$NON-NLS-1$
 		}
 	}
 	
-	private boolean validateResources() {
-		List modifiedFiles= new ArrayList();
-		List openedFilesInNonTextEditor= new ArrayList();
-		List notFiles= new ArrayList();
-		IWorkbenchPage activePage =  fSite.getWorkbenchWindow().getActivePage();
-
-		for (Iterator iter = fElements.iterator(); iter.hasNext();) {
-			SearchResultViewEntry entry= (SearchResultViewEntry) iter.next();
-			IResource resource= entry.getResource();
-			if (resource instanceof IFile) {
-				IFile file= (IFile)resource;
-				if (file.getModificationStamp() != entry.getModificationStamp() || !file.isSynchronized(IResource.DEPTH_ZERO)) {
-					modifiedFiles.add(resource);
-				} else if (activePage != null) {
-					IEditorPart part= activePage.findEditor(new FileEditorInput(file));
-					if (part != null && !(part instanceof ITextEditor))
-						openedFilesInNonTextEditor.add(file);
+	private boolean validateResources(final TextSearchOperation operation) {
+		final List outOfDateEntries= new ArrayList();
+		for (Iterator elements = fElements.iterator(); elements.hasNext();) {
+			SearchResultViewEntry entry = (SearchResultViewEntry) elements.next();
+			if (isOutOfDate(entry)) {
+				outOfDateEntries.add(entry);
+			}
+		}
+	
+		final List outOfSyncEntries= new ArrayList();
+		for (Iterator elements = fElements.iterator(); elements.hasNext();) {
+			SearchResultViewEntry entry = (SearchResultViewEntry) elements.next();
+			if (isOutOfSync(entry)) {
+				outOfSyncEntries.add(entry);
+			}
+		}
+		
+		if (outOfDateEntries.size() > 0 || outOfSyncEntries.size() > 0) {
+			if (askForResearch(outOfDateEntries, outOfSyncEntries)) {
+				ProgressMonitorDialog pmd= new ProgressMonitorDialog(fSite.getShell());
+				try {
+					pmd.run(true, true, new WorkspaceModifyOperation(null) {
+						protected void execute(IProgressMonitor monitor) throws CoreException {
+							research(monitor, outOfDateEntries, operation);
+						}
+					});
+					return true;
+				} catch (InvocationTargetException e) {
+					ExceptionHandler.handle(e, fSite.getShell(), SearchMessages.getString("ReplaceAction.label"), SearchMessages.getString("ReplaceAction.research.error")); //$NON-NLS-1$ //$NON-NLS-2$
+				} catch (InterruptedException e) {
+					// canceled
 				}
-			} else {
-				if (resource != null)
-					notFiles.add(resource);
 			}
-		}
-		if (!modifiedFiles.isEmpty()) {
-			showModifiedFileDialog(modifiedFiles);
-			return false;
-		}
-		if (!openedFilesInNonTextEditor.isEmpty()) {
-			showOpenedFileDialog(openedFilesInNonTextEditor);
-			return false;
-		}
-		if (!notFiles.isEmpty()) {
-			showNotFilesDialog(openedFilesInNonTextEditor);
-			return false;
-		}
-		IFile[] readOnlyFiles= getReadOnlyFiles();
-		if (readOnlyFiles.length == 0)
-			return true;
-		Map currentStamps= createModificationStampMap(readOnlyFiles);
-		IStatus status= ResourcesPlugin.getWorkspace().validateEdit(readOnlyFiles, fSite.getShell());
-		if (!status.isOK()) {
-			ErrorDialog.openError(fSite.getShell(), getDialogTitle(), SearchMessages.getString("ReplaceAction.error.unable_to_perform"), status); //$NON-NLS-1$
-			return false;
-		}
-		modifiedFiles= new ArrayList();
-		Map newStamps= createModificationStampMap(readOnlyFiles);
-		for (Iterator iter= currentStamps.keySet().iterator(); iter.hasNext();) {
-			IFile file= (IFile) iter.next();
-			if (! currentStamps.get(file).equals(newStamps.get(file))) {
-				modifiedFiles.add(file);
-			}
-		}
-		if (!modifiedFiles.isEmpty()) {
-			showModifiedFileDialog(modifiedFiles);
 			return false;
 		}
 		return true;
 	}
 
-	private void showModifiedFileDialog(List modifiedFiles) {
-		String message= (modifiedFiles.size() == 1
-			? SearchMessages.getString("ReplaceAction.error.changed_file")  //$NON-NLS-1$
-			: SearchMessages.getString("ReplaceAction.error.changed_files"));  //$NON-NLS-1$
-		ListDialog dialog= new ListDialog(fSite.getShell(), modifiedFiles, getDialogTitle(), 
-			message,
-			new IStructuredContentProvider() {
-				public Object[] getElements(Object inputElement) {
-					return ((List)inputElement).toArray();
-				}
-				public void dispose() {
-				}
-				public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-				}
-			}, 
-			new WorkbenchLabelProvider());
-		dialog.setCreateCancelButton(false);
-		dialog.open();
-	}
-	
-	private IFile[] getReadOnlyFiles() {
-		List result= new ArrayList();
-		for (Iterator iter = fElements.iterator(); iter.hasNext();) {
-			IResource resource= ((SearchResultViewEntry) iter.next()).getResource();
-			if (resource instanceof IFile && resource.isReadOnly())
-				result.add(resource);
+	private void research(IProgressMonitor monitor, List outOfDateEntries, TextSearchOperation operation) throws CoreException {
+		IStatus status= null;
+		for (Iterator elements = outOfDateEntries.iterator(); elements.hasNext();) {
+			SearchResultViewEntry entry = (SearchResultViewEntry) elements.next();
+				status = research(operation, monitor, entry);
+			if (status != null && !status.isOK()) {
+				throw new CoreException(status);
+			}
 		}
-		return (IFile[]) result.toArray(new IFile[result.size()]);
 	}
-	
-	private static Map createModificationStampMap(IFile[] files){
-		Map map= new HashMap();
-		for (int i= 0; i < files.length; i++) {
-			IFile file= files[i];
-			map.put(file, new Long(file.getModificationStamp()));
-		}
-		return map;
+
+	private boolean askForResearch(List outOfDateEntries, List outOfSyncEntries) {
+		SearchAgainConfirmationDialog dialog= new SearchAgainConfirmationDialog(fSite.getShell(), outOfSyncEntries, outOfDateEntries);
+		return dialog.open() == IDialogConstants.OK_ID;
 	}
-	
+
 	private String getDialogTitle() {
 		return SearchMessages.getString("ReplaceAction.dialog.title"); //$NON-NLS-1$
-	}
-	
-	private void showOpenedFileDialog(List openedFilesInNonTextEditor) {
-		String message= (openedFilesInNonTextEditor.size() == 1
-			? SearchMessages.getString("ReplaceAction.error.opened_file")  //$NON-NLS-1$
-			: SearchMessages.getString("ReplaceAction.error.opened_files"));  //$NON-NLS-1$
-		ListDialog dialog= new ListDialog(fSite.getShell(), openedFilesInNonTextEditor, getDialogTitle(), 
-			message,
-			new IStructuredContentProvider() {
-				public Object[] getElements(Object inputElement) {
-					return ((List)inputElement).toArray();
-				}
-				public void dispose() {
-				}
-				public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-				}
-			}, 
-			new WorkbenchLabelProvider());
-		dialog.setCreateCancelButton(false);
-		dialog.open();
-	}
-	
-	private void showNotFilesDialog(List notFiles) {
-		String message= (notFiles.size() == 1
-			? SearchMessages.getString("ReplaceAction.error.not_file")  //$NON-NLS-1$
-			: SearchMessages.getString("ReplaceAction.error.not_files"));  //$NON-NLS-1$
-		ListDialog dialog= new ListDialog(fSite.getShell(), notFiles, getDialogTitle(), 
-			message,
-			new IStructuredContentProvider() {
-				public Object[] getElements(Object inputElement) {
-					return ((List)inputElement).toArray();
-				}
-				public void dispose() {
-				}
-				public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-				}
-			}, 
-			new WorkbenchLabelProvider());
-		dialog.setCreateCancelButton(false);
-		dialog.open();
 	}		
+	
+	private boolean isOutOfDate(SearchResultViewEntry entry) {
+		IResource resource= entry.getResource();
+		if (entry.getModificationStamp() != resource.getModificationStamp())
+			return true;
+		ITextFileBufferManager bm= FileBuffers.getTextFileBufferManager();
+		ITextFileBuffer fb= bm.getTextFileBuffer(resource.getFullPath());
+		if (fb != null && fb.isDirty())
+			return true;
+		return false;
+	}
+
+	private boolean isOutOfSync(SearchResultViewEntry entry) {
+		return !entry.getResource().isSynchronized(IResource.DEPTH_ZERO); 
+	}
+		
+	private IStatus research(TextSearchOperation operation, final IProgressMonitor monitor, SearchResultViewEntry entry) throws CoreException {
+		List markers= new ArrayList();
+		markers.addAll(entry.getMarkers());
+		operation.searchInFile((IFile) entry.getResource(), new ITextSearchResultCollector() {
+			public IProgressMonitor getProgressMonitor() {
+				return monitor;
+			}
+			
+			public void aboutToStart() {
+			}
+			
+			public void accept(IResourceProxy proxy, String line, int start, int length, int lineNumber) throws CoreException {
+				IFile file= (IFile)proxy.requestResource();
+				if (start < 0 || length < 1)
+					return;
+				IMarker marker= file.createMarker(SearchUI.SEARCH_MARKER);
+				HashMap attributes= new HashMap(4);
+				attributes.put(SearchUI.LINE, line);
+				attributes.put(IMarker.CHAR_START, new Integer(start));
+				attributes.put(IMarker.CHAR_END, new Integer(start + length));
+				attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber));
+				marker.setAttributes(attributes);
+			}
+			
+			public void done(){
+			}
+		});
+		IStatus status = operation.getStatus();
+		if (status == null || status.isOK()) {
+			for (Iterator markerIter = markers.iterator(); markerIter.hasNext();) {
+				IMarker marker = (IMarker) markerIter.next();
+				marker.delete();
+			}
+		}
+		return status;
+	}
+	
 }
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog.java
index 6603688..a967c50 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceDialog.java
@@ -10,20 +10,39 @@
  *******************************************************************************/
 package org.eclipse.search.internal.ui.text;
 
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceDescription;
-import org.eclipse.core.resources.IncrementalProjectBuilder;
-import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.search.internal.ui.SearchMessages;
+import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search.internal.ui.SearchResultView;
+import org.eclipse.search.internal.ui.SearchResultViewEntry;
+import org.eclipse.search.internal.ui.SearchResultViewer;
+import org.eclipse.search.internal.ui.util.ExtendedDialogWindow;
+import org.eclipse.search.ui.SearchUI;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -32,348 +51,624 @@
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.Text;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.Position;
-import org.eclipse.jface.util.Assert;
-
 import org.eclipse.ui.IEditorDescriptor;
-import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IReusableEditor;
 import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.actions.GlobalBuildAction;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
 import org.eclipse.ui.ide.IDE;
 import org.eclipse.ui.part.FileEditorInput;
-import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel;
-import org.eclipse.ui.texteditor.IDocumentProvider;
 import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.MarkerUtilities;
 
-import org.eclipse.search.ui.ISearchResultView;
-
-import org.eclipse.search.internal.ui.SearchMessages;
-import org.eclipse.search.internal.ui.SearchPlugin;
-import org.eclipse.search.internal.ui.SearchResultView;
-import org.eclipse.search.internal.ui.SearchResultViewEntry;
-import org.eclipse.search.internal.ui.util.ExceptionHandler;
-
-public class ReplaceDialog extends Dialog {
-
-	private static final int REPLACE_NEXT= IDialogConstants.CLIENT_ID;
-	private static final int REPLACE= IDialogConstants.CLIENT_ID + 1;
-	private static final int NEXT= IDialogConstants.CLIENT_ID + 2;
-
-	private String fSearchPattern;
-
-	private IWorkbenchWindow fWindow;
-	private boolean fAutobuild;
-	private boolean fFatalError;
-	
-	// UI
-	private Text fTextField;
-	private Button fSaveButton;
-	private Button fReplaceNextButton;
-	private Button fReplaceButton;
-	private Button fNextButton;
-
+class ReplaceDialog extends ExtendedDialogWindow {
 		
-	private boolean fSaved;
-	private ITextEditor fEditor;
-	private boolean fCloseEditor;
-	private IDocument fDocument;
-	private AbstractMarkerAnnotationModel fAnnotationModel;
-
-	
-	private List fElements;
-	private int fElementIndex;
-	private SearchResultViewEntry fCurrentEntry;
-	private List fCurrentMarkers;
-	private int fMarkerIndex;
-	private IMarker fCurrentMatch;
-	
-	private static class MarkerNotPresentableException extends Exception {
-		private IFile fFile;
-		MarkerNotPresentableException(IFile file) {
-			fFile= file;
+	/**
+	 * A class wrapping a resource marker, adding a position.
+	 */
+	private static class ReplaceMarker {
+		private Position fPosition;
+		private IMarker fMarker;
+		
+		ReplaceMarker(IMarker marker) {
+			fMarker= marker;
 		}
+		
 		public IFile getFile() {
-			return fFile;
+			return (IFile)fMarker.getResource();
+		}
+		
+		public void deletePosition(IDocument doc) {
+			if (fPosition != null) {
+				MarkerUtilities.setCharStart(fMarker, fPosition.getOffset());
+				MarkerUtilities.setCharEnd(fMarker, fPosition.getOffset()+fPosition.getLength());
+				doc.removePosition(fPosition);
+				fPosition= null;
+			}
+		}
+		
+		public void delete() throws CoreException {
+			fMarker.delete();
+		}
+		
+		public void createPosition(IDocument doc) throws BadLocationException {
+			if (fPosition == null) {
+				int charStart= MarkerUtilities.getCharStart(fMarker);
+				fPosition= new Position(charStart, MarkerUtilities.getCharEnd(fMarker)-charStart);
+				doc.addPosition(fPosition);
+			}
+		}
+		
+		public int getLength() {
+			if (fPosition != null)
+				return fPosition.getLength();
+			return MarkerUtilities.getCharEnd(fMarker)-MarkerUtilities.getCharStart(fMarker);
+		}
+		
+		public int getOffset() {
+			if (fPosition != null)
+				return fPosition.getOffset();
+			return MarkerUtilities.getCharStart(fMarker);
 		}
 	}
 	
-	protected ReplaceDialog(Shell parentShell, List elements, IWorkbenchWindow window, String searchPattern) {
-		super(parentShell);
-		Assert.isNotNull(elements);
-		Assert.isNotNull(searchPattern);
-		fElements= new ArrayList(elements);
-		Assert.isNotNull(window);
-		fWindow= window;
-		fSearchPattern= searchPattern;
+	private abstract static class ReplaceOperation extends WorkspaceModifyOperation {
+		public void execute(IProgressMonitor monitor) throws InvocationTargetException {
+			try {
+				doReplace(monitor);
+			} catch (BadLocationException e) {
+				throw new InvocationTargetException(e);
+			} catch (CoreException e) {
+				throw new InvocationTargetException(e);
+			} catch (IOException e) {
+				throw new InvocationTargetException(e);
+			}
+		}
+		
+		protected abstract void doReplace(IProgressMonitor pm) throws BadLocationException, CoreException, IOException;
 	}
-
+		
+	// various widget related constants
+	private static final int REPLACE= IDialogConstants.CLIENT_ID + 1;
+	private static final int REPLACE_ALL_IN_FILE= IDialogConstants.CLIENT_ID + 2;
+	private static final int REPLACE_ALL= IDialogConstants.CLIENT_ID + 3;
+	private static final int SKIP= IDialogConstants.CLIENT_ID + 4;
+	private static final int SKIP_FILE= IDialogConstants.CLIENT_ID + 5;
+	private static final int SKIP_ALL= IDialogConstants.CLIENT_ID + 6;
+	
+	// Widgets
+	private Text fTextField;
+	private Button fReplaceButton;
+	private Button fReplaceAllInFileButton;
+	private Button fReplaceAllButton;
+	private Button fSkipButton;
+	private Button fSkipFileButton;
+	
+	private List fMarkers;
+	private TextSearchOperation fOperation;
+	private boolean fSkipReadonly= false;
+	
+	// reuse editors stuff
+	private IReusableEditor fEditor;
+	
+	protected ReplaceDialog(Shell parentShell, List entries, TextSearchOperation operation) {
+		super(parentShell);
+		Assert.isNotNull(entries);
+		Assert.isNotNull(operation);
+		fMarkers= new ArrayList();
+		initializeMarkers(entries);
+		fOperation= operation;
+	}
+	
+	private void initializeMarkers(List entries) {
+		for (Iterator elements= entries.iterator(); elements.hasNext(); ) {
+			SearchResultViewEntry element= (SearchResultViewEntry)elements.next();
+			List markerList= element.getMarkers();
+			for (Iterator markers= markerList.iterator(); markers.hasNext(); ) {
+				IMarker marker= (IMarker)markers.next();
+				fMarkers.add(new ReplaceMarker(marker));
+			}
+		}
+	}
+	
+	// widget related stuff -----------------------------------------------------------
 	public void create() {
 		super.create();
 		Shell shell= getShell();
 		shell.setText(getDialogTitle());
-		updateButtons();
+		gotoCurrentMarker();
+		enableButtons();
 	}
-
-	public int open() {
-		IWorkspace workspace = ResourcesPlugin.getWorkspace();
-		fAutobuild= workspace.isAutoBuilding();
-		if (fAutobuild) {
-			IWorkspaceDescription description= workspace.getDescription();
-			description.setAutoBuilding(false);
-			try {
-				workspace.setDescription(description);
-			} catch (CoreException e) {
-				ExceptionHandler.handle(e, getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.auto_building")); //$NON-NLS-1$
-				fFatalError= true;
-			}
-		}
-		try {
-			fCurrentMatch= getNextMatch(false);
-		} catch (CoreException e) {
-			ExceptionHandler.handle(e, getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.no_matches")); //$NON-NLS-1$
-			fFatalError= true;
-		} catch (MarkerNotPresentableException e) {
-			handleMarkerNotPresentableException(e);
-			fFatalError= true;
-		}
-		return super.open();
-	}
-
-	public boolean close() {
-		boolean result= super.close();
-		restoreAutoBuildState();
-		return result;
-	}
-
-	protected Control createDialogArea(Composite parent) {
-		Composite result= (Composite)super.createDialogArea(parent);
-		GridLayout layout= (GridLayout)result.getLayout();
+		
+	protected Control createPageArea(Composite parent) {
+		Composite result= new Composite(parent, SWT.NULL);
+		GridLayout layout= new GridLayout();
+		result.setLayout(layout);
 		layout.numColumns= 2;
 		
+		layout.marginHeight =
+			convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+		layout.marginWidth =
+			convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+		layout.verticalSpacing =
+			convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+		layout.horizontalSpacing =
+			convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+		
 		initializeDialogUnits(result);
 		
 		Label label= new Label(result, SWT.NONE);
 		label.setText(SearchMessages.getString("ReplaceDialog.replace_label")); //$NON-NLS-1$
-		
-		CLabel clabel= new CLabel(result, SWT.NONE);
-		clabel.setText(fSearchPattern);
+		Text clabel= new Text(result, SWT.BORDER);
+		clabel.setEnabled(false);
+		clabel.setText(fOperation.getPattern());
 		GridData gd= new GridData(GridData.FILL_HORIZONTAL);
 		gd.widthHint= convertWidthInCharsToPixels(50);
 		clabel.setLayoutData(gd);
 		
+		
 		label= new Label(result, SWT.NONE);
 		label.setText(SearchMessages.getString("ReplaceDialog.with_label")); //$NON-NLS-1$
-		
 		fTextField= new Text(result, SWT.BORDER);
 		gd= new GridData(GridData.FILL_HORIZONTAL);
 		gd.widthHint= convertWidthInCharsToPixels(50);
 		fTextField.setLayoutData(gd);
 		fTextField.setFocus();
 		
-		fSaveButton= new Button(result, SWT.CHECK);
-		fSaveButton.setText(SearchMessages.getString("ReplaceDialog.save_changes")); //$NON-NLS-1$
-		fSaveButton.setSelection(true);
-		gd= new GridData(GridData.FILL_HORIZONTAL);
-		gd.horizontalSpan= 2;
-		fSaveButton.setLayoutData(gd);
+		
+		new Label(result, SWT.NONE);
+		Button replaceWithRegex= new Button(result, SWT.CHECK);
+		replaceWithRegex.setText(SearchMessages.getString("ReplaceDialog.isRegex.label")); //$NON-NLS-1$
+		replaceWithRegex.setEnabled(false);
+		replaceWithRegex.setSelection(false);
 		
 		applyDialogFont(result);
 		return result;
 	}
-
+	
 	protected void createButtonsForButtonBar(Composite parent) {
-		fReplaceNextButton= createButton(parent, REPLACE_NEXT, SearchMessages.getString("ReplaceDialog.replace_next"), false); //$NON-NLS-1$
-		fReplaceButton= createButton(parent, REPLACE, SearchMessages.getString("ReplaceDialog.replace"), false); //$NON-NLS-1$
-		fNextButton= createButton(parent, NEXT, SearchMessages.getString("ReplaceDialog.next"), false); //$NON-NLS-1$
-		createButton(parent, IDialogConstants.CANCEL_ID, SearchMessages.getString("ReplaceDialog.close"), false); //$NON-NLS-1$
-	}
+		fReplaceButton= createButton(parent, REPLACE, SearchMessages.getString("ReplaceDialog.replace"), true); //$NON-NLS-1$
+		fReplaceAllInFileButton= createButton(parent, REPLACE_ALL_IN_FILE, SearchMessages.getString("ReplaceDialog.replaceAllInFile"), false); //$NON-NLS-1$
 
+		Label filler= new Label(parent, SWT.NONE);
+		filler.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
+		
+		fReplaceAllButton= createButton(parent, REPLACE_ALL, SearchMessages.getString("ReplaceDialog.replaceAll"), false); //$NON-NLS-1$
+		fSkipButton= createButton(parent, SKIP, SearchMessages.getString("ReplaceDialog.skip"), false); //$NON-NLS-1$
+		fSkipFileButton= createButton(parent, SKIP_FILE, SearchMessages.getString("ReplaceDialog.skipFile"), false); //$NON-NLS-1$
+
+		filler= new Label(parent, SWT.NONE);
+		filler.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
+		super.createButtonsForButtonBar(parent);
+		((GridLayout)parent.getLayout()).numColumns= 4;
+	}
+	
 	protected Point getInitialLocation(Point initialSize) {
 		SearchResultView view= (SearchResultView)SearchPlugin.getSearchResultView();
 		if (view == null)
 			return super.getInitialLocation(initialSize);
-		Point result= new Point(0,0);
+		Point result= new Point(0, 0);
 		Control control= view.getViewer().getControl();
 		Point size= control.getSize();
 		Point location= control.toDisplay(control.getLocation());
 		result.x= Math.max(0, location.x + size.x - initialSize.x);
-		result.y= Math.max(0, location.y + size. y - initialSize.y);
+		result.y= Math.max(0, location.y + size.y - initialSize.y);
 		return result;
 	}
-
+	
+	private void enableButtons() {
+		fSkipButton.setEnabled(hasNextMarker());
+		fSkipFileButton.setEnabled(hasNextFile());
+		fReplaceButton.setEnabled(canReplace());
+		fReplaceAllInFileButton.setEnabled(canReplace());
+		fReplaceAllButton.setEnabled(canReplace());
+	}
+	
 	protected void buttonPressed(int buttonId) {
+		final String replaceText= fTextField.getText();
 		try {
-			boolean save= fSaveButton.getSelection();
-			String text= fTextField.getText();
-			switch(buttonId) {
-				case REPLACE_NEXT:
-					replace(fCurrentMatch, text, save);
-					fCurrentMatch= getNextMatch(save);
+			switch (buttonId) {
+				case SKIP :
+					skip();
 					break;
-				case REPLACE:
-					replace(fCurrentMatch, text, save);
-					fCurrentMatch= null;
+				case SKIP_FILE :
+					skipFile();
 					break;
-				case NEXT:
-					fCurrentMatch= getNextMatch(save);
+				case REPLACE :
+					run(false, true, new ReplaceOperation() {
+					protected void doReplace(IProgressMonitor pm) throws BadLocationException, CoreException {
+						replace(pm, replaceText);
+					}
+				});
+					if (hasNextMarker())
+						gotoCurrentMarker();
 					break;
-				case IDialogConstants.CANCEL_ID:
-					saveEditor(save);
+				case REPLACE_ALL_IN_FILE :
+					run(false, true, new ReplaceOperation() {
+					protected void doReplace(IProgressMonitor pm) throws BadLocationException, CoreException {
+						replaceInFile(pm, replaceText);
+						
+					}
+				});
+					if (hasNextFile())
+						gotoCurrentMarker();
 					break;
+				case REPLACE_ALL :
+					run(false, true, new ReplaceOperation() {
+					protected void doReplace(IProgressMonitor pm) throws BadLocationException, CoreException {
+						replaceAll(pm, replaceText);
+					}
+				});
+					if (hasNextFile())
+						gotoCurrentMarker();
+					break;
+				default :
+					{
+					super.buttonPressed(buttonId);
+					return;
+				}
 			}
-		} catch (CoreException e) {
-			ExceptionHandler.handle(e, getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.unexpected_exception")); //$NON-NLS-1$
-			fFatalError= true;
-		} catch (BadLocationException e) {
-			MessageDialog.openError(getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.different_content")); //$NON-NLS-1$
-			fFatalError= true;
-		} catch (MarkerNotPresentableException e) {
-			handleMarkerNotPresentableException(e);
-			fFatalError= true;
+		} catch (InvocationTargetException e) {
+			SearchPlugin.log(e);
+			String message= SearchMessages.getFormattedString("ReplaceDialog.error.unable_to_replace", getCurrentMarker().getFile().getName()); //$NON-NLS-1$
+			MessageDialog.openError(getParentShell(), getDialogTitle(), message);
+		} catch (InterruptedException e) {
+			// means operation canceled
 		}
-		updateButtons();
-		super.buttonPressed(buttonId);
+		if (!hasNextMarker() && !hasNextFile() && !canReplace())
+			close();
+		else {
+			enableButtons();
+		}
 	}
 	
-	private void replace(IMarker source, String text, boolean save) throws CoreException, BadLocationException {
-		Position position= fAnnotationModel.getMarkerPosition(source);
-		fDocument.replace(position.getOffset(), position.getLength(), text);
-		SearchPlugin.getWorkspace().deleteMarkers(new IMarker[] {source});
+	private ReplaceMarker getCurrentMarker() {
+		return (ReplaceMarker)fMarkers.get(0);
 	}
 	
-	private boolean hasNextMatch() {
-		if (fCurrentMarkers != null)
-			return true;
-		return fElementIndex < fElements.size();
+	private void replace(IProgressMonitor pm, String replacementText) throws BadLocationException, CoreException {
+		ReplaceMarker marker= getCurrentMarker();
+		pm.beginTask(SearchMessages.getString("ReplaceDialog.task.replace"), 10); //$NON-NLS-1$
+		replaceInFile(pm, marker.getFile(), replacementText, new ReplaceMarker[]{marker});
 	}
 	
-	private IMarker getNextMatch(boolean save) throws CoreException, MarkerNotPresentableException {
-		if (fCurrentMarkers == null) {
-			if (fElementIndex >= fElements.size())
-				return null;
-			saveEditor(save);
-			fCurrentEntry= (SearchResultViewEntry)fElements.get(fElementIndex++);
-			fCurrentMarkers= new ArrayList(fCurrentEntry.getMarkers());
-			fMarkerIndex= 0;
-		}
-		IMarker result= (IMarker)fCurrentMarkers.get(fMarkerIndex);
-		if (fEditor == null) {
-			IWorkbenchPage activePage = fWindow.getActivePage();
-			int openEditors= activePage.getEditorReferences().length;
-			
-			fEditor= openFile(result, activePage);
-			IDE.gotoMarker(fEditor, result);
-			IDocumentProvider provider= fEditor.getDocumentProvider();
-			IEditorInput input = fEditor.getEditorInput();
-			fDocument= provider.getDocument(input);
-			fAnnotationModel= (AbstractMarkerAnnotationModel)provider.getAnnotationModel(input);
-			fCloseEditor= openEditors < activePage.getEditorReferences().length;
-		} else {
-			IDE.gotoMarker(fEditor, result);
-		}
-		if (fMarkerIndex == fCurrentMarkers.size() - 1) {
-			fCurrentMarkers= null;
-		} else {
-			fMarkerIndex++;
-		}
-		return result;
+	private void replaceInFile(IProgressMonitor pm, String replacementText) throws BadLocationException, CoreException {
+		ReplaceMarker firstMarker= getCurrentMarker();
+		ReplaceMarker[] markers= collectMarkers(firstMarker.getFile());
+		pm.beginTask(SearchMessages.getFormattedString("ReplaceDialog.task.replaceInFile", firstMarker.getFile().getFullPath().toOSString()), 4); //$NON-NLS-1$
+		replaceInFile(pm, firstMarker.getFile(), replacementText, markers);
 	}
-
-	private ITextEditor openFile(IMarker marker, IWorkbenchPage activePage) throws MarkerNotPresentableException, PartInitException {
-		IFile markerFile= marker.getResource() instanceof IFile ? (IFile)marker.getResource() : null;
-		if (markerFile == null)
-			throw new MarkerNotPresentableException(null);
-			
-		String currentEditorId= null;
-		IEditorDescriptor desc= IDE.getDefaultEditor(markerFile);
-		if (desc != null)
-			currentEditorId= desc.getId();
+	
+	private void replaceAll(IProgressMonitor pm, String replacementText) throws BadLocationException, CoreException {
+		int resourceCount= countResources();
+		pm.beginTask(SearchMessages.getString("ReplaceDialog.task.replace.replaceAll"), resourceCount); //$NON-NLS-1$
+		while (fMarkers.size() > 0) {
+			replaceInFile(new SubProgressMonitor(pm, 1, 0), replacementText);
+		}
+		pm.done();
+	}
+	
+	private void replaceInFile(final IProgressMonitor pm, final IFile file, final String replacementText, final ReplaceMarker[] markers) throws BadLocationException, CoreException {
+		if (pm.isCanceled())
+			throw new OperationCanceledException();
+		doReplaceInFile(pm, file, replacementText, markers);
+	}
+	
+	private void doReplaceInFile(IProgressMonitor pm, IFile file, String replacementText, final ReplaceMarker[] markers) throws BadLocationException, CoreException {
 		try {
-			IEditorPart result= activePage.openEditor(new FileEditorInput(markerFile), "org.eclipse.ui.DefaultTextEditor", false); //$NON-NLS-1$
-			if (!(result instanceof ITextEditor))
-				throw new MarkerNotPresentableException(markerFile);
-			return (ITextEditor)result;
-		} finally {
-			if (currentEditorId != null)
-				IDE.setDefaultEditor(markerFile, currentEditorId);
-		}
-	}
-
-	private void saveEditor(boolean save) throws CoreException {
-		if (fEditor == null)
-			return;
-			
-		save= save && fEditor.isDirty();
-		if (save) {
-			IDocumentProvider provider= fEditor.getDocumentProvider();
-			IEditorInput input = fEditor.getEditorInput();
+			if (file.isReadOnly()) {
+				file.getWorkspace().validateEdit(new IFile[]{file}, null);
+			}
+			if (file.isReadOnly()) {
+				if (fSkipReadonly) {
+					skipFile();
+					return;
+				}
+				int rc= askForSkip(file);
+				switch (rc) {
+					case CANCEL :
+						throw new OperationCanceledException();
+					case SKIP_FILE :
+						skipFile();
+						return;
+					case SKIP_ALL :
+						fSkipReadonly= true;
+						skipFile();
+						return;
+				}
+			}
+			ITextFileBufferManager bm= FileBuffers.getTextFileBufferManager();
 			try {
-				provider.aboutToChange(input);
-				provider.saveDocument(new NullProgressMonitor(), input, fDocument, true);
-				fSaved= true;
+				bm.connect(file.getFullPath(), new SubProgressMonitor(pm, 1));
+				ITextFileBuffer fb= bm.getTextFileBuffer(file.getFullPath());
+				boolean wasDirty= fb.isDirty();
+				IDocument doc= fb.getDocument();
+				try {
+					createPositionsInFile(file, doc);
+					for (int i= 0; i < markers.length; i++) {
+						doc.replace(markers[i].getOffset(), markers[i].getLength(), replacementText);
+						fMarkers.remove(0);
+						markers[i].delete();
+					}
+				} finally {
+					removePositonsInFile(file, doc);
+				}
+				if (!wasDirty)
+					fb.commit(new SubProgressMonitor(pm, 1), true);
 			} finally {
-				provider.changed(input);
+				bm.disconnect(file.getFullPath(), new SubProgressMonitor(pm, 1));
 			}
+		} finally {
+			pm.done();
 		}
-		if (fCloseEditor && !fEditor.isDirty())
-			fEditor.close(false);
-		fEditor= null;
-		fDocument= null;
-		fAnnotationModel= null;
-		fCloseEditor= false;
+	}
+	
+	private void removePositonsInFile(IFile file, IDocument doc) {
+		for (Iterator markers= fMarkers.iterator(); markers.hasNext(); ) {
+			ReplaceMarker marker= (ReplaceMarker)markers.next();
+			if (!marker.getFile().equals(file))
+				return;
+			marker.deletePosition(doc);
+		}
+	}
+	
+	private void createPositionsInFile(IFile file, IDocument doc) throws BadLocationException {
+		for (Iterator markers= fMarkers.iterator(); markers.hasNext(); ) {
+			ReplaceMarker marker= (ReplaceMarker)markers.next();
+			if (!marker.getFile().equals(file))
+				return;
+			marker.createPosition(doc);
+		}
+	}
+	
+	private int askForSkip(final IFile file) {
 		
-	}
-	
-	private void updateButtons() {
-		boolean hasNext= hasNextMatch();
-		fReplaceNextButton.setEnabled(!fFatalError && fCurrentMatch != null);
-		fReplaceButton.setEnabled(!fFatalError && fCurrentMatch != null);
-		fNextButton.setEnabled(!fFatalError && hasNext);
-	}
-	
-	private void restoreAutoBuildState() {
-		if (!fAutobuild)
-			return;
-		IWorkspace workspace= ResourcesPlugin.getWorkspace();
-		IWorkspaceDescription description= workspace.getDescription();
-		description.setAutoBuilding(true);
-		try {
-			workspace.setDescription(description);
-		} catch (CoreException e) {
-			ExceptionHandler.handle(e, getShell(), getDialogTitle(), SearchMessages.getString("ReplaceDialog.error.reenable_auto_build_failed")); //$NON-NLS-1$
-			return;
+		String message= SearchMessages.getFormattedString("ReadOnlyDialog.message", file.getFullPath().toOSString()); //$NON-NLS-1$
+		String[] buttonLabels= null;
+		boolean showSkip= countResources() > 1;
+		if (showSkip) {
+			String skipLabel= SearchMessages.getString("ReadOnlyDialog.skipFile"); //$NON-NLS-1$
+			String skipAllLabel= SearchMessages.getString("ReadOnlyDialog.skipAll"); //$NON-NLS-1$
+			buttonLabels= new String[]{skipLabel, skipAllLabel, IDialogConstants.CANCEL_LABEL};
+		} else {
+			buttonLabels= new String[]{IDialogConstants.CANCEL_LABEL};
+			
 		}
 		
-		ISearchResultView view= SearchPlugin.getSearchResultView();
-		if (fSaved && view != null) {
-			new GlobalBuildAction(
-				view.getSite().getWorkbenchWindow(),
-				IncrementalProjectBuilder.INCREMENTAL_BUILD).run();
+		MessageDialog msd= new MessageDialog(getShell(), getShell().getText(), null, message, MessageDialog.ERROR, buttonLabels, 0);
+		int rc= msd.open();
+		switch (rc) {
+			case 0 :
+				return showSkip ? SKIP_FILE : CANCEL;
+			case 1 :
+				return SKIP_ALL;
+			default :
+				return CANCEL;
 		}
 	}
-	
+		
 	private String getDialogTitle() {
 		return SearchMessages.getString("ReplaceDialog.dialog.title"); //$NON-NLS-1$
 	}
 	
-	private void handleMarkerNotPresentableException(MarkerNotPresentableException e) {
-		IFile file= e.getFile();
-		String message;
-		if (file == null) {
-			message= SearchMessages.getString("ReplaceDialog.error.no_file_for_marker"); //$NON-NLS-1$
-		} else {
-			message= SearchMessages.getFormattedString("ReplaceDialog.error.unable_to_open_text_editor", file.getName()); //$NON-NLS-1$
-		}
-		MessageDialog.openError(getParentShell(), getDialogTitle(), message);
+	private void skip() {
+		fMarkers.remove(0);
+		Assert.isTrue(fMarkers.size() > 0);
+		gotoCurrentMarker();
 	}
-}
+	
+	private void skipFile() {
+		ReplaceMarker currentMarker= getCurrentMarker();
+		if (currentMarker == null)
+			return;
+		IResource currentFile= currentMarker.getFile();
+		while (fMarkers.size() > 0 && getCurrentMarker().getFile().equals(currentFile))
+			fMarkers.remove(0);
+		if (fMarkers.size() > 0)
+			gotoCurrentMarker();
+	}
+	
+	private void gotoCurrentMarker() {
+		if (fMarkers.size() > 0) {
+			ReplaceMarker marker= getCurrentMarker();
+			Control focusControl= getShell().getDisplay().getFocusControl();
+			try {
+				selectEntry(marker);
+				ITextEditor editor= null;
+				if (SearchUI.reuseEditor())
+					editor= openEditorReuse(marker);
+				else
+					editor= openEditorNoReuse(marker);
+				editor.selectAndReveal(marker.getOffset(), marker.getLength());
+				if (focusControl != null && !focusControl.isDisposed())
+					focusControl.setFocus();
+			} catch (PartInitException e) {
+				String message= SearchMessages.getFormattedString("ReplaceDialog.error.unable_to_open_text_editor", marker.getFile().getName()); //$NON-NLS-1$
+				MessageDialog.openError(getParentShell(), getDialogTitle(), message);
+			}
+		}
+	}
+	
+	private void selectEntry(ReplaceMarker marker) {
+		SearchResultView view= (SearchResultView) SearchPlugin.getSearchResultView();
+		if (view == null)
+			return;
+		SearchResultViewer viewer= view.getViewer();
+		if (viewer == null)
+			return;
+		ISelection sel= viewer.getSelection();
+		if (!(sel instanceof IStructuredSelection))
+			return;
+		IStructuredSelection ss= (IStructuredSelection) sel;
+		IFile file= marker.getFile();
+		if (ss.size() == 1 && file.equals(ss.getFirstElement()))
+			return;
+		Table table= viewer.getTable();
+		if (table == null || table.isDisposed())
+			return;
+		int selectionIndex= table.getSelectionIndex();
+		if (selectionIndex < 0)
+			selectionIndex= 0;
+		for (int i= 0; i < table.getItemCount(); i++) {
+			int currentTableIndex= (selectionIndex+i) % table.getItemCount();
+			SearchResultViewEntry entry= (SearchResultViewEntry) viewer.getElementAt(currentTableIndex);
+			if (file.equals(entry.getGroupByKey())) {
+				viewer.setSelection(new StructuredSelection(entry));
+				return;
+			}
+		}
+	}
+
+	// opening editors ------------------------------------------
+	private ITextEditor openEditorNoReuse(ReplaceMarker marker) throws PartInitException {
+		IFile file= marker.getFile();
+		IWorkbenchPage activePage= SearchPlugin.getActivePage();
+		if (activePage == null)
+			return null;
+		ITextEditor textEditor= showOpenTextEditor(activePage, file);
+		if (textEditor != null)
+			return textEditor;
+		return openNewTextEditor(file, activePage);
+	}
+	
+	private ITextEditor openNewTextEditor(IFile file, IWorkbenchPage activePage) throws PartInitException {
+		IEditorDescriptor desc= IDE.getDefaultEditor(file);
+		if (desc != null) {
+			String editorID= desc.getId();
+			IEditorPart editor;
+			if (desc.isInternal()) {
+				editor= activePage.openEditor(new FileEditorInput(file), editorID);
+				if (editor instanceof ITextEditor) {
+					if (editor instanceof IReusableEditor)
+						fEditor= (IReusableEditor) editor;
+					return (ITextEditor)editor;
+				} else
+					activePage.closeEditor(editor, false);
+			}
+		}
+		IEditorPart editor= activePage.openEditor(new FileEditorInput(file), "org.eclipse.ui.DefaultTextEditor"); //$NON-NLS-1$
+		return (ITextEditor)editor;
+	}
+
+	private ITextEditor openEditorReuse(ReplaceMarker marker) throws PartInitException {
+		IWorkbenchPage page= SearchPlugin.getActivePage();
+		IFile file= marker.getFile();
+		if (page == null)
+			return null;
+
+		ITextEditor textEditor= showOpenTextEditor(page, file);
+		if (textEditor != null)
+			return textEditor;
+
+		String editorId= null;
+		IEditorDescriptor desc= IDE.getDefaultEditor(file);
+		if (desc != null && desc.isInternal())
+			editorId= desc.getId();
+
+		boolean isOpen= isEditorOpen(page, fEditor);
+
+		boolean canBeReused= isOpen && !fEditor.isDirty() && !isPinned(fEditor);
+		boolean showsSameInputType= fEditor != null && (editorId == null || fEditor.getSite().getId().equals(editorId));
+
+		if (canBeReused) {
+			if (showsSameInputType) {
+				fEditor.setInput(new FileEditorInput(file));
+				page.bringToTop(fEditor);
+				return (ITextEditor) fEditor;
+			} else {
+				page.closeEditor(fEditor, false);
+				fEditor= null;
+			}
+		}
+		return openNewTextEditor(file, page);
+	}
+
+	private boolean isEditorOpen(IWorkbenchPage page, IEditorPart editor) {
+		if (editor != null) {
+			IEditorReference[] parts= page.getEditorReferences();
+			int i= 0;
+			for (int j = 0; j < parts.length; j++) {
+				if (editor == parts[i++].getEditor(false))
+					return true;
+			}
+		}
+		return false;
+	}
+
+	private ITextEditor showOpenTextEditor(IWorkbenchPage page, IFile file) {
+		IEditorPart editor= page.findEditor(new FileEditorInput(file));
+		if (editor instanceof ITextEditor) {
+			page.bringToTop(editor);
+			return (ITextEditor) editor;
+		}
+		return null;
+	}
+
+	private boolean isPinned(IEditorPart editor) {
+		if (editor == null)
+			return false;
+		
+		IEditorReference[] editorRefs= editor.getEditorSite().getPage().getEditorReferences();
+		int i= 0;
+		while (i < editorRefs.length) {
+			if (editor.equals(editorRefs[i].getEditor(false)))
+				return editorRefs[i].isPinned();
+			i++;
+		}
+		return false;
+	}
+	
+	// resource related  -------------------------------------------------------------
+	/**
+	 * @return the number of resources referred to in fMarkers
+	 */
+	private int countResources() {
+		IResource r= null;
+		int count= 0;
+		for (Iterator elements= fMarkers.iterator(); elements.hasNext(); ) {
+			ReplaceMarker element= (ReplaceMarker)elements.next();
+			if (!element.getFile().equals(r)) {
+				count++;
+				r= element.getFile();
+			}
+		}
+		return count;
+	}
+	
+	private ReplaceMarker[] collectMarkers(IResource resource) {
+		List matching= new ArrayList();
+		for (int i= 0; i < fMarkers.size(); i++) {
+			ReplaceMarker marker= (ReplaceMarker)fMarkers.get(i);
+			if (!marker.getFile().equals(resource))
+				break;
+			matching.add(marker);
+		}
+		ReplaceMarker[] markers= new ReplaceMarker[matching.size()];
+		return (ReplaceMarker[])matching.toArray(markers);
+	}
+	
+	
+	// some queries -------------------------------------------------------------
+	private boolean hasNextMarker() {
+		return fMarkers.size() > 1;
+	}
+	
+	private boolean hasNextFile() {
+		if (!hasNextMarker())
+			return false;
+		IResource currentFile= getCurrentMarker().getFile();
+		for (int i= 0; i < fMarkers.size(); i++) {
+			if (!((ReplaceMarker)fMarkers.get(i)).getFile().equals(currentFile))
+				return true;
+		}
+		return false;
+	}
+	
+	private boolean canReplace() {
+		return fMarkers.size() > 0;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ResourceStructureProvider.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ResourceStructureProvider.java
new file mode 100644
index 0000000..a6f7c25
--- /dev/null
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ResourceStructureProvider.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.search.internal.ui.text;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+
+import org.eclipse.search2.ui.text.IStructureProvider;
+import org.eclipse.search2.ui.text.ITextSearchResult;
+import org.eclipse.search2.ui.text.Match;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IFileEditorInput;
+
+/**
+ * @author Thomas Mäder
+ *
+ */
+public class ResourceStructureProvider implements IStructureProvider {
+	public Object getParent(Object child) {
+		if (child instanceof IProject)
+			return null;
+		if (child instanceof IResource) {
+			IResource resource= (IResource) child;
+			return  resource.getParent();
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search.ui.ISearchResultCategory#getFile(java.lang.Object)
+	 */
+	public IFile getFile(Object element) {
+		if (element instanceof IFile)
+			return (IFile)element;
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search.ui.ISearchResultCategory#findContainedMatches(org.eclipse.search.ui.model.text.ITextSearchResult, org.eclipse.core.resources.IFile)
+	 */
+	public Match[] findContainedMatches(ITextSearchResult result, IFile file) {
+		return result.getMatches(file);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search2.ui.text.IStructureProvider#findContainedMatches(org.eclipse.search2.ui.text.ITextSearchResult, org.eclipse.ui.IEditorInput)
+	 */
+	public Match[] findContainedMatches(ITextSearchResult result, IEditorInput editorInput) {
+		if (editorInput instanceof IFileEditorInput) {
+			IFileEditorInput fileEditorInput= (IFileEditorInput) editorInput;
+			return findContainedMatches(result, fileEditorInput.getFile());
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search.ui.IStructureProvider#dispose()
+	 */
+	public void dispose() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.search2.ui.text.IStructureProvider#isShownInEditor(org.eclipse.search2.ui.text.Match, org.eclipse.ui.IEditorPart)
+	 */
+	public boolean isShownInEditor(Match match, IEditorPart editor) {
+		IEditorInput editorInput= editor.getEditorInput();
+		if (editorInput instanceof IFileEditorInput) {
+			return ((IFileEditorInput)editorInput).getFile().equals(match.getElement());
+		}
+		return false;
+	}
+
+
+}
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchActionGroup.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchActionGroup.java
index dd8e89d..4441887 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchActionGroup.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchActionGroup.java
@@ -10,10 +10,10 @@
  *******************************************************************************/
 package org.eclipse.search.internal.ui.text;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.core.resources.IFile;
-
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.operation.IRunnableWithProgress;
@@ -22,23 +22,25 @@
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
-
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.IWorkbenchActionConstants;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchPartSite;
-import org.eclipse.ui.actions.ActionGroup;
-import org.eclipse.ui.actions.OpenWithMenu;
-import org.eclipse.ui.dialogs.PropertyDialogAction;
-
+import org.eclipse.search.internal.ui.SearchManager;
+import org.eclipse.search.internal.ui.SearchMessages;
+import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search.internal.ui.SearchResultView;
+import org.eclipse.search.internal.ui.SearchResultViewer;
 import org.eclipse.search.ui.IContextMenuConstants;
 import org.eclipse.search.ui.ISearchResultView;
 import org.eclipse.search.ui.ISearchResultViewEntry;
 import org.eclipse.search.ui.SearchUI;
-
-import org.eclipse.search.internal.ui.SearchManager;
-import org.eclipse.search.internal.ui.SearchMessages;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.ActionGroup;
+import org.eclipse.ui.actions.OpenWithMenu;
+import org.eclipse.ui.dialogs.PropertyDialogAction;
 
 /**
  * Action group that adds the Text search actions to a context menu and
@@ -85,7 +87,7 @@
 		
 		addOpenWithMenu(menu, selection);
 			
-		ReplaceAction replaceAll= new ReplaceAction(view.getSite(), (List)getContext().getInput());
+		ReplaceAction replaceAll= new ReplaceAction(view.getSite(), getSearchResultEntries());
 		if (replaceAll.isEnabled())
 			menu.appendToGroup(IContextMenuConstants.GROUP_REORGANIZE, replaceAll);
 		ReplaceAction replaceSelected= new ReplaceAction(view.getSite(), selection);
@@ -96,6 +98,19 @@
 			menu.appendToGroup(IContextMenuConstants.GROUP_PROPERTIES, fOpenPropertiesDialog);
 	}
 	
+	private List getSearchResultEntries() {
+		SearchResultView view= (SearchResultView) SearchPlugin.getSearchResultView();
+		// we can assume we have a view, how else would we be called?
+		SearchResultViewer viewer= view.getViewer();
+		Table table= viewer.getTable();
+		TableItem[] items= table.getItems();
+		List elements = new ArrayList(items.length);
+		for (int i = 0; i < items.length; i++) {
+			elements.add(items[i].getData());
+		}
+		return elements;
+	}
+
 	private boolean isTextSearch() {
 		IRunnableWithProgress operation= SearchManager.getDefault().getCurrentSearch().getOperation();
 		if (operation instanceof TextSearchOperation) {
@@ -134,6 +149,6 @@
 	}
 	
 	private void setGlobalActionHandlers(IActionBars actionBars) {
-		actionBars.setGlobalActionHandler(IWorkbenchActionConstants.PROPERTIES, fOpenPropertiesDialog);		
+		actionBars.setGlobalActionHandler(ActionFactory.PROPERTIES.getId(), fOpenPropertiesDialog);		
 	}
 }	
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchOperation.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchOperation.java
index a8a37b4..6bcc6bc 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchOperation.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchOperation.java
@@ -10,19 +10,20 @@
  *******************************************************************************/
 package org.eclipse.search.internal.ui.text;
 
+import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
-
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.util.Assert;
-
-import org.eclipse.ui.actions.WorkspaceModifyOperation;
-
 import org.eclipse.search.internal.core.ISearchScope;
+import org.eclipse.search.internal.core.text.ITextSearchResultCollector;
+import org.eclipse.search.internal.core.text.MatchLocator;
 import org.eclipse.search.internal.core.text.TextSearchEngine;
+import org.eclipse.search.internal.core.text.TextSearchScope;
 import org.eclipse.search.internal.ui.SearchMessages;
 import org.eclipse.search.internal.ui.SearchPluginImages;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
 
 /**
  * An operation to perform a regular text search.
@@ -32,8 +33,7 @@
 	public static final int NO_PRIORITY_CHANGE= -1;
 	
 	private IWorkspace fWorkspace;
-	private String fPattern;
-	private String fOptions;
+	private MatchLocator fMatchLocator;
 	private ISearchScope fScope;
 	private TextSearchResultCollector fCollector;
 	private IStatus fStatus;
@@ -42,11 +42,11 @@
 	 * Creates a new text search operation.
 	 */
 	public TextSearchOperation(IWorkspace workspace,  String pattern, String options, 
-			ISearchScope scope, TextSearchResultCollector collector)  {
+		ISearchScope scope, TextSearchResultCollector collector)  {
+		super(null);
 		Assert.isNotNull(collector);
 		fWorkspace= workspace;
-		fPattern= pattern;
-		fOptions= options;
+		fMatchLocator= new MatchLocator(pattern, options);
 		fScope= scope;
 		fCollector= collector;
 		fCollector.setOperation(this);
@@ -58,21 +58,31 @@
 	protected void execute(IProgressMonitor monitor) {
 		fCollector.setProgressMonitor(monitor);		
 		TextSearchEngine engine= new TextSearchEngine();
-		fStatus= engine.search(fWorkspace, fPattern, fOptions, fScope, fCollector);
+		fStatus= engine.search(fWorkspace, fScope, fCollector, fMatchLocator);
 	}	
+	
+	void searchInFile(IFile file, ITextSearchResultCollector collector) {
+		TextSearchEngine engine= new TextSearchEngine();
+		TextSearchScope scope= new TextSearchScope(""); //$NON-NLS-1$
+		scope.add(file);
+		scope.addExtension("*"); //$NON-NLS-1$
+		fStatus= engine.search(fWorkspace, scope, collector, fMatchLocator);
+	}
 
 	String getSingularLabel() {
-		if (fPattern == null || fPattern.length() < 1)
+		String pattern= fMatchLocator.getPattern();
+		if (pattern == null || pattern.length() < 1)
 			return SearchMessages.getFormattedString("FileSearchOperation.singularLabelPostfix", new String[] {fScope.getDescription()}); //$NON-NLS-1$
 		else
-			return SearchMessages.getFormattedString("TextSearchOperation.singularLabelPostfix", new String[] {fPattern, fScope.getDescription()}); //$NON-NLS-1$
+			return SearchMessages.getFormattedString("TextSearchOperation.singularLabelPostfix", new String[] {fMatchLocator.getPattern(), fScope.getDescription()}); //$NON-NLS-1$
 	}
 
 	String getPluralLabelPattern() {
-		if (fPattern == null || fPattern.length() < 1)
+		String pattern= fMatchLocator.getPattern();
+		if (pattern == null || pattern.length() < 1)
 			return SearchMessages.getFormattedString("FileSearchOperation.pluralLabelPatternPostfix", new String[] {"{0}", fScope.getDescription()}); //$NON-NLS-2$ //$NON-NLS-1$
 		else
-			return SearchMessages.getFormattedString("TextSearchOperation.pluralLabelPatternPostfix", new String[] {fPattern, "{0}", fScope.getDescription()}); //$NON-NLS-2$ //$NON-NLS-1$
+			return SearchMessages.getFormattedString("TextSearchOperation.pluralLabelPatternPostfix", new String[] {fMatchLocator.getPattern(), "{0}", fScope.getDescription()}); //$NON-NLS-2$ //$NON-NLS-1$
 	}
 	
 	ImageDescriptor getImageDescriptor() {
@@ -84,6 +94,10 @@
 	}
 	
 	String getPattern() {
-		return fPattern;
+		return fMatchLocator.getPattern();
 	}
+	
+	boolean isRegexSearch() {
+		return fMatchLocator.isRegExSearch();
+}
 }
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java
index f32e0e4..0fdf226 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/TextSearchPage.java
@@ -40,6 +40,7 @@
 import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 
@@ -55,28 +56,38 @@
 
 import org.eclipse.jface.text.ITextSelection;
 
+import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkingSet;
 import org.eclipse.ui.help.WorkbenchHelp;
 import org.eclipse.ui.model.IWorkbenchAdapter;
 
+import org.eclipse.search.ui.IReplacePage;
 import org.eclipse.search.ui.ISearchPage;
 import org.eclipse.search.ui.ISearchPageContainer;
 import org.eclipse.search.ui.ISearchResultViewEntry;
 import org.eclipse.search.ui.SearchUI;
 
+import org.eclipse.search.internal.core.text.TextSearchJob;
 import org.eclipse.search.internal.core.text.TextSearchScope;
 import org.eclipse.search.internal.ui.ISearchHelpContextIds;
 import org.eclipse.search.internal.ui.ScopePart;
 import org.eclipse.search.internal.ui.SearchMessages;
 import org.eclipse.search.internal.ui.SearchPlugin;
+import org.eclipse.search.internal.ui.SearchResultView;
+import org.eclipse.search.internal.ui.WorkInProgressPreferencePage;
 import org.eclipse.search.internal.ui.util.ExceptionHandler;
 import org.eclipse.search.internal.ui.util.FileTypeEditor;
 import org.eclipse.search.internal.ui.util.RowLayouter;
 import org.eclipse.search.internal.ui.util.SWTUtil;
 
-public class TextSearchPage extends DialogPage implements ISearchPage {
+import org.eclipse.search2.ui.ISearchJob;
+import org.eclipse.search2.ui.text.ITextSearchResult;
+import org.eclipse.search2.ui.text.TextSearchResultFactory;
+
+public class TextSearchPage extends DialogPage implements ISearchPage, IReplacePage {
 
 	public static final String EXTENSION_POINT_ID= "org.eclipse.search.internal.ui.text.TextSearchPage"; //$NON-NLS-1$
 
@@ -122,8 +133,50 @@
 	//---- Action Handling ------------------------------------------------
 	
 	public boolean performAction() {
-		
-		SearchUI.activateSearchResultView();
+		if (WorkInProgressPreferencePage.useNewSearch())
+			return performNewSearch();
+		else
+			return performOldSearch();
+	}
+	
+	private boolean performOldSearch() {
+				
+		TextSearchOperation op = createTextSearchOperation();
+			
+		return runOperation(op);
+	}
+	
+	private boolean runOperation(final TextSearchOperation op) {
+		IRunnableContext context=  null;
+		context= getContainer().getRunnableContext();
+			
+		Shell shell= fPattern.getShell();
+		if (context == null)
+			context= new ProgressMonitorDialog(shell);
+
+		try {			
+			context.run(true, true, op);
+		} catch (InvocationTargetException ex) {
+			if (ex.getTargetException() instanceof PatternSyntaxException)
+				showRegExSyntaxError((PatternSyntaxException)ex.getTargetException());
+			else
+				ExceptionHandler.handle(ex, SearchMessages.getString("Search.Error.search.title"),SearchMessages.getString("Search.Error.search.message")); //$NON-NLS-2$ //$NON-NLS-1$
+			return false;
+		} catch (InterruptedException e) {
+			return false;
+		}
+		IStatus status= op.getStatus();
+		if (status != null && !status.isOK()) {
+			String title= SearchMessages.getString("Search.Problems.title"); //$NON-NLS-1$
+			ErrorDialog.openError(getShell(), title, null, status); //$NON-NLS-1$
+			return false;
+		}
+
+		return true;
+	}
+
+	
+	private TextSearchOperation createTextSearchOperation() {
 		
 		SearchPatternData patternData= getPatternData();
 		if (patternData.fileNamePatterns == null || fExtensions.getText().length() <= 0) {
@@ -150,41 +203,74 @@
 		}		
 		scope.addExtensions(patternData.fileNamePatterns);
 
+		SearchUI.activateSearchResultView();
 		TextSearchResultCollector collector= new TextSearchResultCollector();
 		
-		TextSearchOperation op= new TextSearchOperation(
+		final TextSearchOperation op= new TextSearchOperation(
 			SearchPlugin.getWorkspace(),
 			patternData.textPattern,
 			getSearchOptions(),
 			scope,
 			collector);
-			
-		IRunnableContext context=  null;
-		context= getContainer().getRunnableContext();
-			
-		Shell shell= fPattern.getShell();
-		if (context == null)
-			context= new ProgressMonitorDialog(shell);
+		return op;
+	}
 
-		try {			
-			context.run(true, true, op);
-		} catch (InvocationTargetException ex) {
-			if (ex.getTargetException() instanceof PatternSyntaxException)
-				showRegExSyntaxError((PatternSyntaxException)ex.getTargetException());
-			else
-				ExceptionHandler.handle(ex, SearchMessages.getString("Search.Error.search.title"),SearchMessages.getString("Search.Error.search.message")); //$NON-NLS-2$ //$NON-NLS-1$
+	/* (non-Javadoc)
+	 * @see org.eclipse.search.ui.IReplacePage#performReplace()
+	 */
+	public boolean performReplace() {
+		final TextSearchOperation op= createTextSearchOperation();
+		
+		if (!runOperation(op))
 			return false;
-		} catch (InterruptedException e) {
-			return false;
-		}
-		IStatus status= op.getStatus();
-		if (status != null && !status.isOK()) {
-			String title= SearchMessages.getString("Search.Problems.title"); //$NON-NLS-1$
-			ErrorDialog.openError(getShell(), title, null, status); //$NON-NLS-1$
-		}		
+		
+		Display.getCurrent().asyncExec(new Runnable() {
+			public void run() {
+				SearchResultView view= (SearchResultView) SearchPlugin.getSearchResultView();
+				new ReplaceDialog(SearchPlugin.getSearchResultView().getViewSite().getShell(), (List) view.getViewer().getInput(), op).open();
+			}
+		});
 		return true;
 	}
+
+	private boolean performNewSearch() {
+		org.eclipse.search2.ui.NewSearchUI.activateSearchResultView();
+		
+		SearchPatternData patternData= getPatternData();
+		if (patternData.fileNamePatterns == null || fExtensions.getText().length() <= 0) {
+			patternData.fileNamePatterns= new HashSet(1);
+			patternData.fileNamePatterns.add("*"); //$NON-NLS-1$
+		}
 	
+		// Setup search scope
+		TextSearchScope scope= null;
+		switch (getContainer().getSelectedScope()) {
+			case ISearchPageContainer.WORKSPACE_SCOPE:
+				scope= TextSearchScope.newWorkspaceScope();
+				break;
+			case ISearchPageContainer.SELECTION_SCOPE:
+				scope= getSelectedResourcesScope(false);
+				break;
+			case ISearchPageContainer.SELECTED_PROJECTS_SCOPE:
+				scope= getSelectedResourcesScope(true);
+				break;
+			case ISearchPageContainer.WORKING_SET_SCOPE:
+				IWorkingSet[] workingSets= getContainer().getSelectedWorkingSets();
+				String desc= SearchMessages.getFormattedString("WorkingSetScope", ScopePart.toString(workingSets)); //$NON-NLS-1$
+				scope= new TextSearchScope(desc, workingSets);
+		}		
+		scope.addExtensions(patternData.fileNamePatterns);
+	
+			
+		ITextSearchResult search= TextSearchResultFactory.createTextSearchResult(new ResourceStructureProvider(), new FilePresentationFactory()	, new FileSearchDesription(patternData.textPattern, scope.getDescription()));
+		org.eclipse.search2.ui.NewSearchUI.getSearchManager().addSearchResult(search);
+		
+		ISearchJob wsJob= new TextSearchJob(search, scope, getSearchOptions(), patternData.textPattern, "Searching for "+patternData.textPattern);
+		org.eclipse.search2.ui.NewSearchUI.runSearchInBackground(search, wsJob);
+	
+		return true;
+	}
+
 	private void showRegExSyntaxError(PatternSyntaxException ex) {
 		String title= SearchMessages.getString("SearchPage.regularExpressionSyntaxProblem.title"); //$NON-NLS-1$
 		MessageDialog.openInformation(getShell(), title, ex.getLocalizedMessage());
@@ -608,6 +694,9 @@
 					scope.add(resource);
 				}
 			}
+		} else if (isProjectScope) {
+			IProject editorProject= getEditorProject();
+			if (editorProject != null)scope.add(editorProject);
 		}
 		if (isProjectScope) {
 			if (elementCount > 1)
@@ -620,6 +709,17 @@
 		return scope;
 	}
 
+	private IProject getEditorProject() {
+		IWorkbenchPart activePart= SearchPlugin.getActivePage().getActivePart();
+		if (activePart instanceof IEditorPart) {
+			IEditorPart editor= (IEditorPart) activePart;
+			IEditorInput input= editor.getEditorInput();
+			if (input instanceof IFileEditorInput) {
+				return ((IFileEditorInput)input).getFile().getProject();
+			}
+		}
+		return null;
+	}
 	//--------------- Configuration handling --------------
 	
 	/**
diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/util/ExtendedDialogWindow.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/util/ExtendedDialogWindow.java
index ad544ee..1f5c705 100644
--- a/org.eclipse.search/search/org/eclipse/search/internal/ui/util/ExtendedDialogWindow.java
+++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/util/ExtendedDialogWindow.java
@@ -12,7 +12,21 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
 
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.ControlEnableState;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.wizard.ProgressMonitorPart;
+import org.eclipse.search.internal.ui.SearchMessages;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Cursor;
 import org.eclipse.swt.layout.GridData;
@@ -24,29 +38,12 @@
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 
-import org.eclipse.jface.dialogs.ControlEnableState;
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.operation.IRunnableContext;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-import org.eclipse.jface.operation.ModalContext;
-import org.eclipse.jface.resource.JFaceResources;
-import org.eclipse.jface.util.Assert;
-import org.eclipse.jface.wizard.ProgressMonitorPart;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-
-import org.eclipse.search.internal.ui.SearchMessages;
-
 
 public abstract class ExtendedDialogWindow extends Dialog  implements IRunnableContext {
 	
 	private Control fContents;
 	private Button fCancelButton;
-	private Button fSearchButton;
-	
-	private String fPerformActionLabel= JFaceResources.getString("finish"); //$NON-NLS-1$
+	private Set fActionButtons;
 	
 	// The number of long running operation executed from the dialog.	
 	private long fActiveRunningOperations;
@@ -61,6 +58,7 @@
 
 	public ExtendedDialogWindow(Shell shell) {
 		super(shell);
+		fActionButtons= new HashSet();
 	}
 	
 	//---- Hooks to reimplement in subclasses -----------------------------------
@@ -70,7 +68,7 @@
 	 * the dialog's action. If the method returns <code>false</code>
 	 * the dialog stays open. Otherwise the dialog is going to be closed.
 	 */
-	protected boolean performAction() {
+	protected boolean performAction(int buttonId) {
 		return true;
 	}
 	 
@@ -98,10 +96,15 @@
 	 * @param parent the button bar composite
 	 */
 	protected void createButtonsForButtonBar(Composite parent) {
-		
-		fSearchButton= createButton(parent, IDialogConstants.FINISH_ID, fPerformActionLabel, true);
 		fCancelButton= createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
 	}
+	
+	protected Button createActionButton(Composite parent, int id, String label,
+			boolean defaultButton) {
+		Button actionButton= createButton(parent, id, label, defaultButton);
+		fActionButtons.add(actionButton);
+		return actionButton;
+	}
 	 
 	/**
 	 * Creates the layout of the extended dialog window.
@@ -117,6 +120,7 @@
 		result.setLayoutData(new GridData(GridData.FILL_BOTH));
 		
 		fContents= createPageArea(result);
+		fContents.setLayoutData(new GridData(GridData.FILL_BOTH));
 		
 		// Insert a progress monitor
 		GridLayout pmlayout= new GridLayout();
@@ -132,36 +136,29 @@
 		applyDialogFont(result);
 		return result;
 	}
-	
-	
+
 	protected void buttonPressed(int buttonId) {
 		switch (buttonId) {
-			case IDialogConstants.FINISH_ID:
-				if (performAction())
-					close();
-				break;
 			case IDialogConstants.CANCEL_ID:
 				if (fActiveRunningOperations == 0)
 					close();
 				break;	
+			default:
+				if (performAction(buttonId))
+					close();
 		}
 	}
 	
 	//---- Setters and Getters --------------------------------------------------
 	
 	/**
-	 * Sets the label text of the perform action button.
-	 */
-	public void setPerformActionLabel(String label) {
-		fPerformActionLabel= label;
-	} 
-
-	/**
 	 * Set the enable state of the perform action button.
 	 */
 	public void setPerformActionEnabled(boolean state) {
-		if (fSearchButton != null)
-			fSearchButton.setEnabled(state);
+		for (Iterator buttons = fActionButtons.iterator(); buttons.hasNext(); ) {
+			Button element = (Button) buttons.next();
+			element.setEnabled(state);
+		}
 	} 
 
 	//---- Operation stuff ------------------------------------------------------
@@ -272,8 +269,11 @@
 	//---- UI state save and restoring ---------------------------------------------
 	
 	private void restoreUIState(HashMap state) {
-		restoreEnableState(fCancelButton, state, "cancel"); //$NON-NLS-1$
-		restoreEnableState(fSearchButton, state, "search"); //$NON-NLS-1$
+		restoreEnableState(fCancelButton, state); //$NON-NLS-1$
+		for (Iterator actionButtons = fActionButtons.iterator(); actionButtons.hasNext(); ) {
+			Button button = (Button) actionButtons.next();
+			restoreEnableState(button, state);
+		}
 		ControlEnableState pageState= (ControlEnableState)state.get("tabForm"); //$NON-NLS-1$
 		pageState.restore();
 	}
@@ -282,9 +282,9 @@
 	 * Restores the enable state of the given control.
 	 * @private
 	 */
-	protected void restoreEnableState(Control w, HashMap h, String key) {
+	protected void restoreEnableState(Control w, HashMap h) {
 		if (!w.isDisposed()) {
-			Boolean b= (Boolean)h.get(key);
+			Boolean b= (Boolean)h.get(w);
 			if (b != null)
 				w.setEnabled(b.booleanValue());
 		}
@@ -292,16 +292,19 @@
 	
 	private HashMap saveUIState(boolean keepCancelEnabled) {
 		HashMap savedState= new HashMap(10);
-		saveEnableStateAndSet(fCancelButton, savedState, "cancel", keepCancelEnabled); //$NON-NLS-1$
-		saveEnableStateAndSet(fSearchButton, savedState, "search", false); //$NON-NLS-1$
+		saveEnableStateAndSet(fCancelButton, savedState, keepCancelEnabled); //$NON-NLS-1$
+		for (Iterator actionButtons = fActionButtons.iterator(); actionButtons.hasNext(); ) {
+			Button button = (Button) actionButtons.next();
+			saveEnableStateAndSet(button, savedState, false);
+		}
 		savedState.put("tabForm", ControlEnableState.disable(fContents)); //$NON-NLS-1$
 		
 		return savedState;
 	}
 	
-	private void saveEnableStateAndSet(Control w, HashMap h, String key, boolean enabled) {
+	private void saveEnableStateAndSet(Control w, HashMap h, boolean enabled) {
 		if (!w.isDisposed()) {
-			h.put(key, new Boolean(w.isEnabled()));
+			h.put(w, new Boolean(w.isEnabled()));
 			w.setEnabled(enabled);
 		}	
 	}