/*******************************************************************************
 * Copyright (c) 2010, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.lineSeparator();
		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.parseInt(lineNumber);
			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.parseInt(lineNumber);
			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.parseInt(lineNumber);

			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.parseInt(lineNumber);
			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.isEmpty()) {
			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) {
	}
}
