/*******************************************************************************
 * Copyright (c) 2010, 2019 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 *   Zeligsoft - Bug 237205
 *   Patrick Könemann - Bug 294200 (history)
 *   E.D.Willink - rework of LPG OCL Console for Xtext
 *******************************************************************************/
package org.eclipse.ocl.examples.xtext.console;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ocl.common.internal.preferences.BooleanPreference;
import org.eclipse.ocl.examples.debug.vm.core.VMVariable;
import org.eclipse.ocl.examples.debug.vm.data.VMVariableData;
import org.eclipse.ocl.examples.xtext.console.actions.CloseAction;
import org.eclipse.ocl.examples.xtext.console.actions.DebugAction;
import org.eclipse.ocl.examples.xtext.console.actions.LoadExpressionAction;
import org.eclipse.ocl.examples.xtext.console.actions.SaveExpressionAction;
import org.eclipse.ocl.examples.xtext.console.messages.ConsoleMessages;
import org.eclipse.ocl.examples.xtext.console.xtfo.EmbeddedXtextEditor;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.ElementExtension;
import org.eclipse.ocl.pivot.ExpressionInOCL;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.evaluation.AbstractLogger;
import org.eclipse.ocl.pivot.evaluation.EvaluationEnvironment;
import org.eclipse.ocl.pivot.evaluation.EvaluationHaltedException;
import org.eclipse.ocl.pivot.evaluation.EvaluationVisitor;
import org.eclipse.ocl.pivot.evaluation.ModelManager;
import org.eclipse.ocl.pivot.ids.IdResolver;
import org.eclipse.ocl.pivot.internal.context.ClassContext;
import org.eclipse.ocl.pivot.internal.evaluation.ExecutorInternal;
import org.eclipse.ocl.pivot.internal.resource.EnvironmentFactoryAdapter;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal.EnvironmentFactoryInternalExtension;
import org.eclipse.ocl.pivot.options.PivotConsoleOptions;
import org.eclipse.ocl.pivot.resource.CSResource;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory.EnvironmentFactoryExtension;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.pivot.utilities.OCLHelper;
import org.eclipse.ocl.pivot.utilities.ParserContext;
import org.eclipse.ocl.pivot.utilities.ParserException;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.Pivotable;
import org.eclipse.ocl.pivot.utilities.ValueUtil;
import org.eclipse.ocl.pivot.values.CollectionValue;
import org.eclipse.ocl.pivot.values.InvalidValueException;
import org.eclipse.ocl.pivot.values.Value;
import org.eclipse.ocl.xtext.base.ui.model.BaseDocument;
import org.eclipse.ocl.xtext.base.ui.utilities.BaseUIUtil;
import org.eclipse.ocl.xtext.base.utilities.BaseCSResource;
import org.eclipse.ocl.xtext.essentialocl.utilities.EssentialOCLCSResource;
import org.eclipse.ocl.xtext.essentialocl.utilities.EssentialOCLPlugin;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.actions.ClearOutputAction;
import org.eclipse.ui.part.IPage;
import org.eclipse.ui.part.Page;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.contentassist.DefaultContentAssistantFactory;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.ui.editor.outline.impl.EObjectNode;
import org.eclipse.xtext.ui.editor.outline.impl.OutlinePage;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;

import com.google.inject.Injector;

/**
 * The page implementing the Interactive OCL console.
 */
public class OCLConsolePage extends Page //implements MetamodelManagerListener
{
	public static enum ColorChoices
	{
		DEFAULT,
		ERROR
	}

	public static class InterrogatableContentAssistantFactory extends DefaultContentAssistantFactory
	{
		@Override
		protected ContentAssistant createAssistant() {
			return new InterrogatableContentAssistant();
		}
	}

	public static final class InterrogatableContentAssistant extends ContentAssistant
	{
		@Override
		public boolean isProposalPopupActive() {
			return super.isProposalPopupActive();
		}
	}

	private class EvaluationRunnable implements IRunnableWithProgress
	{
		private final @NonNull CSResource resource;
		private final @NonNull String expression;
		private Object value = null;

		public EvaluationRunnable(@NonNull CSResource resource, @NonNull String expression) {
			this.resource = resource;
			this.expression = expression;
		}

		public Object getValue() {
			return value;
		}

		@Override
		public void run(final IProgressMonitor monitor) {
			monitor.beginTask(NLS.bind(ConsoleMessages.Progress_Title, expression), 10);
			monitor.subTask(ConsoleMessages.Progress_Synchronising);
			monitor.worked(1);
			//			CS2ASResourceAdapter csAdapter = CS2ASResourceAdapter.getAdapter((BaseCSResource)resource, metamodelManager);
			EnvironmentFactory environmentFactory = editor.getEnvironmentFactory();
			//			monitor.subTask(ConsoleMessages.Progress_CST);
			//			try {
			//				csAdapter.refreshPivotMappings();
			//			} catch (Exception e) {
			//				value = new ExceptionValue(valueFactory, ConsoleMessages.Result_MappingFailure, e);
			//				return;
			//			}
			//			monitor.worked(2);
			//			monitor.subTask(ConsoleMessages.Progress_AST);
			ExpressionInOCL expressionInOCL;
			try {
				PivotUtil.checkResourceErrors("", resource); //$NON-NLS-1$
				expressionInOCL = parserContext.getExpression(resource);
			} catch (ParserException e) {
				value = new InvalidValueException(e, ConsoleMessages.Result_ParsingFailure);
				return;
			}
			if (expressionInOCL != null) {
				//			monitor.worked(2);
				monitor.subTask(ConsoleMessages.Progress_Extent);
				ModelManager modelManager = environmentFactory.createModelManager(contextObject);
				//				EvaluationEnvironment evaluationEnvironment = environmentFactory.createEvaluationEnvironment(expressionInOCL, modelManager);
				ExecutorInternal executor = ((EnvironmentFactoryExtension)environmentFactory).createExecutor(modelManager);
				executor.initializeEvaluationEnvironment(expressionInOCL);
				EvaluationEnvironment evaluationEnvironment = executor.getRootEvaluationEnvironment();
				Object contextValue = executor.getIdResolver().boxedValueOf(contextObject);
				evaluationEnvironment.add(ClassUtil.nonNullModel(expressionInOCL.getOwnedContext()), contextValue);
				monitor.worked(2);
				monitor.subTask(ConsoleMessages.Progress_Evaluating);
				try {
					//				metamodelManager.setMonitor(monitor);
					EvaluationVisitor evaluationVisitor = executor.getEvaluationVisitor();
					evaluationVisitor.setMonitor(BasicMonitor.toMonitor(monitor));
					executor.setLogger(new AbstractLogger()
					{
						@Override
						public void print(final @NonNull String message) {
							OCLConsolePage.this.getControl().getDisplay().asyncExec(new Runnable()
							{
								@Override
								public void run() {
									OCLConsolePage.this.append(message, ColorManager.DEFAULT, false);
								}
							});
						}
					});
					value = evaluationVisitor.visitExpressionInOCL(expressionInOCL);
				} catch (EvaluationHaltedException e) {
					value = new InvalidValueException(ConsoleMessages.Result_EvaluationTerminated);
				} catch (InvalidValueException e) {
					value = e;
				} catch (Exception e) {
					value = new InvalidValueException(e, ConsoleMessages.Result_EvaluationFailure);
				} finally {
					//				metamodelManager.setMonitor(null);
				}
			}
			monitor.worked(4);
		}
	}

	/**
	 * A key listener that listens for the Enter key to evaluate the OCL
	 * expression.
	 */
	private class InputKeyListener implements KeyListener {
		private boolean evaluationSuccess = false;
		private List<String> history = new ArrayList<String>();
		private int currentHistoryPointer = 0;

		@Override
		public void keyPressed(KeyEvent e) {
			IContentAssistant contentAssistant = editor.getViewer().getContentAssistant();
			if ((contentAssistant instanceof InterrogatableContentAssistant)
					&& ((InterrogatableContentAssistant)contentAssistant).isProposalPopupActive()) {
				return;
			}
			switch (e.keyCode) {
				case SWT.CR :
					if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
						String text = getEditorDocument().get();
						evaluationSuccess = evaluate(text.trim());
					}
					break;
				case SWT.PAGE_UP :
					if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
						// history
						if (currentHistoryPointer == 0 && history.size() > 0) {
							if (history.size() > 0 && history.get(0).length() == 0) {
								history.remove(0);
							}
							history.add(0, getEditorDocument().get().trim());
							currentHistoryPointer = 1;
							setTextFromHistory();
						} else if (currentHistoryPointer < history.size() - 1) {
							currentHistoryPointer++;
							setTextFromHistory();
						}
					}
					break;
				case SWT.PAGE_DOWN :
					if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
						// history
						if (currentHistoryPointer > 0) {
							currentHistoryPointer--;
							setTextFromHistory();
						}
					}
					break;
			}
		}

		@Override
		public void keyReleased(KeyEvent e) {
			switch (e.keyCode) {
				case SWT.CR :
					if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
						if (evaluationSuccess) {
							getEditorDocument().set(""); //$NON-NLS-1$
							// history
							if (history.size() > 0 && history.get(0).trim().length() == 0) {
								history.remove(0);
							}
							if (history.size() == 0 || !history.get(0).equals(lastOCLExpression.trim())) {
								history.add(0, lastOCLExpression.trim());
							}
							currentHistoryPointer = 0;
						}
						evaluationSuccess = false;
					}
					break;
					//			case ' ':
					//			    if ((e.stateMask & SWT.CTRL) == SWT.CTRL) {
					//			        input.getContentAssistant().showPossibleCompletions();
					//			    }
			}
		}

		protected void setTextFromHistory() {
			String newText = history.get(currentHistoryPointer);
			getEditorDocument().set(newText);
			input.setSelectedRange(newText.length(), 0);
		}
	}

	private final OCLConsole console;
	private Composite page;

	private ITextViewer output;
	private ColorManager colorManager;

	private SourceViewer input;
	private EmbeddedXtextEditor editor;
	private String lastOCLExpression;
	private DebugAction debugAction;

	private ISelectionService selectionService;
	private ISelectionListener selectionListener;
	private @Nullable EObject contextObject = null;
	private @Nullable Iterable<org.eclipse.ocl.pivot.@NonNull Class> contextModelClasses = null;
	private ParserContext parserContext;

	/*	public IItemLabelProvider tupleTypeLabelProvider = new IItemLabelProvider() {

		public Object getImage(Object object) {
			return null;
		}

		public String getText(Object object) {
		    @SuppressWarnings("unchecked")
            TupleValue tuple = (TupleValue) object;
			TupleType tupleType = tuple.getTupleType();

			StringBuilder result = new StringBuilder();
			result.append("Tuple{");//$NON-NLS-1$

			for (Iterator<?> iter = tupleType.oclProperties().iterator();
					iter.hasNext();) {

				Object next = iter.next();

				result.append(oclFactory.getName(next));
				result.append(" = "); //$NON-NLS-1$
				result.append(OCLConsolePage.this.toString(tuple.getValue(next)));

				if (iter.hasNext()) {
					result.append(", "); //$NON-NLS-1$
				}
			}

			result.append('}');

			return result.toString();
		}}; */

	/**
	 * Initializes me.
	 * @param console
	 */
	protected OCLConsolePage(OCLConsole console) {
		super();
		//		this.metamodelManager = new CancelableMetamodelManager();
		this.console = console;
		//		System.out.println("Create " + getClass() + "@" + Integer.toHexString(System.identityHashCode(this)));
	}

	/**
	 * Appends the specified text to the output viewer.
	 *
	 * @param text the text to append
	 * @param rgb the color to print the text with
	 * @param bold whether to print the text bold
	 */
	protected void append(String text, RGB rgb, boolean bold) {

		IDocument doc = getDocument();
		try {
			int offset = doc.getLength();
			text = (text != null ? text : "") + '\n';
			int length = text.length();
			if (offset > 0) {
				doc.replace(offset, 0, text);
			} else {
				doc.set(text);
			}
			StyleRange style = new StyleRange();
			style.start = offset;
			style.length = length;
			style.foreground = colorManager.getColor(rgb);

			if (bold) {
				style.fontStyle = SWT.BOLD;
			}

			output.getTextWidget().setStyleRange(style);
		} catch (BadLocationException e) {
			IStatus status = new Status(IStatus.ERROR, XtextConsolePlugin.getPluginId(),
				1, ConsoleMessages.Output_Exception, e);
			XtextConsolePlugin.getInstance().getLog().log(status);
		}
	}

	public void cancelValidation() {
		BaseDocument editorDocument = getEditorDocument();
		Job validationJob = editorDocument.getValidationJob();
		if (validationJob != null) {
			validationJob.cancel();
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {}
			while (validationJob.getState() == Job.RUNNING) {
				validationJob.cancel();
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {}
			};
		}
	}

	@Override
	public void createControl(Composite parent) {
		// force left-to-right text direction in the console, because it
		//    works with OCL text and the OCL language is based on English
		page = new SashForm(parent, SWT.VERTICAL | SWT.LEFT_TO_RIGHT);

		output = new TextViewer(page, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
		output.getTextWidget().setLayoutData(new GridData(GridData.FILL_BOTH));
		output.getTextWidget().setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT));
		output.setEditable(false);
		output.setDocument(new Document());

		colorManager = new ColorManager();
		//		document.setOCLFactory(oclFactory);
		//		document.setModelingLevel(modelingLevel);

		createEditor(page);
		input = editor.getViewer();
		input.getTextWidget().addKeyListener(new InputKeyListener());
		input.getTextWidget().setFont(JFaceResources.getFont(JFaceResources.TEXT_FONT));

		selectionListener = new ISelectionListener() {
			@Override
			public void selectionChanged(IWorkbenchPart part, final ISelection selection) {
				//				System.out.println("selectionChanged: ");
				if (part instanceof IConsoleView) {
					IConsole console = ((IConsoleView)part).getConsole();
					if (console instanceof OCLConsole) {
						return;
					}
				}
				if (part instanceof ContentOutline) {
					ContentOutline contentOutline = (ContentOutline)part;
					IPage currentPage = contentOutline.getCurrentPage();
					if (currentPage instanceof OutlinePage) {
						OutlinePage outlinePage = (OutlinePage)currentPage;
						IXtextDocument xtextDocument = outlinePage.getXtextDocument();
						Element pivotElement = xtextDocument.readOnly(new IUnitOfWork<Element, XtextResource>()
						{
							@Override
							public Element exec(@Nullable XtextResource state) throws Exception {
								if ((state != null) && (selection instanceof IStructuredSelection)) {
									IStructuredSelection structuredSelection = (IStructuredSelection) selection;
									if (structuredSelection.size() == 1) {
										Object selectedObject = structuredSelection.getFirstElement();
										if (selectedObject instanceof EObjectNode) {
											EObjectNode eObjectNode = (EObjectNode)selectedObject;
											URI uri = eObjectNode.getEObjectURI();
											if (uri != null) {
												EObject csObject = state.getEObject(uri.fragment());
												if (csObject instanceof Pivotable) {
													Element pivotObject = ((Pivotable) csObject).getPivot();
													if (pivotObject != null) {
														return pivotObject;
													}
												}
											}
										}
									}
								}
								return null;
							}
						});
						if (pivotElement != null) {
							OCLConsolePage.this.selectionChanged(new StructuredSelection(pivotElement));
							return;
						}
					}
				}
				OCLConsolePage.this.selectionChanged(selection);
			}};
			selectionService = getSite().getWorkbenchWindow().getSelectionService();
			selectionService.addPostSelectionListener(selectionListener);

			// get current selection
			//		ISelection selection = selectionService.getSelection();			// Doesn't have a value preceding console start
			ISelection selection = BaseUIUtil.getActiveSelection(getSite());
			selectionChanged(selection);

			((SashForm) page).setWeights(new int[] {2, 1});

			ClearOutputAction clear = new ClearOutputAction(output);
			CloseAction close = new CloseAction();
			SaveExpressionAction saveExpression = new SaveExpressionAction(this);
			LoadExpressionAction loadExpression = new LoadExpressionAction(this);
			debugAction = new DebugAction(this);

			IMenuManager menu = getSite().getActionBars().getMenuManager();
			menu.add(loadExpression);
			menu.add(saveExpression);
			menu.add(clear);
			menu.add(close);
			menu.add(debugAction);

			IToolBarManager toolbar = getSite().getActionBars().getToolBarManager();
			toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, loadExpression);
			toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, saveExpression);
			toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, clear);
			toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, close);
			toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, debugAction);
	}

	private int convertHeightInCharsToPixels(int i) {
		// Create a GC to calculate font's dimensions
		GC gc = new GC(Display.getDefault());
		gc.setFont(editor.getViewer().getTextWidget().getFont());

		// Determine string's dimensions
		FontMetrics fontMetrics = gc.getFontMetrics();

		int ret = (fontMetrics.getHeight() + fontMetrics.getAscent() + fontMetrics.getDescent() + fontMetrics.getLeading()) * i;

		// Dispose that gc
		gc.dispose();

		return ret;
	}

	protected @Nullable EnvironmentFactoryAdapter createEditor(Composite s1) {
		Composite client = s1; //new Composite(s1, SWT.NULL);
		Injector injector = XtextConsolePlugin.getInstance().getInjector(EssentialOCLPlugin.LANGUAGE_ID);
		Composite editorComposite = client; //new Composite(client, SWT.NULL);
		editor = new EmbeddedXtextEditor(editorComposite, injector, /*SWT.BORDER |*/ SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
		//		MetamodelManagerResourceSetAdapter.getAdapter(editor.getResourceSet(), metamodelManager);

		/*		editor.getViewer().getTextWidget().addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				String text = editor.getViewer().getTextWidget().getText();
				System.out.println("modifyText: " + text);
//				if (!text.equals(getEditedEObject().getAsString())) {
//					getEditor().setDirty(true);
//					getEditor().firePropertyChange(IEditorPart.PROP_DIRTY);
//				} else {
//					getEditor().setDirty(false);
//					getEditor().firePropertyChange(IEditorPart.PROP_DIRTY);
//				}
			}
		}); */
		/*		editor.getDocument().addModelListener(new IXtextModelListener() {
			public void modelChanged(XtextResource resource) {
				System.out.println("modelChanged: " + resource);
//				reconcileChangedModel();
			}
		}); */

		editor.getViewer().getTextWidget().addVerifyKeyListener(new VerifyKeyListener() {
			@Override
			public void verifyKey(VerifyEvent e) {
				//				System.out.println("verifyKey: " + e.keyCode);
				if (e.keyCode == SWT.KEYPAD_CR || e.keyCode == SWT.CR) {
					if ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
						e.doit = false;
					}
				}
			}
		});

		GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
		data.heightHint= convertHeightInCharsToPixels(1);
		editorComposite.setLayoutData(data);

		ResourceSet resourceSet = editor.getResourceSet();
		return resourceSet != null ? EnvironmentFactoryAdapter.find(resourceSet) : null;
	}

	/**
	 * Extends the inherited method to dispose of additional colour resources.
	 */
	@Override
	public void dispose() {
		//		System.out.println("Dispose " + getClass() + "@" + Integer.toHexString(System.identityHashCode(this)));
		if (editor != null) {
			editor.dispose();
			editor = null;
		}
		colorManager.dispose();
		selectionService.removePostSelectionListener(selectionListener);
		reset();
		super.dispose();
	}

	/**
	 * Prints an error message to the output viewer, in red text.
	 *
	 * @param message the error message to print
	 */
	private void error(String message) {
		append(message, ColorManager.OUTPUT_ERROR, false);
		scrollText();
	}

	/**
	 * Evaluates an OCL expression using the OCL Interpreter's {@link OCLHelper}
	 * API.
	 *
	 * @param expression an OCL expression
	 *
	 * @return <code>true</code> on successful evaluation; <code>false</code>
	 *    if the expression failed to parse or evaluate
	 */
	protected boolean evaluate(final String expression) {
		//		if (contextObject == null) {
		//			error(OCLInterpreterMessages.console_noContext);
		//			return false;
		//		}
		if ((expression == null) || (expression.trim().length() <= 0)) {
			error(ConsoleMessages.Result_NoExpression);
			return false;
		}
		//		editorDocument.getResource();
		// create an OCL helper to do our parsing and evaluating
		//      ocl = oclFactory.createOCL(modelingLevel);
		//      OCLHelper helper = ocl.createOCLHelper();
		boolean result = true;
		try {
			// set our helper's context classifier to parse against it
			//	        ConstraintKind kind = modelingLevel.setContext(helper, context, oclFactory);

			IDocument doc = getDocument();

			if (doc.getLength() > 0) {
				// separate previous output by a blank line
				append("", ColorManager.DEFAULT, false); //$NON-NLS-1$
			}

			append(ConsoleMessages.Heading_Evaluating, ColorManager.DEFAULT, true);
			append(expression, ColorManager.DEFAULT, false);
			append(ConsoleMessages.Heading_Results, ColorManager.DEFAULT, true);

			final BaseDocument editorDocument = getEditorDocument();
			Object value = null;
			try {
				value = editorDocument.readOnly(new IUnitOfWork<Object, XtextResource>() {

					@Override
					public Object exec(@Nullable XtextResource state) throws Exception {
						if (state != null) {
							IProgressService progressService = PlatformUI.getWorkbench().getProgressService();
							EvaluationRunnable runnable = new EvaluationRunnable((CSResource) state, expression);
							progressService.busyCursorWhile(runnable);
							return runnable.getValue();
						}
						else {
							return null;
						}
					}});
			}
			catch (Exception e) {
				append(e.getMessage(), ColorManager.OUTPUT_ERROR, false);
			}
			if (value instanceof InvalidValueException) {
				InvalidValueException exception = (InvalidValueException)value;
				append(exception.getMessage(), ColorManager.OUTPUT_ERROR, true);
				Throwable cause = exception.getCause();
				if ((cause != null) && (cause != exception)) {
					if (cause instanceof ParserException) {
						append(cause.getMessage(), ColorManager.OUTPUT_ERROR, false);
					}
					else {
						StringWriter s = new StringWriter();
						PrintWriter pw = new PrintWriter(s);
						cause.printStackTrace(pw);
						append(s.toString(), ColorManager.OUTPUT_ERROR, false);
					}
				}
			}
			else if (value != null) {
				CollectionValue collectionValue = ValueUtil.isCollectionValue(value);
				if (collectionValue != null) {
					for (Object elementValue : collectionValue.iterable()) {
						append(ValueUtil.stringValueOf(elementValue), ColorManager.OUTPUT_RESULTS, false);
					}
				}
				else {
					append(ValueUtil.stringValueOf(value), ColorManager.OUTPUT_RESULTS, false);
				}
			}
			else {
				append(ValueUtil.stringValueOf(value), ColorManager.OUTPUT_ERROR, false);
			}
			scrollText();

			// store the successfully parsed expression
			lastOCLExpression = expression;
		} catch (Exception e) {
			result = false;
			error((e.getLocalizedMessage() == null) ? e.getClass().getName()
				: e.getLocalizedMessage());
		}

		return result;
	}

	protected void flushEvents() {
		IWorkbench workbench = PlatformUI.getWorkbench();
		while (workbench.getDisplay().readAndDispatch());
	}

	public @Nullable EObject getContextObject() {
		return contextObject;
	}

	@Override
	public Control getControl() {
		return page;
	}

	/**
	 * Obtains the document in the output viewer.
	 *
	 * @return the output document
	 */
	private IDocument getDocument() {
		return output.getDocument();
	}

	public IXtextDocument getDocument(URI trimFragment) {
		return getEditorDocument();
	}

	public BaseDocument getEditorDocument() {
		return (BaseDocument) editor.getDocument();
	}

	public OCL getEditorOCL() {
		return editor.getOCL();
	}

	public String getLastOCLExpression() {
		return lastOCLExpression;
	}

	public @NonNull EnvironmentFactory getEnvironmentFactory(@Nullable EObject contextObject) {
		ResourceSet contextResourceSet = null;
		if (contextObject != null) {
			Resource contextResource = contextObject.eResource();
			if (contextResource != null) {
				contextResourceSet = contextResource.getResourceSet();
			}
		}
		editor.setContext(contextResourceSet);
		return editor.getEnvironmentFactory();
	}

	protected ILaunch internalLaunchDebugger() {
		return debugAction.launch();
	}

	protected void popUpModelTypesUsageInformation() {
		Shell shell = getControl().getShell();
		if (!shell.isDisposed()) {
			shell.getDisplay().asyncExec(new Runnable()
			{
				@Override
				public void run() {
					MessageDialog.openInformation(shell, ConsoleMessages.ModelTypesUsage_Title, ConsoleMessages.ModelTypesUsage_Message);
					//						MessageDialogWithToggle openInformation = MessageDialogWithToggle.openInformation(getControl().getShell(), ConsoleMessages.ModelTypesUsage_Title, ConsoleMessages.ModelTypesUsage_Message, ConsoleMessages.ModelTypesUsage_Question, false, null, null);
					//						if (openInformation.getToggleState()) {		// Don't show again
					//							option.setDefaultValue(false);			// Don't know how to persist this so don't offer toggle
					//						}
				}
			});
		}
	}

	protected void refreshSelection(final Object selected) {
		if (getControl().isDisposed()) {
			return;
		}
		final BaseDocument editorDocument = getEditorDocument();
		try {
			editorDocument.modify(new IUnitOfWork<Object, XtextResource>()
			{
				@Override
				public Value exec(@Nullable XtextResource resource) throws Exception {
					Object selectedObject = selected;
					if (selectedObject instanceof IAdaptable) {
						Object adapted = ((IAdaptable) selectedObject).getAdapter(EObject.class);
						boolean isNonNull = adapted != null;			// BUG 485093 fixed in Neon reported that adapted was nonNull and so the test was redundant.
						if (isNonNull) {
							selectedObject = adapted;
						}
					}
					if (selectedObject instanceof EObject) {
						contextObject = (EObject) selectedObject;
					}
					else {		// FIXME else Value in particular CollectionValue
						contextObject = null;
					}
					if (resource instanceof BaseCSResource) {
						((BaseCSResource)resource).dispose();
					}

					EnvironmentFactory environmentFactory = getEnvironmentFactory(contextObject);
					IdResolver.IdResolverExtension idResolver = (IdResolver.IdResolverExtension)environmentFactory.getIdResolver();
					//				DomainType staticType = idResolver.getStaticTypeOfValue(null, selectedObject);
					org.eclipse.ocl.pivot.Class staticType = idResolver.getStaticTypeOfValue(null, contextObject);
					org.eclipse.ocl.pivot.Class contextType = environmentFactory.getMetamodelManager().getPrimaryClass(staticType);
					Iterable<org.eclipse.ocl.pivot.@NonNull Class> savedContextModelClasses = contextModelClasses;
					contextModelClasses = contextObject != null ? idResolver.getModelClassesOf(contextObject) : null;
					BooleanPreference option = PivotConsoleOptions.ConsoleModeltypesInformation;
					if ((contextModelClasses != null) && !contextModelClasses.equals(savedContextModelClasses) && option.getPreferredValue()) {
						popUpModelTypesUsageInformation();
					}
					EObject instanceContext = contextObject;
					if ((instanceContext != null) && !(instanceContext instanceof Element)) {
						instanceContext = ((EnvironmentFactoryInternalExtension)environmentFactory).getASOf(Element.class, instanceContext);
					}
					parserContext = new ClassContext(environmentFactory, null, contextType, (instanceContext instanceof Type) && !(instanceContext instanceof ElementExtension) ? (Type)instanceContext : null);
					//				}
					//				else {
					//					parserContext = new ModelContext(metamodelManager, null);
					//				}
					//		        parserContext = new EObjectContext(metamodelManager, null, contextObject);
					EssentialOCLCSResource csResource = (EssentialOCLCSResource) resource;
					if (csResource != null) {
						if (contextObject != null) {
							csResource.getCS2AS();
						}
						ResourceSet resourceSet = editor.getResourceSet();
						if (resourceSet != null) {
							environmentFactory.adapt(resourceSet);
						}
						csResource.setParserContext(parserContext);
					}
					console.setSelection(contextObject, contextType);
					return null;
				}
			});
		}
		catch (WrappedException e) {
			Shell shell = getControl().getShell();
			if (!shell.isDisposed()) {
				Throwable t = e.getCause();
				IStatus status = new Status(IStatus.ERROR, XtextConsolePlugin.PLUGIN_ID, t.getLocalizedMessage(), t);
				ErrorDialog.openError(shell, ConsoleMessages.SelectionError_Title, ConsoleMessages.SelectionError_Message, status);
				console.setSelection(null, null);
			}
		}
		catch (Exception e) {
			Shell shell = getControl().getShell();
			if (!shell.isDisposed()) {
				IStatus status = new Status(IStatus.ERROR, XtextConsolePlugin.PLUGIN_ID, e.getLocalizedMessage(), e);
				ErrorDialog.openError(shell, ConsoleMessages.SelectionError_Title, ConsoleMessages.SelectionError_Message, status);
				console.setSelection(null, null);
			}
		}
	}

	public void reset() {
		if (editor != null) {
			flushEvents();
		}
		parserContext = null;
		contextObject = null;
	}

	protected void resetDocument() {
		IDocument doc = getDocument();
		if (doc != null) {
			doc.set(""); //$NON-NLS-1$
		}
	}

	/**
	 * Ensures that the last text printed to the output viewer is shown.
	 */
	private void scrollText() {
		output.revealRange(getDocument().getLength(), 0);
	}

	private void selectionChanged(ISelection sel) {
		Object selectedObject = BaseUIUtil.getSelectedObject(sel, getSite());
		if (selectedObject instanceof VMVariable) {					// FIXME move to BaseUIUtil once additional dependency acceptable
			VMVariableData vmVar = ((VMVariable)selectedObject).getVmVar();
			if (vmVar != null) {
				selectedObject = vmVar.valueObject;
			}
		}
		refreshSelection(selectedObject);
	}

	@Override
	public void setFocus() {
		input.getTextWidget().setFocus();
	}
}
