/*******************************************************************************
 * Copyright (c) 2000, 2021 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.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension2;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IOrdinaryClassFile;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.SourceRange;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.manipulation.SharedASTProviderCore;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaClassPrepareBreakpoint;
import org.eclipse.jdt.debug.core.IJavaFieldVariable;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext;
import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType;
import org.eclipse.jdt.internal.corext.template.java.JavaContextType;
import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
import org.eclipse.jdt.internal.debug.core.breakpoints.ValidBreakpointLocationLocator;
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
import org.eclipse.jdt.internal.debug.ui.DebugWorkingCopyManager;
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine;
import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal;
import org.eclipse.jdt.ui.IWorkingCopyManager;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.jface.text.templates.DocumentTemplateContext;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;

/**
 * Toggles a line breakpoint in a Java editor.
 *
 * @since 3.0
 */
public class ToggleBreakpointAdapter implements IToggleBreakpointsTargetExtension2 {

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


	/**
	 * Constructor
	 */
	public ToggleBreakpointAdapter() {
		// initialize helper in UI thread
		ActionDelegateHelper.getDefault();
	}

    /**
     * Returns the <code>IType</code> for the given selection
     * @param selection the current text selection
     * @return the <code>IType</code> for the text selection or <code>null</code>
     */
	protected static IType getType(ITextSelection selection) {
        IMember member = ActionDelegateHelper.getDefault().getCurrentMember(selection);
        IType type = null;
        if (member instanceof IType) {
            type = (IType) member;
        } else if (member != null) {
            type = member.getDeclaringType();
        }
        // bug 52385: we don't want local and anonymous types from compilation
        // unit,
        // we are getting 'not-always-correct' names for them.
        try {
            while (type != null && !type.isBinary() && type.isLocal()) {
                type = type.getDeclaringType();
            }
		} catch (JavaModelException e) {
			JDIDebugUIPlugin.log(e);
		}
        return type;
    }

    /**
     * Returns the IType associated with the <code>IJavaElement</code> passed in
     * @param element the <code>IJavaElement</code> to get the type from
     * @return the corresponding <code>IType</code> for the <code>IJavaElement</code>, or <code>null</code> if there is not one.
     * @since 3.3
     */
	protected static IType getType(IJavaElement element) {
    	switch(element.getElementType()) {
	    	case IJavaElement.FIELD: {
	    		return ((IField)element).getDeclaringType();
	    	}
	    	case IJavaElement.METHOD: {
	    		return ((IMethod)element).getDeclaringType();
	    	}
	    	case IJavaElement.TYPE: {
	    		return (IType)element;
	    	}
	    	default: {
	    		return null;
	    	}
    	}
    }

    @Override
	public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
    	toggleLineBreakpoints(part, selection, false, null);
    }

    /**
     * Toggles a line breakpoint.
     * @param part the currently active workbench part
     * @param selection the current selection
     * @param bestMatch if we should make a best match or not
     */
	public static void toggleLineBreakpoints(final IWorkbenchPart part, final ISelection selection, final boolean bestMatch, final ValidBreakpointLocationLocator locator) {
        Job job = new Job("Toggle Line Breakpoint") { //$NON-NLS-1$
            @Override
			protected IStatus run(IProgressMonitor monitor) {
            	return doLineBreakpointToggle(selection, part, locator, bestMatch, monitor);
            }
        };
        job.setPriority(Job.INTERACTIVE);
        job.setSystem(true);
        job.schedule();
    }

    @Override
	public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
    	if (isRemote(part, selection)) {
    		return false;
    	}
        return selection instanceof ITextSelection;
    }

    @Override
	public void toggleMethodBreakpoints(final IWorkbenchPart part, final ISelection finalSelection) {
        Job job = new Job("Toggle Method Breakpoints") { //$NON-NLS-1$
            @Override
			protected IStatus run(IProgressMonitor monitor) {
                if (monitor.isCanceled()) {
                    return Status.CANCEL_STATUS;
                }
                try {
					return doToggleMethodBreakpoints(part, finalSelection, monitor);
                } catch (CoreException e) {
                    return e.getStatus();
				} finally {
					BreakpointToggleUtils.setUnsetTracepoints(false);
				}
            }
        };
        job.setPriority(Job.INTERACTIVE);
        job.setSystem(true);
        job.schedule();
    }

	static IStatus doToggleMethodBreakpoints(IWorkbenchPart part, ISelection finalSelection, IProgressMonitor monitor) throws CoreException {
		BreakpointToggleUtils.report(null, part);
		ISelection selection = finalSelection;
		if (!(selection instanceof IStructuredSelection)) {
			selection = translateToMembers(part, selection);
		}
		boolean isInterface = isInterface(selection, part);
		if (!(selection instanceof IStructuredSelection)) {
			BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_4, part);
			return Status.OK_STATUS;
		}
		IMethod[] members = getMethods((IStructuredSelection) selection, isInterface);
		if (members.length == 0) {
			if (isInterface) {
				BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_6, part);
			} else {
				BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_9, part);
			}
			return Status.OK_STATUS;
		}
		for (IMethod member : members) {
			doToggleMethodBreakpoint(member, part, finalSelection, monitor);
		}
		return Status.OK_STATUS;
	}

	private static void doToggleMethodBreakpoint(IMethod member, IWorkbenchPart part, ISelection finalSelection, IProgressMonitor monitor) throws CoreException {
		IJavaBreakpoint breakpoint = getMethodBreakpoint(member);
		if (breakpoint != null) {
			if (BreakpointToggleUtils.isToggleTracepoints()) {
				deleteTracepoint(breakpoint, part, monitor);
				BreakpointToggleUtils.setUnsetTracepoints(false);
			} else {
				deleteBreakpoint(breakpoint, part, monitor);
			}
			return;
		}
		int start = -1;
		int end = -1;
		ISourceRange range = member.getNameRange();
		if (range != null) {
			start = range.getOffset();
			end = start + range.getLength();
		}
		Map<String, Object> attributes = new HashMap<>(10);
		BreakpointUtils.addJavaBreakpointAttributes(attributes, member);
		IType type = member.getDeclaringType();
		String signature = member.getSignature();
		String mname = member.getElementName();
		if (member.isConstructor()) {
			mname = "<init>"; //$NON-NLS-1$
			if (type.isEnum()) {
				signature = "(Ljava.lang.String;I" + signature.substring(1); //$NON-NLS-1$
			}
		}
		if (!type.isBinary()) {
			signature = resolveMethodSignature(member);
			if (signature == null) {
				BreakpointToggleUtils.report(ActionMessages.ManageMethodBreakpointActionDelegate_methodNonAvailable, part);
				return;
			}
		}
		IResource resource = BreakpointUtils.getBreakpointResource(member);
		String qualifiedName = getQualifiedName(type);
		IJavaMethodBreakpoint methodBreakpoint = JDIDebugModel.createMethodBreakpoint(resource, qualifiedName, mname, signature, true, false, false, -1, start, end, 0, true, attributes);
		if (BreakpointToggleUtils.isToggleTracepoints() && finalSelection instanceof ITextSelection && part instanceof JavaEditor) {
			String pattern = getCodeTemplate((ITextSelection) finalSelection, (JavaEditor) part);
			if (pattern != null) {
				pattern = pattern.trim();
				pattern = pattern.replaceAll("\\\t", ""); //$NON-NLS-1$//$NON-NLS-2$
				methodBreakpoint.setCondition(pattern);
				methodBreakpoint.setConditionEnabled(true);
				methodBreakpoint.setConditionSuspendOnTrue(true);
			}
			BreakpointToggleUtils.setUnsetTracepoints(false);
		}
	}

	/**
	 * Performs the actual toggling of the line breakpoint
     * @param selection the current selection (from the editor or view)
     * @param part the active part
     * @param locator the locator, may be <code>null</code>
     * @param bestMatch if we should consider the best match rather than an exact match
     * @param monitor progress reporting
	 * @return the status of the toggle
	 * @since 3.8
	 */
	static IStatus doLineBreakpointToggle(ISelection selection, IWorkbenchPart part, ValidBreakpointLocationLocator locator, boolean bestMatch, IProgressMonitor monitor) {
		ITextEditor editor = getTextEditor(part);
		if (editor == null || !(selection instanceof ITextSelection)) {
			return Status.CANCEL_STATUS;
		}
		if (monitor.isCanceled()) {
			return Status.CANCEL_STATUS;
		}
		ITextSelection tsel = (ITextSelection) selection;
		if (tsel.getStartLine() < 0) {
			return Status.CANCEL_STATUS;
		}
		try {
			BreakpointToggleUtils.report(null, part);
			ISelection sel = selection;
			if (!(selection instanceof IStructuredSelection)) {
				sel = translateToMembers(part, selection);
			}
			if (!(sel instanceof IStructuredSelection)) {
				BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_3, part);
				return Status.OK_STATUS;
			}
			IMember member = (IMember) ((IStructuredSelection) sel).getFirstElement();
			IType type = null;
			if (member.getElementType() == IJavaElement.TYPE) {
				type = (IType) member;
			} else {
				type = member.getDeclaringType();
			}
			if (type == null) {
				IStatus status = new Status(IStatus.INFO, DebugUIPlugin.getUniqueIdentifier(), ActionMessages.ToggleBreakpointAdapter_ErrorMessage);
				Display.getDefault().asyncExec(() -> ErrorDialog.openError(JDIDebugUIPlugin.getShell(), ActionMessages.ToggleBreakpointAdapter_ErrorTitle, null, status));
				return status;
			}
			if (locator == null && BreakpointToggleUtils.isToggleTracepoints()) {
				CompilationUnit cUnit = parseCompilationUnit(type.getTypeRoot());
				locator = new ValidBreakpointLocationLocator(cUnit, tsel.getStartLine() + 1, true, bestMatch);
				cUnit.accept(locator);
			}
			String tname = null;
			IJavaProject project = type.getJavaProject();
			if (locator == null || (project != null && !project.isOnClasspath(type))) {
				tname = createQualifiedTypeName(type);
			} else {
				tname = locator.getFullyQualifiedTypeName();
			}
			if (tname == null) {
				return Status.CANCEL_STATUS;
			}
			IResource resource = BreakpointUtils.getBreakpointResource(type);
			int lnumber = locator == null ? tsel.getStartLine() + 1 : locator.getLineLocation();
			IJavaLineBreakpoint existingBreakpoint = JDIDebugModel.lineBreakpointExists(resource, tname, lnumber);
			if (existingBreakpoint != null) {
				if (BreakpointToggleUtils.isToggleTracepoints()) {
					deleteTracepoint(existingBreakpoint, editor, monitor);
					BreakpointToggleUtils.setUnsetTracepoints(false);
				} else {
					deleteBreakpoint(existingBreakpoint, editor, monitor);
				}
				return Status.OK_STATUS;
			}
			Map<String, Object> attributes = new HashMap<>(10);
			IDocumentProvider documentProvider = editor.getDocumentProvider();
			if (documentProvider == null) {
				return Status.CANCEL_STATUS;
			}
			IDocument document = documentProvider.getDocument(editor.getEditorInput());
			int charstart = -1, charend = -1;
			try {
				IRegion line = document.getLineInformation(lnumber - 1);
				charstart = line.getOffset();
				charend = charstart + line.getLength();
			} catch (BadLocationException ble) {
				JDIDebugUIPlugin.log(ble);
			}
			BreakpointUtils.addJavaBreakpointAttributes(attributes, type);
			IJavaLineBreakpoint breakpoint = JDIDebugModel.createLineBreakpoint(resource, tname, lnumber, charstart, charend, 0, true, attributes);
			if (BreakpointToggleUtils.isToggleTracepoints() && selection instanceof ITextSelection && part instanceof JavaEditor) {
				String pattern = getCodeTemplate((ITextSelection) selection, (JavaEditor) part);
				if (pattern != null) {
					pattern = pattern.trim();
					pattern = pattern.replaceAll("\\\t", ""); //$NON-NLS-1$//$NON-NLS-2$
					breakpoint.setCondition(pattern);
					breakpoint.setConditionEnabled(true);
					breakpoint.setConditionSuspendOnTrue(true);
				}

				BreakpointToggleUtils.setUnsetTracepoints(false);
			}
			if (locator == null) {
				new BreakpointLocationVerifierJob(document, parseCompilationUnit(type.getTypeRoot()), breakpoint, lnumber, tname, type, editor, bestMatch).schedule();
			}
			if (BreakpointToggleUtils.isToggleTracepoints()) {
				BreakpointToggleUtils.setUnsetTracepoints(false);
			}
		} catch (CoreException ce) {
			return ce.getStatus();
		} finally {
			BreakpointToggleUtils.setUnsetTracepoints(false);
		}
        return Status.OK_STATUS;
    }

    /**
     * Toggles a class load breakpoint
     * @param part the part
     * @param selection the current selection
     * @since 3.3
     */
	public static void toggleClassBreakpoints(final IWorkbenchPart part, final ISelection selection) {
    	Job job = new Job("Toggle Class Load Breakpoints") { //$NON-NLS-1$
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				if (monitor.isCanceled()) {
                    return Status.CANCEL_STATUS;
                }
                try {
					return doToggleClassBreakpoints(part, selection, monitor);
				} catch (CoreException e) {
					return e.getStatus();
				}
			}
    	};
    	job.setPriority(Job.INTERACTIVE);
    	job.setSystem(true);
    	job.schedule();
    }

	static IStatus doToggleClassBreakpoints(IWorkbenchPart part, ISelection selection, IProgressMonitor monitor) throws CoreException {
		BreakpointToggleUtils.report(null, part);
		ISelection sel = selection;
		if (!(selection instanceof IStructuredSelection)) {
			sel = translateToMembers(part, selection);
		}
		if (isInterface(sel, part)) {
			BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_1, part);
			return Status.OK_STATUS;
		}
		if (!(sel instanceof IStructuredSelection)) {
			BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_0, part);
			return Status.OK_STATUS;
		}
		IMember member = (IMember) ((IStructuredSelection) sel).getFirstElement();
		IType type = (IType) member;
		IJavaBreakpoint existing = getClassLoadBreakpoint(type);
		if (existing != null) {
			deleteBreakpoint(existing, part, monitor);
			return Status.OK_STATUS;
		}
		HashMap<String, Object> map = new HashMap<>(10);
		BreakpointUtils.addJavaBreakpointAttributes(map, type);
		ISourceRange range = type.getNameRange();
		int start = -1;
		int end = -1;
		if (range != null) {
			start = range.getOffset();
			end = start + range.getLength();
		}
		IResource resource = BreakpointUtils.getBreakpointResource(member);
		String qualifiedName = getQualifiedName(type);
		JDIDebugModel.createClassPrepareBreakpoint(resource, qualifiedName, IJavaClassPrepareBreakpoint.TYPE_CLASS, start, end, true, map);
		return Status.OK_STATUS;
	}

    /**
     * Returns the class load breakpoint for the specified type or null if none found
     * @param type the type to search for a class load breakpoint for
     * @return the existing class load breakpoint, or null if none
     * @throws CoreException
     * @since 3.3
     */
	protected static IJavaBreakpoint getClassLoadBreakpoint(IType type) throws CoreException {
    	IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(JDIDebugModel.getPluginIdentifier());
    	for (int i = 0; i < breakpoints.length; i++) {
			IJavaBreakpoint breakpoint= (IJavaBreakpoint)breakpoints[i];
			if (breakpoint instanceof IJavaClassPrepareBreakpoint && getQualifiedName(type).equals(breakpoint.getTypeName())) {
				return breakpoint;
			}
		}
		return null;
    }

    /**
     * Returns the binary name for the {@link IType} derived from its {@link ITypeBinding}.
     * <br><br>
     * If the {@link ITypeBinding} cannot be derived this method falls back to calling
     * {@link #createQualifiedTypeName(IType)} to try and compose the type name.
     * @param type
     * @return the binary name for the given {@link IType}
     * @since 3.6
     */
	static String getQualifiedName(IType type) throws JavaModelException {
    	IJavaProject project = type.getJavaProject();
		if (project == null || !project.isOnClasspath(type) || !needsBindings(type)) {
			return createQualifiedTypeName(type);
		}
		CompilationUnit cuNode = parseCompilationUnit(type.getTypeRoot());
		ISourceRange nameRange = type.getNameRange();
		if (cuNode == null || !SourceRange.isAvailable(nameRange)) {
			return createQualifiedTypeName(type);
		}
		ASTNode node = NodeFinder.perform(cuNode, nameRange);
		if (!(node instanceof SimpleName)) {
			return createQualifiedTypeName(type);
		}
		IBinding binding;
		if (node.getLocationInParent() == SimpleType.NAME_PROPERTY && node.getParent().getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY) {
			binding = ((ClassInstanceCreation) node.getParent().getParent()).resolveTypeBinding();
		} else {
			binding = ((SimpleName) node).resolveBinding();
		}
		if (binding instanceof ITypeBinding) {
			String name = ((ITypeBinding) binding).getBinaryName();
			if (name != null) {
				return name;
			}
		}
		return createQualifiedTypeName(type);
    }

    /**
     * Checks if the type or any of its enclosing types are local types.
     * @param type
     * @return <code>true</code> if the type or a parent type are a local type
     * @throws JavaModelException
     * @since 3.6
     */
	static boolean needsBindings(IType type) throws JavaModelException {
    	if(type.isMember()) {
    		if(type.isLocal() && !type.isAnonymous()) {
    			return true;
    		}
    		IJavaElement parent = type.getParent();
    		IType ptype = null;
    		while(parent != null) {
    			if(parent.getElementType() == IJavaElement.TYPE) {
    				ptype = (IType) parent;
    				if(ptype.isLocal() && !ptype.isAnonymous()) {
    					return true;
    				}
    			}
    			parent = parent.getParent();
    		}
    	}
    	return false;
    }

    /**
     * Returns the package qualified name, while accounting for the fact that a source file might
     * not have a project
     * @param type the type to ensure the package qualified name is created for
     * @return the package qualified name
     * @since 3.3
     */
	static String createQualifiedTypeName(IType type) {
    	String tname = pruneAnonymous(type);
    	try {
    		String packName = null;
    		if (type.isBinary()) {
    			packName = type.getPackageFragment().getElementName();
    		} else {
    			IPackageDeclaration[] pd = type.getCompilationUnit().getPackageDeclarations();
				if(pd.length > 0) {
					packName = pd[0].getElementName();
				}
    		}
			if(packName != null && !packName.equals(EMPTY_STRING)) {
				tname =  packName+"."+tname; //$NON-NLS-1$
			}
    	}
    	catch (JavaModelException e) {}
    	return tname;
    }

    /**
     * Prunes out all naming occurrences of anonymous inner types, since these types have no names
     * and cannot be derived visiting an AST (no positive type name matching while visiting ASTs)
     * @param type
     * @return the compiled type name from the given {@link IType} with all occurrences of anonymous inner types removed
     * @since 3.4
     */
	private static String pruneAnonymous(IType type) {
    	StringBuilder buffer = new StringBuilder();
    	IJavaElement parent = type;
    	while(parent != null) {
    		if(parent.getElementType() == IJavaElement.TYPE){
    			IType atype = (IType) parent;
    			try {
	    			if(!atype.isAnonymous()) {
	    				if(buffer.length() > 0) {
	    					buffer.insert(0, '$');
	    				}
	    				buffer.insert(0, atype.getElementName());
	    			}
    			}
    			catch(JavaModelException jme) {}
    		}
    		parent = parent.getParent();
    	}
    	return buffer.toString();
    }

    /**
     * gets the <code>IJavaElement</code> from the editor input
     * @param input the current editor input
     * @return the corresponding <code>IJavaElement</code>
     * @since 3.3
     */
	private static IJavaElement getJavaElement(IEditorInput input) {
    	IJavaElement je = JavaUI.getEditorInputJavaElement(input);
    	if(je != null) {
    		return je;
    	}
    	//try to get from the working copy manager
    	return DebugWorkingCopyManager.getWorkingCopy(input, false);
    }

    @Override
	public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
    	if (isRemote(part, selection)) {
    		return false;
    	}
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection ss = (IStructuredSelection) selection;
            return getMethods(ss, isInterface(selection, part)).length > 0;
        }
        return (selection instanceof ITextSelection) && isMethod((ITextSelection) selection, part);
    }

	/**
	 * Returns whether the given part/selection is remote (viewing a repository)
	 *
	 * @param part
	 * @param selection
	 * @return
	 */
	protected static boolean isRemote(IWorkbenchPart part, ISelection selection) {
    	if (selection instanceof IStructuredSelection) {
			IStructuredSelection ss = (IStructuredSelection) selection;
			Object element = ss.getFirstElement();
			if(element instanceof IMember) {
				IMember member = (IMember) element;
				return !member.getJavaProject().getProject().exists();
			}
		}
		ITextEditor editor = getTextEditor(part);
    	if (editor != null) {
    		IEditorInput input = editor.getEditorInput();
    		Object adapter = Platform.getAdapterManager().getAdapter(input, "org.eclipse.team.core.history.IFileRevision"); //$NON-NLS-1$
    		return adapter != null;
    	}
    	return false;
    }

    /**
     * Returns the text editor associated with the given part or <code>null</code>
     * if none. In case of a multi-page editor, this method should be used to retrieve
     * the correct editor to perform the breakpoint operation on.
     *
     * @param part workbench part
     * @return text editor part or <code>null</code>
     */
	protected static ITextEditor getTextEditor(IWorkbenchPart part) {
    	if (part instanceof ITextEditor) {
    		return (ITextEditor) part;
    	}
    	return part.getAdapter(ITextEditor.class);
    }

    /**
     * Returns the methods from the selection, or an empty array
     * @param selection the selection to get the methods from
     * @return an array of the methods from the selection or an empty array
     */
	protected static IMethod[] getMethods(IStructuredSelection selection, boolean isInterace) {
        if (selection.isEmpty()) {
            return new IMethod[0];
        }
        List<IMethod> methods = new ArrayList<>(selection.size());
        Iterator<?> iterator = selection.iterator();
        while (iterator.hasNext()) {
            Object thing = iterator.next();
            try {
                if (thing instanceof IMethod) {
                	IMethod method = (IMethod) thing;
                	if(isInterace){
                		if (Flags.isDefaultMethod(method.getFlags()) || Flags.isStatic(method.getFlags())) {
							methods.add(method);
						}
                	}
                	else if (!Flags.isAbstract(method.getFlags())) {
                		methods.add(method);
                	}
                }
            }
            catch (JavaModelException e) {}
        }
        return methods.toArray(new IMethod[methods.size()]);
    }

    /**
     * Returns the methods from the selection, or an empty array
     * @param selection the selection to get the methods from
     * @return an array of the methods from the selection or an empty array
     */
	protected static IMethod[] getInterfaceMethods(IStructuredSelection selection) {
        if (selection.isEmpty()) {
            return new IMethod[0];
        }
        List<IMethod> methods = new ArrayList<>(selection.size());
        Iterator<?> iterator = selection.iterator();
        while (iterator.hasNext()) {
            Object thing = iterator.next();
            try {
                if (thing instanceof IMethod) {
                	IMethod method = (IMethod) thing;
                	if (Flags.isDefaultMethod(method.getFlags())) {
                		methods.add(method);
                	}
                }
            }
            catch (JavaModelException e) {}
        }
        return methods.toArray(new IMethod[methods.size()]);
    }

     /**
     * Returns if the text selection is a valid method or not
     * @param selection the text selection
     * @param part the associated workbench part
     * @return true if the selection is a valid method, false otherwise
     */
	private static boolean isMethod(ITextSelection selection, IWorkbenchPart part) {
		ITextEditor editor = getTextEditor(part);
		if (editor != null) {
			IJavaElement element = getJavaElement(editor.getEditorInput());
			if (element != null) {
				try {
					if (element instanceof ICompilationUnit) {
						element = ((ICompilationUnit) element).getElementAt(selection.getOffset());
					} else if (element instanceof IClassFile) {
						element = ((IClassFile) element).getElementAt(selection.getOffset());
					}
					if (element != null && element.getElementType() == IJavaElement.METHOD) {
						IMethod method = (IMethod) element;
						if (method.getDeclaringType().isAnonymous()) {
							return false;
						}
						return true;
					}

				}
				catch (JavaModelException e) {
					return false;
				}
			}
		}
		return false;
	}

    /**
     * Returns a list of <code>IField</code> and <code>IJavaFieldVariable</code> in the given selection.
     * When an <code>IField</code> can be resolved for an <code>IJavaFieldVariable</code>, it is
     * returned in favour of the variable.
     *
     * @param selection
     * @return list of <code>IField</code> and <code>IJavaFieldVariable</code>, possibly empty
     * @throws CoreException
     */
	protected static List<Object> getFields(IStructuredSelection selection) throws CoreException {
        if (selection.isEmpty()) {
            return Collections.EMPTY_LIST;
        }
        List<Object> fields = new ArrayList<>(selection.size());
        Iterator<?> iterator = selection.iterator();
        while (iterator.hasNext()) {
            Object thing = iterator.next();
            if (thing instanceof IField) {
                fields.add(thing);
            } else if (thing instanceof IJavaFieldVariable) {
                IField field = getField((IJavaFieldVariable) thing);
                if (field == null) {
                	fields.add(thing);
                } else {
                    fields.add(field);
                }
            }
        }
        return fields;
    }

    /**
     * Returns if the structured selection is itself or is part of an interface
     * @param selection the current selection
     * @return true if the selection is part of an interface, false otherwise
     * @since 3.2
     */
	private static boolean isInterface(ISelection selection, IWorkbenchPart part) {
		try {
			ISelection sel = selection;
			if(!(sel instanceof IStructuredSelection)) {
				sel = translateToMembers(part, selection);
			}
			if(sel instanceof IStructuredSelection) {
				Object obj = ((IStructuredSelection)sel).getFirstElement();
				if(obj instanceof IMember) {
					IMember member = (IMember) ((IStructuredSelection)sel).getFirstElement();
					if(member.getElementType() == IJavaElement.TYPE) {
						return ((IType)member).isInterface();
					}
					IType type = member.getDeclaringType();
					return type != null && type.isInterface();
				}
				else if(obj instanceof IJavaFieldVariable) {
					IJavaFieldVariable var = (IJavaFieldVariable) obj;
					IType type = JavaDebugUtils.resolveType(var.getDeclaringType());
					return type != null && type.isInterface();
				}
			}
		}
		catch (CoreException e1) {}
    	return false;
    }

    /**
     * Returns if the text selection is a field selection or not
     * @param selection the text selection
     * @param part the associated workbench part
     * @return true if the text selection is a valid field for a watchpoint, false otherwise
     * @since 3.3
     */
	private static boolean isField(ITextSelection selection, IWorkbenchPart part) {
		ITextEditor editor = getTextEditor(part);
    	if(editor != null) {
			IJavaElement element = getJavaElement(editor.getEditorInput());
    		if(element != null) {
    			try {
	    			if(element instanceof ICompilationUnit) {
						element = ((ICompilationUnit) element).getElementAt(selection.getOffset());
	    			}
	    			else if(element instanceof IClassFile) {
	    				element = ((IClassFile) element).getElementAt(selection.getOffset());
	    			}
	    			return element != null && element.getElementType() == IJavaElement.FIELD;
				}
    			catch (JavaModelException e) {return false;}
    		}
    	}
    	return false;
    }


    /**
     * Determines if the selection is a field or not
     * @param selection the current selection
     * @return true if the selection is a field false otherwise
     */
	private static boolean isFields(IStructuredSelection selection) {
		if (selection.isEmpty()) {
			return false;
        }
		try {
			Iterator<?> iterator = selection.iterator();
			while (iterator.hasNext()) {
				Object thing = iterator.next();
				if (thing instanceof IField) {
					int flags = ((IField) thing).getFlags();
					return !Flags.isFinal(flags);
				} else if (thing instanceof IJavaFieldVariable) {
					IJavaFieldVariable fv = (IJavaFieldVariable) thing;
					return !fv.isFinal();
				}
			}
		} catch (JavaModelException | DebugException e) {
			return false;
		}
        return false;
    }

    @Override
	public void toggleWatchpoints(final IWorkbenchPart part, final ISelection finalSelection) {
        Job job = new Job("Toggle Watchpoints") { //$NON-NLS-1$
            @Override
			protected IStatus run(IProgressMonitor monitor) {
                if (monitor.isCanceled()) {
                    return Status.CANCEL_STATUS;
                }
				try {
					return doToggleWatchpoints(part, finalSelection, monitor);
				} catch (CoreException e) {
					return e.getStatus();
				}
            }
        };
        job.setPriority(Job.INTERACTIVE);
        job.setSystem(true);
        job.schedule();
    }

	static IStatus doToggleWatchpoints(IWorkbenchPart part, ISelection finalSelection, IProgressMonitor monitor) throws CoreException {
		BreakpointToggleUtils.report(null, part);
		ISelection selection = finalSelection;
		if (!(selection instanceof IStructuredSelection)) {
			selection = translateToMembers(part, finalSelection);
		}
		if (isInterface(selection, part)) {
			BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_5, part);
			return Status.OK_STATUS;
		}
		boolean allowed = false;
		if (!(selection instanceof IStructuredSelection)) {
			BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_2, part);
			return Status.OK_STATUS;
		}
		List<Object> fields = getFields((IStructuredSelection) selection);
		if (fields.isEmpty()) {
			BreakpointToggleUtils.report(ActionMessages.ToggleBreakpointAdapter_10, part);
			return Status.OK_STATUS;
		}

		IField javaField = null;
		String typeName = null;
		String fieldName = null;

		for (Object element : fields) {
			if (element instanceof IField) {
				javaField = (IField) element;
				IType type = javaField.getDeclaringType();
				typeName = getQualifiedName(type);
				fieldName = javaField.getElementName();
				int f = javaField.getFlags();
				boolean fin = Flags.isFinal(f);
				if (fin) {
					fin = javaField.getConstant() != null; // watch point is allowed if no constant value
				}
				allowed = !fin;
			} else if (element instanceof IJavaFieldVariable) {
				IJavaFieldVariable var = (IJavaFieldVariable) element;
				typeName = var.getDeclaringType().getName();
				fieldName = var.getName();
				boolean fin = var.isFinal();
				if (fin) {
					fin = javaField.getConstant() != null; // watch point is allowed if no constant value
				}
				allowed = !fin;
			}
			IJavaBreakpoint breakpoint = getWatchpoint(typeName, fieldName);
			if (breakpoint != null) {
				deleteBreakpoint(breakpoint, part, monitor);
				continue;
			}
			if (!allowed) {
				return doLineBreakpointToggle(finalSelection, part, null, true, monitor);
			}
			int start = -1;
			int end = -1;
			Map<String, Object> attributes = new HashMap<>(10);
			IResource resource;
			if (javaField == null) {
				resource = ResourcesPlugin.getWorkspace().getRoot();
			} else {
				IType type = javaField.getDeclaringType();
				ISourceRange range = javaField.getNameRange();
				if (range != null) {
					start = range.getOffset();
					end = start + range.getLength();
				}
				BreakpointUtils.addJavaBreakpointAttributes(attributes, javaField);
				resource = BreakpointUtils.getBreakpointResource(type);
			}
			JDIDebugModel.createWatchpoint(resource, typeName, fieldName, -1, start, end, 0, true, attributes);
		}
		return Status.OK_STATUS;
	}

	/**
	 * Returns any existing watchpoint for the given field, or <code>null</code> if none.
	 *
     * @param typeName fully qualified type name on which watchpoint may exist
     * @param fieldName field name
	 * @return any existing watchpoint for the given field, or <code>null</code> if none
	 * @throws CoreException
	 */
	private static IJavaWatchpoint getWatchpoint(String typeName, String fieldName) throws CoreException {
        IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
        IBreakpoint[] breakpoints = breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
        for (int i = 0; i < breakpoints.length; i++) {
            IBreakpoint breakpoint = breakpoints[i];
            if (breakpoint instanceof IJavaWatchpoint) {
                IJavaWatchpoint watchpoint = (IJavaWatchpoint) breakpoint;
                if (typeName.equals(watchpoint.getTypeName()) && fieldName.equals(watchpoint.getFieldName())) {
                    return watchpoint;
                }
            }
        }
        return null;
    }

    /**
     * Returns the resolved signature of the given method
     * @param method method to resolve
     * @return the resolved method signature or <code>null</code> if none
     * @throws JavaModelException
     * @since 3.4
     */
    public static String resolveMethodSignature(IMethod method) throws JavaModelException {
    	String signature = method.getSignature();
        String[] parameterTypes = Signature.getParameterTypes(signature);
        int length = parameterTypes.length;
        String[] resolvedParameterTypes = new String[length];
        for (int i = 0; i < length; i++) {
            resolvedParameterTypes[i] = resolveTypeSignature(method, parameterTypes[i]);
            if (resolvedParameterTypes[i] == null) {
                return null;
            }
        }
        String resolvedReturnType = resolveTypeSignature(method, Signature.getReturnType(signature));
        if (resolvedReturnType == null) {
            return null;
        }
        return Signature.createMethodSignature(resolvedParameterTypes, resolvedReturnType);
    }

    /**
     * Returns the resolved type signature for the given signature in the given
     * method, or <code>null</code> if unable to resolve.
     *
     * @param method method containing the type signature
     * @param typeSignature the type signature to resolve
     * @return the resolved type signature
     * @throws JavaModelException
     */
    private static String resolveTypeSignature(IMethod method, String typeSignature) throws JavaModelException {
        int count = Signature.getArrayCount(typeSignature);
        String elementTypeSignature = Signature.getElementType(typeSignature);
        if (elementTypeSignature.length() == 1) {
            // no need to resolve primitive types
            return typeSignature;
        }
        String elementTypeName = Signature.toString(elementTypeSignature);
        IType type = method.getDeclaringType();
        String[][] resolvedElementTypeNames = type.resolveType(elementTypeName);
        if (resolvedElementTypeNames == null || resolvedElementTypeNames.length != 1) {
        	// check if type parameter
        	ITypeParameter typeParameter = method.getTypeParameter(elementTypeName);
        	if (!typeParameter.exists()) {
        		typeParameter = type.getTypeParameter(elementTypeName);
        	}
        	if (typeParameter.exists()) {
				String[] bounds = typeParameter.getBounds();
				if (bounds.length == 0) {
					return "Ljava/lang/Object;"; //$NON-NLS-1$
				}
				String bound = Signature.createTypeSignature(bounds[0], false);
				return Signature.createArraySignature(resolveTypeSignature(method, bound), count);
    		}
            // the type name cannot be resolved
            return null;
        }

        String[] types = resolvedElementTypeNames[0];
        types[1] = types[1].replace('.', '$');

        String resolvedElementTypeName = Signature.toQualifiedName(types);
		String resolvedElementTypeSignature = EMPTY_STRING;
		if (types[0].equals(EMPTY_STRING)) {
        	resolvedElementTypeName = resolvedElementTypeName.substring(1);
        	resolvedElementTypeSignature = Signature.createTypeSignature(resolvedElementTypeName, true);
        }
        else {
        	resolvedElementTypeSignature = Signature.createTypeSignature(resolvedElementTypeName, true).replace('.', '/');
        }

        return Signature.createArraySignature(resolvedElementTypeSignature, count);
    }

    /**
     * Returns the resource associated with the specified editor part
     * @param editor the currently active editor part
     * @return the corresponding <code>IResource</code> from the editor part
     */
    protected static IResource getResource(IEditorPart editor) {
        IEditorInput editorInput = editor.getEditorInput();
        IResource resource = editorInput.getAdapter(IFile.class);
        if (resource == null) {
            resource = ResourcesPlugin.getWorkspace().getRoot();
        }
        return resource;
    }

    /**
     * Returns a handle to the specified method or <code>null</code> if none.
     *
     * @param editorPart
     *            the editor containing the method
     * @param typeName
     * @param methodName
     * @param signature
     * @return handle or <code>null</code>
     */
	protected static IMethod getMethodHandle(IEditorPart editorPart, String typeName, String methodName, String signature) throws CoreException {
        IJavaElement element = editorPart.getEditorInput().getAdapter(IJavaElement.class);
        IType type = null;
        if (element instanceof ICompilationUnit) {
            IType[] types = ((ICompilationUnit) element).getAllTypes();
            for (int i = 0; i < types.length; i++) {
                if (types[i].getFullyQualifiedName().equals(typeName)) {
                    type = types[i];
                    break;
                }
            }
        } else if (element instanceof IOrdinaryClassFile) {
			type = ((IOrdinaryClassFile) element).getType();
        }
        if (type != null) {
            String[] sigs = Signature.getParameterTypes(signature);
            return type.getMethod(methodName, sigs);
        }
        return null;
    }

    /**
     * Returns the <code>IJavaBreakpoint</code> from the specified <code>IMember</code>
     * @param element the element to get the breakpoint from
     * @return the current breakpoint from the element or <code>null</code>
     */
	protected static IJavaBreakpoint getMethodBreakpoint(IMember element) {
        IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
        IBreakpoint[] breakpoints = breakpointManager.getBreakpoints(JDIDebugModel.getPluginIdentifier());
		if (!(element instanceof IMethod)) {
			return null;
        }
		IMethod method = (IMethod) element;
		for (IBreakpoint breakpoint : breakpoints) {
			if (!(breakpoint instanceof IJavaMethodBreakpoint)) {
				continue;
			}
			IJavaMethodBreakpoint methodBreakpoint = (IJavaMethodBreakpoint) breakpoint;
			IMember container = null;
			try {
				container = BreakpointUtils.getMember(methodBreakpoint);
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
				return null;
			}
			if (container == null) {
				try {
					if (method.getDeclaringType().getFullyQualifiedName().equals(methodBreakpoint.getTypeName())
							&& method.getElementName().equals(methodBreakpoint.getMethodName())
							&& methodBreakpoint.getMethodSignature().equals(resolveMethodSignature(method))) {
						return methodBreakpoint;
					}
				} catch (CoreException e) {
					JDIDebugUIPlugin.log(e);
				}
			} else {
				if (container instanceof IMethod) {
					if (method.getDeclaringType().getFullyQualifiedName().equals(container.getDeclaringType().getFullyQualifiedName())) {
						if (method.isSimilar((IMethod) container)) {
							return methodBreakpoint;
						}
					}
				}
			}
		}
        return null;
    }

    /**
     * Returns the compilation unit from the editor
     * @param editor the editor to get the compilation unit from
     * @return the compilation unit or <code>null</code>
     */
	protected static CompilationUnit parseCompilationUnit(ITextEditor editor) {
        return parseCompilationUnit(getTypeRoot(editor.getEditorInput()));
    }

    /**
	 * Parses the {@link ITypeRoot}.
	 *
	 * @param root
	 *            the root
	 * @return the parsed {@link CompilationUnit} or {@code null}
	 */
	static CompilationUnit parseCompilationUnit(ITypeRoot root) {
    	if(root != null) {
			return SharedASTProviderCore.getAST(root, SharedASTProviderCore.WAIT_YES, null);
        }
        return null;
    }

    @Override
	public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
    	if (isRemote(part, selection)) {
    		return false;
    	}
        if (selection instanceof IStructuredSelection) {
            IStructuredSelection ss = (IStructuredSelection) selection;
            return isFields(ss);
        }
        return (selection instanceof ITextSelection) && isField((ITextSelection) selection, part);
    }

    /**
     * Returns a selection of the member in the given text selection, or the
     * original selection if none.
     *
     * @param part
     * @param selection
     * @return a structured selection of the member in the given text selection,
     *         or the original selection if none
     * @exception CoreException
     *                if an exception occurs
     */
	protected static ISelection translateToMembers(IWorkbenchPart part, ISelection selection) throws CoreException {
    	ITextEditor textEditor = getTextEditor(part);
		if (textEditor == null || !(selection instanceof ITextSelection)) {
			return selection;
        }
		ITextSelection textSelection = (ITextSelection) selection;
		IEditorInput editorInput = textEditor.getEditorInput();
		IDocumentProvider documentProvider = textEditor.getDocumentProvider();
		if (documentProvider == null) {
			throw new CoreException(Status.CANCEL_STATUS);
		}
		IDocument document = documentProvider.getDocument(editorInput);
		int offset = textSelection.getOffset();
		if (document != null) {
			try {
				IRegion region = document.getLineInformationOfOffset(offset);
				int end = region.getOffset() + region.getLength();
				while (Character.isWhitespace(document.getChar(offset)) && offset < end) {
					offset++;
				}
			} catch (BadLocationException e) {
			}
		}
		IMember m = null;
		ITypeRoot root = getTypeRoot(editorInput);
		if (root instanceof ICompilationUnit) {
			ICompilationUnit unit = (ICompilationUnit) root;
			synchronized (unit) {
				unit.reconcile(ICompilationUnit.NO_AST, false, null, null);
			}
		}
		if (root != null) {
			IJavaElement e = root.getElementAt(offset);
			if (e instanceof IMember) {
				m = (IMember) e;
			}
			if (m != null && m.getParent() instanceof IType && ((IType) m.getParent()).isRecord()) {
				m = (IMember) m.getParent();
			}
		}
		if (m != null) {
			return new StructuredSelection(m);
		}
        return selection;
    }

    /**
     * Returns the {@link ITypeRoot} for the given {@link IEditorInput}
     * @param input
     * @return the type root or <code>null</code> if one cannot be derived
	 * @since 3.4
     */
	private static ITypeRoot getTypeRoot(IEditorInput input) {
		ITypeRoot root = input.getAdapter(IClassFile.class);
    	if(root == null) {
    		 IWorkingCopyManager manager = JavaUI.getWorkingCopyManager();
             root = manager.getWorkingCopy(input);
    	}
    	if(root == null) {
    		root = DebugWorkingCopyManager.getWorkingCopy(input, false);
    	}
    	return root;
    }

    /**
     * Return the associated IField (Java model) for the given
     * IJavaFieldVariable (JDI model)
     */
	private static IField getField(IJavaFieldVariable variable) throws CoreException {
        String varName = null;
        try {
            varName = variable.getName();
        } catch (DebugException x) {
            JDIDebugUIPlugin.log(x);
            return null;
        }
        IField field;
        IJavaType declaringType = variable.getDeclaringType();
        IType type = JavaDebugUtils.resolveType(declaringType);
        if (type != null) {
            field = type.getField(varName);
            if (field.exists()) {
                return field;
            }
        }
        return null;
    }

    @Override
	public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
		ISelection sel = translateToMembers(part, selection);
		if (!(sel instanceof IStructuredSelection)) {
			return;
		}
		IMember member = (IMember) ((IStructuredSelection) sel).getFirstElement();
		int mtype = member.getElementType();
		if (mtype == IJavaElement.FIELD || mtype == IJavaElement.METHOD || mtype == IJavaElement.INITIALIZER) {
			toggleFieldOrMethodBreakpoints(part, selection);
		} else if (member.getElementType() == IJavaElement.TYPE) {
			if (BreakpointToggleUtils.isToggleTracepoints()) {
				BreakpointToggleUtils.report(ActionMessages.TracepointToggleAction_Unavailable, part);
				BreakpointToggleUtils.setUnsetTracepoints(false);
				return;
			}
			toggleClassBreakpoints(part, sel);
		} else {
			// fall back to old behavior, always create a line breakpoint
			toggleLineBreakpoints(part, selection, true, null);
		}
	}

	private static IJavaLineBreakpoint findExistingBreakpoint(ITextEditor editor, ITextSelection ts) {
		IDocumentProvider documentProvider = editor.getDocumentProvider();
		if (documentProvider == null) {
			return null;
		}
		IEditorInput editorInput = editor.getEditorInput();
		IAnnotationModel annotationModel = documentProvider.getAnnotationModel(editorInput);
		if (annotationModel == null) {
			return null;
		}
		IDocument document = documentProvider.getDocument(editorInput);
		if (document == null) {
			return null;
		}
		Iterator<Annotation> iterator = annotationModel.getAnnotationIterator();
		while (iterator.hasNext()) {
			Object object = iterator.next();
			if (!(object instanceof SimpleMarkerAnnotation)) {
				continue;
			}
			SimpleMarkerAnnotation markerAnnotation = (SimpleMarkerAnnotation) object;
			IMarker marker = markerAnnotation.getMarker();
			try {
				if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
					Position position = annotationModel.getPosition(markerAnnotation);
					int line = document.getLineOfOffset(position.getOffset());
					if (line == ts.getStartLine()) {
						IBreakpoint oldBreakpoint = DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
						if (oldBreakpoint instanceof IJavaLineBreakpoint) {
							return (IJavaLineBreakpoint) oldBreakpoint;
						}
					}
				}
			} catch (BadLocationException e) {
				JDIDebugUIPlugin.log(e);
			} catch (CoreException e) {
				logBadAnnotation(markerAnnotation, e);
			}
		}
		return null;
	}

	private void toggleFieldOrMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
		if (!(selection instanceof ITextSelection)) {
			return;
		}
		ITextSelection ts = (ITextSelection) selection;
		ITextEditor editor = getTextEditor(part);
		if (editor == null) {
			return;
		}
		// remove line breakpoint if present first
		IJavaLineBreakpoint breakpoint = findExistingBreakpoint(editor, ts);
		if (breakpoint != null) {
			if (BreakpointToggleUtils.isToggleTracepoints()) {
				deleteTracepoint(breakpoint, part, null);
				BreakpointToggleUtils.setUnsetTracepoints(false);
			} else {
				deleteBreakpoint(breakpoint, part, null);
			}
			return;
		}
		// no breakpoint found: we create new one
		CompilationUnit unit = parseCompilationUnit(editor);
		if (unit == null) {
			JDIDebugUIPlugin.log("Failed to parse CU for: " + editor.getTitle(), new IllegalStateException()); //$NON-NLS-1$
			return;
		}
		ValidBreakpointLocationLocator loc = new ValidBreakpointLocationLocator(unit, ts.getStartLine() + 1, true, true);
		unit.accept(loc);
		if (loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_METHOD) {
			toggleMethodBreakpoints(part, ts);
		} else if (loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_FIELD) {
			if (BreakpointToggleUtils.isToggleTracepoints()) {
				BreakpointToggleUtils.report(ActionMessages.TracepointToggleAction_Unavailable, part);
				BreakpointToggleUtils.setUnsetTracepoints(false);
				return;
			}
			toggleWatchpoints(part, ts);
		} else if (loc.getLocationType() == ValidBreakpointLocationLocator.LOCATION_LINE) {
			toggleLineBreakpoints(part, ts, false, loc);
		}
	}

	/**
	 * Additional diagnosis info for bug 528321
	 */
	private static void logBadAnnotation(SimpleMarkerAnnotation annotation, CoreException e) {
		String message = "Editor annotation with non existing marker found: "; //$NON-NLS-1$
		message += "text: " + annotation.getText(); //$NON-NLS-1$
		message += ", type: " + annotation.getType(); //$NON-NLS-1$
		message += ", " + annotation.getMarker(); //$NON-NLS-1$
		JDIDebugUIPlugin.log(message, e);
	}

	/**
	 * Deletes the given breakpoint using the operation history, which allows to undo the deletion.
	 *
	 * @param breakpoint the breakpoint to delete
	 * @param part a workbench part, or <code>null</code> if unknown
	 * @param progressMonitor the progress monitor
	 * @throws CoreException if the deletion fails
	 */
	private static void deleteBreakpoint(IJavaBreakpoint breakpoint, IWorkbenchPart part, IProgressMonitor monitor) throws CoreException {
		final Shell shell = part != null ? part.getSite().getShell() : null;
		final boolean[] result = new boolean[] { true };

		final IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(JDIDebugUIPlugin.getUniqueIdentifier());
		boolean prompt = prefs.getBoolean(IJDIPreferencesConstants.PREF_PROMPT_DELETE_CONDITIONAL_BREAKPOINT, true);
		if (prompt && breakpoint instanceof IJavaLineBreakpoint && ((IJavaLineBreakpoint) breakpoint).getCondition() != null) {
			Display display = shell != null && !shell.isDisposed() ? shell.getDisplay() : PlatformUI.getWorkbench().getDisplay();
			if (!display.isDisposed()) {
				display.syncExec(new Runnable() {
					@Override
					public void run() {
						MessageDialogWithToggle dialog = MessageDialogWithToggle.openOkCancelConfirm(shell, ActionMessages.ToggleBreakpointAdapter_confirmDeleteTitle, ActionMessages.ToggleBreakpointAdapter_confirmDeleteMessage, ActionMessages.ToggleBreakpointAdapter_confirmDeleteShowAgain, false, null, null);
						if (dialog.getToggleState()) {
							prefs.putBoolean(IJDIPreferencesConstants.PREF_PROMPT_DELETE_CONDITIONAL_BREAKPOINT, false);
						}
						result[0] = dialog.getReturnCode() == IDialogConstants.OK_ID;
					}
				});
			}
		}
		if (result[0]) {
			DebugUITools.deleteBreakpoints(new IBreakpoint[] { breakpoint }, shell, monitor);
		}
	}

	private static void deleteTracepoint(IJavaBreakpoint breakpoint, IWorkbenchPart part, IProgressMonitor monitor) throws CoreException {
		final Shell shell = part != null ? part.getSite().getShell() : null;
		final IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(JDIDebugUIPlugin.getUniqueIdentifier());
		boolean prompt = prefs.getBoolean(IJDIPreferencesConstants.PREF_PROMPT_DELETE_CONDITIONAL_BREAKPOINT, true);

		if (!prompt || !(breakpoint instanceof IJavaLineBreakpoint)) {
			DebugUITools.deleteBreakpoints(new IBreakpoint[] { breakpoint }, shell, monitor);
			return;
		}

		final boolean[] result = new boolean[] { true };
		String condition = ((IJavaLineBreakpoint) breakpoint).getCondition();
		boolean conditionChanged = true;
		if (condition != null) {
			int index = condition.indexOf(';');
			if (index != -1) {
				int lastIndex = condition.lastIndexOf(';');
				if (index == lastIndex) {
					conditionChanged = false;
				}

			} else {
				if (condition.indexOf("print") != -1) { //$NON-NLS-1$
					conditionChanged = false;
				}
			}
		}
		if (conditionChanged && condition != null) {
			Display display = shell != null && !shell.isDisposed() ? shell.getDisplay() : PlatformUI.getWorkbench().getDisplay();
			if (!display.isDisposed()) {
				display.syncExec(new Runnable() {
					@Override
					public void run() {
						MessageDialogWithToggle dialog = MessageDialogWithToggle.openOkCancelConfirm(shell, ActionMessages.ToggleBreakpointAdapter_confirmDeleteTitle, ActionMessages.ToggleBreakpointAdapter_confirmDeleteMessage, ActionMessages.ToggleBreakpointAdapter_confirmDeleteShowAgain, false, null, null);
						if (dialog.getToggleState()) {
							prefs.putBoolean(IJDIPreferencesConstants.PREF_PROMPT_DELETE_CONDITIONAL_BREAKPOINT, false);
						}
						result[0] = dialog.getReturnCode() == IDialogConstants.OK_ID;
					}
				});
			}
		}

		if (result[0]) {
			DebugUITools.deleteBreakpoints(new IBreakpoint[] { breakpoint }, shell, monitor);
		}
	}

    @Override
	public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) {
    	if (isRemote(part, selection)) {
    		return false;
    	}
        return canToggleLineBreakpoints(part, selection);
    }

	@Override
	public void toggleBreakpointsWithEvent(IWorkbenchPart part, ISelection selection, Event event) throws CoreException {
		if (event == null) {
			toggleBreakpoints(part, selection);
			return;
		}
		if ((event.stateMask & SWT.MOD2) > 0) {
			ITextEditor editor = getTextEditor(part);
			if (editor != null) {
				IVerticalRulerInfo info = editor.getAdapter(IVerticalRulerInfo.class);
				if (info != null) {
					IBreakpoint bp = BreakpointUtils.getBreakpointFromEditor(editor, info);
					if (bp != null) {
						bp.setEnabled(!bp.isEnabled());
						return;
					}
				}
			}
		} else if ((event.stateMask & SWT.MOD1) > 0) {
			ITextEditor editor = getTextEditor(part);
			if (editor != null) {
				IVerticalRulerInfo info = editor.getAdapter(IVerticalRulerInfo.class);
				if (info != null) {
					IBreakpoint bp = BreakpointUtils.getBreakpointFromEditor(editor, info);
					if (bp != null) {
						PreferencesUtil.createPropertyDialogOn(editor.getSite().getShell(), bp, null, null, null).open();
						return;
					}
				}
			}
		}
		toggleBreakpoints(part, selection);
	}

	@Override
	public boolean canToggleBreakpointsWithEvent(IWorkbenchPart part, ISelection selection, Event event) {
		return canToggleBreakpoints(part, selection);
	}

	/**
	 * Returns the {@link ITypeRoot} for the given {@link IEditorInput}
	 *
	 * @param input
	 * @return the type root or <code>null</code> if one cannot be derived
	 * @since 3.8
	 */
	private static String getCodeTemplate(ITextSelection textSelection, JavaEditor part) {
		ITextViewer viewer = part.getViewer();
		if (viewer == null) {
			return null;
		}
		TemplateContextType contextType = JavaPlugin.getDefault().getTemplateContextRegistry().getContextType(JavaContextType.ID_STATEMENTS);
		final AtomicReference<String> templateBuffer = new AtomicReference<>();
		Display.getDefault().syncExec(() -> doGetCodeTemplate(textSelection, part, viewer, contextType, templateBuffer));
		return templateBuffer.get();
	}

	private static void doGetCodeTemplate(ITextSelection textSelection, JavaEditor part, ITextViewer viewer, TemplateContextType contextType, AtomicReference<String> templateBuffer) {
		ITextEditor editor = getTextEditor(part);
		if (editor == null) {
			return;
		}
		IDocumentProvider documentProvider = editor.getDocumentProvider();
		if (documentProvider == null) {
			return;
		}
		ICompilationUnit cunit = getCompilationUnit(editor);
		if (cunit == null) {
			return;
		}
		TemplateEngine statementEngine = new TemplateEngine(contextType);
		statementEngine.reset();
		IDocument document = documentProvider.getDocument(editor.getEditorInput());
		try {
			IRegion line = document.getLineInformation(textSelection.getStartLine() + 1);
			Point selectedRange = new Point(textSelection.getOffset(), textSelection.getLength());
			statementEngine.complete(viewer, selectedRange, line.getOffset(), cunit);
			TemplateProposal[] templateProposals = statementEngine.getResults();
			for (TemplateProposal templateProposal : templateProposals) {
				Template template = templateProposal.getTemplate();
				if (template.getName().equals("systrace")) { //$NON-NLS-1$
					CompilationUnitContextType cuContextType = (CompilationUnitContextType) JavaPlugin.getDefault().getTemplateContextRegistry().getContextType(template.getContextTypeId());
					DocumentTemplateContext context = cuContextType.createContext(document, line.getOffset(), 0, cunit);
					context.setVariable("selection", EMPTY_STRING); //$NON-NLS-1$
					((CompilationUnitContext) context).setForceEvaluation(true);
					templateBuffer.set(context.evaluate(template).getString());
					return;
				}
			}
		} catch (BadLocationException | TemplateException e) {
			// ignore
		}
	}

	private static ICompilationUnit getCompilationUnit(ITextEditor editor) {
		IJavaElement element = getJavaElement(editor.getEditorInput());
		if (element == null) {
			return null;
		}
		if (element instanceof IOrdinaryClassFile) {
			try {
				return ((IOrdinaryClassFile) element).getWorkingCopy(new WorkingCopyOwner() {}, null);
			} catch (JavaModelException e) {
				// ignore
				return null;
			}
		}
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IFile file = root.getFile(element.getPath());
		return JavaCore.createCompilationUnitFrom(file);
	}

}
