/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Jesper Steen Moller - Enhancement 254677 - filter getters/setters
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui;


import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.ICoreRunnable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointsListener;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchListener;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult;
import org.eclipse.jdt.core.dom.Message;
import org.eclipse.jdt.debug.core.IJavaBreakpoint;
import org.eclipse.jdt.debug.core.IJavaBreakpointListener;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint;
import org.eclipse.jdt.debug.core.IJavaMethodEntryBreakpoint;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
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.debug.ui.IJavaDebugUIConstants;
import org.eclipse.jdt.internal.debug.core.breakpoints.JavaExceptionBreakpoint;
import org.eclipse.jdt.internal.debug.core.logicalstructures.IJavaStructuresListener;
import org.eclipse.jdt.internal.debug.core.logicalstructures.JavaLogicalStructures;
import org.eclipse.jdt.internal.debug.ui.actions.JavaBreakpointPropertiesAction;
import org.eclipse.jdt.internal.debug.ui.breakpoints.SuspendOnCompilationErrorListener;
import org.eclipse.jdt.internal.debug.ui.breakpoints.SuspendOnUncaughtExceptionListener;
import org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookLauncher;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import com.sun.jdi.InvocationException;
import com.sun.jdi.ObjectReference;

/**
 * Manages options for the Java Debugger:<ul>
 * <li>Suspend on compilation errors</li>
 * <li>Suspend on uncaught exceptions</li>
 * <li>Step filters</li>
 * <li>Sets a system property that the Java debugger is active if
 * there are launches that contain running debug targets. Used for Java
 * debug action visibility.
 * </ul>
 */
public class JavaDebugOptionsManager implements IDebugEventSetListener, IPropertyChangeListener, IJavaBreakpointListener, ILaunchListener, IBreakpointsListener, IJavaStructuresListener {

	/**
	 * Singleton options manager
	 */
	private static JavaDebugOptionsManager fgOptionsManager = null;

	/**
	 * Breakpoint used to suspend on uncaught exceptions
	 */
	private IJavaExceptionBreakpoint fSuspendOnExceptionBreakpoint = null;

	/**
	 * Breakpoint used to suspend on compilation errors
	 */
	private IJavaExceptionBreakpoint fSuspendOnErrorBreakpoint = null;

	/**
	 * A label provider
	 */
	private static ILabelProvider fLabelProvider= DebugUITools.newDebugModelPresentation();

	/**
	 * Constants indicating whether a breakpoint
	 * is added, removed, or changed.
	 */
	private static final int ADDED = 0;
	private static final int REMOVED = 1;
	private static final int CHANGED = 2;

	/**
	 * Local cache of active step filters.
	 */
	private String[] fActiveStepFilters = null;

	/**
	 * Preferences that affect variable display options.
	 *
	 * @since 3.3
	 */
	private static Set<String> fgDisplayOptions;

	static {
		fgDisplayOptions = new HashSet<>();
		fgDisplayOptions.add(IJDIPreferencesConstants.PREF_SHOW_CHAR);
		fgDisplayOptions.add(IJDIPreferencesConstants.PREF_SHOW_HEX);
		fgDisplayOptions.add(IJDIPreferencesConstants.PREF_SHOW_UNSIGNED);
	}

	/**
	 * Whether the manager has been activated
	 */
	private boolean fActivated = false;

	class InitJob extends Job {

		public InitJob() {
			super(DebugUIMessages.JavaDebugOptionsManager_0);
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			MultiStatus status = new MultiStatus(JDIDebugUIPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "Java debug options failed to initialize", null);  //$NON-NLS-1$
			// compilation error breakpoint
			try {
				IJavaExceptionBreakpoint bp = JDIDebugModel.createExceptionBreakpoint(ResourcesPlugin.getWorkspace().getRoot(),"java.lang.Error", true, true, false, false, null); //$NON-NLS-1$
				bp.setPersisted(false);
				bp.addBreakpointListener(SuspendOnCompilationErrorListener.ID_COMPILATION_ERROR_LISTENER);
				setSuspendOnCompilationErrorsBreakpoint(bp);
			} catch (CoreException e) {
				status.add(e.getStatus());
			}

			// uncaught exception breakpoint
			try {
				IJavaExceptionBreakpoint bp = JDIDebugModel.createExceptionBreakpoint(ResourcesPlugin.getWorkspace().getRoot(),"java.lang.Throwable", false, true, false, false, null); //$NON-NLS-1$
				((JavaExceptionBreakpoint)bp).setSuspendOnSubclasses(true);
				bp.setPersisted(false);
				bp.addBreakpointListener(SuspendOnUncaughtExceptionListener.ID_UNCAUGHT_EXCEPTION_LISTENER);
				setSuspendOnUncaughtExceptionBreakpoint(bp);
			} catch (CoreException e) {
				status.add(e.getStatus());
			}

			if (status.getChildren().length == 0) {
				return Status.OK_STATUS;
			}
			return status;
		}
	}

	/**
	 * Not to be instantiated
	 *
	 * @see JavaDebugOptionsManager#getDefault();
	 */
	private JavaDebugOptionsManager() {
	}

	/**
	 * Return the default options manager
	 */
	public static JavaDebugOptionsManager getDefault() {
		if (fgOptionsManager == null) {
			fgOptionsManager = new JavaDebugOptionsManager();
		}
		return fgOptionsManager;
	}

	/**
	 * Called at startup by the Java debug ui plug-in
	 */
	public void startup() {
		// lazy initialization will occur on the first launch
		DebugPlugin debugPlugin = DebugPlugin.getDefault();
		debugPlugin.getLaunchManager().addLaunchListener(this);
		debugPlugin.getBreakpointManager().addBreakpointListener(this);
		EvaluationContextManager.startup();
	}

	/**
	 * Called at shutdown by the Java debug ui plug-in
	 */
	public void shutdown() {
		Job.getJobManager().cancel(JavaDebugOptionsManager.class);
		DebugPlugin debugPlugin = DebugPlugin.getDefault();
		debugPlugin.removeDebugEventListener(this);
		debugPlugin.getLaunchManager().removeLaunchListener(this);
		debugPlugin.getBreakpointManager().removeBreakpointListener(this);
		if (!JDIDebugUIPlugin.getDefault().isShuttingDown()) {
			//avert restoring the preference store at shutdown
			JDIDebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		}
		JDIDebugModel.removeJavaBreakpointListener(this);
        JavaLogicalStructures.removeStructuresListener(this);
		System.getProperties().remove(JDIDebugUIPlugin.getUniqueIdentifier() + ".debuggerActive"); //$NON-NLS-1$
	}

	/**
	 * Initializes compilation error handling and suspending
	 * on uncaught exceptions.
	 */
	protected void initializeProblemHandling() {
		InitJob job = new InitJob();
		job.setSystem(true);
		job.schedule();
	}

	/**
	 * Notifies java debug targets of the given breakpoint
	 * addition or removal.
	 *
	 * @param breakpoint a breakpoint
	 * @param kind ADDED, REMOVED, or CHANGED
	 */
	protected void notifyTargets(IBreakpoint breakpoint, int kind) {
		IDebugTarget[] targets = DebugPlugin.getDefault().getLaunchManager().getDebugTargets();
		for (int i = 0; i < targets.length; i++) {
			if (targets[i] instanceof IJavaDebugTarget) {
				IJavaDebugTarget target = (IJavaDebugTarget)targets[i];
				notifyTarget(target, breakpoint, kind);
			}
		}
	}

	/**
	 * Notifies the give debug target of filter specifications
	 *
	 * @param target Java debug target
	 */
	protected void notifyTargetOfFilters(IJavaDebugTarget target) {

		IPreferenceStore store = JDIDebugUIPlugin.getDefault().getPreferenceStore();

		target.setFilterConstructors(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_CONSTRUCTORS));
		target.setFilterStaticInitializers(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_STATIC_INITIALIZERS));
		target.setFilterSynthetics(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_SYNTHETICS));
		target.setFilterGetters(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_GETTERS));
		target.setFilterSetters(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_SETTERS));
		target.setStepThruFilters(store.getBoolean(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS));
		target.setStepFilters(getActiveStepFilters());

	}

	/**
	 * Notifies all targets of current filter specifications.
	 */
	protected void notifyTargetsOfFilters() {
		IDebugTarget[] targets = DebugPlugin.getDefault().getLaunchManager().getDebugTargets();
		for (int i = 0; i < targets.length; i++) {
			if (targets[i] instanceof IJavaDebugTarget) {
				IJavaDebugTarget target = (IJavaDebugTarget)targets[i];
				notifyTargetOfFilters(target);
			}
		}
	}

	/**
	 * Notifies the given target of the given breakpoint
	 * addition or removal.
	 *
	 * @param target Java debug target
	 * @param breakpoint a breakpoint
	 * @param kind ADDED, REMOVED, or CHANGED
	 */
	protected void notifyTarget(IJavaDebugTarget target, IBreakpoint breakpoint, int kind) {
		switch (kind) {
			case ADDED:
				target.breakpointAdded(breakpoint);
				break;
			case REMOVED:
				target.breakpointRemoved(breakpoint,null);
				break;
			case CHANGED:
				target.breakpointChanged(breakpoint,null);
				break;
		}
	}

	/**
	 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {
		String property = event.getProperty();
		if (property.equals(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS)) {
			IBreakpoint breakpoint = getSuspendOnCompilationErrorBreakpoint();
			if (breakpoint != null) {
				int kind = REMOVED;
				if (isSuspendOnCompilationErrors()) {
					kind = ADDED;
				}
				notifyTargets(breakpoint, kind);
			}
		} else if (property.equals(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS)) {
			IBreakpoint breakpoint = getSuspendOnUncaughtExceptionBreakpoint();
			if (breakpoint != null) {
				int kind = REMOVED;
				if (isSuspendOnUncaughtExceptions()) {
					kind = ADDED;
				}
				notifyTargets(breakpoint, kind);
			}
		} else if (fgDisplayOptions.contains(property)) {
			variableViewSettingsChanged();
		} else if (isUseFilterProperty(property)) {
			notifyTargetsOfFilters();
		} else if (isFilterListProperty(property)) {
			updateActiveFilters();
		}
	}

	/**
	 * Returns whether the given property is a property that affects whether
	 * or not step filters are used.
	 */
	private boolean isUseFilterProperty(String property) {
		return property.equals(IJDIPreferencesConstants.PREF_FILTER_CONSTRUCTORS) ||
			property.equals(IJDIPreferencesConstants.PREF_FILTER_STATIC_INITIALIZERS) ||
			property.equals(IJDIPreferencesConstants.PREF_FILTER_GETTERS) ||
			property.equals(IJDIPreferencesConstants.PREF_FILTER_SETTERS) ||
			property.equals(IJDIPreferencesConstants.PREF_FILTER_SYNTHETICS) ||
			property.equals(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS);
	}

	/**
	 * Returns whether the given property is a property that affects
	 * the list of active or inactive step filters.
	 */
	private boolean isFilterListProperty(String property) {
		return property.equals(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST) ||
			property.equals(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST);
	}

	/**
	 * Enable/Disable the given breakpoint and notify
	 * targets of the change.
	 *
	 * @param breakpoint a breakpoint
	 * @param enabled whether enabeld
	 */
	protected void setEnabled(IBreakpoint breakpoint, boolean enabled) {
		try {
			breakpoint.setEnabled(enabled);
			notifyTargets(breakpoint, CHANGED);
		} catch (CoreException e) {
			JDIDebugUIPlugin.log(e);
		}
	}

	/**
	 * Returns whether suspend on compilation errors is
	 * enabled.
	 *
	 * @return whether suspend on compilation errors is
	 * enabled
	 */
	public boolean isSuspendOnCompilationErrors() {
		return JDIDebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS);
	}

	/**
	 * Returns whether suspend on uncaught exception is
	 * enabled
	 *
	 * @return whether suspend on uncaught exception is
	 * enabled
	 */
	protected boolean isSuspendOnUncaughtExceptions() {
		return JDIDebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS);
	}

	/**
	 * Sets the breakpoint used to suspend on uncaught exceptions
	 *
	 * @param breakpoint exception breakpoint
	 */
	private void setSuspendOnUncaughtExceptionBreakpoint(IJavaExceptionBreakpoint breakpoint) {
		fSuspendOnExceptionBreakpoint = breakpoint;
	}

	/**
	 * Returns the breakpoint used to suspend on uncaught exceptions
	 *
	 * @return exception breakpoint
	 */
	protected IJavaExceptionBreakpoint getSuspendOnUncaughtExceptionBreakpoint() {
		return fSuspendOnExceptionBreakpoint;
	}

	/**
	 * Sets the breakpoint used to suspend on compilation
	 * errors.
	 *
	 * @param breakpoint exception breakpoint
	 */
	private void setSuspendOnCompilationErrorsBreakpoint(IJavaExceptionBreakpoint breakpoint) {
		fSuspendOnErrorBreakpoint = breakpoint;
	}

	/**
	 * Returns the breakpoint used to suspend on compilation
	 * errors
	 *
	 * @return exception breakpoint
	 */
	protected IJavaExceptionBreakpoint getSuspendOnCompilationErrorBreakpoint() {
		return fSuspendOnErrorBreakpoint;
	}

	/**
	 * Parses the comma separated string into an array of strings
	 *
	 * @return list
	 */
	public static String[] parseList(String listString) {
		List<String> list = new ArrayList<>(10);
		StringTokenizer tokenizer = new StringTokenizer(listString, ","); //$NON-NLS-1$
		while (tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			list.add(token);
		}
		return list.toArray(new String[list.size()]);
	}

	/**
	 * Serializes the array of strings into one comma
	 * separated string.
	 *
	 * @param list array of strings
	 * @return a single string composed of the given list
	 */
	public static String serializeList(String[] list) {
		if (list == null) {
			return ""; //$NON-NLS-1$
		}
		StringBuilder buffer = new StringBuilder();
		for (int i = 0; i < list.length; i++) {
			if (i > 0) {
				buffer.append(',');
			}
			buffer.append(list[i]);
		}
		return buffer.toString();
	}

	/**
	 * Returns the current list of active step filters.
	 *
	 * @return current list of active step filters
	 */
	protected String[] getActiveStepFilters() {
		if (fActiveStepFilters == null) {
			fActiveStepFilters= parseList(JDIDebugUIPlugin.getDefault().getPreferenceStore().getString(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST));
			// After active filters are cached, register to hear about future changes
			JDIDebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		}
		return fActiveStepFilters;
	}

	/**
	 * Updates local copy of active step filters and
	 * notifies targets.
	 */
	protected void updateActiveFilters() {
		fActiveStepFilters= parseList(JDIDebugUIPlugin.getDefault().getPreferenceStore().getString(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST));
		notifyTargetsOfFilters();
	}

	/**
	 * When a Java debug target is created, install options in
	 * the target and set that the Java debugger is active.
	 * When all Java debug targets are terminated set that that Java debugger is
	 * no longer active.
	 *
	 * @see IDebugEventSetListener#handleDebugEvents(DebugEvent[])
	 */
	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getKind() == DebugEvent.CREATE) {
				Object source = event.getSource();
				if (source instanceof IJavaDebugTarget) {
					IJavaDebugTarget javaTarget = (IJavaDebugTarget)source;

					// compilation breakpoints
					if (isSuspendOnCompilationErrors()) {
						notifyTarget(javaTarget, getSuspendOnCompilationErrorBreakpoint(), ADDED);
					}

					// uncaught exception breakpoint
					if (isSuspendOnUncaughtExceptions()) {
						ILaunchConfiguration launchConfiguration = javaTarget.getLaunch().getLaunchConfiguration();
						boolean isSnippetEditor = false;

						try {
							isSnippetEditor = (launchConfiguration.getAttribute(ScrapbookLauncher.SCRAPBOOK_LAUNCH, (String)null) != null);
						} catch (CoreException e) {
						}

						if (!isSnippetEditor) {
							notifyTarget(javaTarget, getSuspendOnUncaughtExceptionBreakpoint(), ADDED);
						}
					}

					// step filters
					notifyTargetOfFilters(javaTarget);
				}
			}
		}
	}

	/**
	 * @see IJavaBreakpointListener#addingBreakpoint(IJavaDebugTarget, IJavaBreakpoint)
	 */
	@Override
	public void addingBreakpoint(IJavaDebugTarget target, IJavaBreakpoint breakpoint) {
	}

	/**
	 * @see IJavaBreakpointListener#installingBreakpoint(IJavaDebugTarget, IJavaBreakpoint, IJavaType)
	 */
	@Override
	public int installingBreakpoint(IJavaDebugTarget target, IJavaBreakpoint breakpoint, IJavaType type) {
		return DONT_CARE;
	}

	/**
	 * @see IJavaBreakpointListener#breakpointHit(IJavaThread, IJavaBreakpoint)
	 */
	@Override
	public int breakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) {
		return DONT_CARE;
	}

	/**
	 * @see IJavaBreakpointListener#breakpointInstalled(IJavaDebugTarget, IJavaBreakpoint)
	 */
	@Override
	public void breakpointInstalled(IJavaDebugTarget target, IJavaBreakpoint breakpoint) {
	}

	/**
	 * @see IJavaBreakpointListener#breakpointRemoved(IJavaDebugTarget, IJavaBreakpoint)
	 */
	@Override
	public void breakpointRemoved(IJavaDebugTarget target, IJavaBreakpoint breakpoint) {
	}

	/**
	 * Returns any problem marker associated with the current location
	 * of the given stack frame, or <code>null</code> if none.
	 *
	 * @param frame stack frame
	 * @return marker representing compilation problem, or <code>null</code>
	 * @throws DebugException if an exception occurrs retrieveing the problem
	 */
	public IMarker getProblem(IJavaStackFrame frame) {
		ILaunch launch = frame.getLaunch();
		if (launch != null) {
			ISourceLookupResult result = DebugUITools.lookupSource(frame, null);
			Object sourceElement = result.getSourceElement();
			if (sourceElement instanceof IResource) {
				try {
					IResource resource = (IResource) sourceElement;
					IMarker[] markers = resource.findMarkers("org.eclipse.jdt.core.problem", true, IResource.DEPTH_INFINITE); //$NON-NLS-1$
					int line = frame.getLineNumber();
					for (int i = 0; i < markers.length; i++) {
						IMarker marker = markers[i];
						if (marker.getAttribute(IMarker.LINE_NUMBER, -1) == line && marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) {
							return marker;
						}
					}
				} catch (CoreException e) {
				}
			}
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpointListener#breakpointHasRuntimeException(org.eclipse.jdt.debug.core.IJavaLineBreakpoint, org.eclipse.debug.core.DebugException)
	 */
	@Override
	public void breakpointHasRuntimeException(final IJavaLineBreakpoint breakpoint, final DebugException exception) {
		IStatus status;
		Throwable wrappedException= exception.getStatus().getException();
		if (wrappedException instanceof InvocationException) {
			InvocationException ie= (InvocationException) wrappedException;
			ObjectReference ref= ie.exception();
			status= new Status(IStatus.ERROR,JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ref.referenceType().name(), null);
		} else {
			status= exception.getStatus();
		}
		openConditionErrorDialog(breakpoint, DebugUIMessages.JavaDebugOptionsManager_Conditional_breakpoint_encountered_runtime_exception__1, status);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.debug.core.IJavaBreakpointListener#breakpointHasCompilationErrors(org.eclipse.jdt.debug.core.IJavaLineBreakpoint, org.eclipse.jdt.core.dom.Message[])
	 */
	@Override
	public void breakpointHasCompilationErrors(final IJavaLineBreakpoint breakpoint, final Message[] errors) {
		StringBuilder message= new StringBuilder();
		Message error;
		for (int i=0, numErrors= errors.length; i < numErrors; i++) {
			error= errors[i];
			message.append(error.getMessage());
			message.append("\n "); //$NON-NLS-1$
		}
		IStatus status= new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, message.toString(), null);
		openConditionErrorDialog(breakpoint, DebugUIMessages.JavaDebugOptionsManager_Conditional_breakpoint_has_compilation_error_s___2, status);
	}

	private void openConditionErrorDialog(final IJavaLineBreakpoint breakpoint, final String errorMessage, final IStatus status) {
		final Display display= JDIDebugUIPlugin.getStandardDisplay();
		if (display.isDisposed()) {
			return;
		}
		final String message= NLS.bind(errorMessage, new String[] {fLabelProvider.getText(breakpoint)});
		display.asyncExec(new Runnable() {
			@Override
			public void run() {
				if (display.isDisposed()) {
					return;
				}
				Shell shell= JDIDebugUIPlugin.getActiveWorkbenchShell();
				ConditionalBreakpointErrorDialog dialog= new ConditionalBreakpointErrorDialog(shell, message, status);
				int result = dialog.open();
				if (result == Window.OK) {
					JavaBreakpointPropertiesAction action= new JavaBreakpointPropertiesAction();
					action.selectionChanged(null, new StructuredSelection(breakpoint));
					action.run(null);
				}
			}
		});
	}

	/**
	 * Activates this debug options manager. When active, this
	 * manager becomes a listener to many notifications and updates
	 * running debug targets based on these notifications.
	 *
	 * A debug options manager does not need to be activated until
	 * there is a running debug target.
	 */
	private void activate() {
		if (fActivated) {
			return;
		}
		fActivated = true;
		initializeProblemHandling();
		notifyTargetsOfFilters();
		DebugPlugin.getDefault().addDebugEventListener(this);
		JDIDebugModel.addJavaBreakpointListener(this);
        JavaLogicalStructures.addStructuresListener(this);
	}

	/**
	 * Startup problem handling on the first launch.
	 *
	 * @see ILaunchListener#launchAdded(ILaunch)
	 */
	@Override
	public void launchAdded(ILaunch launch) {
		launchChanged(launch);
	}
	/**
	 * @see ILaunchListener#launchChanged(ILaunch)
	 */
	@Override
	public void launchChanged(ILaunch launch) {
		activate();
		DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
	}

	/**
	 * @see ILaunchListener#launchRemoved(ILaunch)
	 */
	@Override
	public void launchRemoved(ILaunch launch) {
	}

	/**
	 * Adds message attributes to java breakpoints.
	 *
	 * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[])
	 */
	@Override
	public void breakpointsAdded(final IBreakpoint[] breakpoints) {
		// if a breakpoint is added, but already has a message, do not update it
		List<IBreakpoint> update = new ArrayList<>();
		for (int i = 0; i < breakpoints.length; i++) {
			IBreakpoint breakpoint = breakpoints[i];
			try {
				if (breakpoint instanceof IJavaBreakpoint && breakpoint.getMarker().getAttribute(IMarker.MESSAGE) == null) {
					update.add(breakpoint);
				}
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
			}
		}
		if (!update.isEmpty()) {
			updateBreakpointMessages(update.toArray(new IBreakpoint[update.size()]));
		}
	}

	/**
	 * Updates message attributes on the given java breakpoints.
	 *
	 * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[])
	 */
	private void updateBreakpointMessages(final IBreakpoint[] breakpoints) {
		IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
			@Override
			public void run(IProgressMonitor monitor) throws CoreException {
				for (int i = 0; i < breakpoints.length; i++) {
					IBreakpoint breakpoint = breakpoints[i];
					if (breakpoint instanceof IJavaBreakpoint) {
						String info = fLabelProvider.getText(breakpoint);
						String type = DebugUIMessages.JavaDebugOptionsManager_Breakpoint___1;
						if (breakpoint instanceof IJavaMethodBreakpoint || breakpoint instanceof IJavaMethodEntryBreakpoint) {
							type = DebugUIMessages.JavaDebugOptionsManager_Method_breakpoint___2;
						} else if (breakpoint instanceof IJavaWatchpoint) {
							type = DebugUIMessages.JavaDebugOptionsManager_Watchpoint___3;
						} else if (breakpoint instanceof IJavaLineBreakpoint) {
							type = DebugUIMessages.JavaDebugOptionsManager_Line_breakpoint___4;
						}
						IMarker marker = breakpoint.getMarker();
						if (marker.exists()) {
							marker.setAttribute(IMarker.MESSAGE, type + info);
						}
					}
				}
			}
		};

		final ISchedulingRule modifyWorkspaceRule = modifyWorkspaceRule();

		ISchedulingRule currentRule = Job.getJobManager().currentRule();
		if (currentRule != null && currentRule.contains(modifyWorkspaceRule)) {
			try {
				ResourcesPlugin.getWorkspace().run(runnable, null, 0, null);
			} catch (CoreException e) {
				JDIDebugUIPlugin.log(e);
			}
		} else {
			UpdateBreakpointMessagesJob updateBreakpointMessagesJob = new UpdateBreakpointMessagesJob(modifyWorkspaceRule, runnable);
			updateBreakpointMessagesJob.schedule();
		}
	}

	private static ISchedulingRule modifyWorkspaceRule() {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRoot workspaceRoot = workspace.getRoot();
		IResourceRuleFactory rootFactory = workspace.getRuleFactory();
		ISchedulingRule modifyWorkspaceRule = rootFactory.modifyRule(workspaceRoot);
		return modifyWorkspaceRule;
	}

	private static class UpdateBreakpointMessagesJob extends Job {

		private ISchedulingRule rule;
		private ICoreRunnable runnable;

		UpdateBreakpointMessagesJob(ISchedulingRule rule, ICoreRunnable runnable) {
			super("Updating breakpoint messages"); //$NON-NLS-1$
			this.rule = rule;
			this.runnable = runnable;
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			if (monitor.isCanceled()) {
				return Status.CANCEL_STATUS;
			}
			try {
				ResourcesPlugin.getWorkspace().run(runnable, rule, 0, monitor);
			} catch (CoreException e) {
				String errorMessage = "Failed to update breakpoint messages"; //$NON-NLS-1$
				IStatus errorStatus = new Status(IStatus.ERROR, IJavaDebugUIConstants.PLUGIN_ID, errorMessage, e);
				return errorStatus;
			}
			return Status.OK_STATUS;
		}

		@Override
		public boolean belongsTo(Object family) {
			return JavaDebugOptionsManager.class == family;
		}
	}

	/**
	 * Updates message attributes on java breakpoints.
	 *
	 * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsChanged(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
	 */
	@Override
	public void breakpointsChanged(
		IBreakpoint[] breakpoints,
		IMarkerDelta[] deltas) {
			updateBreakpointMessages(breakpoints);

	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsRemoved(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[])
	 */
	@Override
	public void breakpointsRemoved(
		IBreakpoint[] breakpoints,
		IMarkerDelta[] deltas) {
	}

    /* (non-Javadoc)
     * @see org.eclipse.jdt.internal.debug.core.logicalstructures.IJavaStructuresListener#logicalStructuresChanged()
     */
    @Override
	public void logicalStructuresChanged() {
    	variableViewSettingsChanged();
    }

    /**
	 * Refreshes the variables view by firing a change event on a stack frame (active
	 * debug context).
	 */
    protected void variableViewSettingsChanged() {
        // If a Java stack frame is selected in the Debug view, fire a change event on
        // it so the variables view will update for any structure changes.
        IAdaptable selected = DebugUITools.getDebugContext();
        if (selected != null) {
			IJavaStackFrame frame = selected.getAdapter(IJavaStackFrame.class);
            if (frame != null) {
                DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {
                        new DebugEvent(frame, DebugEvent.CHANGE)
                });
            }
        }
    }

}
