bug 354430: [search] provide API to enable programatic creation of desktop search queries 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=354430
diff --git a/org.eclipse.mylyn.sandbox.search.ui/plugin.xml b/org.eclipse.mylyn.sandbox.search.ui/plugin.xml
index 4fe3079..1f94b29 100644
--- a/org.eclipse.mylyn.sandbox.search.ui/plugin.xml
+++ b/org.eclipse.mylyn.sandbox.search.ui/plugin.xml
@@ -30,6 +30,16 @@
             id="org.eclipse.mylyn.internal.sandbox.search.ui.openDesktopSearchCommand"
             name="%command.name">
       </command>
+      <command
+            categoryId="org.eclipse.search.ui.category.search"
+            description="Perform a search"
+            id="org.eclipse.mylyn.sandbox.search.ui.performSearchCommand"
+            name="Perform search">
+            <commandParameter
+                  id="org.eclipse.mylyn.sandbox.search.ui.searchText" name="Search Text" optional="false"/>
+            <commandParameter
+                  id="org.eclipse.mylyn.sandbox.search.ui.filenameFilter" name="Filename Filter" optional="true"/>
+      </command>
    </extension>
    <extension
          point="org.eclipse.ui.handlers">
@@ -37,6 +47,10 @@
             commandId="org.eclipse.mylyn.internal.sandbox.search.ui.openDesktopSearchCommand"
             class="org.eclipse.mylyn.internal.sandbox.search.ui.OpenDesktopSearchHandler">
       </handler>
+      <handler
+            commandId="org.eclipse.mylyn.sandbox.search.ui.performSearchCommand"
+            class="org.eclipse.mylyn.internal.sandbox.search.ui.PerfomSearchHandler">
+      </handler>
    </extension>
    <extension
          point="org.eclipse.ui.actionSets">
diff --git a/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/AbstractUiHandler.java b/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/AbstractUiHandler.java
new file mode 100644
index 0000000..ef4b4bf
--- /dev/null
+++ b/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/AbstractUiHandler.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.sandbox.search.ui;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * @author David Green
+ */
+public abstract class AbstractUiHandler extends AbstractHandler {
+
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		Display display = computeDisplay(event);
+		display.asyncExec(computeUiRunnable(event));
+		return null;
+	}
+
+	protected abstract Runnable computeUiRunnable(ExecutionEvent event);
+
+	protected IWorkbenchWindow computeWorkbenchWindow(ExecutionEvent event) {
+		IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
+		if (window == null) {
+			window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+			if (window == null) {
+				window = PlatformUI.getWorkbench().getWorkbenchWindows()[0];
+			}
+		}
+		return window;
+	}
+
+	protected Display computeDisplay(ExecutionEvent event) {
+		Display display = null;
+		final IWorkbenchWindow workbenchWindow = computeWorkbenchWindow(event);
+		if (workbenchWindow != null) {
+			display = workbenchWindow.getShell().getDisplay();
+		}
+		if (display == null) {
+			display = Display.getDefault();
+		}
+		return display;
+	}
+}
diff --git a/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/OpenDesktopSearchHandler.java b/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/OpenDesktopSearchHandler.java
index 18386cf..2846bc2 100644
--- a/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/OpenDesktopSearchHandler.java
+++ b/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/OpenDesktopSearchHandler.java
@@ -10,33 +10,22 @@
  *******************************************************************************/
 package org.eclipse.mylyn.internal.sandbox.search.ui;
 
-import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.commands.IHandler;
 import org.eclipse.search.ui.NewSearchUI;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.handlers.HandlerUtil;
 
 /**
  * @author David Green
  */
-public class OpenDesktopSearchHandler extends AbstractHandler implements IHandler {
+public class OpenDesktopSearchHandler extends AbstractUiHandler implements IHandler {
 
-	public Object execute(ExecutionEvent event) throws ExecutionException {
-		Display display = null;
-		final IWorkbenchWindow workbenchWindow = HandlerUtil.getActiveWorkbenchWindow(event);
-		if (workbenchWindow != null) {
-			display = workbenchWindow.getShell().getDisplay();
-		}
-		if (display == null) {
-			display = Display.getDefault();
-		}
-		display.asyncExec(new Runnable() {
+	@Override
+	protected Runnable computeUiRunnable(final ExecutionEvent event) {
+		return new Runnable() {
 			public void run() {
-				IWorkbenchWindow window = workbenchWindow;
+				IWorkbenchWindow window = computeWorkbenchWindow(event);
 				if (window == null) {
 					window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
 					if (window == null) {
@@ -45,8 +34,7 @@
 				}
 				NewSearchUI.openSearchDialog(window, DesktopSearchPage.PAGE_ID);
 			}
-		});
-		return null;
+		};
 	}
 
 }
diff --git a/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/PerfomSearchHandler.java b/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/PerfomSearchHandler.java
new file mode 100644
index 0000000..011e8e6
--- /dev/null
+++ b/org.eclipse.mylyn.sandbox.search.ui/src/org/eclipse/mylyn/internal/sandbox/search/ui/PerfomSearchHandler.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Tasktop Technologies.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Tasktop Technologies - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.mylyn.internal.sandbox.search.ui;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.mylyn.sandbox.search.ui.Search;
+import org.eclipse.mylyn.sandbox.search.ui.SearchCriteria;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.search.ui.ISearchQuery;
+import org.eclipse.search.ui.NewSearchUI;
+
+/**
+ * A handler that performs a search.
+ * 
+ * @author David Green
+ */
+public class PerfomSearchHandler extends AbstractUiHandler implements IHandler {
+
+	public static final String PARAM_SEARCH_TEXT = "org.eclipse.mylyn.sandbox.search.ui.searchText"; //$NON-NLS-1$
+
+	public static final String PARAM_FILENAME_FILTER = "org.eclipse.mylyn.sandbox.search.ui.filenameFilter"; //$NON-NLS-1$
+
+	@Override
+	protected Runnable computeUiRunnable(final ExecutionEvent event) {
+		String searchText = event.getParameter(PARAM_SEARCH_TEXT);
+		String filenameFilter = event.getParameter(PARAM_FILENAME_FILTER);
+		final SearchCriteria criteria = new SearchCriteria();
+		criteria.setFilenamePatternsAsText(filenameFilter);
+		criteria.setText(searchText);
+		return new Runnable() {
+			public void run() {
+				ISearchQuery searchQuery;
+				try {
+					searchQuery = Search.createSearchQuery(criteria);
+				} catch (CoreException e) {
+					ErrorDialog.openError(computeWorkbenchWindow(event).getShell(),
+							Messages.DesktopSearchPage_SearchFailedTitle,
+							NLS.bind(Messages.DesktopSearchPage_SearchFailedMessage, e.getStatus().getMessage()),
+							e.getStatus());
+					return;
+				}
+				NewSearchUI.runQueryInBackground(searchQuery);
+			}
+		};
+	}
+
+}