/*******************************************************************************
 * 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.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 if (breakpoint instanceof IJavaWatchpoint) {
			context = new TypeContext(type, 0);
		} 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 lineNumber = breakpoint.getMarker().getAttribute(IMarker.LINE_NUMBER, -1);
			int position= -1;
			if (source != null && lineNumber != -1) {
				try {
					position = new Document(source).getLineOffset(lineNumber - 1);
				} 
				catch (BadLocationException e) {JDIDebugUIPlugin.log(e);}
			}
			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<IJavaLineBreakpoint, Stack<String>>();
			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<IJavaLineBreakpoint, Stack<String>>(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<String>();
			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);
			}
		}
	}

}
