/*******************************************************************************
 * Copyright (c) 2005, 2018 IBM Corporation, Zeligsoft Inc. 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)
 *******************************************************************************/

package org.eclipse.ocl.examples.interpreter.console;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
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.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ocl.OCL;
import org.eclipse.ocl.ecore.EcoreEnvironmentFactory;
import org.eclipse.ocl.examples.interpreter.OCLExamplePlugin;
import org.eclipse.ocl.examples.interpreter.console.text.ColorManager;
import org.eclipse.ocl.examples.interpreter.console.text.OCLDocument;
import org.eclipse.ocl.examples.interpreter.console.text.OCLSourceViewer;
import org.eclipse.ocl.examples.interpreter.internal.l10n.OCLInterpreterMessages;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.helper.ConstraintKind;
import org.eclipse.ocl.helper.OCLHelper;
import org.eclipse.ocl.options.EvaluationOptions;
import org.eclipse.ocl.types.TupleType;
import org.eclipse.ocl.uml.UMLEnvironmentFactory;
import org.eclipse.ocl.uml.options.EvaluationMode;
import org.eclipse.ocl.uml.options.UMLEvaluationOptions;
import org.eclipse.ocl.uml.util.OCLUMLUtil;
import org.eclipse.ocl.util.Tuple;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.console.actions.ClearOutputAction;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.Page;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.UMLFactory;
import org.osgi.framework.Bundle;


/**
 * The page implementing the Interactive OCL console.
 */
public class OCLConsolePage
extends Page {

	private static int BUNDLE_AVAILABLE = Bundle.RESOLVED | Bundle.ACTIVE |
			Bundle.STARTING;

	private Composite page;

	private ITextViewer output;
	private OCLSourceViewer input;
	private OCLDocument document;

	private ColorManager colorManager;

	private String lastOCLExpression;
	private EObject context;

	private ISelectionService selectionService;
	private ISelectionListener selectionListener;

	private IOCLFactory<Object> oclFactory = new EcoreOCLFactory();
	private OCL<?, Object, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> ocl;
	private ModelingLevel modelingLevel = ModelingLevel.M2;

	private Map<TargetMetamodel, IAction> metamodelActions =
			new java.util.HashMap<TargetMetamodel, IAction>();

	private static final AdapterFactory reflectiveAdapterFactory =
			new ReflectiveItemProviderAdapterFactory();

	private static final AdapterFactory defaultAdapterFactory =
			new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);

	public IItemLabelProvider tupleTypeLabelProvider = new IItemLabelProvider() {

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

		public String getText(Object object) {
			@SuppressWarnings("unchecked")
			Tuple<?, Object> tuple = (Tuple<?, Object>) 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.
		 */
		OCLConsolePage() {
			super();
		}

		@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 = new OCLDocument();
			document.setOCLFactory(oclFactory);
			document.setModelingLevel(modelingLevel);

			input = new OCLSourceViewer(page, colorManager, SWT.BORDER | SWT.MULTI);
			input.setDocument(document);
			input.getTextWidget().addKeyListener(new InputKeyListener());

			selectionListener = new ISelectionListener() {
				public void selectionChanged(IWorkbenchPart part, ISelection selection) {
					OCLConsolePage.this.selectionChanged(selection);
				}};
				selectionService = getSite().getWorkbenchWindow().getSelectionService();
				selectionService.addPostSelectionListener(selectionListener);

				// get current selection
				ISelection selection = selectionService.getSelection();
				if (selection == null) {
					selection = getActiveSelection();
				}
				selectionChanged(selection);

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

				ClearOutputAction clear = new ClearOutputAction(output);
				CloseAction close = new CloseAction();
				SaveAction save = new SaveAction();
				LoadAction load = new LoadAction();

				IMenuManager menu = getSite().getActionBars().getMenuManager();
				menu.add(load);
				menu.add(save);
				menu.add(clear);
				menu.add(close);

				IMenuManager metamodelMenu = new MenuManager(
					OCLInterpreterMessages.console_metamodelMenu,
						"org.eclipse.ocl.examples.interpreter.metamodel"); //$NON-NLS-1$
				menu.add(metamodelMenu);
				DropDownAction metamodelAction = new DropDownAction();
				metamodelAction.setToolTipText(OCLInterpreterMessages.console_metamodelTip);
				addMetamodelActions(metamodelMenu, metamodelAction);

				IMenuManager levelMenu = new MenuManager(OCLInterpreterMessages.console_modelingLevel);
				menu.add(levelMenu);
				DropDownAction levelAction = new DropDownAction();
				levelAction.setToolTipText(OCLInterpreterMessages.console_modelingLevelTip);
				IAction m2 = new ModelingLevelAction(ModelingLevel.M2);
				m2.setChecked(true);
				levelMenu.add(m2);
				levelAction.addAction(m2);
				IAction m1 = new ModelingLevelAction(ModelingLevel.M1);
				levelMenu.add(m1);
				levelAction.addAction(m1);

				ActionContributionItem metamodelItem = new ActionContributionItem(
					metamodelAction);
				metamodelItem.setMode(ActionContributionItem.MODE_FORCE_TEXT);

				IToolBarManager toolbar = getSite().getActionBars().getToolBarManager();
				toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, metamodelItem);
				toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, levelAction);
				toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, load);
				toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, save);
				toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, clear);
				toolbar.appendToGroup(IConsoleConstants.OUTPUT_GROUP, close);
		}

		/**
		 * Adds actions for the available target metamodels to the action bars.
		 *
		 * @param metamodelMenu the console's drop-down action bar menu
		 * @param metamodelAction the console's drop-down tool bar button
		 */
		private void addMetamodelActions(IMenuManager metamodelMenu,
				DropDownAction metamodelAction) {
			IAction ecore = new EcoreMetamodelAction();
			ecore.setChecked(true);
			ImageDescriptor img = getImage(EcoreFactory.eINSTANCE.getEPackage());
			if (img != null) {
				ecore.setImageDescriptor(img);
			}

			metamodelMenu.add(ecore);
			metamodelAction.addAction(ecore);
			metamodelActions.put(TargetMetamodel.Ecore, ecore);

			Bundle umlBundle = Platform.getBundle("org.eclipse.uml2.uml"); //$NON-NLS-1$
			if ((umlBundle != null) && isAvailable(umlBundle)) {
				IAction uml = new UMLMetamodelAction();
				img = getImage(UMLFactory.eINSTANCE.createModel());
				if (img != null) {
					uml.setImageDescriptor(img);
				}

				metamodelMenu.add(uml);
				metamodelAction.addAction(uml);
				metamodelActions.put(TargetMetamodel.UML, uml);
			}
		}

		/**
		 * Queries whether a bundle is available.
		 *
		 * @param bundle a bundle
		 * @return whether it is active or resolved
		 */
		static boolean isAvailable(Bundle bundle) {
			return (bundle.getState() & BUNDLE_AVAILABLE) != 0;
		}

		/**
		 * Gets the editor image for the specified element.
		 *
		 * @param element a model element
		 *
		 * @return the corresponding image
		 */
		private ImageDescriptor getImage(EObject element) {
			ImageDescriptor result = null;

			IItemLabelProvider provider = (IItemLabelProvider) new ComposedAdapterFactory(
				ComposedAdapterFactory.Descriptor.Registry.INSTANCE).adapt(
					element, IItemLabelProvider.class);
			if (provider != null) {
				Object image = provider.getImage(element);
				if (image != null) {
					result = ExtendedImageRegistry.INSTANCE.getImageDescriptor(image);
				}
			}

			return result;
		}

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

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

		/**
		 * Extends the inherited method to dispose of additional colour resources.
		 */
		@Override
		public void dispose() {
			colorManager.dispose();
			selectionService.removePostSelectionListener(selectionListener);

			super.dispose();
		}

		/**
		 * Programmatically sets my target metamodel.
		 *
		 * @param metamodel the target metamodel
		 */
		public void setTargetMetamodel(TargetMetamodel metamodel) {
			IAction action = metamodelActions.get(metamodel);

			if (action != null) {
				// deselect the old one
				metamodelActions.get(oclFactory.getTargetMetamodel()).setChecked(false);

				action.run();
				action.setChecked(true);
			}
		}

		private ISelection getActiveSelection() {
			try {
				IPageSite site = getSite();
				if (site == null) {
					return null;
				}
				IWorkbenchWindow workbenchWindow = site.getWorkbenchWindow();
				if (workbenchWindow == null) {
					return null;
				}
				IWorkbenchPage activePage = workbenchWindow.getActivePage();
				if (activePage == null) {
					return null;
				}
				IEditorPart activeEditor = activePage.getActiveEditor();
				if (activeEditor == null) {
					return null;
				}
				IEditorSite editorSite = activeEditor.getEditorSite();
				if (editorSite == null) {
					return null;
				}
				ISelectionProvider selectionProvider = editorSite.getSelectionProvider();
				if (selectionProvider == null) {
					return null;
				}
				return selectionProvider.getSelection();
			}
			catch (Exception e) {
				return  null;
			}
		}

		private void selectionChanged(ISelection sel) {
			if (sel instanceof IStructuredSelection) {
				IStructuredSelection ssel = (IStructuredSelection) sel;

				if (!ssel.isEmpty()) {
					Object selected = ssel.getFirstElement();

					if (selected instanceof EObject) {
						context = (EObject) selected;
					} else if (selected instanceof IAdaptable) {
						EObject adapter = ((IAdaptable) selected).getAdapter(EObject.class);
						context = adapter;
					}

					document.setOCLContext(context);
				}
			}
		}

		/**
		 * 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
		 */
		boolean evaluate(String expression) {
			boolean result = true;

			if (context == null) {
				result = false;
				error(OCLInterpreterMessages.console_noContext);
			} else {
				// create an OCL helper to do our parsing and evaluating
				ocl = oclFactory.createOCL(modelingLevel);
				OCLHelper<Object, ?, ?, ?> helper = ocl.createOCLHelper();

				try {
					// set our helper's context classifier to parse against it
					ConstraintKind kind = modelingLevel.setContext(helper, context, oclFactory);

					IDocument doc = getDocument();
					Color outputDefault = colorManager.getColor(ColorManager.DEFAULT);
					Color outputResults = colorManager.getColor(ColorManager.OUTPUT_RESULTS);

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

					append(OCLInterpreterMessages.console_evaluating, outputDefault, true);
					append(expression, outputDefault, false);
					append(OCLInterpreterMessages.console_results, outputDefault, true);

					switch (modelingLevel) {
						case M2:
							OCLExpression<Object> parsed = helper.createQuery(expression);

							// evaluate the query
							print(ocl.evaluate(context, parsed), outputResults, false);
							break;
						case M1:
							helper.createConstraint(kind, expression);

							// just report a successful parse
							print(OCLInterpreterMessages.console_parsed,
								outputResults, false);
							break;
					}

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

			return result;
		}

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

		/**
		 * Prints the specified <code>object</code> to the output viewer.  The
		 * object is converted to a string using the best matching EMF label
		 * provider adapter if it is an {@link EObject}; otherwise, just use
		 * {@link String#valueOf(java.lang.Object)} on it.  If the
		 * <code>object</code> is a collection or an array, then we print each
		 * element on a separate line.
		 *
		 * @param object the object or collection to print
		 * @param color the color to print the <code>object</code> with
		 * @param bold whether to display it in bold text
		 */
		private void print(Object object, Color color, boolean bold) {
			Collection<?> toPrint;

			if (object == null) {
				toPrint = Collections.EMPTY_SET;
			} else if (object instanceof Collection) {
				toPrint = (Collection<?>) object;
			} else if (object.getClass().isArray()) {
				toPrint = Arrays.asList((Object[]) object);
			} else {
				toPrint = Collections.singleton(object);
			}

			for (Iterator<?> iter = toPrint.iterator(); iter.hasNext();) {
				append(toString(iter.next()), color, bold);
			}

			scrollText();
		}

		/**
		 * Converts a single object to a string, according to the rules described
		 * for the {@link #print(Object, Color, boolean)} method.
		 *
		 * @param object the object to print (not a collection type)
		 * @return the string form of the <code>object</code>
		 *
		 * @see #print(Object, Color, boolean)
		 */
		String toString(Object object) {
			if (ocl.isInvalid(object)) {
				return "OclInvalid"; //$NON-NLS-1$
			} else if (object instanceof String) {
				return "'" + object + "'";  //$NON-NLS-1$//$NON-NLS-2$
			} else if (object instanceof Tuple) {
				return tupleTypeLabelProvider.getText(object);
			} else if (object instanceof EObject) {
				EObject eObject = (EObject) object;

				IItemLabelProvider labeler =
						(IItemLabelProvider) defaultAdapterFactory.adapt(
							eObject,
							IItemLabelProvider.class);

				if (labeler == null) {
					labeler = (IItemLabelProvider) reflectiveAdapterFactory.adapt(
						eObject,
						IItemLabelProvider.class);
				}

				if (labeler != null) {
					return labeler.getText(object);
				}
			}

			return String.valueOf(object);
		}

		/**
		 * 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.getColor(ColorManager.OUTPUT_ERROR), false);
			scrollText();
		}

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

		/**
		 * Appends the specidied text to the output viewer.
		 *
		 * @param text the text to append
		 * @param color the color to print the text with
		 * @param bold whether to print the text bold
		 */
		private void append(String text, Color color, boolean bold) {

			IDocument doc = getDocument();
			try {
				int offset = doc.getLength();
				int length = text.length();

				text = text + '\n';

				if (offset > 0) {
					doc.replace(offset, 0, text);
				} else {
					doc.set(text);
				}

				StyleRange style = new StyleRange();
				style.start = offset;
				style.length = length;
				style.foreground = color;

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

				output.getTextWidget().setStyleRange(style);
			} catch (BadLocationException e) {
				IStatus status = new Status(
					IStatus.ERROR,
					OCLExamplePlugin.getPluginId(),
					1,
					OCLInterpreterMessages.console_outputExc,
					e);

				OCLExamplePlugin.getDefault().getLog().log(status);
			}
		}

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

			public void keyPressed(KeyEvent e) {
				switch (e.keyCode) {
					case SWT.CR :
						if (!input.isContentAssistActive()
								&& (e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
							String text = document.get();
							evaluationSuccess = evaluate(text.trim());
						}
						break;
					case SWT.PAGE_UP :
						if (!input.isContentAssistActive()
								&& (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, document.get().trim());
								currentHistoryPointer = 1;
								setTextFromHistory();
							} else if (currentHistoryPointer < history.size() - 1) {
								currentHistoryPointer++;
								setTextFromHistory();
							}
						}
						break;
					case SWT.PAGE_DOWN :
						if (!input.isContentAssistActive()
								&& (e.stateMask & (SWT.CTRL | SWT.SHIFT)) == 0) {
							// history
							if (currentHistoryPointer > 0) {
								currentHistoryPointer--;
								setTextFromHistory();
							}
						}
						break;
				}
			}

			public void keyReleased(KeyEvent e) {
				switch (e.keyCode) {
					case SWT.CR :
						if ((e.stateMask & SWT.CTRL) == 0) {
							if (evaluationSuccess) {
								document.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);
				document.set(newText);
				input.setSelectedRange(newText.length(), 0);
			}
		}

		/**
		 * An action that closes the Interactive OCL console.
		 */
		private class CloseAction extends Action {
			private final String tip;

			/**
			 * Initializes me.
			 */
			CloseAction() {
				super(
					OCLInterpreterMessages.console_closeAction_label,
					PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
						ISharedImages.IMG_TOOL_DELETE));

				tip = OCLInterpreterMessages.console_closeAction_tip;
			}

			@Override
			public String getToolTipText() {
				return tip;
			}

			@Override
			public void run() {
				OCLConsole.getInstance().close();
			}
		}

		/**
		 * An action that saves the last-evaluated OCL expression to an XMI file.
		 */
		private class SaveAction extends Action {
			private final String tip;

			/**
			 * Initializes me.
			 */
			SaveAction() {
				super(
					OCLInterpreterMessages.console_saveAction_label,
					ImageDescriptor.createFromURL(
						FileLocator.find(
							OCLExamplePlugin.getDefault().getBundle(),
							new Path("$nl$/icons/elcl16/save.gif"), //$NON-NLS-1$
							null)));

				tip = OCLInterpreterMessages.console_saveAction_tip;
			}

			@Override
			public String getToolTipText() {
				return tip;
			}

			@Override
			public void run() {
				Shell shell = getControl().getShell();

				if (lastOCLExpression != null) {
					FileDialog dlg = new FileDialog(shell, SWT.SAVE);
					dlg.setFilterExtensions(new String[] {"*.xmi"}); //$NON-NLS-1$
					dlg.setText(OCLInterpreterMessages.console_saveDlg_title);

					String file = dlg.open();
					if (file != null) {
						try {
							OCLResource.save(file, document, lastOCLExpression);
						} catch (Exception e) {
							MessageDialog.openError(
								shell,
								OCLInterpreterMessages.console_saveError_title,
								e.getLocalizedMessage());
						}
					}
				} else {
					MessageDialog.openWarning(
						shell,
						OCLInterpreterMessages.console_saveWarn_title,
						OCLInterpreterMessages.console_saveWarn_noExpr);
				}
			}
		}

		/**
		 * An action that loads the last-evaluated OCL expression to an XMI file.
		 */
		private class LoadAction extends Action {
			private final String tip;

			/**
			 * Initializes me.
			 */
			LoadAction() {
				super(
					OCLInterpreterMessages.console_loadAction_label,
					PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
						ISharedImages.IMG_OBJ_FILE));

				tip = OCLInterpreterMessages.console_loadAction_tip;
			}

			@Override
			public String getToolTipText() {
				return tip;
			}

			@Override
			public void run() {
				Shell shell = getControl().getShell();

				FileDialog dlg = new FileDialog(shell, SWT.OPEN);
				dlg.setFilterExtensions(new String[] {"*.xmi"}); //$NON-NLS-1$
				dlg.setText(OCLInterpreterMessages.console_loadDlg_title);

				String file = dlg.open();
				if (file != null) {
					try {
						String text = OCLResource.load(file);

						if (text != null) {
							document.set(text);
						} else {
							MessageDialog.openWarning(
								shell,
								OCLInterpreterMessages.console_loadWarn_title,
								OCLInterpreterMessages.console_loadWarn_noExpr);
						}
					} catch (Exception e) {
						MessageDialog.openError(
							shell,
							OCLInterpreterMessages.console_loadError_title,
							e.getLocalizedMessage());
					}
				}
			}
		}

		private class EcoreMetamodelAction extends Action {
			private final String tip;

			/**
			 * Initializes me.
			 */
			EcoreMetamodelAction() {
				super(OCLInterpreterMessages.console_metamodel_ecore);

				tip = OCLInterpreterMessages.console_metamodel_ecoreTip;
			}

			@Override
			public int getStyle() {
				return AS_RADIO_BUTTON;
			}

			@Override
			public String getToolTipText() {
				return tip;
			}

			@Override
			public void run() {
				oclFactory = new EcoreOCLFactory();
				document.setOCLFactory(oclFactory);
			}
		}

		private class EcoreOCLFactory implements IOCLFactory<Object> {
			public TargetMetamodel getTargetMetamodel() {
				return TargetMetamodel.Ecore;
			}

			private EcoreEnvironmentFactory createEnvironmentFactory() {
				Resource eResource = context.eResource();
				ResourceSet resourceSet = eResource != null ? eResource.getResourceSet() : null;
				EPackage.Registry packageRegistry = resourceSet != null ? resourceSet.getPackageRegistry() : null;
				EPackage.Registry compositeRegistry = packageRegistry != null ? new DelegatingPackageRegistry(packageRegistry,
					EPackage.Registry.INSTANCE) : EPackage.Registry.INSTANCE;
				return new EcoreEnvironmentFactory(compositeRegistry);
			}

			@SuppressWarnings("unchecked")
			public OCL<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> createOCL(ModelingLevel level) {
				EcoreEnvironmentFactory envFactory = createEnvironmentFactory();
				return OCL.newInstance(envFactory);
			}

			@SuppressWarnings("unchecked")
			public OCL<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> createOCL(ModelingLevel level,
					Resource res) {
				EcoreEnvironmentFactory envFactory = createEnvironmentFactory();
				return OCL.newInstance(envFactory, res);
			}

			public Object getContextClassifier(EObject object) {
				return context.eClass();
			}

			public String getName(Object modelElement) {
				return ((ENamedElement) modelElement).getName();
			}
		}

		private class UMLMetamodelAction extends Action {
			private final String tip;

			/**
			 * Initializes me.
			 */
			UMLMetamodelAction() {
				super(OCLInterpreterMessages.console_metamodel_uml);

				tip = OCLInterpreterMessages.console_metamodel_umlTip;
			}

			@Override
			public int getStyle() {
				return AS_RADIO_BUTTON;
			}

			@Override
			public String getToolTipText() {
				return tip;
			}

			@Override
			public void run() {
				oclFactory = new UMLOCLFactory();
				document.setOCLFactory(oclFactory);
			}
		}

		private class UMLOCLFactory implements IOCLFactory<Object> {
			public TargetMetamodel getTargetMetamodel() {
				return TargetMetamodel.UML;
			}

			@SuppressWarnings("unchecked")
			public OCL<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> createOCL(ModelingLevel level) {
				UMLEnvironmentFactory factory = new UMLEnvironmentFactory(
					new DelegatingPackageRegistry(
						context.eResource().getResourceSet().getPackageRegistry(),
						EPackage.Registry.INSTANCE),
					context.eResource().getResourceSet());


				OCL<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> result = OCL.newInstance(factory);

				switch (level) {
					case M2:
						EvaluationOptions.setOption(result.getEvaluationEnvironment(),
							UMLEvaluationOptions.EVALUATION_MODE,
							EvaluationMode.RUNTIME_OBJECTS);
						break;
					default:
						EvaluationOptions.setOption(result.getEvaluationEnvironment(),
							UMLEvaluationOptions.EVALUATION_MODE,
							EvaluationMode.INSTANCE_MODEL);
						break;
				}

				return result;
			}

			@SuppressWarnings("unchecked")
			public OCL<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> createOCL(ModelingLevel level,
					Resource res) {

				UMLEnvironmentFactory factory = new UMLEnvironmentFactory(
					new DelegatingPackageRegistry(
						context.eResource().getResourceSet().getPackageRegistry(),
						EPackage.Registry.INSTANCE),
					context.eResource().getResourceSet());

				OCL<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> result = OCL.newInstance(factory, res);

				switch (level) {
					case M2:
						EvaluationOptions.setOption(result.getEvaluationEnvironment(),
							UMLEvaluationOptions.EVALUATION_MODE,
							EvaluationMode.RUNTIME_OBJECTS);
						break;
					default:
						EvaluationOptions.setOption(result.getEvaluationEnvironment(),
							UMLEvaluationOptions.EVALUATION_MODE,
							EvaluationMode.INSTANCE_MODEL);
						break;
				}

				return result;
			}

			public Object getContextClassifier(EObject object) {
				return OCLUMLUtil.getClassifier(context.eClass(),
					context.eResource().getResourceSet());
			}

			public String getName(Object modelElement) {
				return ((NamedElement) modelElement).getName();
			}
		}

		private class ModelingLevelAction extends Action {
			private final ModelingLevel level;

			/**
			 * Initializes me.
			 */
			ModelingLevelAction(ModelingLevel level) {
				super(level.name());

				this.level = level;
			}

			@Override
			public int getStyle() {
				return AS_RADIO_BUTTON;
			}

			@Override
			public void run() {
				modelingLevel = level;
				document.setModelingLevel(level);
			}
		}

		private class DropDownAction extends Action implements IMenuCreator {
			private Menu menu;
			private List<IAction> actions = new java.util.ArrayList<IAction>();

			private IPropertyChangeListener listener = new IPropertyChangeListener() {
				public void propertyChange(PropertyChangeEvent event) {
					if (IAction.CHECKED.equals(event.getProperty())) {
						if (Boolean.TRUE.equals(event.getNewValue())) {
							actionChecked((IAction) event.getSource());
						}
					}
				}};

				DropDownAction() {
					super();

					setMenuCreator(this);
				}

				public void addAction(IAction action) {
					actions.add(action);
					action.addPropertyChangeListener(listener);

					if (action.isChecked()) {
						actionChecked(action);
					}
				}

				private void actionChecked(IAction action) {
					setImageDescriptor(action.getImageDescriptor());
					setText(action.getText());
				}

				public Menu getMenu(Control parent) {
					if (menu == null) {
						menu = new Menu(parent);

						for (IAction action : actions) {
							addAction(menu, action);
						}
					}

					return menu;
				}

				private void addAction(Menu m, IAction action) {
					ActionContributionItem contrib = new ActionContributionItem(action);
					contrib.fill(m, -1);
				}

				public void dispose() {
					if (menu != null) {
						menu.dispose();
					}
				}

				public Menu getMenu(Menu parent) {
					return null;
				}
		}
}
