/*******************************************************************************
 * Copyright (c) 2010, 2016 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.actions;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jdt.core.search.TypeNameMatch;
import org.eclipse.jdt.core.search.TypeNameMatchRequestor;
import org.eclipse.jdt.debug.ui.console.JavaStackTraceConsoleFactory;
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsole;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * Action delegate for Open from Clipboard action.
 *
 * @since 3.7
 */
public class OpenFromClipboardAction implements IWorkbenchWindowActionDelegate {

	/**
	 * Pattern to match a simple name e.g. <code>OpenFromClipboardAction</code>
	 */
	private static final String SIMPLE_NAME_PATTERN= "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"; //$NON-NLS-1$

	/**
	 * Pattern to match a qualified name e.g.
	 * <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction</code>, or match a
	 * simple name e.g. <code>OpenFromClipboardAction</code>.
	 */
	private static final String QUALIFIED_NAME_PATTERN = "(" + SIMPLE_NAME_PATTERN //$NON-NLS-1$
			+ "\\.)*" + SIMPLE_NAME_PATTERN; //$NON-NLS-1$

	/**
	 * Pattern to match a qualified name e.g.
	 * <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction</code>.
	 */
	private static final String STRICT_QUALIFIED_NAME_PATTERN = "(" + SIMPLE_NAME_PATTERN //$NON-NLS-1$
			+ "\\.)+" + SIMPLE_NAME_PATTERN; //$NON-NLS-1$

	/**
	 * Pattern to match whitespace characters.
	 */
	private static final String WS = "\\s*"; //$NON-NLS-1$

	/**
	 * Pattern to match a java file name e.g. <code>OpenFromClipboardAction.java</code>
	 */
	private static final String JAVA_FILE_PATTERN = SIMPLE_NAME_PATTERN + "\\.java"; //$NON-NLS-1$

	/**
	 * Pattern to match a java file name followed by line number e.g.
	 * <code>OpenFromClipboardAction.java : 21</code>
	 */
	private static final String JAVA_FILE_LINE_PATTERN = JAVA_FILE_PATTERN + WS + ":" + WS + "\\d+"; //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * Pattern to match a qualified name followed by line number e.g.
	 * <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction : 21</code>
	 */
	private static final String TYPE_LINE_PATTERN = QUALIFIED_NAME_PATTERN + WS + ":" + WS + "\\d+"; //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * Pattern to match a line from a stack trace e.g.
	 * <code>(Assert.java:41)</code>
	 */
	private static final String STACK_TRACE_PARENTHESIZED_PATTERN = "\\(" + WS + JAVA_FILE_LINE_PATTERN + WS + "\\)"; //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * Pattern to match a line from a stack trace e.g.
	 * <code> at org.eclipse.core.runtime.Assert.isLegal(Assert.java:41)</code>
	 */
	private static final String STACK_TRACE_LINE_PATTERN = "[^()]*?" + STACK_TRACE_PARENTHESIZED_PATTERN; //$NON-NLS-1$

	/**
	 * Pattern to match a line from a stack trace e.g.
	 * <code> at org.eclipse.core.runtime.Assert.isLegal(Assert.java:41)</code>
	 */
	private static final String STACK_TRACE_QUALIFIED_LINE_PATTERN = "[^()]*?(" + STRICT_QUALIFIED_NAME_PATTERN + ")" + WS + STACK_TRACE_PARENTHESIZED_PATTERN; //$NON-NLS-1$ //$NON-NLS-2$

	/**
	 * Pattern to match a method e.g.
	 * <code>org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction.run(IAction)</code> ,
	 * <code>Worker.run()</code>
	 */
	private static final String METHOD_PATTERN = QUALIFIED_NAME_PATTERN + "\\(.*\\)"; //$NON-NLS-1$

	/**
	 * Pattern to match a stack element e.g. <code>java.lang.String.valueOf(char) line: 1456</code>
	 */
	private static final String STACK_PATTERN = METHOD_PATTERN + ".*\\d+"; //$NON-NLS-1$

	/**
	 * Pattern to match a member (field or method) of a type e.g.
	 * <code>OpenFromClipboardAction#run</code>, <code>Worker#run</code>
	 */
	private static final String MEMBER_PATTERN = QUALIFIED_NAME_PATTERN + "#" //$NON-NLS-1$
			+ SIMPLE_NAME_PATTERN;

	/**
	 * Pattern to match a method e.g. <code>OpenFromClipboardAction#run(IAction)</code>,
	 * <code>Worker#run()</code>
	 */
	private static final String METHOD_JAVADOC_REFERENCE_PATTERN = QUALIFIED_NAME_PATTERN + "#" //$NON-NLS-1$
			+ SIMPLE_NAME_PATTERN + "\\(.*\\)"; //$NON-NLS-1$

	/*
	 * Constants to indicate the pattern matched
	 */
	private static final int INVALID = 0;

	private static final int QUALIFIED_NAME = 1;

	private static final int JAVA_FILE = 2;

	private static final int JAVA_FILE_LINE = 3;

	private static final int TYPE_LINE = 4;

	private static final int STACK_TRACE_LINE = 5;

	private static final int METHOD = 6;

	private static final int STACK = 7;

	private static final int MEMBER = 8;

	private static final int METHOD_JAVADOC_REFERENCE = 9;

	private static final String TASK_NAME = ActionMessages.OpenFromClipboardAction_OpeningFromClipboard;

	/*
	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
	 */
	@Override
	public void run(IAction action) {
		Clipboard clipboard = new Clipboard(Display.getDefault());
		TextTransfer textTransfer = TextTransfer.getInstance();
		final String inputText = (String) clipboard.getContents(textTransfer);
		if (inputText == null || inputText.length() == 0) {
			openInputEditDialog(""); //$NON-NLS-1$
			return;
		}

		String trimmedText = inputText.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$
		List<Object> matches = new ArrayList<>();
		int line = 0;
		try {
			line = getJavaElementMatches(trimmedText, matches);
		}
		catch (InterruptedException e) {
			matches.clear(); // don't show partial matches
		}
		if (matches.size() > 0 || isSingleLineInput(inputText)) {
			handleMatches(matches, line, trimmedText);
			return;
		}
		handleMultipleLineInput(inputText);

		return;
	}

	private static JavaStackTraceConsole getJavaStackTraceConsole() {
		IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
		IConsole[] consoles = consoleManager.getConsoles();
		for (int i = 0; i < consoles.length; i++) {
			if (consoles[i] instanceof JavaStackTraceConsole) {
				return (JavaStackTraceConsole) consoles[i];
			}
		}
		return null;
	}

	private static void handleMultipleLineInput(String inputText) {
		// multiple lines - simply paste to the console and open it
		IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
		JavaStackTraceConsole console = getJavaStackTraceConsole();
		if (console != null) {
			console.getDocument().set(inputText);
			consoleManager.showConsoleView(console);
		} else {
			JavaStackTraceConsoleFactory javaStackTraceConsoleFactory = new JavaStackTraceConsoleFactory();
			javaStackTraceConsoleFactory.openConsole(inputText);
			console = getJavaStackTraceConsole();
		}
		IPreferenceStore preferenceStore = JDIDebugUIPlugin.getDefault().getPreferenceStore();
		if (preferenceStore.getBoolean(IJDIPreferencesConstants.PREF_AUTO_FORMAT_JSTCONSOLE)) {
			console.format();
		}
	}

	private static boolean isSingleLineInput(String inputText) {
		String lineDelimiter = System.getProperty("line.separator"); //$NON-NLS-1$
		String s = inputText.trim();
		return s.indexOf(lineDelimiter) == -1;
	}

	private static int getMatchingPattern(String s) {
		if (s.matches(JAVA_FILE_LINE_PATTERN)) {
			return JAVA_FILE_LINE;
		}
		if (s.matches(JAVA_FILE_PATTERN)) {
			return JAVA_FILE;
		}
		if (s.matches(TYPE_LINE_PATTERN)) {
			return TYPE_LINE;
		}
		if (s.matches(STACK_TRACE_LINE_PATTERN)) {
			return STACK_TRACE_LINE;
		}
		if (s.matches(METHOD_PATTERN)) {
			return METHOD;
		}
		if (s.matches(STACK_PATTERN)) {
			return STACK;
		}
		if (s.matches(MEMBER_PATTERN)) {
			return MEMBER;
		}
		if (s.matches(METHOD_JAVADOC_REFERENCE_PATTERN)) {
			return METHOD_JAVADOC_REFERENCE;
		}
		if (s.matches(QUALIFIED_NAME_PATTERN)) {
			return QUALIFIED_NAME;
		}
		return INVALID;
	}

	private static void handleSingleLineInput(String inputText) {
		List<Object> matches = new ArrayList<>();
		try {
			int line= getJavaElementMatches(inputText, matches);
			handleMatches(matches, line, inputText);
		} catch (InterruptedException ex) {
			// Do nothing
		}
	}

	/**
	 * Parse the input text and search for the corresponding Java elements.
	 *
	 * @param inputText the line number
	 * @param matches matched Java elements
	 * @return the line number
	 * @throws InterruptedException if canceled by the user
	 */
	private static int getJavaElementMatches(String inputText, List<Object> matches) throws InterruptedException {
		String s = inputText.trim();
		switch (getMatchingPattern(s)) {
		case JAVA_FILE_LINE: {
			int index = s.indexOf(':');
			String typeName = s.substring(0, index);
			typeName = s.substring(0, typeName.indexOf(".java")); //$NON-NLS-1$
			String lineNumber = s.substring(index + 1, s.length());
			lineNumber = lineNumber.trim();
			int line = (Integer.valueOf(lineNumber)).intValue();
			getTypeMatches(typeName, matches);
			return line;
		}
		case JAVA_FILE: {
			String typeName = s.substring(0, s.indexOf(".java")); //$NON-NLS-1$
			getTypeMatches(typeName, matches);
			return -1;
		}
		case TYPE_LINE: {
			int index = s.indexOf(':');
			String typeName = s.substring(0, index);
			typeName = typeName.trim();
			String lineNumber = s.substring(index + 1, s.length());
			lineNumber = lineNumber.trim();
			int line = (Integer.valueOf(lineNumber)).intValue();
			getTypeMatches(typeName, matches);
			return line;
		}
		case STACK_TRACE_LINE: {
			int index1 = s.lastIndexOf('(');
			int index2 = s.lastIndexOf(')');
			String typeLine = s.substring(index1 + 1, index2).trim();
			int index = typeLine.indexOf(':');
			String lineNumber = typeLine.substring(index + 1, typeLine.length()).trim();
			int line = (Integer.valueOf(lineNumber)).intValue();

			Pattern pattern = Pattern.compile(STACK_TRACE_QUALIFIED_LINE_PATTERN);
			Matcher matcher = pattern.matcher(s);
			if (matcher.find()) {
				String qualifiedName = matcher.group(1);
				index = qualifiedName.lastIndexOf('.');
				qualifiedName = qualifiedName.substring(0, index);
				getTypeMatches(qualifiedName, matches);
			} else {
				String typeName = typeLine.substring(0, index);
				typeName = typeLine.substring(0, typeName.indexOf(".java")); //$NON-NLS-1$
				getTypeMatches(typeName, matches);
			}
			return line;
		}
		case METHOD: {
			getMethodMatches(s, matches);
			return -1;
		}
		case STACK: {
			int index = s.indexOf(')');
			String method = s.substring(0, index + 1);
			index = s.indexOf(':');
			String lineNumber = s.substring(index + 1).trim();
			int line = (Integer.valueOf(lineNumber)).intValue();
			getMethodMatches(method, matches);
			return line;
		}
		case MEMBER:
			getMemberMatches(s.replace('#', '.'), matches);
			return -1;
		case METHOD_JAVADOC_REFERENCE:
			getMethodMatches(s.replace('#', '.'), matches);
			return -1;
		case QUALIFIED_NAME:
			getNameMatches(s, matches);
			return -1;
		default:
			return -1;
		}
	}

	/**
	 * Perform a Java search for the type and return the corresponding Java elements.
	 *
	 * @param typeName the Type name
	 * @param matches matched Java elements
	 * @throws InterruptedException if canceled by the user
	 */
	private static void getTypeMatches(final String typeName, final List<Object> matches) throws InterruptedException {
		executeRunnable(new IRunnableWithProgress() {
			@Override
			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				doTypeSearch(typeName, matches, monitor);
			}
		});
	}

	/**
	 * Perform a Java search for methods and constructors and return the corresponding Java
	 * elements.
	 *
	 * @param s the method pattern
	 * @param matches matched Java elements
	 * @throws InterruptedException if canceled by the user
	 */
	private static void getMethodMatches(final String s, final List<Object> matches) throws InterruptedException {
		executeRunnable(new IRunnableWithProgress() {
			@Override
			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				doMemberSearch(s, matches, true, true, false, monitor, 100);
			}
		});
	}

	/**
	 * Perform a Java search for fields, methods and constructors and return the corresponding Java
	 * elements.
	 *
	 * @param s the member pattern
	 * @param matches matched Java elements
	 * @throws InterruptedException if canceled by the user
	 */
	private static void getMemberMatches(final String s, final List<Object> matches) throws InterruptedException {
		executeRunnable(new IRunnableWithProgress() {
			@Override
			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				doMemberSearch(s, matches, true, true, true, monitor, 100);
			}
		});
	}

	/**
	 * Perform a Java search for types, fields and methods and return the corresponding Java
	 * elements.
	 *
	 * @param s the qualified name pattern
	 * @param matches matched Java elements
	 * @throws InterruptedException if canceled by the user
	 */
	private static void getNameMatches(final String s, final List<Object> matches) throws InterruptedException {
		executeRunnable(new IRunnableWithProgress() {
			@Override
			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
				SubMonitor progress = SubMonitor.convert(monitor, 100);
				progress.beginTask(TASK_NAME, 100);
				doTypeSearch(s, matches, progress.newChild(34));
				doMemberSearch(s, matches, true, false, true, progress.newChild(34), 66);
			}
		});
	}

	private static void executeRunnable(IRunnableWithProgress runnableWithProgress) throws InterruptedException {
		try {
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(runnableWithProgress);
		} catch (InvocationTargetException e) {
			JDIDebugUIPlugin.log(e);
		}
	}

	/**
	 * Handles the given matches.
	 *
	 * @param matches matched Java elements
	 * @param line the line number
	 * @param inputText the input text
	 * @throws InterruptedException if canceled by the user
	 */
	private static void handleMatches(List<Object> matches, int line, String inputText) {
		if (matches.size() > 1) {
			int flags = JavaElementLabelProvider.SHOW_DEFAULT | JavaElementLabelProvider.SHOW_QUALIFIED | JavaElementLabelProvider.SHOW_ROOT;
			IWorkbenchWindow window = JDIDebugUIPlugin.getActiveWorkbenchWindow();
			ElementListSelectionDialog dialog = new ElementListSelectionDialog(window.getShell(), new JavaElementLabelProvider(flags)) {
				/*
				 * @see org.eclipse.ui.dialogs.SelectionDialog#getDialogBoundsSettings()
				 * @since 4.3
				 */
				@Override
				protected IDialogSettings getDialogBoundsSettings() {
					IDialogSettings settings = JDIDebugUIPlugin.getDefault().getDialogSettings();
					return DialogSettings.getOrCreateSection(settings, "OpenFromClipboardAction_dialogBounds"); //$NON-NLS-1$
				}
			};
			dialog.setTitle(ActionMessages.OpenFromClipboardAction_OpenFromClipboard);
			dialog.setMessage(ActionMessages.OpenFromClipboardAction_SelectOrEnterTheElementToOpen);
			dialog.setElements(matches.toArray());
			dialog.setMultipleSelection(true);

			int result = dialog.open();
			if (result != IDialogConstants.OK_ID) {
				return;
			}

			Object[] elements = dialog.getResult();
			if (elements != null && elements.length > 0) {
				openJavaElements(elements, line);
			}
		} else if (matches.size() == 1) {
			openJavaElements(matches.toArray(), line);
		} else if (matches.size() == 0) {
			openInputEditDialog(inputText);
		}
	}

	/**
	 * Opens each specified Java element in a Java editor and navigates to the specified line
	 * number.
	 *
	 * @param elements
	 *            the Java elements
	 * @param line
	 *            the line number
	 */
	private static void openJavaElements(Object[] elements, int line) {
		for (int i = 0; i < elements.length; i++) {
			Object ob = elements[i];
			if (ob instanceof IJavaElement) {
				IJavaElement element = (IJavaElement) ob;
				try {
					IEditorPart editorPart = JavaUI.openInEditor(element);
					gotoLine(editorPart, line, element);
				} catch (PartInitException e) {
					JDIDebugUIPlugin.log(e);
				} catch (JavaModelException e) {
					JDIDebugUIPlugin.log(e);
				}
			}
		}
	}

	/**
	 * Jumps to the given line in the editor if the line number lies within the given Java element.
	 *
	 * @param editorPart the Editor part
	 * @param line the line to jump to
	 * @param element the Java Element
	 * @throws JavaModelException if fetching the Java element's source range fails
	 */
	private static void gotoLine(IEditorPart editorPart, int line, IJavaElement element) throws JavaModelException {
		if (line <= 0) {
			return;
		}
		ITextEditor editor = (ITextEditor) editorPart;
		IDocumentProvider provider = editor.getDocumentProvider();
		IDocument document = provider.getDocument(editor.getEditorInput());
		try {
			if (element instanceof IMethod) {
				ISourceRange sourceRange = ((IMethod) element).getSourceRange();
				int start = sourceRange.getOffset();
				int end = start + sourceRange.getLength();
				start = document.getLineOfOffset(start);
				end = document.getLineOfOffset(end);
				if (start > line || end < line) {
					return;
				}
			}
			int start = document.getLineOffset(line - 1);
			editor.selectAndReveal(start, 0);
			IWorkbenchPage page = editor.getSite().getPage();
			page.activate(editor);
		} catch (BadLocationException e) {
			// ignore
		}
	}

	/**
	 * Opens an text input dialog to let the user refine the input text.
	 *
	 * @param inputText the input text
	 */
	private static void openInputEditDialog(String inputText) {
		IWorkbenchWindow window = JDIDebugUIPlugin.getActiveWorkbenchWindow();
		IInputValidator validator = new IInputValidator() {
			@Override
			public String isValid(String newText) {
				return newText.length() == 0 ? "" : null; //$NON-NLS-1$
			}
		};
		InputDialog dialog = new InputDialog(window.getShell(), ActionMessages.OpenFromClipboardAction_OpenFromClipboard, ActionMessages.OpenFromClipboardAction_ElementToOpen, inputText, validator);
		int result = dialog.open();
		if (result != IDialogConstants.OK_ID) {
			return;
		}

		inputText = dialog.getValue();
		handleSingleLineInput(inputText);
	}

	private static SearchPattern createSearchPattern(String s, int searchFor) {
		return SearchPattern.createPattern(s, searchFor, IJavaSearchConstants.DECLARATIONS, getSearchFlags());
	}

	private static int getSearchFlags() {
		return SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_ERASURE_MATCH;
	}

	private static SearchRequestor createSearchRequestor(final List<Object> matches) {
		return new SearchRequestor() {
			@Override
			public void acceptSearchMatch(SearchMatch match) {
				if (match.getAccuracy() == SearchMatch.A_ACCURATE) {
					matches.add(match.getElement());
				}
			}
		};
	}

	private static SearchParticipant[] createSearchParticipant() {
		return new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() };
	}

	/**
	 * Perform a Java search for the type and return the corresponding Java elements.
	 *
	 * <p>
	 * TODO: Because of faster performance SearchEngine.searchAllTypeNames(...) is used to do the
	 * Java Search, instead of the usual SearchEngine.search(...) API. This logic should be moved to
	 * JDT/Core.
	 * </p>
	 *
	 * @param typeName
	 *            the Type Name
	 * @param matches
	 *            matched Java Elements
	 * @param monitor
	 *            the Progress Monitor
	 */
	private static void doTypeSearch(String typeName, final List<Object> matches, IProgressMonitor monitor) {
		IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
		SearchEngine searchEngine = new SearchEngine();

		String packageName = null;
		int index = typeName.lastIndexOf('.');
		if (index != -1) {
			packageName = typeName.substring(0, index);
			typeName = typeName.substring(index + 1);
		}
		try {
			searchEngine.searchAllTypeNames(packageName == null ? null : packageName.toCharArray(), packageName == null ? SearchPattern.R_EXACT_MATCH : getSearchFlags(), typeName.toCharArray(),
					getSearchFlags(), IJavaSearchConstants.TYPE, scope, new TypeNameMatchRequestor() {
						@Override
						public void acceptTypeNameMatch(TypeNameMatch match) {
							matches.add(match.getType());
						}
					}, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, monitor);
		} catch (CoreException e) {
			JDIDebugUIPlugin.log(e);
		}
	}

	/**
	 * Perform a Java search for one or more of fields, methods and constructors and return the
	 * corresponding Java elements.
	 *
	 * <p>
	 * TODO: Because of faster performance, if the type name is available
	 * SearchEngine.searchAllTypeNames(...) is used to narrow the scope of Java Search. This logic
	 * should be moved to JDT/Core.
	 * </p>
	 *
	 * @param memberName
	 *            the Member Name
	 * @param matches
	 *            matched Java Elements
	 * @param searchForMethods
	 *            if <code>true</code>, a method search is performed
	 * @param searchForConstructors
	 *            if <code>true</code>, a constructor search is performed
	 * @param searchForFields
	 *            if <code>true</code>, a field search is performed
	 * @param monitor
	 *            the Progress Monitor
	 * @param work
	 *            the remaining Work
	 */
	private static void doMemberSearch(String memberName, final List<Object> matches, boolean searchForMethods, boolean searchForConstructors, boolean searchForFields, IProgressMonitor monitor, int work) {
		int noOfSearches = 0;
		noOfSearches = searchForMethods ? noOfSearches + 1 : noOfSearches;
		noOfSearches = searchForConstructors ? noOfSearches + 1 : noOfSearches;
		noOfSearches = searchForFields ? noOfSearches + 1 : noOfSearches;
		if (noOfSearches == 0) {
			return;
		}

		SubMonitor progress = SubMonitor.convert(monitor);
		progress.beginTask(TASK_NAME, work);

		IJavaSearchScope scope = null;
		SearchRequestor requestor = createSearchRequestor(matches);
		SearchEngine searchEngine = new SearchEngine();

		String typeName = null;
		int index = memberName.lastIndexOf('.');
		if (index != -1) {
			typeName = memberName.substring(0, index);
			memberName = memberName.substring(index + 1);
			final List<Object> typeMatches = new ArrayList<>();
			noOfSearches++;
			doTypeSearch(typeName, typeMatches, progress.newChild(work / noOfSearches));
			IType[] types = new IType[typeMatches.size()];
			for (int i = 0; i < typeMatches.size(); i++) {
				types[i] = (IType) typeMatches.get(i);
			}
			scope = SearchEngine.createJavaSearchScope(types);
		} else {
			scope = SearchEngine.createWorkspaceScope();
		}
		try {
			int workPerSearch = work / noOfSearches;
			if (searchForMethods) {
				doMemberSearch(searchEngine, memberName, IJavaSearchConstants.METHOD, scope, requestor, progress.newChild(workPerSearch));
			}
			if (searchForConstructors) {
				doMemberSearch(searchEngine, memberName, IJavaSearchConstants.CONSTRUCTOR, scope, requestor, progress.newChild(workPerSearch));
			}
			if (searchForFields) {
				doMemberSearch(searchEngine, memberName, IJavaSearchConstants.FIELD, scope, requestor, progress.newChild(workPerSearch));
			}
		} catch (CoreException e) {
			JDIDebugUIPlugin.log(e);
		}
	}

	private static void doMemberSearch(SearchEngine searchEngine, String memberName, int searchFor, IJavaSearchScope scope, SearchRequestor requestor, SubMonitor progressMonitor) throws CoreException {
		SearchPattern pattern = createSearchPattern(memberName, searchFor);
		if (pattern != null) {
			searchEngine.search(pattern, createSearchParticipant(), scope, requestor, progressMonitor);
		}
	}

	/*
	 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action .IAction,
	 * org.eclipse.jface.viewers.ISelection)
	 */
	@Override
	public void selectionChanged(IAction action, ISelection selection) {
	}

	/*
	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
	 */
	@Override
	public void dispose() {
	}

	/*
	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui. IWorkbenchWindow)
	 */
	@Override
	public void init(IWorkbenchWindow window) {
	}
}
