Bug 484398 - Create a programmatic way to define core expressions

* Changed the name to imperative expression
* Added tracking property to editor

Change-Id: I4a749962cd8176973f549e5b80f503afc73aef42
Signed-off-by: Simon Scholz <simon.scholz@vogella.com>
diff --git a/bundles/org.eclipse.e4.tools.emf.editor3x/plugin.xml b/bundles/org.eclipse.e4.tools.emf.editor3x/plugin.xml
index 95ff227..0eb33e7 100644
--- a/bundles/org.eclipse.e4.tools.emf.editor3x/plugin.xml
+++ b/bundles/org.eclipse.e4.tools.emf.editor3x/plugin.xml
@@ -29,6 +29,9 @@
       <contributionClassCreator
             class="org.eclipse.e4.tools.emf.editor3x.extension.ToolControlContributionEditor">
       </contributionClassCreator>
+      <contributionClassCreator
+            class="org.eclipse.e4.tools.emf.editor3x.extension.ImperativeExpressionContributionEditor">
+      </contributionClassCreator>
    </extension>
    <extension
          point="org.eclipse.ui.preferencePages">
diff --git a/bundles/org.eclipse.e4.tools.emf.editor3x/src/org/eclipse/e4/tools/emf/editor3x/extension/ImperativeExpressionContributionEditor.java b/bundles/org.eclipse.e4.tools.emf.editor3x/src/org/eclipse/e4/tools/emf/editor3x/extension/ImperativeExpressionContributionEditor.java
new file mode 100644
index 0000000..a08260d
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.emf.editor3x/src/org/eclipse/e4/tools/emf/editor3x/extension/ImperativeExpressionContributionEditor.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2016 vogella GmbH 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:
+ * Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.tools.emf.editor3x.extension;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.e4.internal.tools.wizards.classes.NewImperativeExpressionClassWizard;
+import org.eclipse.e4.tools.emf.editor3x.Messages;
+import org.eclipse.e4.tools.emf.ui.common.IContributionClassCreator;
+import org.eclipse.e4.ui.model.application.MContribution;
+import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PartInitException;
+
+@SuppressWarnings("restriction")
+public class ImperativeExpressionContributionEditor implements IContributionClassCreator {
+	@Override
+	public void createOpen(MContribution contribution, EditingDomain domain, IProject project, Shell shell) {
+		createOpen(contribution, domain, project, shell, false);
+	}
+
+	private void createOpen(MContribution contribution, EditingDomain domain, IProject project, Shell shell,
+			boolean forceNew) {
+		if (forceNew || contribution.getContributionURI() == null
+				|| contribution.getContributionURI().trim().length() == 0
+				|| !contribution.getContributionURI().startsWith("bundleclass:")) { //$NON-NLS-1$
+			NewImperativeExpressionClassWizard wizard = new NewImperativeExpressionClassWizard(contribution.getContributionURI());
+			wizard.init(null, new StructuredSelection(project));
+			WizardDialog dialog = new WizardDialog(shell, wizard);
+			if (dialog.open() == Window.OK) {
+				final IFile f = wizard.getFile();
+				final ICompilationUnit el = JavaCore.createCompilationUnitFrom(f);
+				try {
+					String fullyQualified;
+					if (el.getPackageDeclarations() != null && el.getPackageDeclarations().length > 0) {
+						final String packageName = el.getPackageDeclarations()[0].getElementName();
+						final String className = wizard.getDomainClass().getName();
+						if (packageName.trim().length() > 0) {
+							fullyQualified = packageName + "." + className; //$NON-NLS-1$
+						} else {
+							fullyQualified = className;
+						}
+					} else {
+						fullyQualified = wizard.getDomainClass().getName();
+					}
+
+					final Command cmd = SetCommand.create(domain, contribution,
+							ApplicationPackageImpl.Literals.CONTRIBUTION__CONTRIBUTION_URI,
+							"bundleclass://" + Util.getBundleSymbolicName(f.getProject()) + "/" + fullyQualified); //$NON-NLS-1$//$NON-NLS-2$
+					if (cmd.canExecute()) {
+						domain.getCommandStack().execute(cmd);
+					}
+				} catch (final JavaModelException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		} else {
+			final URI uri = URI.createURI(contribution.getContributionURI());
+			if (uri.hasAuthority() && uri.segmentCount() == 1) {
+				final String symbolicName = uri.authority();
+				final String fullyQualified = uri.segment(0);
+				IProject p = ResourcesPlugin.getWorkspace().getRoot()
+						.getProject(symbolicName);
+
+				if (!p.exists()) {
+					for (final IProject check : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
+						final String name = Util.getBundleSymbolicName(check);
+						if (symbolicName.equals(name)) {
+							p = check;
+							break;
+						}
+					}
+				}
+
+				// TODO If this is not a WS-Resource we need to open differently
+				if (p != null) {
+					final IJavaProject jp = JavaCore.create(p);
+					IType t = null;
+					try {
+						if (p.exists()) {
+							t = jp.findType(fullyQualified);
+						}
+						else
+						{
+							final IJavaProject pprim = JavaCore.create(project);
+							t = pprim.findType(fullyQualified);
+						}
+						if (t != null) {
+							JavaUI.openInEditor(t);
+						} else {
+							createOpen(contribution, domain, project, shell, true);
+						}
+					} catch (final JavaModelException e) {
+						createOpen(contribution, domain, project, shell, true);
+					} catch (final PartInitException e) {
+						MessageDialog.openError(shell, Messages.ContributionEditor_FailedToOpenEditor, e.getMessage());
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+			} else {
+				MessageDialog.openError(shell, Messages.ContributionEditor_InvalidURL,
+						Messages.ContributionEditor_CurrentURLIsInvalid);
+			}
+		}
+	}
+
+	@Override
+	public boolean isSupported(EClass element) {
+		return Util.isTypeOrSuper(UiPackageImpl.Literals.IMPERATIVE_EXPRESSION, element);
+	}
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.java
index 705731e..68def5f 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.java
@@ -678,6 +678,10 @@
 	public String CoreExpressionEditor_TreeLabelDescription;
 	public String CoreExpressionEditor_ExpressionId;
 
+	public String ImperativeExpressionEditor_TreeLabel;
+	public String ImperativeExpressionEditor_TreeLabelDescription;
+	public String ImperativeExpressionEditor_TrackingLabel;
+
 	public String ExpressionIdDialog_ShellTitle;
 	public String ExpressionIdDialog_DialogTitle;
 	public String ExpressionIdDialog_DialogMessage;
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.properties b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.properties
index 6b7cf65..e5c7249 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.properties
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/Messages.properties
@@ -685,6 +685,10 @@
 CoreExpressionEditor_TreeLabelDescription=Core Expression
 CoreExpressionEditor_ExpressionId=Expression ID
 
+ImperativeExpressionEditor_TreeLabel=Imperative Expression
+ImperativeExpressionEditor_TreeLabelDescription=Imperative Expression
+ImperativeExpressionEditor_TrackingLabel=Tracking
+
 ExpressionIdDialog_ShellTitle=Find Expression ID
 ExpressionIdDialog_DialogTitle=Find Expression ID
 ExpressionIdDialog_DialogMessage=Find the expression ID defined through the 'org.eclipse.core.expressions.definitions' extension point
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/ModelEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/ModelEditor.java
index 0c9706c..6fd042a 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/ModelEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/ModelEditor.java
@@ -91,6 +91,7 @@
 import org.eclipse.e4.tools.emf.ui.internal.common.component.HandledMenuItemEditor;
 import org.eclipse.e4.tools.emf.ui.internal.common.component.HandledToolItemEditor;
 import org.eclipse.e4.tools.emf.ui.internal.common.component.HandlerEditor;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.ImperativeExpressionEditor;
 import org.eclipse.e4.tools.emf.ui.internal.common.component.KeyBindingEditor;
 import org.eclipse.e4.tools.emf.ui.internal.common.component.MenuContributionEditor;
 import org.eclipse.e4.tools.emf.ui.internal.common.component.MenuEditor;
@@ -1368,6 +1369,8 @@
 
 		registerEditor(UiPackageImpl.Literals.CORE_EXPRESSION,
 				ContextInjectionFactory.make(CoreExpressionEditor.class, context));
+		registerEditor(UiPackageImpl.Literals.IMPERATIVE_EXPRESSION,
+				ContextInjectionFactory.make(ImperativeExpressionEditor.class, context));
 
 		registerEditor(BasicPackageImpl.Literals.COMPOSITE_PART,
 				ContextInjectionFactory.make(CompositePartEditor.class, context));
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ImperativeExpressionEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ImperativeExpressionEditor.java
new file mode 100644
index 0000000..90406f4
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ImperativeExpressionEditor.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2016 vogella GmbH 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:
+ * Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.tools.emf.ui.internal.common.component;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.WritableValue;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.tools.emf.ui.common.ContributionURIValidator;
+import org.eclipse.e4.tools.emf.ui.common.IContributionClassCreator;
+import org.eclipse.e4.tools.emf.ui.common.Util;
+import org.eclipse.e4.tools.emf.ui.common.component.AbstractComponentEditor;
+import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.ControlFactory.TextPasteHandler;
+import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.ContributionClassDialog;
+import org.eclipse.e4.ui.model.application.MContribution;
+import org.eclipse.e4.ui.model.application.impl.ApplicationPackageImpl;
+import org.eclipse.e4.ui.model.application.ui.MImperativeExpression;
+import org.eclipse.e4.ui.model.application.ui.impl.UiPackageImpl;
+import org.eclipse.emf.databinding.EMFDataBindingContext;
+import org.eclipse.emf.databinding.edit.EMFEditProperties;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.IWidgetValueProperty;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Text;
+
+public class ImperativeExpressionEditor extends AbstractComponentEditor {
+	private Composite composite;
+	private EMFDataBindingContext context;
+
+	@Inject
+	IEclipseContext eclipseContext;
+
+	@Inject
+	public ImperativeExpressionEditor() {
+		super();
+	}
+
+	@Override
+	public Image getImage(Object element) {
+		return getImage(element, ResourceProvider.IMG_Obj16_class_obj);
+	}
+
+	@Override
+	public String getLabel(Object element) {
+		return Messages.ImperativeExpressionEditor_TreeLabel;
+	}
+
+	@Override
+	public String getDetailLabel(Object element) {
+		String contributionURI = ((MImperativeExpression) element).getContributionURI();
+		if (contributionURI != null && contributionURI.trim().length() > 0) {
+			int lastIndexOf = contributionURI.lastIndexOf("."); //$NON-NLS-1$
+			if (contributionURI.length() > lastIndexOf + 1) {
+				return contributionURI.substring(lastIndexOf + 1);
+			}
+			return contributionURI;
+		}
+		return null;
+	}
+
+	@Override
+	public String getDescription(Object element) {
+		return Messages.CoreExpressionEditor_TreeLabelDescription;
+	}
+
+	@Override
+	public Composite doGetEditor(Composite parent, Object object) {
+		if (composite == null) {
+			context = new EMFDataBindingContext();
+			composite = new Composite(parent, SWT.NONE);
+			composite.setLayout(new FillLayout());
+			createForm(composite, context, getMaster());
+		}
+		getMaster().setValue(object);
+		return composite;
+	}
+
+	private Composite createForm(Composite parent, EMFDataBindingContext context, WritableValue master) {
+		final CTabFolder folder = new CTabFolder(parent, SWT.BOTTOM);
+
+		CTabItem item = new CTabItem(folder, SWT.NONE);
+		item.setText(Messages.ModelTooling_Common_TabDefault);
+
+		parent = createScrollableContainer(folder);
+		item.setControl(parent.getParent());
+
+		if (getEditor().isShowXMIId() || getEditor().isLiveModel()) {
+			ControlFactory.createXMIId(parent, this);
+		}
+
+		final IWidgetValueProperty textProp = WidgetProperties.text(SWT.Modify);
+
+		final Link lnk;
+		{
+			final IContributionClassCreator c = getEditor()
+					.getContributionCreator(UiPackageImpl.Literals.IMPERATIVE_EXPRESSION);
+			if (project != null && c != null) {
+				lnk = new Link(parent, SWT.NONE);
+				lnk.setText("<A>" + Messages.HandlerEditor_ClassURI + "</A>"); //$NON-NLS-1$//$NON-NLS-2$
+				lnk.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+				lnk.addSelectionListener(new SelectionAdapter() {
+					@Override
+					public void widgetSelected(SelectionEvent e) {
+						c.createOpen((MContribution) getMaster().getValue(), getEditingDomain(), project,
+								lnk.getShell());
+					}
+				});
+			} else {
+				lnk = null;
+				final Label l = new Label(parent, SWT.NONE);
+				l.setText(Messages.HandlerEditor_ClassURI);
+				l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+			}
+
+			final Text t = new Text(parent, SWT.BORDER);
+			TextPasteHandler.createFor(t);
+			t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			t.addModifyListener(new ModifyListener() {
+
+				@Override
+				public void modifyText(ModifyEvent e) {
+					if (lnk != null) {
+						lnk.setToolTipText(((Text) e.getSource()).getText());
+					}
+				}
+			});
+			final Binding binding = context.bindValue(textProp.observeDelayed(200, t),
+					EMFEditProperties
+					.value(getEditingDomain(), ApplicationPackageImpl.Literals.CONTRIBUTION__CONTRIBUTION_URI)
+					.observeDetail(getMaster()),
+					new UpdateValueStrategy().setAfterConvertValidator(new ContributionURIValidator()),
+					new UpdateValueStrategy());
+			Util.addDecoration(t, binding);
+
+			final Button b = new Button(parent, SWT.PUSH | SWT.FLAT);
+			b.setImage(createImage(ResourceProvider.IMG_Obj16_zoom));
+			b.setText(Messages.ModelTooling_Common_FindEllipsis);
+			b.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false));
+			b.addSelectionListener(new SelectionAdapter() {
+				@Override
+				public void widgetSelected(SelectionEvent e) {
+					final ContributionClassDialog dialog = new ContributionClassDialog(b.getShell(), eclipseContext,
+							getEditingDomain(), (MContribution) getMaster().getValue(),
+							ApplicationPackageImpl.Literals.CONTRIBUTION__CONTRIBUTION_URI, Messages);
+					dialog.open();
+				}
+			});
+
+			final Label l = new Label(parent, SWT.NONE);
+			l.setText(Messages.ImperativeExpressionEditor_TrackingLabel);
+			l.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+
+			Button trackingButton = new Button(parent, SWT.CHECK);
+			ISWTObservableValue observeTrackingSelection = WidgetProperties.selection().observe(trackingButton);
+			context.bindValue(observeTrackingSelection,
+					EMFEditProperties
+					.value(getEditingDomain(), UiPackageImpl.Literals.IMPERATIVE_EXPRESSION__TRACKING)
+					.observeDetail(getMaster()));
+		}
+
+		item = new CTabItem(folder, SWT.NONE);
+		item.setText(Messages.ModelTooling_Common_TabSupplementary);
+
+		parent = createScrollableContainer(folder);
+		item.setControl(parent.getParent());
+
+		ControlFactory.createStringListWidget(parent, Messages, this, Messages.CategoryEditor_Tags,
+				ApplicationPackageImpl.Literals.APPLICATION_ELEMENT__TAGS, VERTICAL_LIST_WIDGET_INDENT);
+		ControlFactory.createMapProperties(parent, Messages, this, Messages.ModelTooling_Contribution_PersistedState,
+				ApplicationPackageImpl.Literals.APPLICATION_ELEMENT__PERSISTED_STATE, VERTICAL_LIST_WIDGET_INDENT);
+
+		createContributedEditorTabs(folder, context, getMaster(), MImperativeExpression.class);
+
+		folder.setSelection(0);
+
+		return folder;
+	}
+
+	@Override
+	public IObservableList getChildList(Object element) {
+		return null;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuEditor.java
index c511eba..f6bb192 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuEditor.java
@@ -339,6 +339,7 @@
 			final List<Object> list = new ArrayList<>();
 			list.add(Messages.MenuItemEditor_NoExpression);
 			list.add(UiPackageImpl.Literals.CORE_EXPRESSION);
+			list.add(UiPackageImpl.Literals.IMPERATIVE_EXPRESSION);
 			list.addAll(getEditor().getFeatureClasses(UiPackageImpl.Literals.EXPRESSION,
 					UiPackageImpl.Literals.UI_ELEMENT__VISIBLE_WHEN));
 			combo.setInput(list);
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuItemEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuItemEditor.java
index 7b533fa..5527052 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuItemEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/MenuItemEditor.java
@@ -306,6 +306,7 @@
 			final List<Object> list = new ArrayList<>();
 			list.add(Messages.MenuItemEditor_NoExpression);
 			list.add(UiPackageImpl.Literals.CORE_EXPRESSION);
+			list.add(UiPackageImpl.Literals.IMPERATIVE_EXPRESSION);
 			list.addAll(getEditor().getFeatureClasses(UiPackageImpl.Literals.EXPRESSION,
 					UiPackageImpl.Literals.UI_ELEMENT__VISIBLE_WHEN));
 			combo.setInput(list);
diff --git a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ToolItemEditor.java b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ToolItemEditor.java
index 32f300a..0fc349a 100644
--- a/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ToolItemEditor.java
+++ b/bundles/org.eclipse.e4.tools.emf.ui/src/org/eclipse/e4/tools/emf/ui/internal/common/component/ToolItemEditor.java
@@ -315,6 +315,7 @@
 			final List<Object> list = new ArrayList<>();
 			list.add(Messages.ToolItemEditor_NoExpression);
 			list.add(UiPackageImpl.Literals.CORE_EXPRESSION);
+			list.add(UiPackageImpl.Literals.IMPERATIVE_EXPRESSION);
 			list.addAll(getEditor().getFeatureClasses(UiPackageImpl.Literals.EXPRESSION, UiPackageImpl.Literals.UI_ELEMENT__VISIBLE_WHEN));
 			combo.setInput(list);
 			context.bindValue(ViewerProperties.singleSelection().observe(combo), EMFEditProperties.value(getEditingDomain(), UiPackageImpl.Literals.UI_ELEMENT__VISIBLE_WHEN).observeDetail(getMaster()), new UpdateValueStrategy().setConverter(new EClass2EObject(Messages)), new UpdateValueStrategy().setConverter(new EObject2EClass(Messages)));
diff --git a/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/Messages.java b/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/Messages.java
index 5d0840c..70551d8 100644
--- a/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/Messages.java
+++ b/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/Messages.java
@@ -73,6 +73,9 @@
 	public static String NewHandlerClassWizard_CreateNewHandler;
 	public static String NewHandlerClassWizard_ExecuteMethod;
 	public static String NewHandlerClassWizard_NewHandler;
+	public static String NewImperativeExpressionClassWizard_CreateNewImperativeExpression;
+	public static String NewImperativeExpressionClassWizard_EvaluateMethod;
+	public static String NewImperativeExpressionClassWizard_NewImperativeExpression;
 	public static String NewModelFilePage_Browse;
 	public static String NewModelFilePage_Container;
 	public static String NewModelFilePage_FileContainerMustBeSpecified;
diff --git a/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/messages.properties b/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/messages.properties
index 7bd9193..33c49ca 100644
--- a/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/messages.properties
+++ b/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/messages.properties
@@ -53,6 +53,9 @@
 NewHandlerClassWizard_CreateNewHandler=Create a new handler class
 NewHandlerClassWizard_ExecuteMethod=Execute Method
 NewHandlerClassWizard_NewHandler=New Handler
+NewImperativeExpressionClassWizard_CreateNewImperativeExpression=Create a new Imperative expression class
+NewImperativeExpressionClassWizard_EvaluateMethod=Evaluate method
+NewImperativeExpressionClassWizard_NewImperativeExpression=New Imperative Expression
 NewModelFilePage_Browse=Browse...
 NewModelFilePage_Container=&Container:
 NewModelFilePage_FileContainerMustBeSpecified=File container must be specified
diff --git a/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/wizards/classes/NewImperativeExpressionClassWizard.java b/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/wizards/classes/NewImperativeExpressionClassWizard.java
new file mode 100644
index 0000000..cad413b
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/wizards/classes/NewImperativeExpressionClassWizard.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2016 vogella GmbH 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:
+ * Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.internal.tools.wizards.classes;
+
+import java.util.Set;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.e4.internal.tools.Messages;
+import org.eclipse.e4.internal.tools.wizards.classes.AbstractNewClassPage.JavaClass;
+import org.eclipse.e4.internal.tools.wizards.classes.templates.ImperativeExpressionTemplate;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jface.databinding.swt.IWidgetValueProperty;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class NewImperativeExpressionClassWizard extends AbstractNewClassWizard {
+	private static final String EVALUATE_METHOD_NAME = "evaluateMethodName"; //$NON-NLS-1$
+
+	private String initialString;
+
+	public NewImperativeExpressionClassWizard(String contributionURI) {
+		initialString = contributionURI;
+	}
+
+	public NewImperativeExpressionClassWizard() {
+		// Intentially left empty
+	}
+
+	@Override
+	protected String getContent() {
+		final ImperativeExpressionTemplate template = new ImperativeExpressionTemplate();
+		return template.generate(getDomainClass());
+	}
+
+	@Override
+	public void addPages() {
+		addPage(new AbstractNewClassPage(
+				"Classinformation", //$NON-NLS-1$
+				Messages.NewImperativeExpressionClassWizard_NewImperativeExpression,
+				Messages.NewImperativeExpressionClassWizard_CreateNewImperativeExpression, root,
+				ResourcesPlugin.getWorkspace().getRoot(),
+				initialString) {
+
+			@Override
+			protected JavaClass createInstance() {
+				return new ImperativeExpressionClass(root);
+			}
+
+			@Override
+			protected void createFields(Composite parent, DataBindingContext dbc) {
+				final IWidgetValueProperty textProp = WidgetProperties
+						.text(SWT.Modify);
+
+				{
+					Label l = new Label(parent, SWT.NONE);
+					l.setText(Messages.NewImperativeExpressionClassWizard_EvaluateMethod);
+
+					final Text t = new Text(parent, SWT.BORDER);
+					t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+					dbc.bindValue(
+							textProp.observe(t),
+							BeanProperties.value(EVALUATE_METHOD_NAME).observe(
+									getClazz()));
+
+					l = new Label(parent, SWT.NONE);
+				}
+			}
+		});
+	}
+
+	@Override
+	protected Set<String> getRequiredBundles() {
+		final Set<String> set = super.getRequiredBundles();
+		set.add("org.eclipse.e4.core.di"); //$NON-NLS-1$
+		return set;
+	}
+
+	public static class ImperativeExpressionClass extends JavaClass {
+		private String evaluateMethodName = "evaluate"; //$NON-NLS-1$
+
+		public ImperativeExpressionClass(IPackageFragmentRoot root) {
+			super(root);
+		}
+
+		public String getEvaluateMethodName() {
+			return evaluateMethodName;
+		}
+
+		public void setEvaluateMethodName(String evaluateMethodName) {
+			support.firePropertyChange(EVALUATE_METHOD_NAME,
+					this.evaluateMethodName,
+					this.evaluateMethodName = evaluateMethodName);
+		}
+
+	}
+}
diff --git a/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/wizards/classes/templates/ImperativeExpressionTemplate.java b/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/wizards/classes/templates/ImperativeExpressionTemplate.java
new file mode 100644
index 0000000..9ddc137
--- /dev/null
+++ b/bundles/org.eclipse.e4.tools/src/org/eclipse/e4/internal/tools/wizards/classes/templates/ImperativeExpressionTemplate.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2016 vogella GmbH 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:
+ * Simon Scholz <simon.scholz@vogella.com> - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.e4.internal.tools.wizards.classes.templates;
+
+import org.eclipse.e4.internal.tools.wizards.classes.NewImperativeExpressionClassWizard.ImperativeExpressionClass;
+
+public class ImperativeExpressionTemplate
+{
+	protected static String nl;
+	public static synchronized ImperativeExpressionTemplate create(String lineSeparator)
+	{
+		nl = lineSeparator;
+		ImperativeExpressionTemplate result = new ImperativeExpressionTemplate();
+		nl = null;
+		return result;
+	}
+
+	public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;
+	protected final String TEXT_1 = " ";
+	protected final String TEXT_2 = NL + "package ";
+	protected final String TEXT_3 = ";";
+	protected final String TEXT_4 = NL + NL
+			+ "import org.eclipse.e4.core.di.annotations.Evaluate;" + NL + NL + "public class ";
+	protected final String TEXT_7 = " {" + NL + "\t@Evaluate" + NL + "\tpublic boolean ";
+	protected final String TEXT_8 = "() {" + NL + "\t\treturn true;" + NL + "\t}" + NL + "}" + NL;
+
+	public String generate(Object argument)
+	{
+		final StringBuffer stringBuffer = new StringBuffer();
+		ImperativeExpressionClass domainClass = (ImperativeExpressionClass) argument;
+		stringBuffer.append(TEXT_1);
+		if( domainClass.getPackageFragment() != null && domainClass.getPackageFragment().getElementName().trim().length() > 0 ) {
+			stringBuffer.append(TEXT_2);
+			stringBuffer.append( domainClass.getPackageFragment().getElementName() );
+			stringBuffer.append(TEXT_3);
+		}
+		stringBuffer.append(TEXT_4);
+		stringBuffer.append( domainClass.getName() );
+		stringBuffer.append(TEXT_7);
+		stringBuffer.append(domainClass.getEvaluateMethodName());
+		stringBuffer.append(TEXT_8);
+		return stringBuffer.toString();
+	}
+}