Bug 331581 - Concept work on integrating existing search contributors
Throw away prototype proving the concept that org.eclipse.search
extensions can be integrated in Search Console
diff --git a/bundles/org.eclipse.platform.discovery.compatibility/META-INF/MANIFEST.MF b/bundles/org.eclipse.platform.discovery.compatibility/META-INF/MANIFEST.MF
index 9303c50..00fc5ef 100644
--- a/bundles/org.eclipse.platform.discovery.compatibility/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.platform.discovery.compatibility/META-INF/MANIFEST.MF
@@ -9,5 +9,8 @@
  org.eclipse.platform.discovery.runtime,
  org.eclipse.platform.discovery.util,
  org.eclipse.ui,
- org.eclipse.search
+ org.eclipse.search,
+ org.eclipse.platform.discovery.ui,
+ org.eclipse.ui.forms,
+ org.eclipse.platform.discovery.core
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/DiscoveryCompatibilityPlugin.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/DiscoveryCompatibilityPlugin.java
index 8deca7d..de144df 100644
--- a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/DiscoveryCompatibilityPlugin.java
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/DiscoveryCompatibilityPlugin.java
@@ -18,12 +18,21 @@
 import org.eclipse.core.runtime.Plugin;

 import org.eclipse.platform.discovery.compatibility.internal.contributors.ContributionFailedException;

 import org.eclipse.platform.discovery.compatibility.internal.contributors.IDynamicRegistryContributor;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.DynamicCustomResultUiContributor;

 import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.DynamicObjectTypeContributor;

 import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.DynamicSearchProviderContributor;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.DynamicSearchUiContributor;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.IdCalculator;

+import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchPageDescription;

 import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchPageParser;

+import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchResultPageDescription;

 import org.eclipse.platform.discovery.compatibility.internal.readers.impl.SearchPageParser;

+import org.eclipse.platform.discovery.compatibility.internal.readers.impl.SearchResultPageParser;

+import org.eclipse.platform.discovery.runtime.internal.xp.IContributionsReader;

+import org.eclipse.platform.discovery.runtime.internal.xp.impl.SearchProvidersExtensionParser;

 import org.eclipse.platform.discovery.util.internal.logging.ILogger;

 import org.eclipse.platform.discovery.util.internal.logging.Logger;

+import org.eclipse.search.ui.ISearchPage;

 import org.eclipse.ui.IStartup;

 import org.osgi.framework.BundleContext;

 

@@ -65,8 +74,15 @@
 		ISearchPageParser parser = new SearchPageParser(getRegistry());

 		contributeDynamicObjectTypes(parser);

 		contributeDynamicSearchProviders(parser);

+		contributeDynamicSearchParamUis(parser);

+		

+		makeDynamicContribution(new DynamicCustomResultUiContributor(new SearchProvidersExtensionParser(getRegistry())));

 	}

 	

+	private void contributeDynamicSearchParamUis(ISearchPageParser parser) {

+		makeDynamicContribution(new DynamicSearchUiContributor(parser)); 

+	}

+

 	private void contributeDynamicObjectTypes(ISearchPageParser parser) {

 		makeDynamicContribution(new DynamicObjectTypeContributor( parser ));

 		

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/container/OperationRunnerToRunnableContextAdapter.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/container/OperationRunnerToRunnableContextAdapter.java
new file mode 100644
index 0000000..3aaa89a
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/container/OperationRunnerToRunnableContextAdapter.java
@@ -0,0 +1,82 @@
+package org.eclipse.platform.discovery.compatibility.internal.container;

+

+import java.lang.reflect.InvocationTargetException;

+

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.OperationCanceledException;

+import org.eclipse.core.runtime.jobs.ISchedulingRule;

+import org.eclipse.jface.operation.IRunnableContext;

+import org.eclipse.jface.operation.IRunnableWithProgress;

+import org.eclipse.platform.discovery.util.api.longop.ILongOperation;

+import org.eclipse.platform.discovery.util.api.longop.ILongOperationRunner;

+import org.eclipse.platform.discovery.util.api.longop.LongOpCanceledException;

+import org.eclipse.platform.discovery.util.internal.longop.CurrentThreadOperationRunner;

+import org.eclipse.platform.discovery.util.internal.longop.ModalContextLongOpRunner;

+

+public class OperationRunnerToRunnableContextAdapter implements IRunnableContext {

+

+	private static final ISchedulingRule rule = new MutexSchedRule();

+	private IProgressMonitor monitor;

+

+	public OperationRunnerToRunnableContextAdapter(IProgressMonitor monitor) {

+		this.monitor = monitor;

+	}

+

+	@Override

+	public void run(boolean fork, boolean cancelable, final IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {

+		try {

+			ILongOperationRunner runner = fork ? new ModalContextLongOpRunner(monitor, rule) : new CurrentThreadOperationRunner(monitor);

+			runner.run(new ILongOperation<Void>() {

+

+				@Override

+				public Void run(IProgressMonitor monitor) throws LongOpCanceledException, Exception {

+					try{

+						runnable.run(monitor);

+						return null;

+					}catch(InterruptedException ex) {

+						throw new LongOpCanceledException(ex);

+					}

+				}

+			});

+		} catch (LongOpCanceledException e) {

+			throw (InterruptedException)e.getCause();

+		} catch(InvocationTargetException ex) {

+			//We need to handle these

+			//See modalcontext implementation

+			OperationCanceledException cancelledEx = extractOpCancelled(ex);

+			if(cancelledEx!=null) {

+				throw new InterruptedException();

+			}

+			throw ex;

+		}catch(OperationCanceledException ex) {

+			throw new InterruptedException();

+		}

+

+	}

+	

+	private OperationCanceledException extractOpCancelled(Throwable ex) {

+		Throwable cause = ex.getCause();

+		if(cause==null) {

+			return null;

+		}

+		if(cause instanceof OperationCanceledException) {

+			return (OperationCanceledException) cause;

+		}

+		return extractOpCancelled(cause);

+	}

+

+	private static class MutexSchedRule implements ISchedulingRule {

+

+		@Override

+		public boolean contains(ISchedulingRule rule) {

+			return rule==this;

+		}

+

+		@Override

+		public boolean isConflicting(ISchedulingRule rule) {

+			return rule==this;

+		}

+		

+	}

+

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/container/SearchPageContainer.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/container/SearchPageContainer.java
new file mode 100644
index 0000000..2e27c28
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/container/SearchPageContainer.java
@@ -0,0 +1,74 @@
+package org.eclipse.platform.discovery.compatibility.internal.container;

+

+import org.eclipse.jface.operation.IRunnableContext;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.platform.discovery.ui.api.ISearchParametersUI.IConsoleContext;

+import org.eclipse.platform.discovery.util.api.longop.ILongOperationRunner;

+import org.eclipse.search.ui.ISearchPageContainer;

+import org.eclipse.ui.IEditorInput;

+import org.eclipse.ui.IWorkingSet;

+

+public class SearchPageContainer implements ISearchPageContainer {

+	

+	private IConsoleContext consoleContext;

+

+	public SearchPageContainer(IConsoleContext consoleContext) {

+		this.consoleContext = consoleContext;

+	}

+

+	@Override

+	public ISelection getSelection() {

+		return null;

+	}

+

+	@Override

+	public IRunnableContext getRunnableContext() {

+		return new OperationRunnerToRunnableContextAdapter(consoleContext.progressMonitor());

+	}

+	

+	@Override

+	public void setPerformActionEnabled(boolean state) {

+		consoleContext.notifyComplete(state);

+	}

+

+	@Override

+	public int getSelectedScope() {

+		return WORKSPACE_SCOPE;

+	}

+

+	@Override

+	public void setSelectedScope(int scope) {

+//		throw new UnsupportedOperationException();

+	}

+

+	@Override

+	public boolean hasValidScope() {

+		return true;

+	}

+

+	@Override

+	public void setActiveEditorCanProvideScopeSelection(boolean state) {

+		

+	}

+

+	@Override

+	public IEditorInput getActiveEditorInput() {

+		return null;

+	}

+

+	@Override

+	public IWorkingSet[] getSelectedWorkingSets() {

+		return null;

+	}

+

+	@Override

+	public void setSelectedWorkingSets(IWorkingSet[] workingSets) {

+		throw new UnsupportedOperationException();

+	}

+

+	@Override

+	public String[] getSelectedProjectNames() {

+		return null;

+	}

+

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/BasicRegistryContributor.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/BasicRegistryContributor.java
new file mode 100644
index 0000000..2a89a7c
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/BasicRegistryContributor.java
@@ -0,0 +1,43 @@
+package org.eclipse.platform.discovery.compatibility.internal.contributors.impl;

+

+import java.util.ResourceBundle;

+

+import org.eclipse.core.runtime.IContributor;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.platform.discovery.util.internal.StringInputStreamAdapter;

+import org.eclipse.platform.discovery.util.internal.xml.IPluginXmlUtils;

+import org.eclipse.platform.discovery.util.internal.xml.PluginXmlUtils;

+import org.w3c.dom.Element;

+

+public class BasicRegistryContributor {

+	

+	protected static final boolean PERSIST = false;

+

+	private IPluginXmlUtils xmlUtils() {

+		return new PluginXmlUtils();

+	}

+	

+	protected Element createPluginSnippet(String xpId) {

+		return xmlUtils().createPluginSnippet(xpId);

+	}

+	

+	/*

+	 * @param plugin - the plugin.xml to contribute. This method expects that any string literals eligible for translation are already translated to the current locale.

+	 * This method will make no additional translation efforts, meaning registry.addContribution will be invoked with a null resource bundle.

+	 */

+	protected boolean writeToRegistry(Element plugin, IExtensionRegistry registry, IContributor contributor, Object token,  String name) {

+		

+		String xml = xmlUtils().toXML(plugin);

+		StringInputStreamAdapter inputStream = new StringInputStreamAdapter(xml);

+

+		/* generated plugin is expected to be already translated, so we do not need a translation bundle */

+		ResourceBundle translationBundle = null;

+		return registry.addContribution(inputStream, contributor, PERSIST, name, translationBundle, token);

+

+	}

+	

+	protected void addElementToPluginSnippet(Element pluginSnippet, Element elementToAdd) {

+		Element extension = (Element)pluginSnippet.getFirstChild();

+		extension.appendChild(elementToAdd);

+	}

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicCustomResultUiContributor.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicCustomResultUiContributor.java
new file mode 100644
index 0000000..4d3ff8e
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicCustomResultUiContributor.java
@@ -0,0 +1,56 @@
+package org.eclipse.platform.discovery.compatibility.internal.contributors.impl;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.eclipse.core.runtime.IContributor;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.ContributionFailedException;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.IDynamicRegistryContributor;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.results.CompatCustomResultsUiCreator;

+import org.eclipse.platform.discovery.runtime.internal.model.descriptions.ISearchProviderDescription;

+import org.eclipse.platform.discovery.runtime.internal.xp.IContributionsReader;

+import org.eclipse.platform.discovery.ui.internal.xp.impl.CustomResultUiXpParser;

+import org.w3c.dom.Element;

+

+public class DynamicCustomResultUiContributor extends BasicRegistryContributor implements IDynamicRegistryContributor{

+

+	private final IContributionsReader<ISearchProviderDescription> parser;

+	private final IdCalculator idCalculator;

+

+	public DynamicCustomResultUiContributor(IContributionsReader<ISearchProviderDescription> providersParser) {

+		this.parser = providersParser;

+		this.idCalculator = new IdCalculator();

+	}

+	

+	

+	@Override

+	public void contribute(IExtensionRegistry registry, IContributor contributor, Object token) throws ContributionFailedException {

+		List<String> failed = new ArrayList<String>();

+		

+		for(ISearchProviderDescription providerDescription: parser.readContributions()) {

+			if(idCalculator.isCompatibilitySearchProvider(providerDescription)) {

+				String compatProviderId = providerDescription.getId();

+				Element pluginElement = createPluginSnippet(CustomResultUiXpParser.XP_ID);

+				

+				Element contributorElement = pluginElement.getOwnerDocument().createElement(CustomResultUiXpParser.XP_ELEMENT_NAME);

+				contributorElement.setAttribute(CustomResultUiXpParser.ID_ATTR_NAME, idCalculator.calculateSearchResultUiId(idCalculator.calculateSearchPageId(compatProviderId)));

+				contributorElement.setAttribute(CustomResultUiXpParser.SEARCH_PROVIDER_ID_ATTR_NAME, compatProviderId);

+				contributorElement.setAttribute(CustomResultUiXpParser.UI_CREATOR_CLASS_NAME_ATTR_NAME, CompatCustomResultsUiCreator.class.getName());

+				

+				addElementToPluginSnippet(pluginElement, contributorElement);

+				String description = "result Ui contribution for search provider"+compatProviderId;

+				if(!writeToRegistry(pluginElement, registry, contributor, token, description)) {

+					failed.add(description);

+				}

+

+			}

+			

+		}

+		

+		if(!failed.isEmpty()) {

+			throw new ContributionFailedException(failed.toString());

+		}

+	}

+	

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicRegistryContributor.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicRegistryContributor.java
index 3470cc3..4bb288a 100644
--- a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicRegistryContributor.java
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicRegistryContributor.java
@@ -12,25 +12,20 @@
 

 import java.util.ArrayList;

 import java.util.Collection;

-import java.util.ResourceBundle;

 

 import org.eclipse.core.runtime.IContributor;

 import org.eclipse.core.runtime.IExtensionRegistry;

 import org.eclipse.platform.discovery.compatibility.internal.contributors.ContributionFailedException;

 import org.eclipse.platform.discovery.compatibility.internal.contributors.IDynamicRegistryContributor;

 import org.eclipse.platform.discovery.runtime.internal.xp.IContributionsReader;

-import org.eclipse.platform.discovery.util.internal.StringInputStreamAdapter;

-import org.eclipse.platform.discovery.util.internal.xml.IPluginXmlUtils;

-import org.eclipse.platform.discovery.util.internal.xml.PluginXmlUtils;

 import org.w3c.dom.Element;

 

 /**

  * A dynamic registry contributor contributes extensions to search console based on extensions to some other extension point, possibly org.eclipse.search  

  * @param <T> - the type of extensions based on which data is contributed.

  */

-public abstract class DynamicRegistryContributor<T> implements IDynamicRegistryContributor {

+public abstract class DynamicRegistryContributor<T> extends BasicRegistryContributor implements IDynamicRegistryContributor {

 	

-	private static final boolean PERSIST = false;

 

 	private final IContributionsReader<T> contributionsReader;

 	private final String targetExtensionPointId;

@@ -49,7 +44,7 @@
 		Collection<T> failedContributors = new ArrayList<T>();

 		for (T data : contributionsReader.readContributions()) {

 

-			Element plugin = xmlUtils().createPluginSnippet(targetExtensionPointId);

+			Element plugin = createPluginSnippet(targetExtensionPointId);

 

 			configurePluginElement(data, plugin);

 			

@@ -87,32 +82,14 @@
 		

 		Element targetElement = element.getOwnerDocument().createElement(targetElementName);

 		configureTargetElement(targetElement, data);

-		Element extension = (Element)element.getFirstChild();

-		extension.appendChild(targetElement);

+		addElementToPluginSnippet(element, targetElement);

 	}

-	

+

 	/**

 	 * Configure the target element attributes/children/executable extensions. It will already have its name set to <code>targetElementName</code>

 	 */

 	protected abstract void configureTargetElement(Element element, T data);

 

-	/*

-	 * @param plugin - the plugin.xml to contribute. This method expects that any string literals eligible for translation are already translated to the current locale.

-	 * This method will make no additional translation efforts, meaning registry.addContribution will be invoked with a null resource bundle.

-	 */

-	private boolean writeToRegistry(Element plugin, IExtensionRegistry registry, IContributor contributor, Object token,  String name) {

-		

-		String xml = xmlUtils().toXML(plugin);

-		StringInputStreamAdapter inputStream = new StringInputStreamAdapter(xml);

-

-		/* generated plugin is expected to be already translated, so we do not need a translation bundle */

-		ResourceBundle translationBundle = null;

-		return registry.addContribution(inputStream, contributor, PERSIST, name, translationBundle, token);

-

-	}

 	

-	private IPluginXmlUtils xmlUtils() {

-		return new PluginXmlUtils();

-	}

 	

 }

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicSearchProviderContributor.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicSearchProviderContributor.java
index eb9f398..7ddbe82 100644
--- a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicSearchProviderContributor.java
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicSearchProviderContributor.java
@@ -42,5 +42,5 @@
 		element.setAttribute(SearchProvidersExtensionParser.OBJECT_ID_ATTR, idCalculator.calculateObjectTypeId(data));

 		element.setAttribute(SearchProvidersExtensionParser.PROVIDER_INSTANCE_ATTR, CompatibilitySearchProvider.class.getName());

 	}

-

+	

 }

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicSearchUiContributor.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicSearchUiContributor.java
new file mode 100644
index 0000000..bc89784
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/DynamicSearchUiContributor.java
@@ -0,0 +1,39 @@
+package org.eclipse.platform.discovery.compatibility.internal.contributors.impl;

+

+import java.util.Collection;

+

+import org.eclipse.platform.discovery.compatibility.internal.contributors.IDynamicRegistryContributor;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.searchparams.SearchPageToSearchParamsUIAdapter;

+import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchPageDescription;

+import org.eclipse.platform.discovery.runtime.internal.xp.IContributionsReader;

+import org.eclipse.platform.discovery.ui.internal.xp.impl.CustomSearchParametersUiParser;

+import org.w3c.dom.Element;

+

+public class DynamicSearchUiContributor extends DynamicRegistryContributor<ISearchPageDescription> implements IDynamicRegistryContributor{

+	private final IdCalculator idCalculator = new IdCalculator();

+	public DynamicSearchUiContributor(

+			IContributionsReader<ISearchPageDescription> contributionsReader) {

+		super(contributionsReader, CustomSearchParametersUiParser.XP_ID, CustomSearchParametersUiParser.XP_ELEMENT_NAME);

+	}

+

+	@Override

+	protected String getFailureMessage(Collection<ISearchPageDescription> failedContributors) {

+		return "failed to contribute search param uis for the following search pages:" + failedContributors.toString();

+	}

+

+	@Override

+	protected String getContributionDescription(ISearchPageDescription data) {

+		return "search param ui for search page"+data;

+	}

+

+	@Override

+	protected void configureTargetElement(Element element,ISearchPageDescription data) {

+		element.setAttribute(CustomSearchParametersUiParser.ID_ARRT, idCalculator.calculateSearchParametersUiId(data));

+		element.setAttribute(CustomSearchParametersUiParser.SEARCH_PROVIDER_ID_ATTR, idCalculator.calculateSearchProviderId(data));

+		element.setAttribute(CustomSearchParametersUiParser.CLASS_ATTR, SearchPageToSearchParamsUIAdapter.class.getName());

+

+

+	}

+

+	

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/IdCalculator.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/IdCalculator.java
index 593b304..27f2192 100644
--- a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/IdCalculator.java
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/IdCalculator.java
@@ -11,11 +11,18 @@
 package org.eclipse.platform.discovery.compatibility.internal.contributors.impl;

 

 import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchPageDescription;

+import org.eclipse.platform.discovery.runtime.internal.model.descriptions.ISearchProviderDescription;

+

 import static org.eclipse.platform.discovery.util.internal.ContractChecker.nullCheckParam;

 

 public class IdCalculator {

 	

+	private static final String SEARCHPROVIDER = "searchprovider";

+	private static final String OBJECTTYPE = "objecttype";

 	private static final String DOT = "."; //$NON-NLS-1$

+	private static final String COMPATIBILITY = "compatibility";

+	private static final String SEARCHPARAMSUI = "searchparamsui";

+	private static final String SEARCHRESULTUI  = "searchresultui";

 

 	public String calculateObjectTypeId(ISearchPageDescription description) {

 		return calculateObjectTypeId(description.getId());

@@ -23,7 +30,7 @@
 	

 	public String calculateObjectTypeId(String searchPageId) {

 		nullCheckParam(searchPageId);

-		return searchPageId + DOT + "compatibility.objecttype"; //$NON-NLS-1$

+		return searchPageId + DOT + COMPATIBILITY + DOT + OBJECTTYPE; //$NON-NLS-1$

 	}

 	

 	public String calculateSearchProviderId(ISearchPageDescription description) {

@@ -32,6 +39,31 @@
 

 	public String calculateSearchProviderId(String searchPageId) {

 		nullCheckParam(searchPageId);

-		return searchPageId + DOT + "compatibility.searchprovider"; //$NON-NLS-1$

+		return searchPageId + DOT + COMPATIBILITY + DOT + SEARCHPROVIDER; //$NON-NLS-1$

+	}

+	

+	public String calculateSearchParametersUiId(ISearchPageDescription description) {

+		return calculateSearchParametersUiId(description.getId());

+	}

+	

+	public String calculateSearchParametersUiId(String searhpageId) {

+		nullCheckParam(searhpageId);

+		return searhpageId + DOT + COMPATIBILITY + DOT + SEARCHPARAMSUI;

+	}

+	

+	public String calculateSearchPageId(String searchProviderId) {

+		return searchProviderId.replace(DOT+COMPATIBILITY+DOT+SEARCHPROVIDER, "");

+	}

+	

+	public String calculateResultUiId(ISearchPageDescription desc) {

+		return calculateSearchResultUiId(desc.getId());

+	}

+	

+	public String calculateSearchResultUiId(String searchPageId) {

+		return searchPageId + DOT + COMPATIBILITY + DOT + SEARCHRESULTUI;

+	}

+	

+	public boolean isCompatibilitySearchProvider(ISearchProviderDescription providerDescription) {

+		return providerDescription.getId().endsWith(DOT + COMPATIBILITY + DOT + SEARCHPROVIDER);

 	}

 }

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/results/CompatCustomResultsUiCreator.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/results/CompatCustomResultsUiCreator.java
new file mode 100644
index 0000000..157649e
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/results/CompatCustomResultsUiCreator.java
@@ -0,0 +1,209 @@
+package org.eclipse.platform.discovery.compatibility.internal.contributors.impl.results;

+

+import java.util.Map;

+import java.util.Set;

+

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.jface.action.IMenuManager;

+import org.eclipse.jface.action.Separator;

+import org.eclipse.jface.layout.GridDataFactory;

+import org.eclipse.jface.viewers.ISelectionChangedListener;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.searchparams.SearchPageToSearchParamsUIAdapter;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.searchparams.SearchPageToSearchParamsUIAdapter.WokbenchContext;

+import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchResultPageDescription;

+import org.eclipse.platform.discovery.compatibility.internal.readers.impl.SearchResultPageParser;

+import org.eclipse.platform.discovery.core.api.IContributedAction;

+import org.eclipse.platform.discovery.core.api.ISearchContext;

+import org.eclipse.platform.discovery.ui.api.ISearchConsoleCustomization;

+import org.eclipse.platform.discovery.ui.api.ISearchResultCustomUiCreator;

+import org.eclipse.search.ui.ISearchResult;

+import org.eclipse.search.ui.ISearchResultPage;

+import org.eclipse.search.ui.ISearchResultViewPart;

+import org.eclipse.swt.graphics.Image;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Label;

+import org.eclipse.ui.IActionBars;

+import org.eclipse.ui.IMemento;

+import org.eclipse.ui.IPropertyListener;

+import org.eclipse.ui.IViewPart;

+import org.eclipse.ui.IViewSite;

+import org.eclipse.ui.IWorkbenchPartSite;

+import org.eclipse.ui.PartInitException;

+import org.eclipse.ui.forms.widgets.FormToolkit;

+import org.eclipse.ui.part.IPageSite;

+

+public class CompatCustomResultsUiCreator implements ISearchResultCustomUiCreator {

+

+	private ISearchResultPage page;

+	private IPageSite site;

+	private Label label;

+	

+

+	@Override

+	public Composite createSearchUi(Composite parent, ISearchContext searchContext, FormToolkit formToolkit, Set<IContributedAction> actions,

+			Set<ISearchConsoleCustomization> viewCustomizations) {

+		 page = getResultPage(searchContext.searchResult().getClass().getName());

+		parent.setLayout(new GridLayout());

+		

+		Map<Object, Object> custParams = searchContext.searchParameters().getCustomParameters();

+		SearchPageToSearchParamsUIAdapter.WokbenchContext ctx = (WokbenchContext) custParams.get(SearchPageToSearchParamsUIAdapter.WORKBENCH_CONTEXT);

+

+		site = ctx.pageSite;

+		site.getActionBars().getMenuManager().add(new Separator("group.viewerSetup"));

+		site.getActionBars().getMenuManager().add(new Separator("group.properties"));

+		site.getActionBars().getMenuManager().add(new Separator("group.filtering"));

+		page.setViewPart(adapter(ctx.viewPart));

+		try {

+			page.init(ctx.pageSite);

+		} catch (PartInitException e) {

+			throw new RuntimeException(e);

+		}

+		

+		Composite result = formToolkit.createComposite(parent);

+		GridDataFactory.defaultsFor(result).grab(true, true).applyTo(result);

+		result.setLayout(new GridLayout());

+

+		label = formToolkit.createLabel(result, page.getLabel());

+		GridDataFactory.defaultsFor(label).grab(true, false).applyTo(label);

+		

+		page.createControl(result);

+		page.setInput((ISearchResult) searchContext.searchResult(), null);

+		label.setText(page.getLabel());

+		

+		site.getActionBars().updateActionBars();

+		

+		return result;

+	}

+

+

+	private ISearchResultPage getResultPage(String resultClassName) {

+		SearchResultPageParser parser = new SearchResultPageParser(Platform.getExtensionRegistry());

+		for(ISearchResultPageDescription desc: parser.readContributions()) {

+			if(resultClassName.equals(desc.getSearchResultClassName())) {

+				return desc.getPage();

+			}

+		}

+		throw new RuntimeException("not found");

+	}

+

+	@Override

+	public void registerResultSelectionChangedListener(ISelectionChangedListener selChangedListener) {

+		

+	}

+

+	@Override

+	public Object restoreData() {

+		return new Object();

+	}

+

+	@Override

+	public void restore(Object data) {

+		

+	}

+	

+	private ISearchResultViewPart adapter(final IViewPart part) {

+		return new ISearchResultViewPart() {

+			

+			@Override

+			public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {

+				return part.getAdapter(adapter);

+			}

+			

+			@Override

+			public void setFocus() {

+				part.setFocus();

+			}

+			

+			@Override

+			public void removePropertyListener(IPropertyListener listener) {

+				part.removePropertyListener(listener);

+			}

+			

+			@Override

+			public String getTitleToolTip() {

+				return part.getTitleToolTip();

+			}

+			

+			@Override

+			public Image getTitleImage() {

+				return part.getTitleImage();

+			}

+			

+			@Override

+			public String getTitle() {

+				return part.getTitle();

+			}

+			

+			@Override

+			public IWorkbenchPartSite getSite() {

+				return part.getSite();

+			}

+			

+			@Override

+			public void dispose() {

+				part.dispose();

+			}

+			

+			@Override

+			public void createPartControl(Composite parent) {

+				part.createPartControl(parent);

+			}

+			

+			@Override

+			public void addPropertyListener(IPropertyListener listener) {

+				part.addPropertyListener(listener);

+			}

+			

+			@Override

+			public void saveState(IMemento memento) {

+				part.saveState(memento);

+			}

+			

+			@Override

+			public void init(IViewSite site, IMemento memento) throws PartInitException {

+				part.init(site, memento);

+			}

+			

+			@Override

+			public void init(IViewSite site) throws PartInitException {

+				part.init(site);

+			}

+			

+			@Override

+			public IViewSite getViewSite() {

+				return part.getViewSite();

+			}

+			

+			@Override

+			public void updateLabel() {

+//				label.setText(page.getLabel());

+			}

+			

+			@Override

+			public ISearchResultPage getActivePage() {

+				return page;

+			}

+			

+			@Override

+			public void fillContextMenu(IMenuManager menuManager) {

+				//TODO

+			}

+		};

+	}

+

+	@Override

+	public void dispose() {

+		if(site!=null) {

+			IActionBars bars = site.getActionBars();

+			bars.getMenuManager().removeAll();

+			bars.getMenuManager().update(true);

+			bars.getToolBarManager().removeAll();

+			bars.getToolBarManager().update(true);

+

+			bars.updateActionBars();

+		}

+		page.dispose();

+	}

+

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchparams/SearchPageToSearchParamsUIAdapter.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchparams/SearchPageToSearchParamsUIAdapter.java
new file mode 100644
index 0000000..0274e8d
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchparams/SearchPageToSearchParamsUIAdapter.java
@@ -0,0 +1,115 @@
+package org.eclipse.platform.discovery.compatibility.internal.contributors.impl.searchparams;

+

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.jface.layout.GridDataFactory;

+import org.eclipse.platform.discovery.compatibility.internal.container.SearchPageContainer;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.IdCalculator;

+import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchPageDescription;

+import org.eclipse.platform.discovery.compatibility.internal.readers.impl.SearchPageParser;

+import org.eclipse.platform.discovery.runtime.api.GroupingHierarchy;

+import org.eclipse.platform.discovery.runtime.internal.model.descriptions.ISearchProviderDescription;

+import org.eclipse.platform.discovery.ui.api.ISearchParametersUI;

+import org.eclipse.platform.discovery.ui.api.ISearchParametersUI.IConsoleContext;

+import org.eclipse.search.ui.ISearchPage;

+import org.eclipse.search.ui.ISearchPageContainer;

+import org.eclipse.swt.layout.GridLayout;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.ui.IViewPart;

+import org.eclipse.ui.forms.widgets.FormToolkit;

+import org.eclipse.ui.part.IPageSite;

+

+public class SearchPageToSearchParamsUIAdapter implements ISearchParametersUI {

+	

+	public static final String SEARCH_PAGE_INSTANCE = "searchPageInstance";

+	public static final String SEARCH_PAGE_CONTAINER = "searchPageContainer";

+	public static final String WORKBENCH_CONTEXT = "wbContext";

+	

+	private ISearchPage searchPage;

+	private ISearchPageContainer container;

+	private IConsoleContext consoleContext;

+	

+	@Override

+	public void createUI(Composite parent, FormToolkit toolkit, IConsoleContext consoleContext) {

+		this.consoleContext = consoleContext;

+		parent.setLayout(new GridLayout(1, false));

+

+		ISearchPageDescription pageDescription = getActivePage(consoleContext);

+		searchPage = pageDescription.getSearchPage();

+

+		container = new SearchPageContainer(consoleContext );

+		searchPage.setContainer(container);

+

+		searchPage.createControl(parent);

+		searchPage.setVisible(true);

+		Control control = searchPage.getControl();

+//		if(control instanceof Composite) {

+//			toolkit.adapt((Composite)control);

+//		}else{

+//			toolkit.adapt(control, false, false);

+//		}

+		

+		GridDataFactory.defaultsFor(control).applyTo(control);

+	}

+

+	private ISearchPageDescription getActivePage(IConsoleContext consoleContext) {

+		String searchPageId = new IdCalculator().calculateSearchPageId(consoleContext.searchProvider().getId());

+		ISearchPageDescription pageDescription = null;

+		for(ISearchPageDescription description: new SearchPageParser(Platform.getExtensionRegistry()).readContributions()) {

+			if(description.getId().equals(searchPageId)) {

+				pageDescription = description;

+				break;

+			}

+		}

+		if(pageDescription==null) {

+			throw new IllegalStateException("not found");

+		}

+		return pageDescription;

+	}

+

+	@Override

+	public void searchProviderSelected(ISearchProviderDescription selectedProvider) {

+	}

+

+	@Override

+	public Map<Object, Object> getParameters() {

+		Map<Object, Object> params = new HashMap<Object, Object>();

+		params.put(SEARCH_PAGE_INSTANCE, searchPage);

+		params.put(SEARCH_PAGE_CONTAINER, container);

+		WokbenchContext ctx = new WokbenchContext();

+		ctx.pageSite = consoleContext.site();

+		ctx.viewPart = consoleContext.consolePart();

+		params.put(WORKBENCH_CONTEXT, ctx);

+		return params;

+	}

+

+	@Override

+	public String getKeyword() {

+		return null;

+	}

+

+	@Override

+	public GroupingHierarchy getGroupingHierarchy() {

+		return null;

+	}

+

+	@Override

+	public void showGroupingHierarchies(List<GroupingHierarchy> groupingHierarchies) {

+	}

+	

+	public static class WokbenchContext {

+		public IViewPart viewPart;

+		public IPageSite pageSite;

+	}

+

+	@Override

+	public void dispose() {

+		searchPage.dispose();

+	}

+	

+

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchprovider/CompatibilitySearchProvider.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchprovider/CompatibilitySearchProvider.java
index a5e7fcc..dac1f30 100644
--- a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchprovider/CompatibilitySearchProvider.java
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchprovider/CompatibilitySearchProvider.java
@@ -10,28 +10,27 @@
  *******************************************************************************/

 package org.eclipse.platform.discovery.compatibility.internal.contributors.impl.searchprovider;

 

+

+import org.eclipse.platform.discovery.compatibility.internal.container.SearchPageContainer;

+import org.eclipse.platform.discovery.compatibility.internal.contributors.impl.searchparams.SearchPageToSearchParamsUIAdapter;

 import org.eclipse.platform.discovery.runtime.api.ISearchParameters;

 import org.eclipse.platform.discovery.runtime.api.ISearchProvider;

 import org.eclipse.platform.discovery.runtime.api.ISearchQuery;

-import org.eclipse.platform.discovery.runtime.api.SearchCancelledException;

-import org.eclipse.platform.discovery.runtime.api.SearchFailedException;

 import org.eclipse.platform.discovery.runtime.api.impl.SearchProvider;

-import org.eclipse.platform.discovery.util.api.longop.ILongOperationRunner;

+import org.eclipse.search.ui.ISearchPage;

 

 public class CompatibilitySearchProvider extends SearchProvider implements ISearchProvider {

-	@Override

-	public ISearchQuery createQuery(ISearchParameters searchParameters) {

-		return new CompatibilitySearchQuery();

+	

+	

+	public CompatibilitySearchProvider() {

 	}

 	

-	private class CompatibilitySearchQuery implements ISearchQuery {

-

-		@Override

-		public Object execute(ILongOperationRunner lor)

-				throws SearchFailedException, SearchCancelledException {

-			return "foo"; //$NON-NLS-1$

-		}

-		

+	@Override

+	public ISearchQuery createQuery(ISearchParameters searchParameters) {

+		CompatibilitySearchQuery query = CompatibilitySearchQuery.getInstance();

+		query.setContext((ISearchPage) searchParameters.getCustomParameters().get(SearchPageToSearchParamsUIAdapter.SEARCH_PAGE_INSTANCE),

+				(SearchPageContainer)searchParameters.getCustomParameters().get(SearchPageToSearchParamsUIAdapter.SEARCH_PAGE_CONTAINER));

+		return query;

 	}

 

 }

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchprovider/CompatibilitySearchQuery.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchprovider/CompatibilitySearchQuery.java
new file mode 100644
index 0000000..f823166
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/contributors/impl/searchprovider/CompatibilitySearchQuery.java
@@ -0,0 +1,101 @@
+package org.eclipse.platform.discovery.compatibility.internal.contributors.impl.searchprovider;

+

+import java.lang.reflect.InvocationTargetException;

+import java.util.concurrent.atomic.AtomicReference;

+

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.platform.discovery.compatibility.internal.container.SearchPageContainer;

+import org.eclipse.platform.discovery.runtime.api.ISearchQuery;

+import org.eclipse.platform.discovery.runtime.api.SearchCancelledException;

+import org.eclipse.platform.discovery.runtime.api.SearchFailedException;

+import org.eclipse.platform.discovery.util.api.longop.ILongOperation;

+import org.eclipse.platform.discovery.util.api.longop.ILongOperationRunner;

+import org.eclipse.platform.discovery.util.api.longop.LongOpCanceledException;

+import org.eclipse.search.ui.IQueryListener;

+import org.eclipse.search.ui.ISearchPage;

+import org.eclipse.search.ui.ISearchResult;

+import org.eclipse.search.ui.NewSearchUI;

+import org.eclipse.ui.PlatformUI;

+

+class CompatibilitySearchQuery implements ISearchQuery , IQueryListener{

+	

+	private static final CompatibilitySearchQuery instance = new CompatibilitySearchQuery();

+	

+	public static CompatibilitySearchQuery getInstance() {

+		return instance;

+	}

+

+	private ISearchPage page;

+	private SearchPageContainer container;

+	private AtomicReference<ISearchResult> result = new AtomicReference<ISearchResult>();

+

+	private CompatibilitySearchQuery() {

+		NewSearchUI.addQueryListener(this);

+	}

+

+	@Override

+	public Object execute(ILongOperationRunner lor) throws SearchFailedException, SearchCancelledException {

+			

+

+		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

+			@Override

+			public void run() {

+				page.performAction();

+			}

+		});

+		

+		final ILongOperation<Void> searchOp = new  ILongOperation<Void>() {

+			

+			@Override

+			public Void run(IProgressMonitor monitor) throws LongOpCanceledException, Exception {

+				while(result.get() == null)

+				{

+					if(monitor.isCanceled())

+					{

+						throw new LongOpCanceledException();

+					}

+					Thread.sleep(50);

+				}

+				return null;

+			}

+		};

+

+		try {

+			lor.run(searchOp);

+		} catch (LongOpCanceledException e) {

+			throw new SearchCancelledException(e);

+		} catch (InvocationTargetException e) {

+			throw new SearchFailedException(e.getCause());

+		}

+		

+		ISearchResult theResult = result.get();

+		

+		result.set(null);

+		setContext(null, null);

+

+		return theResult;

+	}

+

+	@Override

+	public void queryAdded(org.eclipse.search.ui.ISearchQuery query) {

+	}

+

+	@Override

+	public void queryRemoved(org.eclipse.search.ui.ISearchQuery query) {

+	}

+

+	@Override

+	public void queryStarting(org.eclipse.search.ui.ISearchQuery query) {

+	}

+

+	@Override

+	public void queryFinished(org.eclipse.search.ui.ISearchQuery query) {

+		result.set(query.getSearchResult());

+	}

+	

+	public void setContext(ISearchPage page, SearchPageContainer container) {

+		this.page = page;

+		this.container = container;

+	}

+	

+} 
\ No newline at end of file
diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/ISearchResultPageDescription.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/ISearchResultPageDescription.java
new file mode 100644
index 0000000..f03e5a3
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/ISearchResultPageDescription.java
@@ -0,0 +1,9 @@
+package org.eclipse.platform.discovery.compatibility.internal.readers;

+

+import org.eclipse.platform.discovery.runtime.api.IDescriptiveObject;

+import org.eclipse.search.ui.ISearchResultPage;

+

+public interface ISearchResultPageDescription extends IDescriptiveObject {

+	public String getSearchResultClassName();

+	public ISearchResultPage getPage();

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/impl/SearchResultPageDescription.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/impl/SearchResultPageDescription.java
new file mode 100644
index 0000000..caec476
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/impl/SearchResultPageDescription.java
@@ -0,0 +1,49 @@
+package org.eclipse.platform.discovery.compatibility.internal.readers.impl;

+

+import static java.text.MessageFormat.format;

+

+import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchResultPageDescription;

+import org.eclipse.search.ui.ISearchResultPage;

+

+public class SearchResultPageDescription implements

+		ISearchResultPageDescription {

+

+	private final String id;

+	private final String label;

+	private final String resultClassFqName;

+	private final ISearchResultPage page;

+

+	public SearchResultPageDescription(String id, String label, String resultClassFqName, ISearchResultPage page) {

+		this.id = id;

+		this.label = label;

+		this.resultClassFqName = resultClassFqName;

+		this.page = page;

+	}

+

+	@Override

+	public String getId() {

+		return id;

+	}

+

+	@Override

+	public String getDisplayName() {

+		return label;

+	}

+

+	@Override

+	public String getSearchResultClassName() {

+		return resultClassFqName;

+	}

+

+	@Override

+	public ISearchResultPage getPage() {

+		return page;

+	}

+	

+	@Override

+	public String toString() {

+		

+		return format("Search result page. Id:{0} ; label: {1}", id, label);

+	}

+

+}

diff --git a/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/impl/SearchResultPageParser.java b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/impl/SearchResultPageParser.java
new file mode 100644
index 0000000..647e5a0
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.compatibility/src/org/eclipse/platform/discovery/compatibility/internal/readers/impl/SearchResultPageParser.java
@@ -0,0 +1,26 @@
+package org.eclipse.platform.discovery.compatibility.internal.readers.impl;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.platform.discovery.compatibility.internal.readers.ISearchResultPageDescription;

+import org.eclipse.platform.discovery.runtime.internal.xp.impl.AbstractExtensionPointParser;

+import org.eclipse.search.ui.ISearchResultPage;

+

+public class SearchResultPageParser extends AbstractExtensionPointParser<ISearchResultPageDescription>{

+

+	public static final String ID_ATTR = "id";

+	public static final String LABEL_ATTR = "label";

+	public static final String SEARCH_RESULT_CLASS_ATTR = "searchResultClass";

+	public static final String CLASS_ATTR = "class";

+

+	public SearchResultPageParser(IExtensionRegistry extRegistry) {

+		super(extRegistry, "org.eclipse.search.searchResultViewPages", "viewPage");

+	}

+

+	@Override

+	protected ISearchResultPageDescription createObject(IConfigurationElement element) throws CoreException {

+		return new SearchResultPageDescription(element.getAttribute(ID_ATTR), element.getAttribute(LABEL_ATTR),  element.getAttribute(SEARCH_RESULT_CLASS_ATTR), (ISearchResultPage)element.createExecutableExtension(CLASS_ATTR));

+	}

+	

+}

diff --git a/bundles/org.eclipse.platform.discovery.core/src/org/eclipse/platform/discovery/core/api/ISearchContext.java b/bundles/org.eclipse.platform.discovery.core/src/org/eclipse/platform/discovery/core/api/ISearchContext.java
index da61d86..60e03bd 100644
--- a/bundles/org.eclipse.platform.discovery.core/src/org/eclipse/platform/discovery/core/api/ISearchContext.java
+++ b/bundles/org.eclipse.platform.discovery.core/src/org/eclipse/platform/discovery/core/api/ISearchContext.java
@@ -43,5 +43,6 @@
 

 	public String description();

 

-	public Map<Object, Object> data();

+	public Map<Object, Object> data();
+	
 }

diff --git a/bundles/org.eclipse.platform.discovery.integration/src/org/eclipse/platform/discovery/integration/internal/plugin/DiscoveryIntegrationPlugin.java b/bundles/org.eclipse.platform.discovery.integration/src/org/eclipse/platform/discovery/integration/internal/plugin/DiscoveryIntegrationPlugin.java
index a7e2e05..0ff07ea 100644
--- a/bundles/org.eclipse.platform.discovery.integration/src/org/eclipse/platform/discovery/integration/internal/plugin/DiscoveryIntegrationPlugin.java
+++ b/bundles/org.eclipse.platform.discovery.integration/src/org/eclipse/platform/discovery/integration/internal/plugin/DiscoveryIntegrationPlugin.java
@@ -98,8 +98,8 @@
 	private static DiscoveryIntegrationPlugin plugin;

 	

 	private ISchedulingRule searchRule = new SearchScheudlingRule();

-	private final Set<Thread> threadTracker = new HashSet<Thread>();

-	

+	private final Set<Thread> threadTracker = new HashSet<Thread>();
+	
 	/**

 	 * The constructor

 	 */

@@ -319,6 +319,8 @@
 			final ISearchConsoleView consoleView = getBusinessViewFromPart(wbPart);

 			final ICustomizableView customizableView = getCustomizableViewFromPart(wbPart);

 			final IMasterDiscoveryView masterView = getMasterViewFromPart(wbPart);

+			
+			
 			

 			final ILongOperationRunner runner = longOperationRunner(consoleView.getProgressMonitor());

 			final IDiscoveryEnvironment environment = createConsoleEnvironment(errorHandler(), runner, consoleView);

@@ -392,8 +394,8 @@
 		{

 			Logger.instance().logWarn("Search favorites view could not be created"); //$NON-NLS-1$

 		}

-	}

-	

+	}
+	
 	private void customizeView(final ICustomizableView customizableView, final IMasterDiscoveryView masterView, final Set<ISlaveController> slaveControllers, final Set<IGenericViewCustomization> viewCustomizations)

 	{

 		customizableView.setUiContext(createViewUiContext());

diff --git a/bundles/org.eclipse.platform.discovery.ui/schema/org.eclipse.platform.discovery.ui.customsearchparametersui.exsd b/bundles/org.eclipse.platform.discovery.ui/schema/org.eclipse.platform.discovery.ui.customsearchparametersui.exsd
index 39ce97a..0d2df7a 100644
--- a/bundles/org.eclipse.platform.discovery.ui/schema/org.eclipse.platform.discovery.ui.customsearchparametersui.exsd
+++ b/bundles/org.eclipse.platform.discovery.ui/schema/org.eclipse.platform.discovery.ui.customsearchparametersui.exsd
@@ -55,14 +55,14 @@
 

    <element name="contributor">

       <complexType>

-         <attribute name="id" type="string">

+         <attribute name="id" type="string" use="required">

             <annotation>

                <documentation>

                   The unique id of this contributor

                </documentation>

             </annotation>

          </attribute>

-         <attribute name="searchproviderid" type="string">

+         <attribute name="searchproviderid" type="string" use="required">

             <annotation>

                <documentation>

                   The ID of the Search provider for which this contributor provides a custom search parameters UI

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/ISearchParametersUI.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/ISearchParametersUI.java
index 2cae418..7d4e439 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/ISearchParametersUI.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/ISearchParametersUI.java
@@ -13,6 +13,7 @@
 import java.util.List;

 import java.util.Map;

 

+import org.eclipse.core.runtime.IProgressMonitor;

 import org.eclipse.platform.discovery.runtime.api.GroupingHierarchy;

 import org.eclipse.platform.discovery.runtime.api.ISearchDestination;

 import org.eclipse.platform.discovery.runtime.api.ISearchParameters;

@@ -22,7 +23,9 @@
 import org.eclipse.platform.discovery.runtime.internal.model.descriptions.IObjectTypeDescription;

 import org.eclipse.platform.discovery.runtime.internal.model.descriptions.ISearchProviderDescription;

 import org.eclipse.swt.widgets.Composite;

+import org.eclipse.ui.IViewPart;

 import org.eclipse.ui.forms.widgets.FormToolkit;

+import org.eclipse.ui.part.IPageSite;

 

 /**

  * The UI via which the user enters the search parameters.

@@ -80,6 +83,12 @@
 		 * relative offset at which the second column starts. Contributors may have this value in mind in order to align their custom user interface gracefully 

 		 */

 		public int secondColumnLeftOffset();

+		

+		public IProgressMonitor progressMonitor();

+		

+		public IViewPart consolePart();

+		

+		public IPageSite site();

 	}

 	

 	/**

@@ -120,4 +129,6 @@
 	 * Displays the hierarchies which can be used to present the search result

 	 */

 	public void showGroupingHierarchies(final List<GroupingHierarchy> groupingHierarchies);	

+	

+	public void dispose();

 }

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/ISearchResultCustomUiCreator.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/ISearchResultCustomUiCreator.java
index e7e0bb5..dc89835 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/ISearchResultCustomUiCreator.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/ISearchResultCustomUiCreator.java
@@ -17,6 +17,7 @@
 import org.eclipse.platform.discovery.core.api.ISearchContext;
 import org.eclipse.platform.discovery.ui.api.impl.SearchResultCustomUiCreator;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.ToolBar;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 

 

@@ -63,5 +64,7 @@
 	 * @param data

 	 * @see #restoreData()

 	 */

-	public void restore(Object data);

+	public void restore(Object data);
+	
+	public void dispose();

 }

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/impl/SearchResultCustomUiCreator.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/impl/SearchResultCustomUiCreator.java
index af57558..d23001a 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/impl/SearchResultCustomUiCreator.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/api/impl/SearchResultCustomUiCreator.java
@@ -55,5 +55,10 @@
 	@Override

 	public Object restoreData() {

 		return null;

+	}
+
+	@Override
+	public void dispose() {
+		
 	}

 }

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/SearchParametersUI.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/SearchParametersUI.java
index 98686f5..bff52ae 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/SearchParametersUI.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/SearchParametersUI.java
@@ -203,5 +203,11 @@
 		

 		

 	}

+

+	@Override

+	public void dispose() {

+		// TODO Auto-generated method stub

+		

+	}

 	

 }

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/ActionBarsAdapter.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/ActionBarsAdapter.java
new file mode 100644
index 0000000..6cd88a7
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/ActionBarsAdapter.java
@@ -0,0 +1,73 @@
+package org.eclipse.platform.discovery.ui.internal.view;

+

+import org.eclipse.jface.action.IAction;

+import org.eclipse.jface.action.IMenuManager;

+import org.eclipse.jface.action.IStatusLineManager;

+import org.eclipse.jface.action.IToolBarManager;

+import org.eclipse.jface.internal.provisional.action.ToolBarManager2;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.graphics.Point;

+import org.eclipse.swt.graphics.Rectangle;

+import org.eclipse.swt.widgets.ToolBar;

+import org.eclipse.ui.IActionBars;

+import org.eclipse.ui.services.IServiceLocator;

+

+public class ActionBarsAdapter implements IActionBars {

+

+	private final ToolBar toolbar;

+	private final IActionBars barsDelegate;

+	private final IToolBarManager toolbarmanager;

+

+	public ActionBarsAdapter(ToolBar theToolbar, IActionBars delegate) {

+		this.toolbar = theToolbar;

+		this.barsDelegate = delegate;

+		this.toolbarmanager = new ToolBarManager2(toolbar);

+	}

+	

+	@Override

+	public IAction getGlobalActionHandler(String actionId) {

+		return barsDelegate.getGlobalActionHandler(actionId);

+	}

+

+	@Override

+	public IMenuManager getMenuManager() {

+		return barsDelegate.getMenuManager();

+	}

+

+	@Override

+	public IServiceLocator getServiceLocator() {

+		return barsDelegate.getServiceLocator();

+	}

+

+	@Override

+	public IStatusLineManager getStatusLineManager() {

+		return barsDelegate.getStatusLineManager();

+	}

+

+	@Override

+	public void setGlobalActionHandler(String actionId, IAction handler) {

+		barsDelegate.setGlobalActionHandler(actionId, handler);

+	}

+

+	@Override

+	public void updateActionBars() {

+		barsDelegate.updateActionBars();

+		getToolBarManager().update(true);

+		final Point parentSize = toolbar.getParent().getSize();

+		final Point tbSize = toolbar.computeSize(SWT.DEFAULT, SWT.DEFAULT);

+		final Rectangle tbBounds = toolbar.getBounds();

+		toolbar.setBounds(parentSize.x - tbSize.x, tbBounds.y, tbSize.x, tbBounds.height);

+	}

+

+

+	@Override

+	public void clearGlobalActionHandlers() {

+		barsDelegate.clearGlobalActionHandlers();

+	}

+

+

+	@Override

+	public IToolBarManager getToolBarManager() {

+		return toolbarmanager;

+	}

+}

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/ISearchProviderSelector.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/ISearchProviderSelector.java
index 530c012..7203040 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/ISearchProviderSelector.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/ISearchProviderSelector.java
@@ -59,4 +59,6 @@
 	public void updateDestinationsUI();

 

 	public void setController(ISearchConsoleController controller);

+	

+	public void hide();

 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/PageSiteAdapter.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/PageSiteAdapter.java
new file mode 100644
index 0000000..6c12e27
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/PageSiteAdapter.java
@@ -0,0 +1,83 @@
+package org.eclipse.platform.discovery.ui.internal.view;

+

+import org.eclipse.jface.action.MenuManager;

+import org.eclipse.jface.viewers.ISelectionProvider;

+import org.eclipse.platform.discovery.ui.internal.view.result.impl.TabbedSessionDisplayer;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.ui.IActionBars;

+import org.eclipse.ui.IViewSite;

+import org.eclipse.ui.IWorkbenchPage;

+import org.eclipse.ui.IWorkbenchWindow;

+import org.eclipse.ui.application.ActionBarAdvisor;

+import org.eclipse.ui.part.IPageSite;

+

+public class PageSiteAdapter implements IPageSite {

+

+	/**

+	 * 

+	 */

+	private final SearchConsoleView searchConsoleView;

+	private final  IViewSite viewSite;

+	private IActionBars actionBarsAdapter;

+

+	public PageSiteAdapter(SearchConsoleView searchConsoleView, IViewSite viewSite) {

+		this.searchConsoleView = searchConsoleView;

+		this.viewSite = viewSite;

+	}

+

+	@Override

+	public IWorkbenchPage getPage() {

+		return viewSite.getPage();

+	}

+

+	@Override

+	public ISelectionProvider getSelectionProvider() {

+		return viewSite.getSelectionProvider();

+	}

+

+	@Override

+	public Shell getShell() {

+		return viewSite.getShell();

+	}

+

+	@Override

+	public IWorkbenchWindow getWorkbenchWindow() {

+		return viewSite.getWorkbenchWindow();

+	}

+

+	@Override

+	public void setSelectionProvider(ISelectionProvider provider) {

+		viewSite.setSelectionProvider(provider);

+	}

+

+	@Override

+	public Object getAdapter(Class adapter) {

+		return viewSite.getAdapter(adapter);

+	}

+

+	@Override

+	public Object getService(Class api) {

+		return viewSite.getService(api);

+	}

+

+	@Override

+	public boolean hasService(Class api) {

+		return viewSite.hasService(api);

+	}

+

+	@Override

+	public void registerContextMenu(String menuId, MenuManager menuManager,

+			ISelectionProvider selectionProvider) {

+		viewSite.registerContextMenu(menuId, menuManager, selectionProvider);

+	}

+

+	@Override

+	public IActionBars getActionBars() {

+		if(actionBarsAdapter==null) {

+			actionBarsAdapter = new ActionBarsAdapter(((TabbedSessionDisplayer<?>)this.searchConsoleView.sdm).getTheToolbar(), viewSite.getActionBars());

+		}

+		return actionBarsAdapter;

+	}

+

+	

+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/SearchConsoleView.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/SearchConsoleView.java
index de70f8c..f642c10 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/SearchConsoleView.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/SearchConsoleView.java
@@ -10,6 +10,9 @@
  *******************************************************************************/
 package org.eclipse.platform.discovery.ui.internal.view;

 

+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
@@ -18,6 +21,9 @@
 import java.util.Set;
 
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.internal.provisional.action.ToolBarManager2;
 import org.eclipse.jface.preference.PreferenceDialog;
 import org.eclipse.platform.discovery.core.api.ISearchContext;
 import org.eclipse.platform.discovery.core.api.SearchEvent;
@@ -27,6 +33,7 @@
 import org.eclipse.platform.discovery.runtime.api.GroupingHierarchy;
 import org.eclipse.platform.discovery.runtime.api.ISearchDestination;
 import org.eclipse.platform.discovery.runtime.api.ISearchParameters;
+import org.eclipse.platform.discovery.runtime.api.ISearchProvider;
 import org.eclipse.platform.discovery.runtime.api.ISearchSubdestination;
 import org.eclipse.platform.discovery.runtime.api.SearchFailedException;
 import org.eclipse.platform.discovery.runtime.api.SearchFailedForKnownReasonException;
@@ -57,6 +64,9 @@
 import org.eclipse.platform.discovery.ui.internal.view.impl.SearchParameters;
 import org.eclipse.platform.discovery.ui.internal.view.result.impl.ContributedUIFactory;
 import org.eclipse.platform.discovery.ui.internal.view.result.impl.TabbedSessionDisplayer;
+import org.eclipse.platform.discovery.ui.internal.xp.ICustomSearchParametersUIDescription;
+import org.eclipse.platform.discovery.ui.internal.xp.impl.CustomSearchParametersUiDescription;
+import org.eclipse.platform.discovery.ui.internal.xp.impl.CustomSearchParametersUiParser;
 import org.eclipse.platform.discovery.util.internal.logging.ILogger;
 import org.eclipse.platform.discovery.util.internal.logging.Logger;
 import org.eclipse.platform.discovery.util.internal.property.IPropertyAttributeListener;
@@ -80,12 +90,19 @@
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IActionBars2;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.dialogs.PreferencesUtil;
 import org.eclipse.ui.forms.events.HyperlinkEvent;
 import org.eclipse.ui.forms.events.IHyperlinkListener;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.ui.part.IPageSite;
 

 

 /**

@@ -115,7 +132,7 @@
 	private ISearchProviderSelector searchProviderSelector;
 	

 	private IAdvancedSearchParamsDisplayer advancedSearchParamsDisplayer;

-	private ITabbedSessionDisplayer<ISearchContext> sdm;

+	ITabbedSessionDisplayer<ISearchContext> sdm;

 	private IProgressMonitor viewProgressMonitor;

 	private String defaultSessionId;

 	
@@ -135,7 +152,11 @@
 	

 	private ControlBackgroundImageManager upperCompositeGradientManager;

 

-	private ISearchConsoleController controller;

+	private ISearchConsoleController controller;
+
+	private Composite searchParametersUIComposite;
+	
+	private IPartListener searchConsoleClosedListener;

 	

 	public SearchConsoleView()

 	{

@@ -211,7 +232,38 @@
 		

 		currentOrientation.registerValueListener(new OrientationChangedListener(), true);

 		parent.layout(true, true);

-		upperCompositeSizeProperty.set(upperComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));

+		upperCompositeSizeProperty.set(upperComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+		
+		searchConsoleClosedListener = new IPartListener() {
+			
+			@Override
+			public void partOpened(IWorkbenchPart part) {
+			}
+			
+			@Override
+			public void partDeactivated(IWorkbenchPart part) {
+			}
+			
+			@Override
+			public void partClosed(IWorkbenchPart part) {
+				if(part.equals(getViewSite().getPart())) {
+					if(searchParametersUI!=null) {
+						searchParametersUI.dispose();
+					}
+				}
+			}
+			
+			@Override
+			public void partBroughtToTop(IWorkbenchPart part) {
+				
+			}
+			
+			@Override
+			public void partActivated(IWorkbenchPart part) {
+				
+			}
+		};
+		getSite().getPage().addPartListener(searchConsoleClosedListener);

 	}

 	

 	protected ITabbedSessionDisplayer<ISearchContext> createSessionsDisplayer() {

@@ -318,6 +370,19 @@
 		
 		final ISearchProviderSelector.IConsoleContext selectorContext = new ISearchProviderSelector.IConsoleContext() {
 			
+			private ISearchProviderDescription lastProvider = null;
+			
+			private boolean providerChanged(ISearchProviderDescription selectedProvider) {
+				if(selectedProvider==null) {
+					lastProvider = selectedProvider;
+					return true;
+				}
+				
+				boolean changed = lastProvider == null ? true : !selectedProvider.getId().equals(lastProvider.getId());
+				lastProvider = selectedProvider;
+				return changed;
+			}
+			
 			@Override
 			public int secondColumnLeftOffset() {
 				return leftLabelsSize;
@@ -332,6 +397,20 @@
 			public void notifyComplete(boolean complete) {
 				final ISearchProviderDescription selectedProvider = searchProviderSelector.getSelectedSearchProvider();
 				final ISearchDestination selectedDestination = searchProviderSelector.getSelectedDestination();
+				
+				if(providerChanged(selectedProvider)) {
+					
+					
+					ISearchParametersUI custom = getCustomSearchParametersUI(selectedProvider);
+					if(custom!=null || !(searchParametersUI instanceof SearchParametersUI) ) {
+						searchParametersUI.dispose();
+						searchParametersUIComposite.dispose();
+						createSearchParametersUI(fixedSearchParamComposite, formToolkit, selectedProvider);
+						upperCompositeSizeProperty.set(upperComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+						
+					}					
+				}
+				
 				searchParametersUI.searchProviderSelected(selectedProvider);
 
 				advancedSearchParamsDisplayer.update(getSelectedObjectType(), selectedDestination, getEnvironment(), uiContext());
@@ -351,7 +430,7 @@
 		searchProviderSelector.getControl().setLayoutData(createSearchProviderSelectorLayoutData());
 		

 		createHyperLink(fixedSearchParamComposite, formToolkit);
-		createSearchParametersUI(fixedSearchParamComposite, formToolkit);
+		createSearchParametersUI(fixedSearchParamComposite, formToolkit, null);
 		
 		advancedSearchParamsComposite =  new Composite(upperComposite , SWT.NONE);

 		adaptAdvancedSearchParamsComposite(advancedSearchParamsComposite, fixedSearchParamComposite, false);		

@@ -375,12 +454,16 @@
 		return data;
 	}
 
-	private void createSearchParametersUI(final Composite parent, final FormToolkit toolkit)
+	private void createSearchParametersUI(final Composite parent, final FormToolkit toolkit, final ISearchProviderDescription provider)
 	{
-		final Composite searchParametersUIComposite = new Composite(parent, SWT.NONE);// formToolkit.createComposite(parent);
+		searchParametersUIComposite = new Composite(parent, SWT.NONE);// formToolkit.createComposite(parent);
 		searchParametersUIComposite.setLayoutData(createSearchParametersLayoutData());
-		searchParametersUI = new SearchParametersUI();
+		ISearchParametersUI customSearchParamsUi = getCustomSearchParametersUI(provider);
+		
+		searchParametersUI = customSearchParamsUi!=null? customSearchParamsUi : new SearchParametersUI();
 		final IConsoleContext context = new IConsoleContext() {
+			
+			private IPageSite site = new PageSiteAdapter( SearchConsoleView.this, SearchConsoleView.this.getViewSite());
 			@Override
 			public IObjectTypeDescription selectedObjectType() {
 				return getSelectedObjectType();
@@ -420,8 +503,37 @@
 			public int secondColumnLeftOffset() {
 				return getLongestLabelSize(getLeftSideLabels());
 			}
+
+			@Override
+			public IProgressMonitor progressMonitor() {
+				return viewProgressMonitor;
+			}
+
+			@Override
+			public IViewPart consolePart() {
+				return SearchConsoleView.this;
+			}
+
+			@Override
+			public IPageSite site() {
+				return site;
+			}
 		};
 		searchParametersUI.createUI(searchParametersUIComposite, toolkit, context);
+	}
+
+	private ISearchParametersUI getCustomSearchParametersUI(ISearchProviderDescription selectedProvider) {
+		if(selectedProvider==null) {
+			return null;
+		}
+		
+		for(ICustomSearchParametersUIDescription desc: new CustomSearchParametersUiParser(Platform.getExtensionRegistry()).readContributions()) {
+			if(desc.getSearchProviderId().equals(selectedProvider.getId())) {
+				return desc.searchParametersUI();
+			}
+		}
+		
+		return null;
 	}

 

 	

@@ -507,7 +619,8 @@
 	{

 		try

 		{

-			final ISearchParameters params = new SearchParameters(getSelectedObjectType().getId(), getSelectedDestination(), searchParametersUI.getKeyword(), searchParametersUI.getGroupingHierarchy(), activeSubdestinations());
+			final ISearchParameters params = new SearchParameters(getSelectedObjectType().getId(), getSelectedDestination(), searchParametersUI.getKeyword(), searchParametersUI.getGroupingHierarchy(), activeSubdestinations(),
+					searchParametersUI.getParameters());
 			advancedSearchParamsDisplayer.setParams(params);

 			final SearchEvent searchEvent = new SearchEvent(params, DefaultSessionIds.mainSearchSessionId, DiscoveryUIMessages.SEARCH_RESULT_TAB, null);

 			SearchConsoleView.this.controller.search(searchEvent);

@@ -664,6 +777,8 @@
 		super.dispose();

 		hyperlinkCursor.dispose();
 		upperCompositeGradientManager.disposeResources();
+		getViewSite().getPage().removePartListener(searchConsoleClosedListener);
+		
 	}

 

 	protected IAdvancedSearchParamsDisplayer createAdvancedSearchParamsDisplayer(final Composite parent, final FormToolkit formToolkit)

@@ -778,5 +893,7 @@
 	public ISearchConsoleControllerOutputView getControllerView()

 	{

 		return this;

-	}

+	}
+	
+	
 }

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/SearchProviderSelector.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/SearchProviderSelector.java
index 73bbdbf..2cec756 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/SearchProviderSelector.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/SearchProviderSelector.java
@@ -197,4 +197,10 @@
 	public Composite getControl() {

 		return this.selectorComposite;

 	}

+

+	@Override

+	public void hide() {

+		// TODO Auto-generated method stub

+		

+	}

 }

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/impl/SearchParameters.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/impl/SearchParameters.java
index 0fdf9dc..31e9f6b 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/impl/SearchParameters.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/impl/SearchParameters.java
@@ -26,20 +26,22 @@
  */

 public class SearchParameters implements ISearchParameters

 {

-	private final Map<Object, Object> customParameters = new HashMap<Object, Object>();

+	private final Map<Object, Object> customParameters;

 	private final String keywordString;

 	private final GroupingHierarchy groupingHierarchy;

 	private final String objectTypeId;

 	private final ISearchDestination searchDestination;

 	private final Set<ISearchSubdestination> subdestinations;

 	

-	public SearchParameters(final String objectTypeId, final ISearchDestination searchDestination, final String keyword, final GroupingHierarchy groupingH, final Set<ISearchSubdestination> subdestinations)

+	public SearchParameters(final String objectTypeId, final ISearchDestination searchDestination, final String keyword, final GroupingHierarchy groupingH, final Set<ISearchSubdestination> subdestinations,
+			final Map<Object, Object> customParams)

 	{

 		this.objectTypeId = objectTypeId;

 		this.searchDestination = searchDestination;

 		this.keywordString = keyword;

 		this.groupingHierarchy = groupingH;

-		this.subdestinations = subdestinations;

+		this.subdestinations = subdestinations;
+		this.customParameters = customParams;

 	}

 	

 	public String getKeywordString()

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/result/impl/ContributedUIFactory.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/result/impl/ContributedUIFactory.java
index bb2779a..c5dd976 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/result/impl/ContributedUIFactory.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/result/impl/ContributedUIFactory.java
@@ -101,7 +101,8 @@
 		}

 

 		@Override

-		public void dispose() {

+		public void dispose() {
+			srcuc.dispose();

 			parent.dispose();

 		}

 

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/result/impl/TabbedSessionDisplayer.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/result/impl/TabbedSessionDisplayer.java
index 1f2c631..b5fa815 100644
--- a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/result/impl/TabbedSessionDisplayer.java
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/view/result/impl/TabbedSessionDisplayer.java
@@ -88,7 +88,9 @@
 	

 	private final CTabFolder tabsFolder;

 	private Map<String, SessionTab> displayers;

-	private final UIFactory<T> uif;

+	private final UIFactory<T> uif;
+	
+	private ToolBar currentTabToolbar;

 	

 	public TabbedSessionDisplayer(Composite parent, UIFactory<T> uif, int tabFolderStyle)

 	{

@@ -150,7 +152,8 @@
 	}

 	

 	@Override

-	public void display(ISession<T> session) {

+	public void display(ISession<T> session) {
+		
 		sessionTab(session).display();

 	}

 	

@@ -195,7 +198,9 @@
 						toolbar.dispose();

 						tabsFolder.layout(true, true);

 					}

-				}}, false);

+				}}, false);
+			
+			createToolBar();

 		}

 		

 		public void display() {

@@ -203,7 +208,10 @@
 			tabVisibleProperty.set(true);

 			installContrubutedUI(uif);

 			tabItem.setText(currentSessionUI.title());

-			tabsFolder.layout(true, true);

+			tabsFolder.layout(true, true);
+			if(currentTabToolbar!=null) {
+				currentTabToolbar.layout(true, true);
+			}

 		}

 

 		private void updateNavButtons() {

@@ -221,7 +229,7 @@
 			final Composite contributedUiParentComposite = uif.getFormTookit().createComposite(tabComposite);

 			contributedUiParentComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

 			currentSessionUI = uif.create(session.historyTrack().current(), contributedUiParentComposite);

-			currentSessionUI.createControls();

+			currentSessionUI.createControls();
 		}

 

 		private ToolItem createPrevButton()

@@ -269,7 +277,10 @@
 			tb.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));

 			tabsFolder.setTabHeight(Math.max(tb.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, tabsFolder.getTabHeight()));

 			tabsFolder.setTopRight(tb, SWT.RIGHT);

-			tabsFolder.redraw();

+			tabsFolder.redraw();
+			
+			TabbedSessionDisplayer.this.currentTabToolbar = tb;
+

 			

 			return tb;

 		}

@@ -304,7 +315,7 @@
 		

 		private void createToolbarWithNavigationButtons()

 		{

-			toolbar = createToolBar();

+			toolbar = createToolBar();
 			prevButton = createPrevButton();

 			nextButton = createNextButton();

 			updateNavButtons();

@@ -344,5 +355,9 @@
 		}

 		

 		throw new IllegalStateException("Unknown tab item"); //$NON-NLS-1$

+	}
+	
+	public ToolBar getTheToolbar() {
+		return currentTabToolbar;
 	}

 }

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/ICustomSearchParametersUIDescription.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/ICustomSearchParametersUIDescription.java
new file mode 100644
index 0000000..e36b7cf
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/ICustomSearchParametersUIDescription.java
@@ -0,0 +1,14 @@
+package org.eclipse.platform.discovery.ui.internal.xp;

+

+import org.eclipse.platform.discovery.ui.api.ISearchParametersUI;

+

+public interface ICustomSearchParametersUIDescription {

+	

+	public String getId();

+	

+	public String getSearchProviderId();

+	

+	public ISearchParametersUI searchParametersUI();

+	

+	

+}

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/ICustomSearchParametersUIParser.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/ICustomSearchParametersUIParser.java
new file mode 100644
index 0000000..193c6bb
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/ICustomSearchParametersUIParser.java
@@ -0,0 +1,7 @@
+package org.eclipse.platform.discovery.ui.internal.xp;

+

+import org.eclipse.platform.discovery.runtime.internal.xp.IContributionsReader;

+

+public interface ICustomSearchParametersUIParser extends IContributionsReader<ICustomSearchParametersUIDescription> {

+

+}

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/impl/CustomSearchParametersUiDescription.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/impl/CustomSearchParametersUiDescription.java
new file mode 100644
index 0000000..fbb5cc4
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/impl/CustomSearchParametersUiDescription.java
@@ -0,0 +1,34 @@
+package org.eclipse.platform.discovery.ui.internal.xp.impl;

+

+import org.eclipse.platform.discovery.ui.api.ISearchParametersUI;

+import org.eclipse.platform.discovery.ui.internal.xp.ICustomSearchParametersUIDescription;

+

+public class CustomSearchParametersUiDescription implements ICustomSearchParametersUIDescription {

+

+	private final String id;

+	private final String searchProviderId;

+	private final ISearchParametersUI searchParamsUi;

+	

+	public CustomSearchParametersUiDescription(String id, String searchProviderId, ISearchParametersUI searchParamsUi) {

+		super();

+		this.id = id;

+		this.searchProviderId = searchProviderId;

+		this.searchParamsUi = searchParamsUi;

+	}

+

+	@Override

+	public String getId() {

+		return id;

+	}

+

+	@Override

+	public String getSearchProviderId() {

+		return searchProviderId;

+	}

+

+	@Override

+	public ISearchParametersUI searchParametersUI() {

+		return searchParamsUi;

+	}

+

+}

diff --git a/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/impl/CustomSearchParametersUiParser.java b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/impl/CustomSearchParametersUiParser.java
new file mode 100644
index 0000000..c6e1015
--- /dev/null
+++ b/bundles/org.eclipse.platform.discovery.ui/src/org/eclipse/platform/discovery/ui/internal/xp/impl/CustomSearchParametersUiParser.java
@@ -0,0 +1,29 @@
+package org.eclipse.platform.discovery.ui.internal.xp.impl;

+

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionRegistry;

+import org.eclipse.platform.discovery.runtime.internal.xp.impl.AbstractExtensionPointParser;

+import org.eclipse.platform.discovery.ui.api.ISearchParametersUI;

+import org.eclipse.platform.discovery.ui.internal.xp.ICustomSearchParametersUIDescription;

+import org.eclipse.platform.discovery.ui.internal.xp.ICustomSearchParametersUIParser;

+

+public class CustomSearchParametersUiParser extends AbstractExtensionPointParser<ICustomSearchParametersUIDescription> implements ICustomSearchParametersUIParser {

+

+	public static final String XP_ID = "org.eclipse.platform.discovery.ui.customsearchparametersui"; //$NON-NLS-1$

+	public static final String XP_ELEMENT_NAME = "contributor"; //$NON-NLS-1$

+	

+	public static final String ID_ARRT = "id";

+	public static final String SEARCH_PROVIDER_ID_ATTR = "searchproviderid";

+	public static final String CLASS_ATTR = "class";

+	

+	public CustomSearchParametersUiParser(IExtensionRegistry extRegistry) {

+		super(extRegistry, XP_ID, XP_ELEMENT_NAME);

+	}

+

+	@Override

+	protected ICustomSearchParametersUIDescription createObject(IConfigurationElement element) throws CoreException {

+		return new CustomSearchParametersUiDescription(element.getAttribute(ID_ARRT), element.getAttribute(SEARCH_PROVIDER_ID_ATTR), (ISearchParametersUI)element.createExecutableExtension(CLASS_ATTR));

+	}

+	

+}