/*******************************************************************************
 * Copyright (c) 2009, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.debug.ui.breakpoints;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Pattern;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
import org.eclipse.jdt.internal.debug.ui.BreakpointUtils;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.JDISourceViewer;
import org.eclipse.jdt.internal.debug.ui.breakpoints.AbstractJavaBreakpointEditor;
import org.eclipse.jdt.internal.debug.ui.contentassist.IJavaDebugContentAssistContext;
import org.eclipse.jdt.internal.debug.ui.contentassist.JavaDebugContentAssistProcessor;
import org.eclipse.jdt.internal.debug.ui.contentassist.TypeContext;
import org.eclipse.jdt.internal.debug.ui.display.DisplayViewerConfiguration;
import org.eclipse.jdt.internal.debug.ui.propertypages.PropertyPageMessages;
import org.eclipse.jdt.ui.text.IJavaPartitions;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextViewerExtension6;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.IUndoManagerExtension;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.operations.OperationHistoryActionHandler;
import org.eclipse.ui.operations.RedoActionHandler;
import org.eclipse.ui.operations.UndoActionHandler;
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;

/**
 * Controls to edit a breakpoint's conditional expression, condition enabled state,
 * and suspend policy (suspend when condition is <code>true</code> or when the value of the
 * conditional expression changes).
 * <p>
 * The controls are intended to be embedded in a composite provided by the client - for
 * example, in a dialog. Clients must call {@link #createControl(Composite)} as the first
 * life cycle method after instantiation. Clients may then call {@link #setInput(Object)}
 * with the breakpoint object to be displayed/edited. Changes are not applied to the
 * breakpoint until {@link #doSave()} is called. The method {@link #isDirty()} may be used
 * to determine if any changes have been made in the editor, and {@link #getStatus()} may
 * be used to determine if the editor settings are valid. Clients can register for
 * property change notification ({@link #addPropertyListener(IPropertyListener)}). The editor
 * will fire a property change each time a setting is modified. The same editor can be
 * used to display different breakpoints by calling {@link #setInput(Object)} with different
 * breakpoint objects.
 * </p>
 *
 * @since 3.5
 */
public final class JavaBreakpointConditionEditor extends AbstractJavaBreakpointEditor {

	private Button fConditional;
	private Button fWhenTrue;
	private Button fWhenChange;

	private JDISourceViewer fViewer;
	private IContentAssistProcessor fCompletionProcessor;
	private IJavaLineBreakpoint fBreakpoint;
	private IHandlerService fHandlerService;
	private IHandler fContentAssistHandler;
	private IHandlerActivation fContentAssistActivation;
	private IHandler fUndoHandler;
	private IHandlerActivation fUndoActivation;
	private IHandler fRedoHandler;
	private IHandlerActivation fRedoActivation;

	private IDocumentListener fDocumentListener;

	private Combo fConditionHistory;
	private IDialogSettings fConditionHistoryDialogSettings;
	private boolean fReplaceConditionInHistory;
	private Map<IJavaLineBreakpoint, Stack<String>> fLocalConditionHistory;
	private int fSeparatorIndex;

	private IViewSite fBreakpointsViewSite;
	private IAction fViewUndoAction;
	private IAction fViewRedoAction;
	private OperationHistoryActionHandler fViewerUndoAction;
	private OperationHistoryActionHandler fViewerRedoAction;


	/**
	 * Property id for breakpoint condition expression.
	 */
	public static final int PROP_CONDITION= 0x1001;

	/**
	 * Property id for breakpoint condition enabled state.
	 */
	public static final int PROP_CONDITION_ENABLED= 0x1002;

	/**
	 * Property id for breakpoint condition suspend policy.
	 */
	public static final int PROP_CONDITION_SUSPEND_POLICY= 0x1003;

	private static final int MAX_HISTORY_SIZE= 10;
	private static final String DS_SECTION_CONDITION_HISTORY= "conditionHistory"; //$NON-NLS-1$
	private static final String DS_KEY_HISTORY_ENTRY_COUNT= "conditionHistoryEntryCount"; //$NON-NLS-1$
	private static final String DS_KEY_HISTORY_ENTRY_PREFIX= "conditionHistoryEntry_"; //$NON-NLS-1$
	private static final Pattern NEWLINE_PATTERN= Pattern.compile("\r\n|\r|\n"); //$NON-NLS-1$;


	/**
	 * Creates a new Java breakpoint condition editor.
	 */
	public JavaBreakpointConditionEditor() {
	}

	/**
	 * Creates a new Java breakpoint condition editor with a history drop-down list.
	 *
	 * @param dialogSettings the dialog settings for the condition history or <code>null</code> to
	 *            use the default settings (i.e. those used by JDT Debug)
	 * @since 3.6
	 */
	public JavaBreakpointConditionEditor(IDialogSettings dialogSettings) {
		fConditionHistoryDialogSettings= dialogSettings != null ? dialogSettings : DialogSettings.getOrCreateSection(JDIDebugUIPlugin.getDefault().getDialogSettings(), DS_SECTION_CONDITION_HISTORY);
	}

	/**
	 * Adds the given property listener to this editor. Property changes
	 * are reported on the breakpoint being edited. Property identifiers
	 * are breakpoint attribute keys.
	 *
	 * @param listener listener
	 */
	@Override
	public void addPropertyListener(IPropertyListener listener) {
		super.addPropertyListener(listener);
	}

	/**
	 * Removes the property listener from this editor.
	 *
	 * @param listener listener
	 */
	@Override
	public void removePropertyListener(IPropertyListener listener) {
		super.removePropertyListener(listener);
	}

	/**
	 * Sets the breakpoint to editor or <code>null</code> if none.
	 *
	 * @param input breakpoint or <code>null</code>
	 * @throws CoreException if unable to access breakpoint attributes
	 */
	@Override
	public void setInput(Object input) throws CoreException {
		try {
			boolean sameBreakpoint= fBreakpoint == input;
			suppressPropertyChanges(true);
			if (input instanceof IJavaLineBreakpoint) {
				setBreakpoint((IJavaLineBreakpoint)input);
			} else if (input instanceof IJavaWatchpoint) {
				setBreakpoint((IJavaWatchpoint) input);
			} else {
				setBreakpoint(null);
			}
			if (hasConditionHistory()) {
				if (!sameBreakpoint) {
					fReplaceConditionInHistory= false;
				}
				initializeConditionHistoryDropDown();
			}
		} finally {
			suppressPropertyChanges(false);
		}
	}


	/**
	 * Sets the breakpoint to edit. Has no effect if the breakpoint responds
	 * <code>false</code> to {@link IJavaLineBreakpoint#supportsCondition()}.
	 * The same editor can be used iteratively for different breakpoints.
	 *
	 * @param breakpoint the breakpoint to edit or <code>null</code> if none
	 * @exception CoreException if unable to access breakpoint attributes
	 */
	private void setBreakpoint(IJavaLineBreakpoint breakpoint) throws CoreException {
		fBreakpoint = breakpoint;
		if (fDocumentListener != null) {
			fViewer.getDocument().removeDocumentListener(fDocumentListener);
			fDocumentListener = null;
		}
		fViewer.unconfigure();
		IDocument document = new Document();
		JDIDebugUIPlugin.getDefault().getJavaTextTools().setupJavaDocumentPartitioner(document, IJavaPartitions.JAVA_PARTITIONING);
		fViewer.setInput(document);
		String condition = null;
		IType type = null;
		boolean controlsEnabled = false;
		boolean conditionEnabled = false;
		boolean whenTrue = true;
		if (breakpoint != null) {
			controlsEnabled = true;
			if (breakpoint.supportsCondition()) {
				condition = breakpoint.getCondition();
				conditionEnabled = breakpoint.isConditionEnabled();
				whenTrue = breakpoint.isConditionSuspendOnTrue();
				type = BreakpointUtils.getType(breakpoint);
			}
		}
		IJavaDebugContentAssistContext context = null;
		if (type == null || breakpoint == null) {
			context = new TypeContext(null, -1);
		} else {
			String source = null;
			ICompilationUnit compilationUnit = type.getCompilationUnit();
			if (compilationUnit != null && compilationUnit.getJavaProject().getProject().exists()) {
				source = compilationUnit.getSource();
			}
			else {
				IClassFile classFile = type.getClassFile();
				if (classFile != null) {
					source = classFile.getSource();
				}
			}
			int position= -1;
			if (breakpoint instanceof IJavaWatchpoint) {
				IField[] fields = type.getFields();
				// Taking first field
				ISourceRange sourceRange = fields[0].getNameRange();
				position = sourceRange.getOffset();
				if (source != null && position != -1) {
					try {
						// to get offset of the first character of line in which field is defined
						int lineNumber = new Document(source).getLineOfOffset(position);
						position = new Document(source).getLineOffset(lineNumber);
					}
					catch (BadLocationException e) {
						// ignore, breakpoint line is out-of-date with the document
					}
				}

			} else {
				int lineNumber = breakpoint.getMarker().getAttribute(IMarker.LINE_NUMBER, -1);
				if (source != null && lineNumber != -1) {
					try {
						position = new Document(source).getLineOffset(lineNumber - 1);
					}
					catch (BadLocationException e) {
						// ignore, breakpoint line is out-of-date with the document
					}
				}
			}
			context = new TypeContext(type, position);
		}
		fCompletionProcessor = new JavaDebugContentAssistProcessor(context);
		document.set((condition == null ? "" : condition)); //$NON-NLS-1$
		fViewer.configure(new DisplayViewerConfiguration() {
			@Override
			public IContentAssistProcessor getContentAssistantProcessor() {
					return fCompletionProcessor;
			}
		});
		fDocumentListener = new IDocumentListener() {
			@Override
			public void documentAboutToBeChanged(DocumentEvent event) {
			}
			@Override
			public void documentChanged(DocumentEvent event) {
				setDirty(PROP_CONDITION);
			}
		};
		fViewer.getDocument().addDocumentListener(fDocumentListener);
		fConditional.setEnabled(controlsEnabled);
		fConditional.setSelection(conditionEnabled);
		fWhenTrue.setSelection(whenTrue);
		fWhenChange.setSelection(!whenTrue);
		setEnabled(conditionEnabled && breakpoint != null && breakpoint.supportsCondition(), false);
		setDirty(false);
		checkIfUsedInBreakpointsView();
		registerViewerUndoRedoActions();
	}

	/**
	 * Creates the condition editor widgets and returns the top level
	 * control.
	 *
	 * @param parent composite to embed the editor controls in
	 * @return top level control
	 */
	@Override
	public Control createControl(Composite parent) {
		Composite controls = SWTFactory.createComposite(parent, parent.getFont(), 2, 1, GridData.FILL_HORIZONTAL, 0, 0);
		fConditional = SWTFactory.createCheckButton(controls,
				processMnemonics(PropertyPageMessages.JavaBreakpointConditionEditor_0),
				null,
				false,
				1);
		fConditional.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		fConditional.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				boolean checked = fConditional.getSelection();
				setEnabled(checked, true);
				setDirty(PROP_CONDITION_ENABLED);
			}
		});
		Composite radios = SWTFactory.createComposite(controls, controls.getFont(), 2, 1, GridData.FILL_HORIZONTAL, 0, 0);
		fWhenTrue = SWTFactory.createRadioButton(radios, processMnemonics(PropertyPageMessages.JavaBreakpointConditionEditor_1));
		fWhenTrue.setLayoutData(new GridData());
		fWhenChange = SWTFactory.createRadioButton(radios, processMnemonics(PropertyPageMessages.JavaBreakpointConditionEditor_2));
		fWhenChange.setLayoutData(new GridData());
		fWhenTrue.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				setDirty(PROP_CONDITION_SUSPEND_POLICY);
			}
		});
		fWhenChange.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				setDirty(PROP_CONDITION_SUSPEND_POLICY);
			}
		});

		if (fConditionHistoryDialogSettings != null) {
			fLocalConditionHistory= new HashMap<>();
			fConditionHistory= SWTFactory.createCombo(parent, SWT.DROP_DOWN | SWT.READ_ONLY, 1, null);
			initializeConditionHistoryDropDown();
			fConditionHistory.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					int historyIndex= fConditionHistory.getSelectionIndex() - 1;
					if (historyIndex >= 0 && historyIndex != fSeparatorIndex) {
						fViewer.getDocument().set(getConditionHistory()[historyIndex]);
					}
				}
			});
			GridData data= new GridData(GridData.FILL_HORIZONTAL);
			data.widthHint= 10;
			fConditionHistory.setLayoutData(data);
			fLocalConditionHistory= new HashMap<>(10);
		}

		fViewer = new JDISourceViewer(parent, null, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.LEFT_TO_RIGHT);
		fViewer.setEditable(false);
		ControlDecoration decoration = new ControlDecoration(fViewer.getControl(), SWT.TOP | SWT.LEFT);
		decoration.setShowOnlyOnFocus(true);
		FieldDecoration dec = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_CONTENT_PROPOSAL);
		decoration.setImage(dec.getImage());
		decoration.setDescriptionText(dec.getDescription());
		GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
		// set height/width hints based on font
		GC gc = new GC(fViewer.getTextWidget());
		gc.setFont(fViewer.getTextWidget().getFont());
		FontMetrics fontMetrics = gc.getFontMetrics();
		gd.heightHint = Dialog.convertHeightInCharsToPixels(fontMetrics, 17);
		gd.widthHint = Dialog.convertWidthInCharsToPixels(fontMetrics, 40);
		gc.dispose();
		fViewer.getControl().setLayoutData(gd);
		fContentAssistHandler= new AbstractHandler() {
			@Override
			public Object execute(ExecutionEvent event) throws org.eclipse.core.commands.ExecutionException {
				fViewer.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
				return null;
			}
		};
		fUndoHandler= new AbstractHandler() {
			@Override
			public Object execute(ExecutionEvent event) throws org.eclipse.core.commands.ExecutionException {
				fViewer.doOperation(ITextOperationTarget.UNDO);
				return null;
			}
		};
		fRedoHandler= new AbstractHandler() {
			@Override
			public Object execute(ExecutionEvent event) throws org.eclipse.core.commands.ExecutionException {
				fViewer.doOperation(ITextOperationTarget.REDO);
				return null;
			}
		};
		fHandlerService = PlatformUI.getWorkbench().getAdapter(IHandlerService.class);
		fViewer.getControl().addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				activateHandlers();
			}
			@Override
			public void focusLost(FocusEvent e) {
				deactivateHandlers();
			}
		});
		parent.addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(DisposeEvent e) {
				dispose();
			}
		});
		return parent;
	}

	/**
	 * Disposes this editor and its controls. Once disposed, the editor can no
	 * longer be used.
	 */
	@Override
	protected void dispose() {
		super.dispose();
		deactivateHandlers();
		if (fDocumentListener != null) {
			fViewer.getDocument().removeDocumentListener(fDocumentListener);
		}
		fViewer.dispose();
	}

	/**
	 * Gives focus to an appropriate control in the editor.
	 */
	@Override
	public void setFocus() {
		fViewer.getControl().setFocus();
	}

	/**
	 * Saves current settings to the breakpoint being edited. Has no
	 * effect if a breakpoint is not currently being edited or if this
	 * editor is not dirty.
	 *
	 * @exception CoreException if unable to update the breakpoint.
	 */
	@Override
	public void doSave() throws CoreException {
		if (fBreakpoint != null && isDirty()) {
			fBreakpoint.setCondition(fViewer.getDocument().get().trim());
			fBreakpoint.setConditionEnabled(fConditional.getSelection());
			fBreakpoint.setConditionSuspendOnTrue(fWhenTrue.getSelection());
			setDirty(false);
			if (hasConditionHistory()) {
				updateConditionHistories();
			}
		}
	}

	/**
	 * Returns a status describing whether the condition editor is in
	 * a valid state. Returns an OK status when all is good. For example, an error
	 * status is returned when the conditional expression is empty but enabled.
	 *
	 * @return editor status.
	 */
	@Override
	public IStatus getStatus() {
		if (fBreakpoint != null && fBreakpoint.supportsCondition()) {
			if (fConditional.getSelection()) {
				if (fViewer.getDocument().get().trim().length() == 0) {
					return new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(),  PropertyPageMessages.BreakpointConditionEditor_1);
				}
			}
		}
		return Status.OK_STATUS;
	}

	/**
	 * Returns whether the editor needs saving.
	 *
	 * @return whether the editor needs saving
	 */
	@Override
	public boolean isDirty() {
		return super.isDirty();
	}

	/**
	 * Sets whether mnemonics should be displayed in editor controls.
	 * Only has an effect if set before {@link #createControl(Composite)}
	 * is called. By default, mnemonics are displayed.
	 *
	 * @param mnemonics whether to display mnemonics
	 */
	@Override
	public void setMnemonics(boolean mnemonics) {
		super.setMnemonics(mnemonics);
	}

	private void activateHandlers() {
		fContentAssistActivation= fHandlerService.activateHandler(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, fContentAssistHandler);
		checkIfUsedInBreakpointsView();
		if (fBreakpointsViewSite == null) {
			fUndoActivation= fHandlerService.activateHandler(IWorkbenchCommandConstants.EDIT_UNDO, fUndoHandler);
			fRedoActivation= fHandlerService.activateHandler(IWorkbenchCommandConstants.EDIT_REDO, fRedoHandler);
		} else {
			registerViewerUndoRedoActions();
		}
	}

	private void deactivateHandlers() {
		if (fContentAssistActivation != null) {
			fHandlerService.deactivateHandler(fContentAssistActivation);
			fContentAssistActivation= null;
		}
		if (fUndoActivation != null) {
			fHandlerService.deactivateHandler(fUndoActivation);
			fUndoActivation= null;
		}
		if (fRedoActivation != null) {
			fHandlerService.deactivateHandler(fRedoActivation);
			fRedoActivation= null;
		}

		if (fBreakpointsViewSite != null) {
			fBreakpointsViewSite.getActionBars().setGlobalActionHandler(ITextEditorActionConstants.UNDO, fViewUndoAction);
			fBreakpointsViewSite.getActionBars().setGlobalActionHandler(ITextEditorActionConstants.REDO, fViewRedoAction);
			fBreakpointsViewSite.getActionBars().updateActionBars();
			disposeViewerUndoRedoActions();
		}
	}

	private void disposeViewerUndoRedoActions() {
		if (fViewerUndoAction != null) {
			fViewerUndoAction.dispose();
			fViewerUndoAction= null;
		}
		if (fViewerRedoAction != null) {
			fViewerRedoAction.dispose();
			fViewerRedoAction= null;
		}
	}

	/**
	 * Enables controls based on whether the breakpoint's condition is enabled.
	 *
	 * @param enabled <code>true</code> if enabled, <code>false</code> otherwise
	 * @param focus <code>true</code> if focus should be set, <code>false</code> otherwise
	 */
	private void setEnabled(boolean enabled, boolean focus) {
		fViewer.setEditable(enabled);
		fViewer.getTextWidget().setEnabled(enabled);
		fWhenChange.setEnabled(enabled);
		fWhenTrue.setEnabled(enabled);
		if (enabled) {
			fViewer.updateViewerColors();
			if (focus) {
				setFocus();
			}
		} else {
			Color color = fViewer.getControl().getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
			fViewer.getTextWidget().setBackground(color);
		}
		if (hasConditionHistory()) {
			fConditionHistory.setEnabled(enabled);
		}
	}

	/**
	 * Returns the breakpoint being edited or <code>null</code> if none.
	 *
	 * @return breakpoint or <code>null</code>
	 */
	@Override
	public Object getInput() {
		return fBreakpoint;
	}


	/**
	 * Tells whether this editor shows a condition history drop-down list.
	 *
	 * @return <code>true</code> if this editor shows a condition history drop-down list,
	 *         <code>false</code> otherwise
	 */
	private boolean hasConditionHistory() {
		return fConditionHistory != null;
	}

	/**
	 * Initializes the condition history drop-down with values.
	 */
	private void initializeConditionHistoryDropDown() {
		fConditionHistory.setItems(getConditionHistoryLabels());
		String userHint= PropertyPageMessages.JavaBreakpointConditionEditor_choosePreviousCondition;
		fConditionHistory.add(userHint, 0);
		fConditionHistory.setText(userHint);
	}

	/**
	 * Returns the condition history labels for the current breakpoint.
	 *
	 * @return an array of strings containing the condition history labels
	 */
	private String[] getConditionHistoryLabels() {
		String[] conditions= getConditionHistory();
		String[] labels= new String[conditions.length];
		for (int i= 0; i < conditions.length; i++) {
			labels[i]= NEWLINE_PATTERN.matcher(conditions[i]).replaceAll(" "); //$NON-NLS-1$
		}
		return labels;
	}

	/**
	 * Returns the condition history entries for the current breakpoint.
	 *
	 * @return an array of strings containing the history of conditions
	 */
	private String[] getConditionHistory() {
		fSeparatorIndex= -1;

		// Get global history
		String[] globalItems= readConditionHistory(fConditionHistoryDialogSettings);

		// Get local history
		Stack<String> localHistory= fLocalConditionHistory.get(fBreakpoint);
		if (localHistory == null) {
			return globalItems;
		}

		// Create combined history
		int localHistorySize= Math.min(localHistory.size(), MAX_HISTORY_SIZE);
		String[] historyItems= new String[localHistorySize + globalItems.length + 1];
		for (int i= 0; i < localHistorySize; i++) {
			historyItems[i]= localHistory.get(localHistory.size() - i - 1);
		}
		fSeparatorIndex= localHistorySize;
		historyItems[localHistorySize]= getSeparatorLabel();
		System.arraycopy(globalItems, 0, historyItems, localHistorySize + 1, globalItems.length);
		return historyItems;
	}

	/**
	 * Updates the local and global condition histories.
	 */
	private void updateConditionHistories() {
		String newItem= fViewer.getDocument().get();
		if (newItem.length() == 0) {
			return;
		}

		// Update local history
		Stack<String> localHistory= fLocalConditionHistory.get(fBreakpoint);
		if (localHistory == null) {
			localHistory= new Stack<>();
			fLocalConditionHistory.put(fBreakpoint, localHistory);
		}

		localHistory.remove(newItem);
		localHistory.push(newItem);

		// Update global history
		String[] globalItems= readConditionHistory(fConditionHistoryDialogSettings);
		if (globalItems.length > 0 && newItem.equals(globalItems[0])) {
			return;
		}

		if (!fReplaceConditionInHistory) {
			String[] tempItems= new String[globalItems.length + 1];
			System.arraycopy(globalItems, 0, tempItems, 1, globalItems.length);
			globalItems= tempItems;
		} else if (globalItems.length == 0) {
			globalItems= new String[1];
		}
		fReplaceConditionInHistory= true;
		globalItems[0]= newItem;
		storeConditionHistory(globalItems, fConditionHistoryDialogSettings);
	}

	/**
	 * Reads the condition history from the given dialog settings.
	 *
	 * @param dialogSettings the dialog settings
	 * @return the condition history
	 */
	private static String[] readConditionHistory(IDialogSettings dialogSettings) {
		int count= 0;
		try {
			count= dialogSettings.getInt(DS_KEY_HISTORY_ENTRY_COUNT);
		} catch (NumberFormatException ex) {
			// No history yet
		}
		count= Math.min(count, MAX_HISTORY_SIZE);
		String[] conditions= new String[count];
		for (int i= 0; i < count; i++) {
			conditions[i]= dialogSettings.get(DS_KEY_HISTORY_ENTRY_PREFIX + i);
		}
		return conditions;
	}

	/**
	 * Writes the given conditions into the given dialog settings.
	 *
	 * @param conditions an array of strings containing the conditions
	 * @param dialogSettings the dialog settings
	 */
	private static void storeConditionHistory(String[] conditions, IDialogSettings dialogSettings) {
		int length= Math.min(conditions.length, MAX_HISTORY_SIZE);
		int count= 0;
		outer: for (int i= 0; i < length; i++) {
			for (int j= 0; j < i; j++) {
				if (conditions[i].equals(conditions[j])) {
					break outer;
				}
			}
			dialogSettings.put(DS_KEY_HISTORY_ENTRY_PREFIX + count, conditions[i]);
			count= count + 1;
		}
		dialogSettings.put(DS_KEY_HISTORY_ENTRY_COUNT, count);
	}

	/**
	 * Returns the label for the history separator.
	 *
	 * @return the label for the history separator
	 */
	private String getSeparatorLabel() {
		int borderWidth= fConditionHistory.computeTrim(0, 0, 0, 0).width;
		Rectangle rect= fConditionHistory.getBounds();
		int width= rect.width - borderWidth;

		GC gc= new GC(fConditionHistory);
		gc.setFont(fConditionHistory.getFont());

		int fSeparatorWidth= gc.getAdvanceWidth('-');
		String separatorLabel= PropertyPageMessages.JavaBreakpointConditionEditor_historySeparator;
		int fMessageLength= gc.textExtent(separatorLabel).x;

		gc.dispose();

		StringBuffer dashes= new StringBuffer();
		int chars= (((width - fMessageLength) / fSeparatorWidth) / 2) - 2;
		for (int i= 0; i < chars; i++) {
			dashes.append('-');
		}

		StringBuffer result= new StringBuffer();
		result.append(dashes);
		result.append(" " + separatorLabel + " "); //$NON-NLS-1$//$NON-NLS-2$
		result.append(dashes);
		return result.toString().trim();
	}

	private void registerViewerUndoRedoActions() {
		if (!fViewer.getTextWidget().isFocusControl()) {
			return;
		}

		disposeViewerUndoRedoActions();
		IUndoContext undoContext= getUndoContext();
		if (undoContext != null) {
			fViewerUndoAction= new UndoActionHandler(fBreakpointsViewSite, getUndoContext());
			PlatformUI.getWorkbench().getHelpSystem().setHelp(fViewerUndoAction, IAbstractTextEditorHelpContextIds.UNDO_ACTION);
			fViewerUndoAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_UNDO);

			fViewerRedoAction= new RedoActionHandler(fBreakpointsViewSite, getUndoContext());
			PlatformUI.getWorkbench().getHelpSystem().setHelp(fViewerRedoAction, IAbstractTextEditorHelpContextIds.REDO_ACTION);
			fViewerRedoAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_REDO);
		}
		fBreakpointsViewSite.getActionBars().setGlobalActionHandler(ITextEditorActionConstants.UNDO, fViewerUndoAction);
		fBreakpointsViewSite.getActionBars().setGlobalActionHandler(ITextEditorActionConstants.REDO, fViewerRedoAction);
		fBreakpointsViewSite.getActionBars().updateActionBars();
	}

	/**
	 * Returns this editor's viewer's undo manager undo context.
	 *
	 * @return the undo context or <code>null</code> if not available
	 * @since 3.1
	 */
	private IUndoContext getUndoContext() {
		IUndoManager undoManager= ((ITextViewerExtension6)fViewer).getUndoManager();
		if (undoManager instanceof IUndoManagerExtension) {
			return ((IUndoManagerExtension)undoManager).getUndoContext();
		}
		return null;
	}

	private void checkIfUsedInBreakpointsView() {
		if (fBreakpointsViewSite != null) {
			return;
		}

		IWorkbenchWindow activeWorkbenchWindow= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		if (activeWorkbenchWindow != null && activeWorkbenchWindow.getActivePage() != null && activeWorkbenchWindow.getActivePage().getActivePart() != null) {
			IWorkbenchPartSite site= activeWorkbenchWindow.getActivePage().getActivePart().getSite();
			if ("org.eclipse.debug.ui.BreakpointView".equals(site.getId())) { //$NON-NLS-1$
				fBreakpointsViewSite= (IViewSite)site;
				fViewUndoAction= fBreakpointsViewSite.getActionBars().getGlobalActionHandler(ITextEditorActionConstants.UNDO);
				fViewRedoAction= fBreakpointsViewSite.getActionBars().getGlobalActionHandler(ITextEditorActionConstants.REDO);
			}
		}
	}

}
