https://bugs.eclipse.org/bugs/show_bug.cgi?id=378094
updated validation constraints, moved some to jbpm plugin
decorators updating correctly (more or less)
added decorators to Property page fields.
diff --git a/org.eclipse.bpmn2.modeler.core/plugin.xml b/org.eclipse.bpmn2.modeler.core/plugin.xml
index 8791aad..5e90515 100644
--- a/org.eclipse.bpmn2.modeler.core/plugin.xml
+++ b/org.eclipse.bpmn2.modeler.core/plugin.xml
@@ -88,28 +88,33 @@
 			</constraint>
 			<constraint
 					class="org.eclipse.bpmn2.modeler.core.validation.BPMN2BatchValidationConstraint"
-					id="org.eclipse.bpmn2.modeler.core.validation.basic"
+					id="org.eclipse.bpmn2.modeler.core.validation.error"
 					isEnabledByDefault="true"
 					lang="Java"
 					mode="Batch"
-					name="Basic Diagram Validation"
+					name="Errors"
 					severity="ERROR"
 					statusCode="1">
-				<message>
-				    {0}
-				</message>
-				<description>
-				    General Error
-				</description>
-				<target
-				   class="BPMNDiagram">
-				</target>
-				<target
-				   class="Definitions">
-				</target>
-				<target
-				   class="BaseElement">
-				</target>
+				<message>{0}</message>
+				<description>Diagram Validation Errors</description>
+				<target class="BPMNDiagram"/>
+				<target class="Definitions"/>
+				<target class="BaseElement"/>
+			</constraint>
+ 			<constraint
+					class="org.eclipse.bpmn2.modeler.core.validation.BPMN2BatchValidationConstraint"
+					id="org.eclipse.bpmn2.modeler.core.validation.warning"
+					isEnabledByDefault="true"
+					lang="Java"
+					mode="Batch"
+					name="Warnings"
+					severity="WARNING"
+					statusCode="1">
+				<message>{0}</message>
+				<description>Diagram Validation Warnings</description>
+				<target class="BPMNDiagram"/>
+				<target class="Definitions"/>
+				<target class="BaseElement"/>
 			</constraint>
  
          </constraints>
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractBpmn2PropertySection.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractBpmn2PropertySection.java
index fad1fb9..ca4911a 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractBpmn2PropertySection.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractBpmn2PropertySection.java
@@ -219,6 +219,7 @@
 						if (parent.isLayoutDeferred())
 							parent.setLayoutDeferred(false);
 					}
+					sectionRoot.refresh();
 				}
 			}
 		}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractDetailComposite.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractDetailComposite.java
index 61675c2..7d63f06 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractDetailComposite.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractDetailComposite.java
@@ -14,10 +14,13 @@
 package org.eclipse.bpmn2.modeler.core.merrimac.clad;
 
 import java.math.BigInteger;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Stack;
 
+import org.eclipse.bpmn2.Bpmn2Package;
 import org.eclipse.bpmn2.modeler.core.adapters.InsertionAdapter;
+import org.eclipse.bpmn2.modeler.core.merrimac.IConstants;
 import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.BooleanObjectEditor;
 import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ComboObjectEditor;
 import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.FeatureListObjectEditor;
@@ -26,16 +29,21 @@
 import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ReadonlyTextObjectEditor;
 import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.TextObjectEditor;
 import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EAttribute;
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.EReference;
 import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
 import org.eclipse.emf.ecore.util.BasicFeatureMap;
 import org.eclipse.emf.ecore.util.EObjectContainmentEList;
 import org.eclipse.emf.ecore.util.FeatureMap;
 import org.eclipse.emf.ecore.util.FeatureMap.Entry;
+import org.eclipse.emf.edit.provider.INotifyChangedListener;
 import org.eclipse.emf.transaction.ResourceSetListener;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
@@ -44,13 +52,14 @@
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.forms.events.ExpansionEvent;
 import org.eclipse.ui.forms.events.IExpansionListener;
 import org.eclipse.ui.forms.widgets.ExpandableComposite;
 import org.eclipse.ui.forms.widgets.Section;
-
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
 
 /**
  * This is a base class for all Property Sheet Sections. The Composite is used to render
@@ -592,4 +601,30 @@
 			return objectStack.size();
 		}
 	}
+
+	public void refresh() {
+		Display.getDefault().asyncExec( new Runnable() {
+			public void run() {
+				List<Control>kids = new ArrayList<Control>();
+				Composite parent = AbstractDetailComposite.this;
+				try {
+					AbstractBpmn2PropertySection section = AbstractDetailComposite.this.getPropertySection();
+					if (section!=null && section.getTabbedPropertySheetPage()!=null) {
+						parent = (Composite)section.getTabbedPropertySheetPage().getControl();
+					}
+				}
+				catch (Exception e) {
+				}
+				Notification n = new ENotificationImpl(null, Notification.SET, -1, 0, 0);
+				getAllChildWidgets(parent, kids);
+				for (Control c : kids) {
+					INotifyChangedListener listener = (INotifyChangedListener)c.getData(
+							IConstants.NOTIFY_CHANGE_LISTENER_KEY);
+					if (listener!=null) {
+						listener.notifyChanged(n);
+					}
+				}
+			}
+		});
+	}
 }
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/ListAndDetailCompositeBase.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/ListAndDetailCompositeBase.java
index 9822e84..740bc49 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/ListAndDetailCompositeBase.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/ListAndDetailCompositeBase.java
@@ -236,7 +236,7 @@
 		return null;
 	}
 
-	private void getAllChildWidgets(Composite parent, List<Control>kids) {
+	protected void getAllChildWidgets(Composite parent, List<Control>kids) {
 		if (parent!=null && !parent.isDisposed()) {
 			Control[] cs = parent.getChildren();
 			for (Control c : cs) {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/BooleanObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/BooleanObjectEditor.java
index 6eabfa1..bfcaf60 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/BooleanObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/BooleanObjectEditor.java
@@ -102,6 +102,7 @@
 
 	@Override
 	public void notifyChanged(Notification notification) {
+		super.notifyChanged(notification);
 		if (this.object == notification.getNotifier() &&
 				this.feature == notification.getFeature()) {
 			button.setSelection((Boolean) object.eGet(feature));
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ComboObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ComboObjectEditor.java
index c4e17d7..9e05de9 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ComboObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ComboObjectEditor.java
@@ -297,6 +297,7 @@
 	
 	@Override
 	public void notifyChanged(Notification notification) {
+		super.notifyChanged(notification);
 		for (String item : comboViewer.getCombo().getItems()) {
 			Object o = comboViewer.getData(item);
 			if (o == notification.getNotifier()) {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/FeatureListObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/FeatureListObjectEditor.java
index b33f10c..93777c0 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/FeatureListObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/FeatureListObjectEditor.java
@@ -174,6 +174,7 @@
 	public void notifyChanged(Notification notification) {
 		if (this.object == notification.getNotifier() &&
 				this.feature == notification.getFeature()) {
+			super.notifyChanged(notification);
 			updateTextField();
 		}
 	}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/IntObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/IntObjectEditor.java
index 2a7f4fe..64b86d4 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/IntObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/IntObjectEditor.java
@@ -152,6 +152,7 @@
 	
 	@Override
 	public void notifyChanged(Notification notification) {
+		super.notifyChanged(notification);
 		if (this.object == notification.getNotifier() &&
 				this.feature == notification.getFeature()) {
 			updateText();
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditingDialog.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditingDialog.java
index 8baac6b..19b5e75 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditingDialog.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditingDialog.java
@@ -99,6 +99,8 @@
 		data.right = new FormAttachment(100, 0);
 		dialogContent.setLayoutData(data);
 
+		getShell().setSize(600,400);
+		
 		form.setContent(body);
 	}
 	
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditor.java
index f2ce7cf..09f1318 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditor.java
@@ -13,21 +13,33 @@
 
 package org.eclipse.bpmn2.modeler.core.merrimac.dialogs;
 
+import org.eclipse.bpmn2.modeler.core.Activator;
 import org.eclipse.bpmn2.modeler.core.merrimac.IConstants;
 import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractDetailComposite;
 import org.eclipse.bpmn2.modeler.core.utils.ErrorUtils;
 import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.core.validation.ValidationStatusAdapter;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.EcoreUtil;
 import org.eclipse.emf.edit.provider.INotifyChangedListener;
 import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.validation.model.ConstraintStatus;
 import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.platform.IPlatformImageConstants;
+import org.eclipse.graphiti.tb.ImageDecorator;
 import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.jface.fieldassist.ControlDecoration;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 
 /**
@@ -43,6 +55,7 @@
 	protected EStructuralFeature feature;
 	protected AbstractDetailComposite parent;
 	private Label label;
+	protected ControlDecoration decoration;
 	protected int style;
 	
 	public ObjectEditor(AbstractDetailComposite parent, EObject object, EStructuralFeature feature, int style) {
@@ -102,6 +115,8 @@
 	protected Label createLabel(Composite parent, String name) {
 		label = getToolkit().createLabel(parent, name);
 		label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+		decoration = new ControlDecoration(label, SWT.TOP | SWT.LEFT);
+		updateLabelDecorator();
 		return label;
 	}
 	
@@ -109,6 +124,67 @@
 		return label;
 	}
 
+	private boolean statusApplies(IStatus status) {
+        if (status instanceof ConstraintStatus) {
+        	ConstraintStatus cs = (ConstraintStatus)status;
+        	for (EObject f : cs.getResultLocus()) {
+        		if (f instanceof EStructuralFeature && f==this.feature) {
+        			return true;
+        		}
+        	}
+        }
+        return false;
+	}
+	
+	protected void updateLabelDecorator() {
+		boolean applies = false;
+    	String image = null;
+    	String text = null;
+        ValidationStatusAdapter statusAdapter = (ValidationStatusAdapter) EcoreUtil.getRegisteredAdapter(
+        		object, ValidationStatusAdapter.class);
+        if (statusAdapter != null) {
+            final IStatus status = statusAdapter.getValidationStatus();
+            if (status.isMultiStatus()) {
+            	for (IStatus s : status.getChildren()) {
+            		if (statusApplies(s)) {
+            			applies = true;
+            			break;
+            		}
+            	}
+            }
+            else if (statusApplies(status))
+            	applies = true;
+            
+            if (applies) {
+	            text = status.getMessage();
+	            switch (status.getSeverity()) {
+	            case IStatus.INFO:
+	                image = ISharedImages.IMG_OBJS_INFO_TSK;
+	                break;
+	            case IStatus.WARNING:
+	                image = ISharedImages.IMG_DEC_FIELD_WARNING;
+	                break;
+	            case IStatus.ERROR:
+	                image = ISharedImages.IMG_DEC_FIELD_ERROR;
+	                break;
+	            default:
+	                break;
+	            }
+            }
+        }
+        
+        if (applies) {
+        	decoration.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(image));
+        	decoration.show();
+        	decoration.setDescriptionText(text);
+        }
+        else {
+        	decoration.setImage(null);
+        	decoration.setDescriptionText(null);
+        	decoration.hide();
+        }
+	}
+	
 	protected boolean updateObject(final Object result) {
 		TransactionalEditingDomain domain = getDiagramEditor().getEditingDomain();
 		boolean success = ModelUtil.setValue(domain, object, feature, result);
@@ -119,6 +195,12 @@
 					" with value '"+ModelUtil.getDisplayName(result)+"'");
 			return false;
 		}
+		updateLabelDecorator();
 		return true;
 	}
+
+	@Override
+	public void notifyChanged(Notification notification) {
+		updateLabelDecorator();
+	}
 }
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/TextObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/TextObjectEditor.java
index 5bf4263..36204c4 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/TextObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/TextObjectEditor.java
@@ -158,6 +158,7 @@
 
 	@Override
 	public void notifyChanged(Notification notification) {
+		super.notifyChanged(notification);
 		if (this.object == notification.getNotifier() &&
 				this.feature == notification.getFeature()) {
 			updateText();
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ModelUtil.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ModelUtil.java
index c043056..e313fb6 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ModelUtil.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ModelUtil.java
@@ -549,6 +549,43 @@
 		return list;
 	}
 	
+	public static EStructuralFeature getAnyAttribute(EObject object, String name) {
+		EStructuralFeature anyAttribute = ((EObject)object).eClass().getEStructuralFeature("anyAttribute");
+		if (anyAttribute!=null && object.eGet(anyAttribute) instanceof BasicFeatureMap) {
+			BasicFeatureMap map = (BasicFeatureMap)object.eGet(anyAttribute);
+			for (Entry entry : map) {
+				EStructuralFeature feature = entry.getEStructuralFeature();
+				if (feature.getName().equals(name))
+					return feature;
+			}
+		}
+		return null;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static EStructuralFeature addAnyAttribute(EObject childObject, String name, Object value) {
+		return addAnyAttribute(childObject, childObject.eClass().getEPackage().getNsURI(), name, value);
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static EStructuralFeature addAnyAttribute(EObject childObject, String namespace, String name, Object value) {
+		EStructuralFeature anyAttribute = childObject.eClass().getEStructuralFeature(Bpmn2Package.BASE_ELEMENT__ANY_ATTRIBUTE);
+		List<BasicFeatureMap.Entry> anyMap = (List<BasicFeatureMap.Entry>)childObject.eGet(anyAttribute);
+		for (BasicFeatureMap.Entry fe : anyMap) {
+			if (fe.getEStructuralFeature() instanceof EAttributeImpl) {
+				EAttributeImpl a = (EAttributeImpl) fe.getEStructuralFeature();
+				if (namespace.equals(a.getExtendedMetaData().getNamespace()) && name.equals(a.getName())) {
+					return a;
+				}
+			}
+		}
+		
+		// this featuremap can only hold attributes, not elements
+		EStructuralFeature attr = ExtendedMetaData.INSTANCE.demandFeature(namespace, name, false);
+		anyMap.add( FeatureMapUtil.createEntry(attr, value) );
+		return attr;
+	}
+
 	public static EAttribute createDynamicAttribute(EPackage pkg, EObject object, String name, String type) {
 		EClass docRoot = ExtendedMetaData.INSTANCE.getDocumentRoot(pkg);
 		for (EStructuralFeature f : docRoot.getEStructuralFeatures()) {
@@ -594,25 +631,6 @@
 		return ref;
 	}
 
-	@SuppressWarnings("unchecked")
-	public static EStructuralFeature addAnyAttribute(EObject childObject, String namespace, String name, Object value) {
-		EStructuralFeature anyAttribute = childObject.eClass().getEStructuralFeature(Bpmn2Package.BASE_ELEMENT__ANY_ATTRIBUTE);
-		List<BasicFeatureMap.Entry> anyMap = (List<BasicFeatureMap.Entry>)childObject.eGet(anyAttribute);
-		for (BasicFeatureMap.Entry fe : anyMap) {
-			if (fe.getEStructuralFeature() instanceof EAttributeImpl) {
-				EAttributeImpl a = (EAttributeImpl) fe.getEStructuralFeature();
-				if (namespace.equals(a.getExtendedMetaData().getNamespace()) && name.equals(a.getName())) {
-					return a;
-				}
-			}
-		}
-		
-		// this featuremap can only hold attributes, not elements
-		EStructuralFeature attr = ExtendedMetaData.INSTANCE.demandFeature(namespace, name, false);
-		anyMap.add( FeatureMapUtil.createEntry(attr, value) );
-		return attr;
-	}
-
 	public static EObject createStringWrapper(String value) {
 		DynamicEObjectImpl de = new DynamicEObjectImpl();
 		de.eSetClass(EcorePackage.eINSTANCE.getEObject());
@@ -979,7 +997,7 @@
 					InsertionAdapter.executeIfNeeded((EObject)value);
 				}
 				
-				if (isEmpty(value)){
+				if (value==null){ // DO NOT use isEmpty() because this erases an object's anyAttribute feature!
 					domain.getCommandStack().execute(new RecordingCommand(domain) {
 						@Override
 						protected void doExecute() {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2BatchValidationConstraint.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2BatchValidationConstraint.java
index 0329a1b..9b20a6f 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2BatchValidationConstraint.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2BatchValidationConstraint.java
@@ -1,13 +1,10 @@
 package org.eclipse.bpmn2.modeler.core.validation;
 
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
-import org.eclipse.bpmn2.AdHocSubProcess;
 import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.Bpmn2Package;
 import org.eclipse.bpmn2.BusinessRuleTask;
 import org.eclipse.bpmn2.CallActivity;
 import org.eclipse.bpmn2.CatchEvent;
@@ -16,6 +13,13 @@
 import org.eclipse.bpmn2.ConditionalEventDefinition;
 import org.eclipse.bpmn2.DataObject;
 import org.eclipse.bpmn2.Definitions;
+import org.eclipse.bpmn2.Error;
+import org.eclipse.bpmn2.Escalation;
+import org.eclipse.bpmn2.ItemDefinition;
+import org.eclipse.bpmn2.Message;
+import org.eclipse.bpmn2.Resource;
+import org.eclipse.bpmn2.Signal;
+import org.eclipse.bpmn2.DataStore;
 import org.eclipse.bpmn2.EndEvent;
 import org.eclipse.bpmn2.ErrorEventDefinition;
 import org.eclipse.bpmn2.EscalationEventDefinition;
@@ -24,7 +28,6 @@
 import org.eclipse.bpmn2.ExclusiveGateway;
 import org.eclipse.bpmn2.ExtensionAttributeValue;
 import org.eclipse.bpmn2.FlowElement;
-import org.eclipse.bpmn2.FlowElementsContainer;
 import org.eclipse.bpmn2.FlowNode;
 import org.eclipse.bpmn2.FormalExpression;
 import org.eclipse.bpmn2.Gateway;
@@ -32,7 +35,6 @@
 import org.eclipse.bpmn2.InclusiveGateway;
 import org.eclipse.bpmn2.MessageEventDefinition;
 import org.eclipse.bpmn2.ParallelGateway;
-import org.eclipse.bpmn2.Property;
 import org.eclipse.bpmn2.Process;
 import org.eclipse.bpmn2.RootElement;
 import org.eclipse.bpmn2.ScriptTask;
@@ -40,16 +42,12 @@
 import org.eclipse.bpmn2.SequenceFlow;
 import org.eclipse.bpmn2.SignalEventDefinition;
 import org.eclipse.bpmn2.StartEvent;
-import org.eclipse.bpmn2.SubProcess;
 import org.eclipse.bpmn2.Task;
 import org.eclipse.bpmn2.ThrowEvent;
 import org.eclipse.bpmn2.TimerEventDefinition;
 import org.eclipse.bpmn2.UserTask;
 import org.eclipse.bpmn2.di.BPMNDiagram;
-import org.eclipse.bpmn2.modeler.core.Activator;
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Status;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.util.FeatureMap;
 import org.eclipse.emf.validation.AbstractModelConstraint;
@@ -58,19 +56,24 @@
 
 public class BPMN2BatchValidationConstraint extends AbstractModelConstraint {
 
-	List<IStatus> errorList = new ArrayList<IStatus>();
-	IValidationContext context;
-
+	public final static String ERROR_ID = "org.eclipse.bpmn2.modeler.core.validation.error";
+	public final static String WARNING_ID = "org.eclipse.bpmn2.modeler.core.validation.warning";
+	
+	private boolean warnings = false;
+	
 	public BPMN2BatchValidationConstraint() {
 	}
 
 	@Override
 	public IStatus validate(IValidationContext ctx) {
-		this.context = ctx;
 		EObject eObj = ctx.getTarget();
 		EMFEventType eType = ctx.getEventType();
-		errorList.clear();
-
+		String id = ctx.getCurrentConstraintId();
+		if (WARNING_ID.equals(id))
+			warnings = true;
+		else
+			warnings = false;
+		
 		// In the case of batch mode.
 		if (eType == EMFEventType.NULL) {
 			if (eObj instanceof BPMNDiagram) {
@@ -83,7 +86,6 @@
 				return validateBaseElement(ctx, (BaseElement) eObj);
 			}
 		} else { // In the case of live mode.
-			System.err.println("Live: " + getClass().getSimpleName() + ": " + eObj + ": " + ctx.getFeatureNewValue());
 		}
 
 		return ctx.createSuccessStatus();
@@ -99,56 +101,75 @@
 		for (RootElement root : rootElements) {
 			if (root instanceof Process) {
 				Process process = (Process) root;
-				if (process.getFlowElements() != null && process.getFlowElements().size() > 0) {
-					process.getFlowElements().get(0).getId();
-				}
 
-				if (isEmpty(process.getId())) {
-					return ctx.createFailureStatus("Process has no id.");
-				} else {
-					if (!SyntaxCheckerUtils.isNCName(process.getId())) {
-						return ctx.createFailureStatus(
-								"Invalid process id. See http://www.w3.org/TR/REC-xml-names/#NT-NCName for more info.");
-					}
-				}
-
-				String pname = null;
-				Iterator<FeatureMap.Entry> iter = process.getAnyAttribute().iterator();
-				boolean foundPackageName = false;
-				while (iter.hasNext()) {
-					FeatureMap.Entry entry = iter.next();
-					if (entry.getEStructuralFeature().getName().equals("packageName")) {
-						foundPackageName = true;
-						pname = (String) entry.getValue();
-						if (isEmpty(pname)) {
-							return ctx.createFailureStatus("Process has no package name.");
+				if (warnings) {
+					// report warnings only
+					boolean foundStartEvent = false;
+					boolean foundEndEvent = false;
+					List<FlowElement> flowElements = process.getFlowElements();
+					for (FlowElement fe : flowElements) {
+						if (fe instanceof StartEvent) {
+							foundStartEvent = true;
+						}
+						if (fe instanceof EndEvent) {
+							foundEndEvent = true;
 						}
 					}
-				}
-				if (!foundPackageName) {
-					return ctx.createFailureStatus("Process has no package name.");
-				}
-
-				if (isEmpty(process.getName())) {
-					return ctx.createFailureStatus("Process has no name.");
-				}
-
-				boolean foundStartEvent = false;
-				boolean foundEndEvent = false;
-				List<FlowElement> flowElements = process.getFlowElements();
-				for (FlowElement fe : flowElements) {
-					if (fe instanceof StartEvent) {
-						foundStartEvent = true;
+					if (!foundStartEvent) {
+						ctx.addResult(root);
+						return ctx.createFailureStatus("Process has no Start Event");
 					}
-					if (fe instanceof EndEvent) {
-						foundEndEvent = true;
+					if (!foundEndEvent) {
+						ctx.addResult(root);
+						return ctx.createFailureStatus("Process has no End Event");
 					}
 				}
-				if (!foundStartEvent) {
-					return ctx.createFailureStatus("Process has no Start node.");
+				else {
+					// report errors only
+					if (isEmpty(process.getName())) {
+						ctx.addResult(root);
+						return ctx.createFailureStatus("Process has no name");
+					}
 				}
-				if (!foundEndEvent) {
-					return ctx.createFailureStatus("Process has no End node.");
+			}
+			else if (root instanceof Error) {
+				if (warnings) {
+					if (((Error)root).getStructureRef()==null) {
+						ctx.addResult(root);
+						return ctx.createFailureStatus("Error has no type definition");
+					}
+				}
+			}
+			else if (root instanceof Escalation) {
+				if (warnings) {
+					if (((Escalation)root).getStructureRef()==null) {
+						ctx.addResult(root);
+						return ctx.createFailureStatus("Escalation has no type definition");
+					}
+				}
+			}
+			else if (root instanceof Message) {
+				if (warnings) {
+					if (((Message)root).getItemRef()==null) {
+						ctx.addResult(root);
+						return ctx.createFailureStatus("Message has no type definition");
+					}
+				}
+			}
+			else if (root instanceof Signal) {
+				if (warnings) {
+					if (((Signal)root).getStructureRef()==null) {
+						ctx.addResult(root);
+						return ctx.createFailureStatus("Signal has no type definition");
+					}
+				}
+			}
+			else if (root instanceof ItemDefinition) {
+				if (!warnings) {
+					if (((ItemDefinition)root).getStructureRef()==null) {
+						ctx.addResult(root);
+						return ctx.createFailureStatus("Item Definition has no structure");
+					}
 				}
 			}
 		}
@@ -159,301 +180,258 @@
 
 		if (fe instanceof StartEvent) {
 			StartEvent se = (StartEvent) fe;
-			if (se.getOutgoing() == null || se.getOutgoing().size() < 1) {
-				return ctx.createFailureStatus("Start node has no outgoing connections");
+			
+			if (!warnings) {
+				if (se.getOutgoing() == null || se.getOutgoing().size() < 1) {
+					return ctx.createFailureStatus("Start Event has no outgoing connections");
+				}
 			}
-		} else if (fe instanceof EndEvent) {
+		}
+		else if (fe instanceof EndEvent) {
 			EndEvent ee = (EndEvent) fe;
-			if (ee.getIncoming() == null || ee.getIncoming().size() < 1) {
-				return ctx.createFailureStatus("End node has no incoming connections");
+			
+			if (!warnings) {
+				if (ee.getIncoming() == null || ee.getIncoming().size() < 1) {
+					return ctx.createFailureStatus("End Event has no incoming connections");
+				}
 			}
-		} else {
-			if (fe instanceof FlowNode) {
-				FlowNode fn = (FlowNode) fe;
+		}
+		else if (fe instanceof ScriptTask) {
+			ScriptTask st = (ScriptTask) fe;
+			
+			if (warnings) {
+				if (isEmpty(st.getScript())) {
+					return ctx.createFailureStatus("Script Task has no script");
+				}
+				if (isEmpty(st.getScriptFormat())) {
+					return ctx.createFailureStatus("Script Task has no script format");
+				}
+			}
+		}
+		else if (fe instanceof SendTask) {
+			SendTask st = (SendTask) fe;
+
+			if (!warnings) {
+				if (st.getOperationRef() == null) {
+					return ctx.createFailureStatus("Send Task has no operation");
+				}
+				if (st.getMessageRef() == null) {
+					return ctx.createFailureStatus("Send Task has no message");
+				}
+			}
+		}
+		else if (fe instanceof CatchEvent) {
+			CatchEvent event = (CatchEvent) fe;
+
+			if (!warnings) {
+				List<EventDefinition> eventdefs = event.getEventDefinitions();
+				if (eventdefs.size()==0) {
+					return ctx.createFailureStatus("Catch Event has no event definitions");
+				}
+				
+				for (EventDefinition ed : eventdefs) {
+					if (ed instanceof TimerEventDefinition) {
+						TimerEventDefinition ted = (TimerEventDefinition) ed;
+						if (	ted.getTimeDate() == null
+								&& ted.getTimeDuration() == null
+								&& ted.getTimeCycle() == null
+						) {
+							return ctx.createFailureStatus("Timer Event has no timer definition");
+						}
+					} else if (ed instanceof SignalEventDefinition) {
+						if (((SignalEventDefinition) ed).getSignalRef() == null) {
+							return ctx.createFailureStatus("Signal Event has no signal definition");
+						}
+					} else if (ed instanceof ErrorEventDefinition) {
+						if (((ErrorEventDefinition) ed).getErrorRef() == null
+								|| ((ErrorEventDefinition) ed).getErrorRef().getErrorCode() == null) {
+							return ctx.createFailureStatus("Error Event has no error definition");
+						}
+					} else if (ed instanceof ConditionalEventDefinition) {
+						FormalExpression conditionalExp = (FormalExpression) ((ConditionalEventDefinition) ed)
+								.getCondition();
+						if (conditionalExp.getBody() == null) {
+							return ctx.createFailureStatus("Conditional Event has no condition expression");
+						}
+					} else if (ed instanceof EscalationEventDefinition) {
+						if (((EscalationEventDefinition) ed).getEscalationRef() == null) {
+							return ctx.createFailureStatus("Escalation Event has no escalation definition");
+						}
+					} else if (ed instanceof MessageEventDefinition) {
+						if (((MessageEventDefinition) ed).getMessageRef() == null) {
+							return ctx.createFailureStatus("Message Event has no message definition");
+						}
+					} else if (ed instanceof CompensateEventDefinition) {
+						if (((CompensateEventDefinition) ed).getActivityRef() == null) {
+							return ctx.createFailureStatus("Compensate Event has no activity definition");
+						}
+					}
+				}
+			}
+		}
+		else if (fe instanceof ThrowEvent) {
+			ThrowEvent event = (ThrowEvent) fe;
+
+			if (!warnings) {
+				List<EventDefinition> eventdefs = event.getEventDefinitions();
+				if (eventdefs.size()==0) {
+					return ctx.createFailureStatus("Throw Event has no event definitions");
+				}
+
+				for (EventDefinition ed : eventdefs) {
+					if (ed instanceof TimerEventDefinition) {
+						TimerEventDefinition ted = (TimerEventDefinition) ed;
+						if (	ted.getTimeDate() == null
+								&& ted.getTimeDuration() == null
+								&& ted.getTimeCycle() == null
+						) {
+							return ctx.createFailureStatus("Timer Event has no timer definition");
+						}
+					} else if (ed instanceof SignalEventDefinition) {
+						if (((SignalEventDefinition) ed).getSignalRef() == null) {
+							return ctx.createFailureStatus("Signal Event has no signal definition");
+						}
+					} else if (ed instanceof ErrorEventDefinition) {
+						if (((ErrorEventDefinition) ed).getErrorRef() == null
+								|| ((ErrorEventDefinition) ed).getErrorRef().getErrorCode() == null) {
+							return ctx.createFailureStatus("Error Event has no error definition");
+						}
+					} else if (ed instanceof ConditionalEventDefinition) {
+						FormalExpression conditionalExp = (FormalExpression) ((ConditionalEventDefinition) ed)
+								.getCondition();
+						if (conditionalExp.getBody() == null) {
+							return ctx.createFailureStatus("Conditional Event has no condition expression");
+						}
+					} else if (ed instanceof EscalationEventDefinition) {
+						if (((EscalationEventDefinition) ed).getEscalationRef() == null) {
+							return ctx.createFailureStatus("Escalation Event has no conditional escalation definition");
+						}
+					} else if (ed instanceof MessageEventDefinition) {
+						if (((MessageEventDefinition) ed).getMessageRef() == null) {
+							return ctx.createFailureStatus("Message Event has no conditional message definition");
+						}
+					} else if (ed instanceof CompensateEventDefinition) {
+						if (((CompensateEventDefinition) ed).getActivityRef() == null) {
+							return ctx.createFailureStatus("Compensate Event has no conditional activity definition");
+						}
+					}
+				}
+			}
+		}
+		else if (fe instanceof SequenceFlow) {
+			SequenceFlow sf = (SequenceFlow) fe;
+
+			if (!warnings) {
+				if (sf.getSourceRef() == null) {
+					return ctx.createFailureStatus("Sequence Flow is not connected to a source");
+				}
+				if (sf.getTargetRef() == null) {
+					return ctx.createFailureStatus("Sequence Flow is not connected to a target");
+				}
+			}
+		}
+		else if (fe instanceof Gateway) {
+			Gateway gw = (Gateway) fe;
+
+			if (!warnings) {
+				if (gw.getGatewayDirection() == null
+						|| gw.getGatewayDirection().getValue() == GatewayDirection.UNSPECIFIED.getValue()) {
+					ctx.addResult(Bpmn2Package.eINSTANCE.getGateway_GatewayDirection());
+					return ctx.createFailureStatus("Gateway does not specify a valid direction");
+				}
+				if (gw instanceof ExclusiveGateway) {
+					if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
+							&& gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
+						return ctx.createFailureStatus(
+								"Invalid Gateway direction for Exclusing Gateway. It should be 'Converging' or 'Diverging'");
+					}
+				}
+				if (gw instanceof EventBasedGateway) {
+					if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()) {
+						return ctx.createFailureStatus(
+								"Invalid Gateway direction for EventBased Gateway. It should be 'Diverging'");
+					}
+				}
+				if (gw instanceof ParallelGateway) {
+					if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
+							&& gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
+						return ctx.createFailureStatus(
+								"Invalid Gateway direction for Parallel Gateway. It should be 'Converging' or 'Diverging'");
+					}
+				}
+				if (gw instanceof InclusiveGateway) {
+					if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()) {
+						return ctx.createFailureStatus(
+								"Invalid Gateway direction for Inclusive Gateway. It should be 'Diverging'");
+					}
+				}
+				if (gw instanceof ComplexGateway) {
+					if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
+							&& gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
+						return ctx.createFailureStatus(
+								"Invalid Gateway direction for Complex Gateway. It should be 'Converging' or 'Diverging'");
+					}
+				}
+			}
+		}
+		else if (fe instanceof CallActivity) {
+			CallActivity ca = (CallActivity) fe;
+
+			if (!warnings) {
+				if (ca.getCalledElementRef() == null) {
+					return ctx.createFailureStatus(
+							"Reusable Subprocess has no called element specified");
+				}
+			}
+		}
+		else if (fe instanceof DataObject) {
+			DataObject dao = (DataObject) fe;
+
+			if (!warnings) {
+				if (dao.getName() == null || dao.getName().length() < 1) {
+					return ctx.createFailureStatus("Data Object has no name");
+				} else {
+					if (containsWhiteSpace(dao.getName())) {
+						return ctx.createFailureStatus("Data Object name contains whitespace");
+					}
+				}
+			}
+		}
+		
+		
+		if (fe instanceof FlowNode) {
+			return validateFlowNode(ctx, (FlowNode) fe);
+		}
+
+		return ctx.createSuccessStatus();
+	}
+
+	private IStatus validateFlowNode(IValidationContext ctx, FlowNode fn) {
+		if (!warnings) {
+			boolean needIncoming = true;
+			boolean needOutgoing = true;
+			if (fn instanceof ThrowEvent)
+				needOutgoing = false;
+			if (fn instanceof CatchEvent)
+				needIncoming = false;
+			
+			if (needOutgoing) {
 				if ((fn.getOutgoing() == null || fn.getOutgoing().size() < 1)) {
 					return ctx.createFailureStatus("Node has no outgoing connections");
 				}
+			}
+			if (needIncoming) {
 				if ((fn.getIncoming() == null || fn.getIncoming().size() < 1)) {
 					return ctx.createFailureStatus("Node has no incoming connections");
 				}
 			}
 		}
 
-		if (fe instanceof BusinessRuleTask) {
-			BusinessRuleTask bt = (BusinessRuleTask) fe;
-			Iterator<FeatureMap.Entry> biter = bt.getAnyAttribute().iterator();
-			boolean foundRuleflowGroup = false;
-			while (biter.hasNext()) {
-				FeatureMap.Entry entry = biter.next();
-				if (entry.getEStructuralFeature().getName().equals("ruleFlowGroup")) {
-					foundRuleflowGroup = true;
-					String ruleflowGroup = (String) entry.getValue();
-					if (isEmpty(ruleflowGroup)) {
-						return ctx.createFailureStatus("Business Rule Task has no ruleflow-group.");
-					}
-				}
-			}
-			if (!foundRuleflowGroup) {
-				return ctx.createFailureStatus("Business Rule Task has no ruleflow-group.");
-			}
-		}
-
-		if (fe instanceof ScriptTask) {
-			ScriptTask st = (ScriptTask) fe;
-			if (isEmpty(st.getScript())) {
-				return ctx.createFailureStatus("Script Task has no script.");
-			}
-			if (isEmpty(st.getScriptFormat())) {
-				return ctx.createFailureStatus("Script Task has no script format.");
-			}
-		}
-
-		if (fe instanceof SendTask) {
-			SendTask st = (SendTask) fe;
-			if (st.getOperationRef() == null) {
-				return ctx.createFailureStatus("Send Task has no operation.");
-			}
-			if (st.getMessageRef() == null) {
-				return ctx.createFailureStatus("Send Task has no message.");
-			}
-		}
-
-		if (fe instanceof UserTask) {
-			UserTask ut = (UserTask) fe;
-			String taskName = null;
-			Iterator<FeatureMap.Entry> utiter = ut.getAnyAttribute().iterator();
-			boolean foundTaskName = false;
-			while (utiter.hasNext()) {
-				FeatureMap.Entry entry = utiter.next();
-				if (entry.getEStructuralFeature().getName().equals("taskName")) {
-					foundTaskName = true;
-					taskName = (String) entry.getValue();
-					if (isEmpty(taskName)) {
-						return ctx.createFailureStatus("User Task has no task name.");
-					}
-				}
-			}
-			if (!foundTaskName) {
-				return ctx.createFailureStatus("User Task has no task name.");
-			}
-
-			// simulation validation
-			if (ut.getExtensionValues() != null && fe.getExtensionValues().size() > 0) {
-				boolean foundStaffAvailability = false;
-				for (ExtensionAttributeValue extattrval : fe.getExtensionValues()) {
-					FeatureMap extensionElements = extattrval.getValue();
-				}
-				if (!foundStaffAvailability) {
-					return ctx.createFailureStatus("User Task has no staff availability defined.");
-				}
-			}
-		}
-
-		if (fe instanceof Task) {
-			Task ta = (Task) fe;
-			// simulation validation
-			if (ta.getExtensionValues() != null && fe.getExtensionValues().size() > 0) {
-				boolean foundDistributionType = false;
-				String distributionTypeValue = "";
-				boolean foundDuration = false;
-				boolean foundTimeUnits = false;
-				boolean foundRange = false;
-				boolean foundStandardDeviation = false;
-				for (ExtensionAttributeValue extattrval : fe.getExtensionValues()) {
-					FeatureMap extensionElements = extattrval.getValue();
-
-				}
-				if (!foundDistributionType) {
-					return ctx.createFailureStatus("Task has no distribution type defined.");
-				}
-				if (!foundDuration) {
-					return ctx.createFailureStatus("Task has no duration defined.");
-				}
-				if (!foundTimeUnits) {
-					return ctx.createFailureStatus( "Task has no Time Units defined.");
-				}
-				if (foundDistributionType) {
-					if ((distributionTypeValue.equals("random") || distributionTypeValue.equals("uniform"))
-							&& !foundRange) {
-						return ctx.createFailureStatus("Task has no Range defined.");
-					}
-					if (distributionTypeValue.equals("normal") && !foundStandardDeviation) {
-						return ctx.createFailureStatus("Task has no Standard Deviation defined.");
-					}
-				}
-			}
-		}
-
-		if (fe instanceof CatchEvent) {
-			CatchEvent event = (CatchEvent) fe;
-			List<EventDefinition> eventdefs = event.getEventDefinitions();
-			for (EventDefinition ed : eventdefs) {
-				if (ed instanceof TimerEventDefinition) {
-					TimerEventDefinition ted = (TimerEventDefinition) ed;
-					boolean gotTimerDef = (ted.getTimeDate() != null || ted.getTimeDuration() != null || ted
-							.getTimeCycle() != null);
-					if (!gotTimerDef) {
-						return ctx.createFailureStatus("Catch Event has no time value.");
-					}
-				} else if (ed instanceof SignalEventDefinition) {
-					if (((SignalEventDefinition) ed).getSignalRef() == null) {
-						return ctx.createFailureStatus("Catch Event has no signalref.");
-					}
-				} else if (ed instanceof ErrorEventDefinition) {
-					if (((ErrorEventDefinition) ed).getErrorRef() == null
-							|| ((ErrorEventDefinition) ed).getErrorRef().getErrorCode() == null) {
-						return ctx.createFailureStatus("Catch Event has no errorref.");
-					}
-				} else if (ed instanceof ConditionalEventDefinition) {
-					FormalExpression conditionalExp = (FormalExpression) ((ConditionalEventDefinition) ed)
-							.getCondition();
-					if (conditionalExp.getBody() == null) {
-						return ctx.createFailureStatus("Catch Event has no condition expression.");
-					}
-				} else if (ed instanceof EscalationEventDefinition) {
-					if (((EscalationEventDefinition) ed).getEscalationRef() == null) {
-						return ctx.createFailureStatus("Catch Event has no escalationref.");
-					}
-				} else if (ed instanceof MessageEventDefinition) {
-					if (((MessageEventDefinition) ed).getMessageRef() == null) {
-						return ctx.createFailureStatus("Catch Event has no messageref.");
-					}
-				} else if (ed instanceof CompensateEventDefinition) {
-					if (((CompensateEventDefinition) ed).getActivityRef() == null) {
-						return ctx.createFailureStatus("Catch Event has no activityref.");
-					}
-				}
-			}
-		}
-
-		if (fe instanceof ThrowEvent) {
-			ThrowEvent event = (ThrowEvent) fe;
-			List<EventDefinition> eventdefs = event.getEventDefinitions();
-			for (EventDefinition ed : eventdefs) {
-				if (ed instanceof TimerEventDefinition) {
-					TimerEventDefinition ted = (TimerEventDefinition) ed;
-					if (ted.getTimeDate() == null) {
-						return ctx.createFailureStatus("Throw Event has no timedate.");
-					}
-					if (ted.getTimeDuration() == null) {
-						return ctx.createFailureStatus("Throw Event has no timeduration.");
-					}
-					if (ted.getTimeCycle() != null) {
-						return ctx.createFailureStatus("Throw Event has no timecycle.");
-					}
-				} else if (ed instanceof SignalEventDefinition) {
-					if (((SignalEventDefinition) ed).getSignalRef() == null) {
-						return ctx.createFailureStatus("Throw Event has no signalref.");
-					}
-				} else if (ed instanceof ErrorEventDefinition) {
-					if (((ErrorEventDefinition) ed).getErrorRef() == null
-							|| ((ErrorEventDefinition) ed).getErrorRef().getErrorCode() == null) {
-						return ctx.createFailureStatus("Throw Event has no errorref.");
-					}
-				} else if (ed instanceof ConditionalEventDefinition) {
-					FormalExpression conditionalExp = (FormalExpression) ((ConditionalEventDefinition) ed)
-							.getCondition();
-					if (conditionalExp.getBody() == null) {
-						return ctx.createFailureStatus("Throw Event has no conditional expression.");
-					}
-				} else if (ed instanceof EscalationEventDefinition) {
-					if (((EscalationEventDefinition) ed).getEscalationRef() == null) {
-						return ctx.createFailureStatus("Throw Event has no conditional escalationref.");
-					}
-				} else if (ed instanceof MessageEventDefinition) {
-					if (((MessageEventDefinition) ed).getMessageRef() == null) {
-						return ctx.createFailureStatus("Throw Event has no conditional messageref.");
-					}
-				} else if (ed instanceof CompensateEventDefinition) {
-					if (((CompensateEventDefinition) ed).getActivityRef() == null) {
-						return ctx.createFailureStatus("Throw Event has no conditional activityref.");
-					}
-				}
-			}
-		}
-
-		if (fe instanceof SequenceFlow) {
-			SequenceFlow sf = (SequenceFlow) fe;
-			if (sf.getSourceRef() == null) {
-				return ctx.createFailureStatus("An Edge must have a source node.");
-			}
-			if (sf.getTargetRef() == null) {
-				return ctx.createFailureStatus("An Edge must have a target node.");
-			}
-		}
-
-		if (fe instanceof Gateway) {
-			Gateway gw = (Gateway) fe;
-			if (gw.getGatewayDirection() == null
-					|| gw.getGatewayDirection().getValue() == GatewayDirection.UNSPECIFIED.getValue()) {
-				return ctx.createFailureStatus("Gateway does not specify a valid direction.");
-			}
-			if (gw instanceof ExclusiveGateway) {
-				if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
-						&& gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
-					return ctx.createFailureStatus(
-							"Invalid Gateway direction for Exclusing Gateway. It should be 'Converging' or 'Diverging'.");
-				}
-			}
-			if (gw instanceof EventBasedGateway) {
-				if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()) {
-					return ctx.createFailureStatus(
-							"Invalid Gateway direction for EventBased Gateway. It should be 'Diverging'.");
-				}
-			}
-			if (gw instanceof ParallelGateway) {
-				if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
-						&& gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
-					return ctx.createFailureStatus(
-							"Invalid Gateway direction for Parallel Gateway. It should be 'Converging' or 'Diverging'.");
-				}
-			}
-			if (gw instanceof InclusiveGateway) {
-				if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()) {
-					return ctx.createFailureStatus(
-							"Invalid Gateway direction for Inclusive Gateway. It should be 'Diverging'.");
-				}
-			}
-			if (gw instanceof ComplexGateway) {
-				if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
-						&& gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
-					return ctx.createFailureStatus(
-							"Invalid Gateway direction for Complex Gateway. It should be 'Converging' or 'Diverging'.");
-				}
-			}
-		}
-
-		if (fe instanceof CallActivity) {
-			CallActivity ca = (CallActivity) fe;
-			if (ca.getCalledElementRef() == null) {
-				return ctx.createFailureStatus(
-						"Reusable Subprocess has no called element specified.");
-			}
-		}
-
-		if (fe instanceof DataObject) {
-			DataObject dao = (DataObject) fe;
-			if (dao.getName() == null || dao.getName().length() < 1) {
-				return ctx.createFailureStatus("Data Object has no name defined.");
-			} else {
-				if (containsWhiteSpace(dao.getName())) {
-					return ctx.createFailureStatus("Data Object name contains white spaces.");
-				}
-			}
-		}
 		return ctx.createSuccessStatus();
 	}
 
-	private static boolean isEmpty(final CharSequence str) {
-		if (str == null || str.length() == 0) {
-			return true;
-		}
-		for (int i = 0, length = str.length(); i < length; i++) {
-			if (str.charAt(i) != ' ') {
-				return false;
-			}
-		}
-		return true;
+	private static boolean isEmpty(String str) {
+		return str == null || str.isEmpty();
 	}
 
 	private boolean containsWhiteSpace(String testString) {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2ProjectValidator.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2ProjectValidator.java
index 7b1e38b..14aad79 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2ProjectValidator.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2ProjectValidator.java
@@ -13,6 +13,11 @@
 import java.io.IOException;
 
 import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.bpmn2.modeler.core.ProxyURIConverterImplExtension;
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceImpl;
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceSetImpl;
+import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences;
+import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
 import org.eclipse.core.resources.IBuildConfiguration;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
@@ -50,17 +55,27 @@
 
     /** ID for BPMN2 specific problem markers. */
     public static final String BPMN2_MARKER_ID = "org.eclipse.bpmn2.modeler.core.problemMarker";
+	private Bpmn2Preferences preferences;
+	private TargetRuntime targetRuntime;
+	private IFile modelFile;
 
     @Override
     public ValidationResult validate(ValidationEvent event, ValidationState state, IProgressMonitor monitor) {
-        if ((event.getKind() & IResourceDelta.REMOVED) != 0 || event.getResource().isDerived(IResource.CHECK_ANCESTORS)) {
+    	IResource file = event.getResource();
+        if ((event.getKind() & IResourceDelta.REMOVED) != 0 
+        		|| file.isDerived(IResource.CHECK_ANCESTORS)
+        		|| !(file instanceof IFile)) {
             return new ValidationResult();
         }
+    	modelFile = (IFile) file;
 
-        ResourceSet rs = new ResourceSetImpl();
-        Resource resource = rs.createResource(
-                URI.createPlatformResourceURI(event.getResource().getFullPath().toString(), false),
-                "org.eclipse.bpmn2.content-type.xml");
+        ResourceSet rs = new Bpmn2ModelerResourceSetImpl();
+		getTargetRuntime().setResourceSet(rs);
+		rs.setURIConverter(new ProxyURIConverterImplExtension());
+
+		Resource resource = rs.createResource(
+                URI.createPlatformResourceURI(modelFile.getFullPath().toString(), false),
+                Bpmn2ModelerResourceImpl.BPMN2_CONTENT_TYPE_ID);
         try {
             resource.load(null);
         } catch (IOException e) {
@@ -68,12 +83,12 @@
         }
         ValidationResult result = new ValidationResult();
         if (resource.getContents().isEmpty()) {
-            ValidatorMessage message = ValidatorMessage.create("Invalid bpmn2 file", event.getResource());
+            ValidatorMessage message = ValidatorMessage.create("Invalid bpmn2 file", modelFile);
             message.setType(BPMN2_MARKER_ID);
             result.add(message);
         } else {
             IBatchValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH);
-            processStatus(validator.validate(resource.getContents(), monitor), event.getResource(), result);
+            processStatus(validator.validate(resource.getContents(), monitor), modelFile, result);
         }
         return result;
     }
@@ -83,32 +98,35 @@
 		boolean needValidation = false;
 		IWorkspace workspace = ResourcesPlugin.getWorkspace();
 		IWorkspaceDescription description = workspace.getDescription();
+		resource.getURI().toFileString();
+		String pathString = resource.getURI().toPlatformString(true);
+		IPath path = Path.fromOSString(pathString);
+		IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+		IProject project = file.getProject();
+
 		if (!description.isAutoBuilding()) {
 			needValidation = true;
 		}
 		if (!needValidation) {
-			resource.getURI().toFileString();
-			String pathString = resource.getURI().toPlatformString(true);
-			IPath path = Path.fromOSString(pathString);
-			IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
-			IProject project = file.getProject();
 			if (project!=null) {
 				try {
+					// TODO: if there is no project builder, force validation
 					IBuildConfiguration config = project.getActiveBuildConfig();
 					if (config==null || config.getName()==null || config.getName().isEmpty())
 						needValidation = true;
-					IBuildConfiguration[] configs = project.getBuildConfigs();
-					for (IBuildConfiguration c : configs) {
-						System.out.println(c.getName());
-					}
 				} catch (CoreException e) {
-					// TODO Auto-generated catch block
 					e.printStackTrace();
 				}
 			}
 		}
 		
 		if (needValidation) {
+	        try {
+	            project.deleteMarkers(BPMN2_MARKER_ID, false, IProject.DEPTH_INFINITE);
+	        } catch (CoreException e) {
+	            Activator.getDefault().getLog().log(e.getStatus());
+	        }
+			
 	        IBatchValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH);
 	        IStatus status = validator.validate(resource.getContents(), monitor);
 	    	try {
@@ -157,7 +175,8 @@
                     relatedUris.append(EcoreUtil.getURI(eobject).toString()).append(" ");
                 }
                 relatedUris.deleteCharAt(relatedUris.length() - 1);
-                message.setAttribute(EValidator.RELATED_URIS_ATTRIBUTE, relatedUris.toString());
+                String uris = relatedUris.toString();
+                message.setAttribute(EValidator.RELATED_URIS_ATTRIBUTE, uris);
             }
         }
 
@@ -175,6 +194,26 @@
             Activator.getDefault().getLog().log(e.getStatus());
         }
     }
+	
+    protected TargetRuntime getTargetRuntime() {
+		if (targetRuntime==null)
+			targetRuntime = getPreferences().getRuntime(modelFile);
+		return targetRuntime;
+	}
+
+    protected Bpmn2Preferences getPreferences() {
+		if (preferences==null) {
+			assert(modelFile!=null);
+			IProject project = modelFile.getProject();
+			loadPreferences(project);
+		}
+		return preferences;
+	}
+	
+    protected void loadPreferences(IProject project) {
+		preferences = Bpmn2Preferences.getInstance(project);
+		preferences.load();
+	}
 
     public static class MarkerConfigurator implements IMarkerConfigurator {
 
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ProblemsReporter.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ProblemsReporter.java
index 0e8cb97..a20b56e 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ProblemsReporter.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ProblemsReporter.java
@@ -50,5 +50,5 @@
 				}
 	        }
 	    }
-    }
+   }
 }
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/SyntaxCheckerUtils.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/SyntaxCheckerUtils.java
index 4c4e51f..dfcf90b 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/SyntaxCheckerUtils.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/SyntaxCheckerUtils.java
@@ -2,11 +2,10 @@
 
 public class SyntaxCheckerUtils {
 	public static final boolean isNCName(String name) {
-		int nameLength = name.length();
-
-		if (nameLength == 0) {
+		if (name==null || name.isEmpty())
 			return false;
-		}
+		
+		int nameLength = name.length();
 
 		// Check first character
 		char c = name.charAt(0);
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidIdConstraint.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidIdConstraint.java
index 7d019dd..a2a49d4 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidIdConstraint.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidIdConstraint.java
@@ -1,53 +1,51 @@
-/*******************************************************************************

- * Copyright (c) 2011 Red Hat, Inc.

- *  All rights reserved.

- * This program is 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:

- * Red Hat, Inc. - initial API and implementation

- *

- * @author Bob Brodt

- ******************************************************************************/

-package org.eclipse.bpmn2.modeler.core.validation;

-

-import org.eclipse.bpmn2.BaseElement;

-import org.eclipse.core.runtime.IStatus;

-import org.eclipse.emf.ecore.EObject;

-import org.eclipse.emf.validation.AbstractModelConstraint;

-import org.eclipse.emf.validation.EMFEventType;

-import org.eclipse.emf.validation.IValidationContext;

-

-public class ValidIdConstraint extends AbstractModelConstraint {

-	

-	String validIdRegEx = "^[^0-9][a-zA-Z0-9-_]*";

-	

-	@Override

-	public IStatus validate(IValidationContext ctx) {

-		EObject eObj = ctx.getTarget();

-		EMFEventType eType = ctx.getEventType();

-		

-		// In the case of batch mode.

-		if (eType == EMFEventType.NULL) {

-			String id = null;

-			if (eObj instanceof BaseElement) {

-				id = ((BaseElement)eObj).getId(); 

-			}

-			

-			if (id == null || id.length() == 0 || id.indexOf(' ')>=0 || !id.matches(validIdRegEx) ) {

-				return ctx.createFailureStatus(new Object[] {eObj.eClass().getName()});

-			}

-		// In the case of live mode.

-		} else {

-			String newValue = (String) ctx.getFeatureNewValue();

-			

-			if (newValue == null || newValue.length() == 0 || newValue.indexOf(' ')>=0 || !newValue.matches(validIdRegEx)) {

-				return ctx.createFailureStatus(new Object[] {eObj.eClass().getName()});

-			}

-		}

-		

-		return ctx.createSuccessStatus();

-	}

-

-}

+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ *  All rights reserved.
+ * This program is 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:
+ * Red Hat, Inc. - initial API and implementation
+ *
+ * @author Bob Brodt
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.core.validation;
+
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.EMFEventType;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class ValidIdConstraint extends AbstractModelConstraint {
+	
+	@Override
+	public IStatus validate(IValidationContext ctx) {
+		EObject eObj = ctx.getTarget();
+		EMFEventType eType = ctx.getEventType();
+		
+		// In the case of batch mode.
+		if (eType == EMFEventType.NULL) {
+			String id = null;
+			if (eObj instanceof BaseElement) {
+				id = ((BaseElement)eObj).getId(); 
+			}
+			
+			if (!SyntaxCheckerUtils.isNCName(id)) {
+				return ctx.createFailureStatus(new Object[] {eObj.eClass().getName()});
+			}
+		// In the case of live mode.
+		} else {
+			String newValue = (String) ctx.getFeatureNewValue();
+			
+			if (!SyntaxCheckerUtils.isNCName(newValue)) {
+				return ctx.createFailureStatus(new Object[] {eObj.eClass().getName()});
+			}
+		}
+		
+		return ctx.createSuccessStatus();
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidationStatusAdapter.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidationStatusAdapter.java
index 53dd800..dec0793 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidationStatusAdapter.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidationStatusAdapter.java
@@ -27,7 +27,11 @@
  */
 public class ValidationStatusAdapter extends AdapterImpl {
 
-    private List<IStatus> _validationStatus = new ArrayList<IStatus>();
+    public ValidationStatusAdapter() {
+		super();
+	}
+
+	private List<IStatus> _validationStatus = new ArrayList<IStatus>();
 
     @Override
     public boolean isAdapterForType(Object type) {
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
index 9dd93e5..a046d3e 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
@@ -1215,4 +1215,124 @@
     </imageProvider>
  </extension>
 	
+ <extension
+         point="org.eclipse.emf.validation.constraintProviders">
+      <category
+            name="jBPM Constraints"
+            id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5"/>
+      <constraintProvider cache="true">
+         <package namespaceUri="http://www.omg.org/spec/BPMN/20100524/MODEL-XMI"/>
+         <constraints categories="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5">
+            <constraint
+                  lang="Java"
+                  class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.ProcessConstraint"
+                  severity="ERROR"
+                  mode="Batch"
+                  name="Process Validation"
+                  id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.Process"
+                  statusCode="1">
+               <description>
+                  Process Name, ID and Package Name validation.
+               </description>
+               <message>
+                  {0}
+               </message>
+               <target class="Process"/>
+            </constraint>
+            <constraint
+                  lang="Java"
+                  class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.BusinessRuleTaskConstraint"
+                  severity="ERROR"
+                  mode="Batch"
+                  name="Business Rule Task Validation"
+                  id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.BusinessRuleTask"
+                  statusCode="1">
+               <description>
+                  Business Rule Task validation.
+               </description>
+               <message>
+                  {0}
+               </message>
+               <target class="BusinessRuleTask"/>
+            </constraint>
+            <constraint
+                  lang="Java"
+                  class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.UserTaskConstraint"
+                  severity="WARNING"
+                  mode="Batch"
+                  name="User Task Validation"
+                  id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.UserTask"
+                  statusCode="1">
+               <description>
+                  User Task validation.
+               </description>
+               <message>
+                  {0}
+               </message>
+               <target class="UserTask"/>
+            </constraint>
+            <constraint
+                  lang="Java"
+                  class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.TaskConstraint"
+                  severity="WARNING"
+                  mode="Batch"
+                  name="Task Validation"
+                  id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.Task"
+                  statusCode="1">
+               <description>
+                  Task validation.
+               </description>
+               <message>
+                  {0}
+               </message>
+               <target class="Task"/>
+            </constraint>
+            <constraint
+                  lang="Java"
+                  class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.GatewayConstraint"
+                  severity="WARNING"
+                  mode="Batch"
+                  name="Gateway Validation"
+                  id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.Gateway"
+                  statusCode="1">
+               <description>
+                  Gateway validation.
+               </description>
+               <message>
+                  {0}
+               </message>
+               <target class="Gateway"/>
+            </constraint>
+            <constraint
+                  lang="Java"
+                  class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.CallActivityConstraint"
+                  severity="WARNING"
+                  mode="Batch"
+                  name="CallActivity Validation"
+                  id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.CallActivity"
+                  statusCode="1">
+               <description>
+                  CallActivity validation.
+               </description>
+               <message>
+                  {0}
+               </message>
+               <target class="CallActivity"/>
+            </constraint>
+         </constraints>
+      </constraintProvider>
+   </extension>
+
+   <extension
+         point="org.eclipse.emf.validation.constraintBindings">
+      <clientContext
+            default="false"
+            id="org.eclipse.bpmn2.modeler.core.validationContext">
+         <selector class="org.eclipse.bpmn2.modeler.core.validation.ValidationDelegateClientSelector"/>
+      </clientContext>
+      <binding
+            context="org.eclipse.bpmn2.modeler.core.validationContext"
+            category="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5"/>
+   </extension>
+	
 </plugin>
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmDescriptionPropertySection.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmDescriptionPropertySection.java
index 5c23f13..414e5d1 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmDescriptionPropertySection.java
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmDescriptionPropertySection.java
@@ -13,15 +13,20 @@
 
 package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.property;
 
+import java.util.List;
+
 import org.eclipse.bpmn2.BaseElement;
 import org.eclipse.bpmn2.Participant;
 import org.eclipse.bpmn2.Process;
 import org.eclipse.bpmn2.di.BPMNDiagram;
 import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractBpmn2PropertySection;
 import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractDetailComposite;
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
 import org.eclipse.bpmn2.modeler.ui.property.DescriptionPropertySection;
 import org.eclipse.bpmn2.modeler.ui.property.tasks.TaskDetailComposite;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.IWorkbenchPart;
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmUserTaskDetailComposite.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmUserTaskDetailComposite.java
index dcc5b41..882c19e 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmUserTaskDetailComposite.java
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmUserTaskDetailComposite.java
@@ -14,9 +14,11 @@
 package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.property;
 
 import org.eclipse.bpmn2.FormalExpression;
+import org.eclipse.bpmn2.InputOutputSpecification;
 import org.eclipse.bpmn2.PotentialOwner;
 import org.eclipse.bpmn2.ResourceAssignmentExpression;
 import org.eclipse.bpmn2.UserTask;
+import org.eclipse.bpmn2.modeler.core.adapters.InsertionAdapter;
 import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractBpmn2PropertySection;
 import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractListComposite;
 import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.TextObjectEditor;
@@ -50,18 +52,14 @@
 				ResourceAssignmentExpression resourceAssignment = null;
 				FormalExpression expression = null;
 				if (task.getResources().size() == 0) {
-					owner = (PotentialOwner) ModelUtil.createFeature( 
-							task,
-							PACKAGE.getActivity_Resources(),
-							PACKAGE.getPotentialOwner());
-					resourceAssignment = (ResourceAssignmentExpression) ModelUtil.createFeature( 
-							owner,
-							PACKAGE.getResourceRole_ResourceAssignmentExpression(),
-							PACKAGE.getResourceAssignmentExpression());
-					expression = (FormalExpression) ModelUtil.createFeature( 
-							 resourceAssignment,
-							 PACKAGE.getResourceAssignmentExpression_Expression(),
-							 PACKAGE.getFormalExpression());
+					owner = FACTORY.createPotentialOwner();
+					InsertionAdapter.add(task, PACKAGE.getActivity_Resources(), owner);
+					
+					resourceAssignment = FACTORY.createResourceAssignmentExpression(); 
+					InsertionAdapter.add(owner, PACKAGE.getResourceRole_ResourceAssignmentExpression(), resourceAssignment);
+					
+					expression = FACTORY.createFormalExpression(); 
+					InsertionAdapter.add(resourceAssignment, PACKAGE.getResourceAssignmentExpression_Expression(), expression);
 				}
 				else if (task.getResources().get(0) instanceof PotentialOwner){
 					owner = (PotentialOwner)task.getResources().get(0);
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/BusinessRuleTaskConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/BusinessRuleTaskConstraint.java
new file mode 100644
index 0000000..84d489a
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/BusinessRuleTaskConstraint.java
@@ -0,0 +1,39 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.Iterator;
+
+import org.eclipse.bpmn2.BusinessRuleTask;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class BusinessRuleTaskConstraint extends AbstractModelConstraint {
+
+	@Override
+	public IStatus validate(IValidationContext ctx) {
+		EObject eObj = ctx.getTarget();
+		if (eObj instanceof BusinessRuleTask) {
+			BusinessRuleTask bt = (BusinessRuleTask)eObj;
+			
+			Iterator<FeatureMap.Entry> biter = bt.getAnyAttribute().iterator();
+			boolean foundRuleflowGroup = false;
+			while (biter.hasNext()) {
+				FeatureMap.Entry entry = biter.next();
+				if (entry.getEStructuralFeature().getName().equals("ruleFlowGroup")) {
+					foundRuleflowGroup = true;
+					String ruleflowGroup = (String) entry.getValue();
+					if (ruleflowGroup==null || ruleflowGroup.isEmpty()) {
+						return ctx.createFailureStatus("Business Rule Task has no ruleflow group");
+					}
+				}
+			}
+			if (!foundRuleflowGroup) {
+				return ctx.createFailureStatus("Business Rule Task has no ruleflow group");
+			}
+		}	
+		return ctx.createSuccessStatus();
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/CallActivityConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/CallActivityConstraint.java
new file mode 100644
index 0000000..369988f
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/CallActivityConstraint.java
@@ -0,0 +1,49 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.bpmn2.CallActivity;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class CallActivityConstraint extends AbstractModelConstraint {
+	private IDiagramProfile profile;
+	private String uuid = "uuid";
+
+	@Override
+	public IStatus validate(IValidationContext ctx) {
+		EObject eObj = ctx.getTarget();
+		if (eObj instanceof CallActivity) {
+			CallActivity ca = (CallActivity) eObj;
+			if (ca.getCalledElementRef() == null) {
+				ctx.createFailureStatus("Reusable Subprocess has no called element specified.");
+			} else {
+				String[] packageAssetInfo = ServletUtil.findPackageAndAssetInfo(uuid, profile);
+				String packageName = packageAssetInfo[0];
+				List<String> allProcessesInPackage = ServletUtil.getAllProcessesInPackage(packageName, profile);
+				boolean foundCalledElementProcess = false;
+				for (String p : allProcessesInPackage) {
+					String processContent = ServletUtil.getProcessSourceContent(packageName, p, profile);
+					Pattern pattern = Pattern.compile("<\\S*process[\\s\\S]*id=\"" + ca.getCalledElementRef() + "\"",
+							Pattern.MULTILINE);
+					Matcher m = pattern.matcher(processContent);
+					if (m.find()) {
+						foundCalledElementProcess = true;
+						break;
+					}
+				}
+				foundCalledElementProcess = true; // TODO: remove this
+				if (!foundCalledElementProcess) {
+					ctx.createFailureStatus("No existing process with id=" + ca.getCalledElementRef()
+							+ " could be found.");
+				}
+			}
+		}
+		return ctx.createSuccessStatus();
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/DroolsPackage.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/DroolsPackage.java
new file mode 100644
index 0000000..e22a453
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/DroolsPackage.java
@@ -0,0 +1,13 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class DroolsPackage {
+
+	public interface Literals {
+
+		EStructuralFeature DOCUMENT_ROOT__METADATA = null;
+		
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java
new file mode 100644
index 0000000..2381519
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java
@@ -0,0 +1,67 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.List;
+
+import org.eclipse.bpmn2.ExtensionAttributeValue;
+import org.eclipse.bpmn2.Gateway;
+import org.eclipse.bpmn2.ParallelGateway;
+import org.eclipse.bpmn2.SequenceFlow;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class GatewayConstraint extends AbstractModelConstraint {
+
+	@Override
+	public IStatus validate(IValidationContext ctx) {
+		EObject eObj = ctx.getTarget();
+		
+		if (!(eObj instanceof ParallelGateway)) {
+			Gateway gw = (Gateway) eObj;
+
+			List<SequenceFlow> outgoingGwSequenceFlows = gw.getOutgoing();
+			if (outgoingGwSequenceFlows != null && outgoingGwSequenceFlows.size() > 0) {
+				int sum = 0;
+				for (SequenceFlow sf : outgoingGwSequenceFlows) {
+					// simulation validation
+					if (sf.getExtensionValues() != null && sf.getExtensionValues().size() > 0) {
+						boolean foundProbability = false;
+						for (ExtensionAttributeValue extattrval : sf.getExtensionValues()) {
+							FeatureMap extensionElements = extattrval.getValue();
+							@SuppressWarnings("unchecked")
+							List<MetadataType> metadataTypeExtensions = (List<MetadataType>) extensionElements.get(
+									DroolsPackage.Literals.DOCUMENT_ROOT__METADATA, true);
+							if (metadataTypeExtensions != null && metadataTypeExtensions.size() > 0) {
+								MetadataType metaType = metadataTypeExtensions.get(0);
+								for (Object metaEntryObj : metaType.getMetaentry()) {
+									MetaentryType entry = (MetaentryType) metaEntryObj;
+									if (entry.getName() != null && entry.getName().equals("probability")) {
+										Integer i = new Integer(entry.getValue());
+										if (i < 0) {
+											ctx.addResult(sf);
+											ctx.createFailureStatus("Probability value must be positive.");
+										} else {
+											sum += i;
+										}
+										foundProbability = true;
+									}
+								}
+							}
+						}
+						if (!foundProbability) {
+							ctx.addResult(sf);
+							ctx.createFailureStatus("Sequence Flow has no probability defined.");
+						}
+					}
+				}
+				if (sum != 100) {
+					ctx.createFailureStatus("The sum of probability values of all outgoing Sequence Flows must be equal 100.");
+				}
+			}
+		}
+		return ctx.createSuccessStatus();
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/IDiagramProfile.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/IDiagramProfile.java
new file mode 100644
index 0000000..d896802
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/IDiagramProfile.java
@@ -0,0 +1,5 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+public interface IDiagramProfile {
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetadataType.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetadataType.java
new file mode 100644
index 0000000..374d5b2
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetadataType.java
@@ -0,0 +1,12 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.List;
+
+public class MetadataType {
+
+	public List getMetaentry() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetaentryType.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetaentryType.java
new file mode 100644
index 0000000..4e07769
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetaentryType.java
@@ -0,0 +1,15 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+public class MetaentryType {
+
+	public String getValue() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public Object getName() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ProcessConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ProcessConstraint.java
new file mode 100644
index 0000000..5868d8c
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ProcessConstraint.java
@@ -0,0 +1,44 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.Iterator;
+
+import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.Process;
+import org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.model.ModelPackage;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class ProcessConstraint extends AbstractModelConstraint {
+
+	@Override
+	public IStatus validate(IValidationContext ctx) {
+		EObject eObj = ctx.getTarget();
+		if (eObj instanceof Process) {
+			Process process = (Process)eObj;
+			
+			String name = null;
+			Iterator<FeatureMap.Entry> iter = process.getAnyAttribute().iterator();
+			while (iter.hasNext()) {
+				FeatureMap.Entry entry = iter.next();
+				if (entry.getEStructuralFeature().getName().equals("packageName")) {
+					name = (String) entry.getValue();
+					if (name==null || name.isEmpty()) {
+						ctx.addResult(entry.getEStructuralFeature());
+						return ctx.createFailureStatus("Process has no package name.");
+					}
+				}
+			}
+	
+			name = process.getName();
+			if (name==null || name.isEmpty()) {
+				ctx.addResult(process.eClass().getEStructuralFeature("name"));
+				return ctx.createFailureStatus("Process has no name.");
+			}
+		}	
+		return ctx.createSuccessStatus();
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ServletUtil.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ServletUtil.java
new file mode 100644
index 0000000..798ee46
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ServletUtil.java
@@ -0,0 +1,25 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.List;
+
+public class ServletUtil {
+
+	public static String[] findPackageAndAssetInfo(String uuid, IDiagramProfile profile) {
+		return new String[] {uuid};
+	}
+
+	public static boolean assetExistsInGuvnor(String string, String taskFormName, IDiagramProfile profile) {
+		return true;
+	}
+
+	public static List<String> getAllProcessesInPackage(String packageName, IDiagramProfile profile) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public static String getProcessSourceContent(String packageName, String p, IDiagramProfile profile) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java
new file mode 100644
index 0000000..4819666
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java
@@ -0,0 +1,102 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.bpmn2.ExtensionAttributeValue;
+import org.eclipse.bpmn2.Task;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class TaskConstraint extends AbstractModelConstraint {
+
+	@Override
+	public IStatus validate(IValidationContext ctx) {
+		EObject eObj = ctx.getTarget();
+		if (eObj instanceof Task) {
+			Task ta = (Task) eObj;
+
+			if (ta.getExtensionValues() != null && ta.getExtensionValues().size() > 0) {
+				boolean foundDistributionType = false;
+				String distributionTypeValue = "";
+				boolean foundDuration = false;
+				boolean foundTimeUnits = false;
+				boolean foundRange = false;
+				boolean foundStandardDeviation = false;
+				for (ExtensionAttributeValue extattrval : ta.getExtensionValues()) {
+					FeatureMap extensionElements = extattrval.getValue();
+					@SuppressWarnings("unchecked")
+					List<MetadataType> metadataTypeExtensions = (List<MetadataType>) extensionElements.get(
+							DroolsPackage.Literals.DOCUMENT_ROOT__METADATA, true);
+
+					if (metadataTypeExtensions != null && metadataTypeExtensions.size() > 0) {
+						MetadataType metaType = metadataTypeExtensions.get(0);
+						for (Object metaEntryObj : metaType.getMetaentry()) {
+							MetaentryType entry = (MetaentryType) metaEntryObj;
+							if (entry.getName() != null && entry.getName().equals("costpertimeunit")) {
+								Float f = new Float(entry.getValue());
+								if (f.floatValue() < 0) {
+									ctx.createFailureStatus("Cost per Time Unit value must be positive");
+								}
+							}
+							if (entry.getName() != null && entry.getName().equals("distributiontype")) {
+								foundDistributionType = true;
+								distributionTypeValue = entry.getValue();
+							}
+							if (entry.getName() != null && entry.getName().equals("duration")) {
+								Float f = new Float(entry.getValue());
+								if (f.floatValue() < 0) {
+									ctx.createFailureStatus("Duration value must be positive");
+								}
+								foundDuration = true;
+							}
+							if (entry.getName() != null && entry.getName().equals("timeunit")) {
+								foundTimeUnits = true;
+							}
+							if (entry.getName() != null && entry.getName().equals("workinghours")) {
+								Float f = new Float(entry.getValue());
+								if (f.floatValue() < 0) {
+									ctx.createFailureStatus("Working Hours value must be positive");
+								}
+							}
+							if (entry.getName() != null && entry.getName().equals("range")) {
+								Float f = new Float(entry.getValue());
+								if (f.floatValue() < 0) {
+									ctx.createFailureStatus("Range value must be positive");
+								}
+								foundRange = true;
+							}
+							if (entry.getName() != null && entry.getName().equals("standarddeviation")) {
+								foundStandardDeviation = true;
+							}
+						}
+					}
+
+				}
+				if (!foundDistributionType) {
+					ctx.createFailureStatus("Task has no distribution type defined");
+				}
+				if (!foundDuration) {
+					ctx.createFailureStatus("Task has no duration defined");
+				}
+				if (!foundTimeUnits) {
+					ctx.createFailureStatus("Task has no Time Units defined");
+				}
+				if (foundDistributionType) {
+					if ((distributionTypeValue.equals("random") || distributionTypeValue.equals("uniform"))
+							&& !foundRange) {
+						ctx.createFailureStatus("Task has no Range defined");
+					}
+					if (distributionTypeValue.equals("normal") && !foundStandardDeviation) {
+						ctx.createFailureStatus("Task has no Standard Deviation defined");
+					}
+				}
+			}
+		}
+		return ctx.createSuccessStatus();
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java
new file mode 100644
index 0000000..250e66a
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java
@@ -0,0 +1,80 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.bpmn2.ExtensionAttributeValue;
+import org.eclipse.bpmn2.UserTask;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class UserTaskConstraint extends AbstractModelConstraint {
+	private IDiagramProfile profile;
+	private String uuid = "uuid";
+
+	@Override
+	public IStatus validate(IValidationContext ctx) {
+		EObject eObj = ctx.getTarget();
+		if (eObj instanceof UserTask) {
+			UserTask ut = (UserTask)eObj;
+			
+			String taskName = null;
+			Iterator<FeatureMap.Entry> utiter = ut.getAnyAttribute().iterator();
+			boolean foundTaskName = false;
+			while (utiter.hasNext()) {
+				FeatureMap.Entry entry = utiter.next();
+				if (entry.getEStructuralFeature().getName().equals("taskName")) {
+					foundTaskName = true;
+					taskName = (String) entry.getValue();
+					if (taskName==null || taskName.isEmpty()) {
+						return ctx.createFailureStatus("User Task has no task name");
+					}
+				}
+			}
+			if (!foundTaskName) {
+				return ctx.createFailureStatus("User Task has no task name");
+			} else {
+				// TODO:
+				if (taskName != null) {
+					String[] packageAssetInfo = ServletUtil.findPackageAndAssetInfo(uuid, profile);
+					String taskFormName = taskName + "-taskform";
+					if (!ServletUtil.assetExistsInGuvnor(packageAssetInfo[0], taskFormName, profile)) {
+						ctx.createFailureStatus("User Task has no task form defined");
+					}
+				}
+			}
+
+			// simulation validation
+			if (ut.getExtensionValues() != null && ut.getExtensionValues().size() > 0) {
+				boolean foundStaffAvailability = false;
+				for (ExtensionAttributeValue extattrval : ut.getExtensionValues()) {
+					FeatureMap extensionElements = extattrval.getValue();
+					@SuppressWarnings("unchecked")
+					List<MetadataType> metadataTypeExtensions = (List<MetadataType>) extensionElements.get(
+							DroolsPackage.Literals.DOCUMENT_ROOT__METADATA, true);
+					if (metadataTypeExtensions != null && metadataTypeExtensions.size() > 0) {
+						MetadataType metaType = metadataTypeExtensions.get(0);
+						for (Object metaEntryObj : metaType.getMetaentry()) {
+							MetaentryType entry = (MetaentryType) metaEntryObj;
+							if (entry.getName() != null && entry.getName().equals("staffavailability")) {
+								Float f = new Float(entry.getValue());
+								if (f.floatValue() < 0) {
+									ctx.createFailureStatus("Staff Availability value must be positive");
+								}
+								foundStaffAvailability = true;
+							}
+						}
+					}
+					if (!foundStaffAvailability) {
+						return ctx.createFailureStatus("User Task has no staff availability defined");
+					}
+				}
+			}
+		}	
+		return ctx.createSuccessStatus();
+	}
+
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
index 50259a7..763cb1d 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
@@ -93,6 +93,8 @@
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.IFileEditorInput;
 import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchListener;
 import org.eclipse.ui.IWorkbenchPage;
@@ -104,8 +106,10 @@
 import org.eclipse.ui.ide.IGotoMarker;
 import org.eclipse.ui.ide.ResourceUtil;
 import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.IPage;
 import org.eclipse.ui.progress.IProgressService;
 import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.ui.views.properties.PropertySheet;
 import org.eclipse.ui.views.properties.tabbed.ITabDescriptorProvider;
 import org.eclipse.wst.validation.ValidationState;
 
@@ -405,7 +409,23 @@
         } catch (CoreException e) {
             Activator.logStatus(e.getStatus());
         }
-
+        
+		IWorkbenchPage page = getEditorSite().getPage();
+		String viewID = "org.eclipse.ui.views.PropertySheet";
+		try {
+			IViewReference[] views = page.getViewReferences();
+			for (IViewReference v : views) {
+				if (viewID.equals(v.getId())) {
+					PropertySheet ps = (PropertySheet)v.getView(true);
+					IPage pp = ps.getCurrentPage();
+					if (pp instanceof Bpmn2TabbedPropertySheetPage) {
+						((Bpmn2TabbedPropertySheetPage)pp).refresh();
+					}
+				}
+			}
+		}
+		catch (Exception e) {
+		}
     }
     
     private EObject getTargetObject(IMarker marker) {