/*******************************************************************************
 * 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.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) {
	}
}
