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