diff --git a/de.bmotionstudio.gef.editor/.classpath b/de.bmotionstudio.gef.editor/.classpath
index 1650e61be9f7cdd29178addcb2696b1962d4e5ef..0ebdd2991947f519db624b4393a3de4e1e841303 100644
--- a/de.bmotionstudio.gef.editor/.classpath
+++ b/de.bmotionstudio.gef.editor/.classpath
@@ -1,10 +1,11 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry exported="true" kind="lib" path="lib/ext/xpp3_min-1.1.4c.jar"/>
-	<classpathentry exported="true" kind="lib" path="lib/ext/xstream-1.3.1.jar" sourcepath="D:/xstream-distribution-1.3.1-src.zip"/>
-	<classpathentry exported="true" kind="lib" path="lib/ext/animation-1.2.0.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry exported="true" kind="lib" path="lib/ext/groovy-all-1.8.6.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry exported="true" kind="lib" path="lib/ext/xpp3_min-1.1.4c.jar"/>
+	<classpathentry exported="true" kind="lib" path="lib/ext/xstream-1.3.1.jar" sourcepath="D:/xstream-distribution-1.3.1-src.zip"/>
+	<classpathentry exported="true" kind="lib" path="lib/ext/animation-1.2.0.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/de.bmotionstudio.gef.editor/META-INF/MANIFEST.MF b/de.bmotionstudio.gef.editor/META-INF/MANIFEST.MF
index d355a0ebe30c1b7409a83cd969acc203e0a20bcd..9635c4e0ab909d79b334fc49d9d3876b22bd3bc1 100644
--- a/de.bmotionstudio.gef.editor/META-INF/MANIFEST.MF
+++ b/de.bmotionstudio.gef.editor/META-INF/MANIFEST.MF
@@ -57,4 +57,5 @@ Export-Package: com.thoughtworks.xstream,
 Bundle-ClassPath: lib/ext/xpp3_min-1.1.4c.jar,
  lib/ext/xstream-1.3.1.jar,
  lib/ext/animation-1.2.0.jar,
- .
+ .,
+ lib/ext/groovy-all-1.8.6.jar
diff --git a/de.bmotionstudio.gef.editor/build.properties b/de.bmotionstudio.gef.editor/build.properties
index f09a47a63b1eb6bf2a17335833018109364659b8..1243f18c1c52ce2e7e47bf70e1289a643ef7c821 100644
--- a/de.bmotionstudio.gef.editor/build.properties
+++ b/de.bmotionstudio.gef.editor/build.properties
@@ -5,5 +5,6 @@ bin.includes = plugin.xml,\
                .,\
                icons/,\
                schema/,\
-               lib/
+               lib/,\
+               lib/ext/groovy-all-1.8.6.jar
 
diff --git a/de.bmotionstudio.gef.editor/lib/ext/groovy-all-1.8.6.jar b/de.bmotionstudio.gef.editor/lib/ext/groovy-all-1.8.6.jar
new file mode 100644
index 0000000000000000000000000000000000000000..03c02efae3759e2ba7d2a5766ade154550202ded
Binary files /dev/null and b/de.bmotionstudio.gef.editor/lib/ext/groovy-all-1.8.6.jar differ
diff --git a/de.bmotionstudio.gef.editor/plugin.xml b/de.bmotionstudio.gef.editor/plugin.xml
index 0ee2080e5ad77315a48db9c95a41083dd13e0680..07bd7797aed6059c533439e5d67be458ab8235ff 100644
--- a/de.bmotionstudio.gef.editor/plugin.xml
+++ b/de.bmotionstudio.gef.editor/plugin.xml
@@ -259,9 +259,8 @@
             name="Switch Coordinates">
       </observer>
       <observer
-            class="de.bmotionstudio.gef.editor.observer.CloneObserver"
-            description="This observer clones the control depending on an expression rule"
-            name="Clone Observer">
+            class="de.bmotionstudio.gef.editor.observer.ExternalObserverScript"
+            name="External Observer Script">
       </observer>
    </extension>
    <extension
@@ -440,6 +439,33 @@
                   id="de.bmotionstudio.gef.editor.visualization">
             </control>
          </observer>
+         <observer
+               id="de.bmotionstudio.gef.editor.observer.ExternalObserverScript">
+            <control
+                  id="de.bmotionstudio.gef.editor.image">
+            </control>
+            <control
+                  id="de.bmotionstudio.gef.editor.button">
+            </control>
+            <control
+                  id="de.bmotionstudio.gef.editor.composite">
+            </control>
+            <control
+                  id="de.bmotionstudio.gef.editor.text">
+            </control>
+            <control
+                  id="de.bmotionstudio.gef.editor.shape">
+            </control>
+            <control
+                  id="de.bmotionstudio.gef.editor.radiobutton">
+            </control>
+            <control
+                  id="de.bmotionstudio.gef.editor.checkbox">
+            </control>
+            <control
+                  id="de.bmotionstudio.gef.editor.connection">
+            </control>
+         </observer>
       </include>
    </extension>   
 </plugin>
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractExpressionControl.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractExpressionControl.java
index 002567c4e6049d89ea2a355d3bb6899205fb6e80..a08f1e160786898ca1f2c1fa00cd4174398994e2 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractExpressionControl.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/AbstractExpressionControl.java
@@ -6,40 +6,15 @@
 
 package de.bmotionstudio.gef.editor;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import de.be4.classicalb.core.parser.exceptions.BException;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
-import de.bmotionstudio.gef.editor.observer.ObserverEvalObject;
-import de.bmotionstudio.gef.editor.part.AppAbstractEditPart;
+import de.bmotionstudio.gef.editor.observer.IObserver;
 import de.bmotionstudio.gef.editor.scheduler.SchedulerEvent;
-import de.prob.core.command.EvaluationGetValuesCommand;
-import de.prob.core.command.GetOperationByPredicateCommand;
-import de.prob.core.domainobjects.EvaluationElement;
-import de.prob.core.domainobjects.EvaluationStateElement;
-import de.prob.core.domainobjects.Operation;
-import de.prob.core.domainobjects.State;
-import de.prob.exceptions.ProBException;
-import de.prob.parserbase.ProBParseException;
 
 public abstract class AbstractExpressionControl extends BindingObject {
 
-	private static final Pattern PATTERN = Pattern.compile("\\$(.+?)\\$");
-
 	protected transient String ID;
 	protected transient String name;
 	protected transient String description;
-	protected transient Boolean hasError = false;
-	private transient static final String DEFAULT_PREDICATE = "1=1";
-	private transient static final String DEFAULT_BOOLVAL = "true";
 
 	public String getID() {
 		return this.ID;
@@ -53,220 +28,6 @@ public abstract class AbstractExpressionControl extends BindingObject {
 		return this.description;
 	}
 
-	public void addError(BControl control, Animation animation, String message) {
-		// TODO: Implement me!
-		// History history = animation.getAnimator().getHistory();
-		// int currentHistoryPos = history.getCurrentPosition();
-		// control.getVisualization().addError(
-		// new ErrorMessage(history.getAllItems()[currentHistoryPos - 1],
-		// this, control, message));
-	}
-
-	/**
-	 * tbd
-	 * 
-	 * @param expressionString
-	 * @param control
-	 * @param animation
-	 * @param obj
-	 * @return true or false
-	 */
-	protected String parsePredicate(String expressionString, BControl control,
-			Animation animation, ObserverEvalObject obj) {
-		if (expressionString == null || expressionString.trim().length() == 0)
-			return DEFAULT_BOOLVAL;
-		return parseExpression(expressionString, true, control, animation, obj,
-				true);
-	}
-
-	protected String parseExpression(String expressionString, BControl control,
-			Animation animation, ObserverEvalObject obj) {
-		return parseExpression(expressionString, true, control, animation, obj,
-				false);
-	}
-
-	protected String parseExpression(final String expressionString,
-			final boolean evalSingleExpression, final BControl control,
-			final Animation animation, final ObserverEvalObject obj,
-			final boolean isPredicate) {
-
-		Map<EvaluationElement, String> evaluationKeys = new HashMap<EvaluationElement, String>();
-
-		boolean hasSubExpressions = false;
-
-		hasError = false;
-
-		// Find expressions and collect ExpressionEvalElements
-		final Matcher matcher = PATTERN.matcher(expressionString);
-
-		while (matcher.find()) {
-			final String subExpr = matcher.group(1);
-			collectEvalElements(subExpr, "$" + subExpr + "$", isPredicate,
-					animation, control, evaluationKeys);
-			hasSubExpressions = true;
-		}
-
-		// We have only one expression (without "$$")
-		if (!hasSubExpressions) {
-			if (evalSingleExpression) {
-				collectEvalElements(expressionString, expressionString,
-						isPredicate, animation, control, evaluationKeys);
-			} else {
-				return expressionString;
-			}
-		}
-
-		// Try to get expression results and parse expression string
-		Collection<EvaluationStateElement> resultList;
-		try {
-			resultList = getExpressionValues(control, animation,
-					new ArrayList<EvaluationElement>(evaluationKeys.keySet()));
-		} catch (ProBException e) {
-			resultList = Collections.emptyList();
-			hasError = true;
-		}
-
-		// If getting ExpressionEvalElement throws no error, try to get
-		// expression results
-		String result = expressionString;
-		if (!hasError) {
-			for (EvaluationStateElement stateElement : resultList) {
-				final EvaluationElement evalElement = stateElement.getElement();
-				final String text;
-				if (isPredicate) {
-					text = stateElement.getResult().isPredicateTrue() ? "true"
-							: "false";
-				} else {
-					text = stateElement.getText();
-				}
-				final String subExpression = evaluationKeys.get(evalElement);
-				result = result.replace(subExpression, text);
-			}
-		} else {
-			if (obj != null)
-				obj.setHasError(true);
-			addError(control, animation,
-					"An error occurred while evaluating expression\\predicate value: \""
-							+ expressionString
-							+ "\". Please check your expression\\predicate.");
-		}
-
-		return result;
-
-	}
-
-	private void collectEvalElements(final String subexpression,
-			final String key, final boolean isPredicate,
-			final Animation animation, final BControl control,
-			final Map<EvaluationElement, String> evaluationKeys) {
-
-		final String parsedSubexpr = parseControls(subexpression, control);
-		EvaluationElement evalElement;
-		try {
-			evalElement = animation.getCachedEvalElement(parsedSubexpr,
-					isPredicate);
-			evaluationKeys.put(evalElement, key);
-		} catch (UnsupportedOperationException e) {
-			hasError = true;
-		} catch (ProBException e) {
-			hasError = true;
-		} catch (ProBParseException e) {
-			addError(control, animation, e.getMessage());
-			hasError = true;
-		}
-
-	}
-
-	protected List<Operation> parseOperation(final String opName,
-			String opPredicate, int opRandom, final Animation animation,
-			final String currentState, final BControl control) {
-
-		try {
-
-			if (opPredicate != null && opPredicate.length() > 0)
-				opPredicate = parseControls(opPredicate, control);
-			else
-				opPredicate = DEFAULT_PREDICATE;
-
-			if (opRandom < 1)
-				opRandom = 1;
-
-			return GetOperationByPredicateCommand.getOperations(
-					animation.getAnimator(), currentState, opName, opPredicate,
-					opRandom);
-
-		} catch (ProBException e) {
-			addError(control, animation, e.getMessage());
-			hasError = true;
-		} catch (BException e) {
-			addError(control, animation, e.getMessage());
-			hasError = true;
-		}
-
-		return null;
-
-	}
-
-	/**
-	 * This method matches the pattern <i>(\\w+)</i>. This means that the method
-	 * matches alphanumeric words in the given predicate or expression string.
-	 * The method focuses on control id's or the key word <i>this</i>. In the
-	 * first case the method tries to find a reference on the corresponding
-	 * control in the visualization regarding to the matched control id. In the
-	 * second case the method creates a reference to the control which contains
-	 * the observer. In addition in both cases the method returns the value of
-	 * {@link AppAbstractEditPart#getValueOfData()} of the located
-	 * {@link BControl}.
-	 * 
-	 * @param expressionString
-	 * @param control
-	 * @return the parsed expression
-	 */
-	protected String parseControls(String expressionString, BControl control) {
-
-		List<String> allControlIDs = control.getVisualization()
-				.getAllBControlNames();
-
-		// Search for control ids
-		Pattern cPattern = Pattern.compile("(\\w+)");
-		Matcher cMatcher = cPattern.matcher(expressionString);
-
-		while (cMatcher.find()) {
-
-			String controlID = cMatcher.group(1);
-
-			if (controlID.equals("this")) {
-
-				expressionString = expressionString.replace(controlID, control
-						.getAttributeValue(AttributeConstants.ATTRIBUTE_CUSTOM)
-						.toString());
-
-			} else if (allControlIDs.contains(controlID)) {
-
-				expressionString = expressionString.replace(controlID, control
-						.getVisualization().getBControl(controlID)
-						.getValueOfData());
-
-			} else {
-				// TODO: Return error if no control exists
-			}
-		}
-
-		return expressionString;
-
-	}
-
-	protected Collection<EvaluationStateElement> getExpressionValues(
-			final BControl control, final Animation animation,
-			final Collection<EvaluationElement> evalElements)
-			throws ProBException {
-		final State state = animation.getAnimator().getCurrentState();
-		// TODO[DP, 11.04.2011] Add an animator to the parameters!
-		final Collection<EvaluationStateElement> values = EvaluationGetValuesCommand
-				.getValuesForExpressionsCached(state, evalElements);
-		return values;
-	}
-
 	/**
 	 * This method is invoked before the expression control ({@link IObserver}
 	 * or {@link SchedulerEvent}) will be deleted.
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/Animation.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/Animation.java
similarity index 84%
rename from de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/Animation.java
rename to de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/Animation.java
index 6ee861ea1649cebbb6882ddf585aa781aadcfd5a..a109c4607913a05e6d4fe78fc30c85aef14dc384 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/Animation.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/Animation.java
@@ -4,14 +4,17 @@
  * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) 
  * */
 
-package de.bmotionstudio.gef.editor.internal;
+package de.bmotionstudio.gef.editor;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.eclipse.swt.widgets.Display;
 
 import de.bmotionstudio.gef.editor.animation.StaticListenerRegistry;
+import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.model.Visualization;
 import de.prob.core.Animator;
 import de.prob.core.IAnimationListener;
@@ -87,22 +90,34 @@ public class Animation implements IAnimationListener {
 		}
 	}
 
+	public void collectAllBControls(List<BControl> allBControls,
+			BControl control) {
+
+		if (control.getChildrenArray().isEmpty())
+			return;
+
+		for (BControl bcontrol : control.getChildrenArray()) {
+			allBControls.add(bcontrol);
+			collectAllBControls(allBControls, bcontrol);
+		}
+
+	}
+
 	public void checkObserver() {
 		if (visualization.isRunning()) {
 			Display.getDefault().asyncExec(new Runnable() {
 				@Override
 				public void run() {
-					visualization.checkObserver(Animation.this);
-					visualization.afterCheckObserver(Animation.this);
+					List<BControl> allBControls = new ArrayList<BControl>();
+					allBControls.add(visualization);
+					collectAllBControls(allBControls, visualization);
+					for (BControl c : allBControls)
+						c.checkObserver(Animation.this);
 				}
 			});
 		}
 	}
 
-	// public boolean checkObserverCallBack() {
-	// return visualization.checkObserverCallBack();
-	// }
-
 	public State getState() {
 		return currentState;
 	}
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditor.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditor.java
index aea1df6d56a4a9813ebfe1dafb4608409a6faeda..2d5013b10dc8c12cb1449236c5f642b195fd85ca 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditor.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/BMotionStudioEditor.java
@@ -36,7 +36,6 @@ import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.mapper.MapperWrapper;
 
 import de.bmotionstudio.gef.editor.animation.StaticListenerRegistry;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.internal.BMSConverter512;
 import de.bmotionstudio.gef.editor.model.Visualization;
 import de.prob.core.ILifecycleListener;
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/VisualizationProgressBar.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/VisualizationProgressBar.java
index 2bddb21f39064908ae7dcae5856c5fca63877792..4054bf990409224fb3e80c7652aaf57ec4abbeb5 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/VisualizationProgressBar.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/internal/VisualizationProgressBar.java
@@ -31,6 +31,7 @@ import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.io.xml.DomDriver;
 import com.thoughtworks.xstream.mapper.MapperWrapper;
 
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.BMotionEditorPlugin;
 import de.bmotionstudio.gef.editor.BMotionStudioEditor;
 import de.bmotionstudio.gef.editor.ILanguageService;
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControl.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControl.java
index 7ea8dce56ee5f79bb1bf94ad899090bdf0c5a86c..ee137bd0948a34c01e7235d085ecab7b8e3dcce4 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControl.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/BControl.java
@@ -24,6 +24,7 @@ import org.eclipse.draw2d.geometry.Point;
 import org.eclipse.draw2d.geometry.Rectangle;
 import org.eclipse.ui.views.properties.IPropertySource;
 
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.AttributeConstants;
 import de.bmotionstudio.gef.editor.BMotionEditorPlugin;
 import de.bmotionstudio.gef.editor.IBControlService;
@@ -37,7 +38,6 @@ import de.bmotionstudio.gef.editor.attribute.BAttributeVisible;
 import de.bmotionstudio.gef.editor.attribute.BAttributeWidth;
 import de.bmotionstudio.gef.editor.attribute.BAttributeX;
 import de.bmotionstudio.gef.editor.attribute.BAttributeY;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.internal.BControlPropertySource;
 import de.bmotionstudio.gef.editor.observer.IObserverListener;
 import de.bmotionstudio.gef.editor.observer.Observer;
@@ -625,26 +625,6 @@ public abstract class BControl implements IAdaptable, Cloneable {
 			con.checkObserver(animation);
 		}
 
-		// Check Observers of children
-		if (getChildrenArray().size() > 0) {
-			for (BControl bcontrol : getChildrenArray()) {
-				bcontrol.checkObserver(animation);
-			}
-		}
-
-	}
-
-	public void afterCheckObserver(Animation animation) {
-		// Check all Observers
-		for (Observer observer : getObservers().values()) {
-			observer.afterCheck(animation, this);
-		}
-		// Check Observers of children
-		if (getChildrenArray().size() > 0) {
-			for (BControl bcontrol : getChildrenArray()) {
-				bcontrol.afterCheckObserver(animation);
-			}
-		}
 	}
 
 	public void executeEvent(String eventID) {
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/Visualization.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/Visualization.java
index 69ba62cef155c8fc5b03ba690932a5bdd4390678..45a5666c3bf9502579b59251d27dc7f70e8df858 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/Visualization.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/model/Visualization.java
@@ -13,10 +13,10 @@ import org.eclipse.core.resources.IFile;
 import org.eclipse.draw2d.PositionConstants;
 
 import de.be4.classicalb.core.parser.exceptions.BException;
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.AttributeConstants;
 import de.bmotionstudio.gef.editor.ButtonGroupHelper;
 import de.bmotionstudio.gef.editor.IAddErrorListener;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.scheduler.PredicateOperation;
 import de.prob.core.command.ExecuteOperationCommand;
 import de.prob.core.command.GetOperationByPredicateCommand;
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/CloneObserver.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/CloneObserver.java
deleted file mode 100644
index ff38608cc1f88782cc1b6149a09677a6496eca8e..0000000000000000000000000000000000000000
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/CloneObserver.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/** 
- * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, 
- * Heinrich Heine Universitaet Duesseldorf
- * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) 
- * */
-
-package de.bmotionstudio.gef.editor.observer;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import de.bmotionstudio.gef.editor.AttributeConstants;
-import de.bmotionstudio.gef.editor.internal.Animation;
-import de.bmotionstudio.gef.editor.model.BControl;
-import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverClone;
-
-public class CloneObserver extends Observer {
-
-	private transient Collection<BControl> clonedControls;
-	private List<ObserverCloneObject> observerCloneObjects;
-	private boolean newControls = false;
-	private int oldInt = 0;
-
-	public CloneObserver() {
-		observerCloneObjects = new ArrayList<ObserverCloneObject>();
-	}
-
-	@Override
-	public void check(Animation animation, final BControl control) {
-
-		for (ObserverCloneObject obj : observerCloneObjects) {
-
-			final BControl toCloneControl = animation.getVisualization()
-					.getBControl(obj.getControlId());
-			String evalString = obj.getEval();
-
-			String fEval = parseExpression(evalString, control, animation, obj);
-
-			if (toCloneControl == null) {
-				addError(control, animation,
-						"No control found with id: " + obj.getControlId());
-			} else {
-
-				int clones = 0;
-
-				try {
-					clones = Integer.parseInt(fEval);
-				} catch (NumberFormatException e) {
-					addError(control, animation, "The expression: " + fEval
-							+ " should return an integer value!");
-				}
-
-				if (oldInt == clones) {
-
-					newControls = false;
-
-				} else {
-
-					for (BControl c : getClonedControls()) {
-						control.removeChild(c);
-					}
-
-					getClonedControls().clear();
-
-					for (int i = obj.getCounter(); i < clones
-							+ obj.getCounter(); i++) {
-						try {
-							BControl clonedControl = toCloneControl.clone();
-							clonedControl.setAttributeValue(
-									AttributeConstants.ATTRIBUTE_CUSTOM, i);
-							getClonedControls().add(clonedControl);
-						} catch (CloneNotSupportedException e) {
-						}
-					}
-
-					oldInt = clones;
-					newControls = true;
-
-				}
-
-			}
-
-		}
-
-	}
-
-	@Override
-	public ObserverWizard getWizard(BControl control) {
-		return new WizardObserverClone(control, this);
-	}
-
-	public List<ObserverCloneObject> getObserverCloneObjects() {
-		return observerCloneObjects;
-	}
-
-	public void setObserverCloneObjects(
-			List<ObserverCloneObject> observerCloneObjects) {
-		this.observerCloneObjects = observerCloneObjects;
-	}
-
-	public Observer clone() throws CloneNotSupportedException {
-		CloneObserver clonedObserver = (CloneObserver) super.clone();
-		List<ObserverCloneObject> list = new ArrayList<ObserverCloneObject>();
-		for (ObserverCloneObject obj : getObserverCloneObjects()) {
-			list.add(obj.clone());
-		}
-		clonedObserver.setObserverCloneObjects(list);
-		return clonedObserver;
-	}
-
-	@Override
-	public void afterCheck(final Animation animation, final BControl control) {
-		if (newControls) {
-			synchronized (control) {
-				for (BControl c : clonedControls) {
-					control.addChild(c);
-					c.checkObserver(animation);
-				}
-			}
-		}
-	}
-
-	public Collection<BControl> getClonedControls() {
-		if (clonedControls == null)
-			clonedControls = new ArrayList<BControl>();
-		return clonedControls;
-	}
-
-}
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ExternalObserverScript.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ExternalObserverScript.java
new file mode 100644
index 0000000000000000000000000000000000000000..66140364297494279a50836161fc37be784b1379
--- /dev/null
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ExternalObserverScript.java
@@ -0,0 +1,77 @@
+/** 
+ * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, 
+ * Heinrich Heine Universitaet Duesseldorf
+ * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) 
+ * */
+
+package de.bmotionstudio.gef.editor.observer;
+
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyObject;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.eclipse.core.resources.IFile;
+
+import de.bmotionstudio.gef.editor.Animation;
+import de.bmotionstudio.gef.editor.model.BControl;
+import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverExternalObserverScript;
+
+public class ExternalObserverScript extends Observer {
+
+	public static String ID = "de.bmotionstudio.gef.editor.observer.ExternalObserverScript";
+
+	private transient GroovyObject groovyObject;
+
+	private String scriptPath;
+
+	// private String language;
+
+	@Override
+	public void check(Animation animation, BControl control) {
+
+		try {
+
+			if (groovyObject == null) {
+				IFile pFile = control.getVisualization().getProjectFile();
+				String myPath = (pFile.getProject().getLocation() + "/" + scriptPath)
+						.replace("file:", "");
+				ClassLoader parent = getClass().getClassLoader();
+				GroovyClassLoader loader = new GroovyClassLoader(parent);
+				Class<?> groovyClass;
+				groovyClass = loader.parseClass(new File(myPath));
+				// let's call some method on an instance
+				groovyObject = (GroovyObject) groovyClass.newInstance();
+			}
+
+			Object[] args = { animation, control };
+			groovyObject.invokeMethod("check", args);
+
+		} catch (CompilationFailedException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (InstantiationException e) {
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	@Override
+	public ObserverWizard getWizard(BControl control) {
+		return new WizardObserverExternalObserverScript(control, this);
+	}
+
+	public String getScriptPath() {
+		return scriptPath;
+	}
+
+	public void setScriptPath(String scriptPath) {
+		this.scriptPath = scriptPath;
+	}
+
+}
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/IObserver.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/IObserver.java
new file mode 100644
index 0000000000000000000000000000000000000000..78f2e3dcfb65135048560982476042ad26ae3753
--- /dev/null
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/IObserver.java
@@ -0,0 +1,26 @@
+/** 
+ * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, 
+ * Heinrich Heine Universitaet Duesseldorf
+ * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) 
+ * */
+
+package de.bmotionstudio.gef.editor.observer;
+
+import de.bmotionstudio.gef.editor.Animation;
+import de.bmotionstudio.gef.editor.model.BControl;
+
+public interface IObserver {
+
+	/**
+	 * This method is called after every state change. The method tells the
+	 * control how it has to look like and how to behave.
+	 * 
+	 * @param animation
+	 *            The running animation
+	 * @param bcontrol
+	 *            The corresponding control
+	 * @throws BMotionObserverException
+	 */
+	public void check(Animation animation, BControl control);
+
+}
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationByPredicate.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationByPredicate.java
index 9934b534a5cac3df9cb97cbb6778c7350950dc9a..09c9eda4dc38c0a318b6c128fbb03414a0291f62 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationByPredicate.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/ListenOperationByPredicate.java
@@ -10,12 +10,13 @@ import java.util.ArrayList;
 import java.util.List;
 
 import de.be4.classicalb.core.parser.exceptions.BException;
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.AttributeConstants;
 import de.bmotionstudio.gef.editor.attribute.AbstractAttribute;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverListenOperationByPredicate;
 import de.bmotionstudio.gef.editor.scheduler.PredicateOperation;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 import de.prob.core.Animator;
 import de.prob.core.command.GetOperationByPredicateCommand;
 import de.prob.core.domainobjects.Operation;
@@ -70,7 +71,7 @@ public class ListenOperationByPredicate extends Observer {
 				if (animation.getCurrentStateOperations().containsKey(fOpName)) {
 
 					if (fPredicate.length() > 0) {
-						fPredicate = parseControls(fPredicate, control);
+						fPredicate = BMSUtil.parseControls(fPredicate, control);
 					}
 
 					try {
@@ -89,20 +90,21 @@ public class ListenOperationByPredicate extends Observer {
 							Object attributeVal = pop.getValue();
 
 							if (pop.isExpressionMode()) {
-								String strAtrVal = parseExpression(
+								String strAtrVal = BMSUtil.parseExpression(
 										attributeVal.toString(), control,
-										animation, pop);
+										animation);
 								String er = attributeObj.validateValue(
 										strAtrVal, null);
 								if (er != null) {
-									addError(
-											control,
-											animation,
-											"You selected "
-													+ attributeObj.getName()
-													+ " as attribute. There is a problem with your value: "
-													+ strAtrVal + " - Reason: "
-													+ er);
+									// addError(
+									// control,
+									// animation,
+									// "You selected "
+									// + attributeObj.getName()
+									// +
+									// " as attribute. There is a problem with your value: "
+									// + strAtrVal + " - Reason: "
+									// + er);
 									pop.setHasError(true);
 								} else {
 									attributeVal = attributeObj
@@ -123,12 +125,12 @@ public class ListenOperationByPredicate extends Observer {
 
 						}
 					} catch (ProBException e) {
-						addError(control, animation,
-								"An error occurred while evaluating. Reason: "
-										+ e.getMessage());
+						// addError(control, animation,
+						// "An error occurred while evaluating. Reason: "
+						// + e.getMessage());
 					} catch (BException e) {
-						addError(control, animation, "Parsing error in: "
-								+ fPredicate + " Reason: " + e.getMessage());
+						// addError(control, animation, "Parsing error in: "
+						// + fPredicate + " Reason: " + e.getMessage());
 					}
 				}
 
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/Observer.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/Observer.java
index ee4d33324d3f113322f5da7904d8bbc10e794a41..d503290e15669b161bec135606bacc8946c6d84f 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/Observer.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/Observer.java
@@ -11,7 +11,6 @@ import org.eclipse.draw2d.IFigure;
 
 import de.bmotionstudio.gef.editor.AbstractExpressionControl;
 import de.bmotionstudio.gef.editor.BMotionEditorPlugin;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 
 /**
@@ -27,9 +26,8 @@ import de.bmotionstudio.gef.editor.model.BControl;
  * @author Lukas Ladenberger
  * 
  */
-public abstract class Observer extends AbstractExpressionControl {
-
-	// private transient Boolean callBack = false;
+public abstract class Observer extends AbstractExpressionControl implements
+		IObserver {
 
 	public Observer() {
 		init();
@@ -37,7 +35,6 @@ public abstract class Observer extends AbstractExpressionControl {
 
 	protected Object readResolve() {
 		init();
-		// callBack = false;
 		return this;
 	}
 
@@ -64,26 +61,6 @@ public abstract class Observer extends AbstractExpressionControl {
 		return (Observer) super.clone();
 	}
 
-	// public void setCallBack(Boolean callBack) {
-	// this.callBack = callBack;
-	// }
-	//
-	// public Boolean isCallBack() {
-	// return callBack;
-	// }
-
-	/**
-	 * This method is called after every state change. The method tells the
-	 * control how it has to look like and how to behave.
-	 * 
-	 * @param animation
-	 *            The running animation
-	 * @param bcontrol
-	 *            The corresponding control
-	 * @throws BMotionObserverException
-	 */
-	public abstract void check(Animation animation, BControl control);
-
 	/**
 	 * Returns a corresponding wizard for the observer.
 	 * 
@@ -97,7 +74,4 @@ public abstract class Observer extends AbstractExpressionControl {
 		return null;
 	}
 
-	public void afterCheck(Animation animation, BControl control) {
-	}
-
 }
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttribute.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttribute.java
index d4e801a2491df21e32f4d8f53c9b82d87ea69deb..7130363e3678a683be8c1919e5059ef75869eb8c 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttribute.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SetAttribute.java
@@ -11,10 +11,11 @@ import java.util.List;
 
 import org.eclipse.draw2d.IFigure;
 
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.attribute.AbstractAttribute;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverSetAttribute;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 
 public class SetAttribute extends Observer {
 
@@ -34,7 +35,7 @@ public class SetAttribute extends Observer {
 
 	@Override
 	public void check(Animation animation, BControl control) {
-
+		
 		this.setAttributes.clear();
 
 		// Collect evaluate predicate objects in list
@@ -45,8 +46,8 @@ public class SetAttribute extends Observer {
 			// First evaluate predicate (predicate field)
 			String bolValue = "true";
 			if (obj.getEval().length() > 0) {
-				bolValue = parsePredicate(obj.getEval(), control, animation,
-						obj);
+				bolValue = BMSUtil.parsePredicate(obj.getEval(), control,
+						animation);
 			}
 
 			if (!obj.hasError() && Boolean.valueOf(bolValue)) {
@@ -59,17 +60,18 @@ public class SetAttribute extends Observer {
 				Object attributeVal = obj.getValue();
 
 				if (obj.isExpressionMode()) {
-					String strAtrVal = parseExpression(attributeVal.toString(),
-							control, animation, obj);
+					String strAtrVal = BMSUtil.parseExpression(
+							attributeVal.toString(), control, animation);
 					String er = attributeObj.validateValue(strAtrVal, null);
 					if (er != null) {
-						addError(
-								control,
-								animation,
-								"You selected "
-										+ attributeObj.getName()
-										+ " as attribute. There is a problem with your value: "
-										+ strAtrVal + " - Reason: " + er);
+						// addError(
+						// control,
+						// animation,
+						// "You selected "
+						// + attributeObj.getName()
+						// +
+						// " as attribute. There is a problem with your value: "
+						// + strAtrVal + " - Reason: " + er);
 						obj.setHasError(true);
 					} else {
 						attributeVal = attributeObj.unmarshal(strAtrVal);
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SimpleValueDisplay.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SimpleValueDisplay.java
index 832c98aa9b149c3c930e42af3d4b08ef7760783c..9886b3184634dbe24246762aeadd7c237c870bfc 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SimpleValueDisplay.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SimpleValueDisplay.java
@@ -6,10 +6,11 @@
 
 package de.bmotionstudio.gef.editor.observer;
 
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.AttributeConstants;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverSimpleValueDisplay;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 
 public class SimpleValueDisplay extends Observer {
 
@@ -25,12 +26,12 @@ public class SimpleValueDisplay extends Observer {
 		// First evaluate predicate (predicate field)
 		String bolValue = "true";
 		if (predicate != null && predicate.length() > 0) {
-			bolValue = parsePredicate(predicate, bcontrol, animation, null);
+			bolValue = BMSUtil.parsePredicate(predicate, bcontrol, animation);
 		}
 
 		if (Boolean.valueOf(bolValue)) {
 
-			String fEval = parseExpression(eval, bcontrol, animation, null);
+			String fEval = BMSUtil.parseExpression(eval, bcontrol, animation);
 
 			if (!isOrgStringSet) {
 				orgString = bcontrol.getAttributeValue(
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchChildCoordinates.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchChildCoordinates.java
index 87f109d42fa988d24576c35a9a4286d551334b8f..da5a59e940a7199f771aec0a77892b2d2d05e937 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchChildCoordinates.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchChildCoordinates.java
@@ -9,46 +9,23 @@ package de.bmotionstudio.gef.editor.observer;
 import java.util.ArrayList;
 import java.util.List;
 
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.AttributeConstants;
 import de.bmotionstudio.gef.editor.animation.AnimationMove;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverCSwitchCoordinates;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 
 public class SwitchChildCoordinates extends Observer {
 
 	private List<ToggleObjectCoordinates> toggleObjects;
 
-	// private transient AnimationListener animationListener;
-
-	// private transient Boolean checked;
-
 	public SwitchChildCoordinates() {
 		toggleObjects = new ArrayList<ToggleObjectCoordinates>();
 	}
 
 	public void check(final Animation animation, final BControl control) {
 
-		// if (checked == null)
-		// checked = true;
-		//
-		// if (!checked)
-		// return;
-		//
-		// if (animationListener == null) {
-		// animationListener = new AnimationListener() {
-		// public void animationStopped(AnimationEvent evt) {
-		// setCallBack(true);
-		// // checked = true;
-		// }
-		//
-		// public void animationStarted(AnimationEvent evt) {
-		// setCallBack(false);
-		// checked = false;
-		// }
-		// };
-		// }
-
 		// Collect evaluate predicate objects in list
 		for (ToggleObjectCoordinates obj : toggleObjects) {
 
@@ -57,42 +34,42 @@ public class SwitchChildCoordinates extends Observer {
 			// First evaluate predicate (predicate field)
 			String bolValue = "true";
 			if (obj.getEval().length() > 0) {
-				bolValue = parsePredicate(obj.getEval(), control, animation,
-						obj);
+				bolValue = BMSUtil.parsePredicate(obj.getEval(), control,
+						animation);
 			}
 
 			if (!obj.hasError() && Boolean.valueOf(bolValue)) {
 
 				// Handle control field
 				BControl toggleControl = null;
-				String parsedControl = parseExpression(obj.getBcontrol(),
-						false, control, animation, obj, false);
+				String parsedControl = BMSUtil.parseExpression(
+						obj.getBcontrol(), control, animation, false);
 				toggleControl = control.getChild(parsedControl);
 				if (toggleControl == null) {
 					obj.setHasError(true);
-					addError(control, animation, "No such control: "
-							+ parsedControl);
+					// addError(control, animation, "No such control: "
+					// + parsedControl);
 				}
 
 				Integer parsedX = 0;
 				Integer parsedY = 0;
 				// Handle X field
 				try {
-					parsedX = Integer.valueOf(parseExpression(obj.getX(),
-							false, control, animation, obj, false));
+					parsedX = Integer.valueOf(BMSUtil.parseExpression(
+							obj.getX(), control, animation));
 				} catch (NumberFormatException n) {
 					obj.setHasError(true);
-					addError(control, animation, "x is not a valid integer: "
-							+ n.getMessage());
+					// addError(control, animation, "x is not a valid integer: "
+					// + n.getMessage());
 				}
 				// Handle Y field
 				try {
-					parsedY = Integer.valueOf(parseExpression(obj.getY(),
-							false, control, animation, obj, false));
+					parsedY = Integer.valueOf(BMSUtil.parseExpression(
+							obj.getY(), control, animation));
 				} catch (NumberFormatException n) {
 					obj.setHasError(true);
-					addError(control, animation, "y is not a valid integer: "
-							+ n.getMessage());
+					// addError(control, animation, "y is not a valid integer: "
+					// + n.getMessage());
 				}
 
 				if (!obj.hasError()) {
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchCoordinates.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchCoordinates.java
index 8312e52f2da2bda2f91f15ffcab68103e01a0621..5a850642ff9fba70d00e951922aea57f75c3fc75 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchCoordinates.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchCoordinates.java
@@ -9,20 +9,17 @@ package de.bmotionstudio.gef.editor.observer;
 import java.util.ArrayList;
 import java.util.List;
 
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.AttributeConstants;
 import de.bmotionstudio.gef.editor.animation.AnimationMove;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverSwitchCoordinates;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 
 public class SwitchCoordinates extends Observer {
 
 	private List<ToggleObjectCoordinates> toggleObjects;
 
-	// private transient AnimationListener animationListener;
-
-	// private transient Boolean checked;
-
 	public SwitchCoordinates() {
 		toggleObjects = new ArrayList<ToggleObjectCoordinates>();
 	}
@@ -31,27 +28,6 @@ public class SwitchCoordinates extends Observer {
 
 		boolean set = false;
 
-		// if (checked == null)
-		// checked = true;
-
-		// if (animationListener == null) {
-		// animationListener = new AnimationListener() {
-		// public void animationStopped(AnimationEvent evt) {
-		// setCallBack(true);
-		// checked = true;
-		// // System.out
-		// // .println("Animation stopped ---> Set callback to TRUE!");
-		// }
-		//
-		// public void animationStarted(AnimationEvent evt) {
-		// setCallBack(false);
-		// checked = false;
-		// // System.out
-		// // .println("Animation started ---> Set callback to FALSE!");
-		// }
-		// };
-		// }
-
 		// Collect evaluate predicate objects in list
 		for (ToggleObjectCoordinates obj : toggleObjects) {
 
@@ -60,8 +36,8 @@ public class SwitchCoordinates extends Observer {
 			// First evaluate predicate (predicate field)
 			String bolValue = "true";
 			if (obj.getEval().length() > 0) {
-				bolValue = parsePredicate(obj.getEval(), control, animation,
-						obj);
+				bolValue = BMSUtil.parsePredicate(obj.getEval(), control,
+						animation);
 			}
 
 			if (!obj.hasError() && Boolean.valueOf(bolValue)) {
@@ -70,21 +46,21 @@ public class SwitchCoordinates extends Observer {
 				int parsedY = 0;
 				// Handle X field
 				try {
-					parsedX = Integer.valueOf(parseExpression(obj.getX(),
-							false, control, animation, obj, false));
+					parsedX = Integer.valueOf(BMSUtil.parseExpression(
+							obj.getX(), control, animation));
 				} catch (NumberFormatException n) {
 					obj.setHasError(true);
-					addError(control, animation, "x is not a valid integer: "
-							+ n.getMessage());
+					// addError(control, animation, "x is not a valid integer: "
+					// + n.getMessage());
 				}
 				// Handle Y field
 				try {
-					parsedY = Integer.valueOf(parseExpression(obj.getY(),
-							false, control, animation, obj, false));
+					parsedY = Integer.valueOf(BMSUtil.parseExpression(
+							obj.getY(), control, animation));
 				} catch (NumberFormatException n) {
 					obj.setHasError(true);
-					addError(control, animation, "y is not a valid integer: "
-							+ n.getMessage());
+					// addError(control, animation, "y is not a valid integer: "
+					// + n.getMessage());
 				}
 
 				int currentX = Integer.valueOf(control.getAttributeValue(
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchImage.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchImage.java
index 2af5974ceb542cc8ddd5935e8c8d7b2f7b048dec..471e0ae204599a2eebe8848ff3e077a24839d241 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchImage.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/SwitchImage.java
@@ -12,10 +12,11 @@ import java.util.List;
 
 import org.eclipse.core.resources.IFile;
 
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.AttributeConstants;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.observer.wizard.WizardObserverSwitchImage;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 
 public class SwitchImage extends Observer {
 
@@ -37,8 +38,8 @@ public class SwitchImage extends Observer {
 			// First evaluate predicate (predicate field)
 			String bolValue = "true";
 			if (obj.getEval().length() > 0) {
-				bolValue = parsePredicate(obj.getEval(), control, animation,
-						obj);
+				bolValue = BMSUtil.parsePredicate(obj.getEval(), control,
+						animation);
 			}
 
 			if (!obj.hasError() && Boolean.valueOf(bolValue)) {
@@ -46,16 +47,16 @@ public class SwitchImage extends Observer {
 				String fImage = obj.getImage();
 
 				if (obj.isExpressionMode()) { // Expression mode
-					fImage = parseExpression(obj.getImage(), control,
-							animation, obj);
+					fImage = BMSUtil.parseExpression(obj.getImage(), control,
+							animation);
 				}
 
 				IFile pFile = control.getVisualization().getProjectFile();
 				String myPath = (pFile.getProject().getLocation() + "/images/" + fImage)
 						.replace("file:", "");
 				if (!new File(myPath).exists()) {
-					addError(control, animation,
-							"No such image in your library: " + fImage);
+					// addError(control, animation,
+					// "No such image in your library: " + fImage);
 				}
 
 				if (!obj.hasError()) {
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverClone.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverClone.java
deleted file mode 100644
index 9c17c7d43ac6589d3e3d727be449814df8b60b62..0000000000000000000000000000000000000000
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverClone.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/** 
- * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, 
- * Heinrich Heine Universitaet Duesseldorf
- * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) 
- * */
-
-package de.bmotionstudio.gef.editor.observer.wizard;
-
-import org.eclipse.core.databinding.DataBindingContext;
-import org.eclipse.core.databinding.beans.BeansObservables;
-import org.eclipse.core.databinding.observable.list.WritableList;
-import org.eclipse.core.databinding.observable.map.IObservableMap;
-import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
-import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITableColorProvider;
-import org.eclipse.jface.viewers.ITableFontProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.layout.RowLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-
-import de.bmotionstudio.gef.editor.BMotionStudioImage;
-import de.bmotionstudio.gef.editor.EditorImageRegistry;
-import de.bmotionstudio.gef.editor.edit.PredicateEditingSupport;
-import de.bmotionstudio.gef.editor.edit.TextEditingSupport;
-import de.bmotionstudio.gef.editor.model.BControl;
-import de.bmotionstudio.gef.editor.observer.CloneObserver;
-import de.bmotionstudio.gef.editor.observer.Observer;
-import de.bmotionstudio.gef.editor.observer.ObserverCloneObject;
-import de.bmotionstudio.gef.editor.observer.ObserverWizard;
-
-/**
- * @author Lukas Ladenberger
- * 
- */
-public class WizardObserverClone extends ObserverWizard {
-
-	public WizardObserverClone(BControl control, Observer observer) {
-		super(control, observer);
-		addPage(new WizardObserverClonePage("WizardObserverClonePage"));
-	}
-
-	private class WizardObserverClonePage extends WizardPage {
-
-		private TableViewer tableViewer;
-
-		protected WizardObserverClonePage(String pageName) {
-			super(pageName);
-		}
-
-		/*
-		 * (non-Javadoc)
-		 * 
-		 * @see
-		 * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt
-		 * .widgets.Composite)
-		 */
-		@Override
-		public void createControl(Composite parent) {
-
-			DataBindingContext dbc = new DataBindingContext();
-
-			Composite container = new Composite(parent, SWT.NONE);
-			container.setLayout(new GridLayout(1, true));
-
-			setControl(container);
-
-			tableViewer = new TableViewer(container, SWT.BORDER
-					| SWT.FULL_SELECTION);
-			tableViewer.getTable().setLinesVisible(true);
-			tableViewer.getTable().setHeaderVisible(true);
-			tableViewer.getTable().setLayoutData(
-					new GridData(GridData.FILL_BOTH));
-			tableViewer.getTable().setFont(
-					new Font(Display.getDefault(), new FontData("Arial", 10,
-							SWT.NONE)));
-
-			TableViewerColumn column = new TableViewerColumn(tableViewer,
-					SWT.NONE);
-			column.getColumn().setText("Expression");
-			column.getColumn().setWidth(200);
-			column.setEditingSupport(new PredicateEditingSupport(tableViewer,
-					dbc, "eval", getBControl().getVisualization(), getShell()));
-
-			column = new TableViewerColumn(tableViewer, SWT.NONE);
-			column.getColumn().setText("Control");
-			column.getColumn().setWidth(175);
-			column.setEditingSupport(new TextEditingSupport(tableViewer, dbc,
-					"controlId"));
-
-			column = new TableViewerColumn(tableViewer, SWT.NONE);
-			column.getColumn().setText("Count from");
-			column.getColumn().setWidth(125);
-			column.setEditingSupport(new TextEditingSupport(tableViewer, dbc,
-					"counter"));
-
-			ObservableListContentProvider contentProvider = new ObservableListContentProvider();
-			tableViewer.setContentProvider(contentProvider);
-			tableViewer.setLabelProvider(new ObserverLabelProvider(
-					BeansObservables.observeMaps(
-							contentProvider.getKnownElements(), new String[] {
-									"eval", "controlId", "counter" })));
-
-			final WritableList input = new WritableList(
-					((CloneObserver) getObserver()).getObserverCloneObjects(),
-					ObserverCloneObject.class);
-			tableViewer.setInput(input);
-
-			Composite comp = new Composite(container, SWT.NONE);
-			comp.setLayout(new RowLayout());
-			comp.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
-
-			Button btRemove = new Button(comp, SWT.PUSH);
-			btRemove.setText("Remove");
-			btRemove.setImage(BMotionStudioImage
-					.getImage(EditorImageRegistry.IMG_ICON_DELETE));
-			btRemove.addSelectionListener(new SelectionAdapter() {
-				@Override
-				public void widgetSelected(SelectionEvent e) {
-					if (tableViewer.getSelection().isEmpty()) {
-						return;
-					}
-					ObserverCloneObject obj = (ObserverCloneObject) ((IStructuredSelection) tableViewer
-							.getSelection()).getFirstElement();
-					input.remove(obj);
-				}
-			});
-
-			Button btAdd = new Button(comp, SWT.PUSH);
-			btAdd.setText("Add");
-			btAdd.setImage(BMotionStudioImage
-					.getImage(EditorImageRegistry.IMG_ICON_ADD));
-			btAdd.addSelectionListener(new SelectionAdapter() {
-				@Override
-				public void widgetSelected(SelectionEvent e) {
-					ObserverCloneObject obj = new ObserverCloneObject();
-					input.add(obj);
-				}
-			});
-
-		}
-
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see
-	 * de.bmotionstudio.gef.editor.observer.ObserverWizard#prepareToFinish()
-	 */
-	@Override
-	protected Boolean prepareToFinish() {
-		if (((CloneObserver) getObserver()).getObserverCloneObjects().size() == 0) {
-			setObserverDelete(true);
-		} else {
-			for (ObserverCloneObject obj : ((CloneObserver) getObserver())
-					.getObserverCloneObjects()) {
-				if (obj.getEval() == null || obj.getControlId() == null) {
-					MessageDialog
-							.openError(getShell(), "Please check your entries",
-									"Please check your entries. The eval and control field must not be empty.");
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see de.bmotionstudio.gef.editor.observer.ObserverWizard#getSize()
-	 */
-	@Override
-	public Point getSize() {
-		return new Point(700, 500);
-	}
-
-	private static class ObserverLabelProvider extends
-			ObservableMapLabelProvider implements ITableLabelProvider,
-			ITableColorProvider, ITableFontProvider {
-
-		public ObserverLabelProvider(IObservableMap[] attributeMaps) {
-			super(attributeMaps);
-		}
-
-		private final Color errorColor = Display.getDefault().getSystemColor(
-				SWT.COLOR_INFO_BACKGROUND);
-
-		@Override
-		public Image getColumnImage(Object element, int columnIndex) {
-			return null;
-		}
-
-		@Override
-		public String getColumnText(Object element, int columnIndex) {
-			ObserverCloneObject obj = (ObserverCloneObject) element;
-			if (columnIndex == 0) {
-				return obj.getEval();
-			}
-			if (columnIndex == 1) {
-				return obj.getControlId();
-			}
-			return super.getColumnText(element, columnIndex);
-		}
-
-		public Color getBackground(final Object element, final int column) {
-			ObserverCloneObject obj = (ObserverCloneObject) element;
-			if (obj.hasError())
-				return errorColor;
-			return null;
-		}
-
-		public Color getForeground(final Object element, final int column) {
-			return null;
-		}
-
-		public Font getFont(final Object element, final int column) {
-			// return JFaceResources.getFontRegistry().get(
-			// BMotionStudioConstants.RODIN_FONT_KEY);
-			return null;
-		}
-
-	}
-
-}
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverExternalObserverScript.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverExternalObserverScript.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e4c0d4e57f8aaec0519b81a7afdb3c4d932616b
--- /dev/null
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/observer/wizard/WizardObserverExternalObserverScript.java
@@ -0,0 +1,111 @@
+/** 
+ * (c) 2009 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, 
+ * Heinrich Heine Universitaet Duesseldorf
+ * This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) 
+ * */
+
+package de.bmotionstudio.gef.editor.observer.wizard;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeansObservables;
+import org.eclipse.jface.databinding.swt.SWTObservables;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+import de.bmotionstudio.gef.editor.model.BControl;
+import de.bmotionstudio.gef.editor.observer.ExternalObserverScript;
+import de.bmotionstudio.gef.editor.observer.Observer;
+import de.bmotionstudio.gef.editor.observer.ObserverWizard;
+
+public class WizardObserverExternalObserverScript extends ObserverWizard {
+
+	private class ObserverExternalObserverScriptPage extends WizardPage {
+
+		private Text txtScriptPath;
+
+		protected ObserverExternalObserverScriptPage(final String pageName) {
+			super(pageName);
+		}
+
+		public Text getTxtScriptPath() {
+			return txtScriptPath;
+		}
+
+		public void createControl(final Composite parent) {
+
+			final DataBindingContext dbc = new DataBindingContext();
+
+			Composite container = new Composite(parent, SWT.NONE);
+			container.setLayoutData(new GridData(GridData.FILL_BOTH));
+			container.setLayout(new GridLayout(2, false));
+
+			Label lb = new Label(container, SWT.NONE);
+			lb.setText("Script File:");
+
+			txtScriptPath = new Text(container, SWT.BORDER);
+			txtScriptPath.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			txtScriptPath.setFont(new Font(Display.getDefault(), new FontData(
+					"Arial", 10, SWT.NONE)));
+
+			initBindings(dbc);
+
+			setControl(container);
+
+		}
+
+		private void initBindings(DataBindingContext dbc) {
+
+			dbc.bindValue(
+					SWTObservables.observeText(txtScriptPath, SWT.Modify),
+					BeansObservables.observeValue(
+							(ExternalObserverScript) getObserver(),
+							"scriptPath"));
+
+		}
+
+
+	}
+
+	public WizardObserverExternalObserverScript(BControl bcontrol,
+			Observer bobserver) {
+		super(bcontrol, bobserver);
+		addPage(new ObserverExternalObserverScriptPage(
+				"ObserverExternalObserverScriptPage"));
+	}
+
+	@Override
+	protected Boolean prepareToFinish() {
+
+		ObserverExternalObserverScriptPage page = (ObserverExternalObserverScriptPage) getPage("ObserverExternalObserverScriptPage");
+
+		String errorStr = "";
+
+		if (page.getTxtScriptPath().getText().length() == 0)
+			errorStr += "Please enter a path for a script file.\n";
+
+		if (errorStr.length() > 0) {
+			MessageDialog.openError(Display.getDefault().getActiveShell(),
+					"An Error occured", errorStr);
+			return false;
+		}
+
+		return true;
+
+	}
+
+	@Override
+	public Point getSize() {
+		return new Point(600, 500);
+	}
+
+}
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteAnimationScript.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteAnimationScript.java
index 08af0cb8650791926392b3a2870bbc6a5c5cdd9a..20a3c505bb4d594fe051a8be9c882774a7147878 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteAnimationScript.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteAnimationScript.java
@@ -10,9 +10,10 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
 
-import de.bmotionstudio.gef.editor.internal.Animation;
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.scheduler.wizard.WizardExecuteScheduler;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 import de.prob.core.Animator;
 import de.prob.core.command.ExecuteOperationCommand;
 import de.prob.core.command.GetCurrentStateIdCommand;
@@ -45,8 +46,8 @@ public class ExecuteAnimationScript extends SchedulerEvent {
 
 			// First evaluate predicate (predicate field)
 			// If true (execute operation sequence)
-			if (Boolean.valueOf(parsePredicate(obj.getPredicate(), control,
-					animation, null))) {
+			if (Boolean.valueOf(BMSUtil.parsePredicate(obj.getPredicate(),
+					control, animation))) {
 
 				for (AnimationScriptStep step : obj.getSteps()) {
 
@@ -55,7 +56,7 @@ public class ExecuteAnimationScript extends SchedulerEvent {
 						String currentState = GetCurrentStateIdCommand
 								.getID(animator);
 
-						List<Operation> operations = parseOperation(
+						List<Operation> operations = BMSUtil.parseOperation(
 								step.getCommand(), step.getParameter(),
 								step.getMaxrandom(), animation, currentState,
 								control);
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicate.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicate.java
index 1ecb2129b9b7e1595506d61aaca133d002ab4f61..c9114041dd765a0295d88fd92576e5e6278d4090 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicate.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicate.java
@@ -9,9 +9,10 @@ package de.bmotionstudio.gef.editor.scheduler;
 import java.util.List;
 import java.util.Random;
 
-import de.bmotionstudio.gef.editor.internal.Animation;
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.scheduler.wizard.WizardExecuteOperationByPredicate;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 import de.prob.core.Animator;
 import de.prob.core.command.ExecuteOperationCommand;
 import de.prob.core.command.GetCurrentStateIdCommand;
@@ -39,7 +40,7 @@ public class ExecuteOperationByPredicate extends SchedulerEvent {
 					String currentState = GetCurrentStateIdCommand
 							.getID(animator);
 
-					List<Operation> operations = parseOperation(
+					List<Operation> operations = BMSUtil.parseOperation(
 							predicateOperation.getOperationName(),
 							predicateOperation.getPredicate(),
 							predicateOperation.getMaxrandom(), animation,
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicateMulti.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicateMulti.java
index 064189f6fd125e410c1bf0c287e54c040fa144a5..eb2b2c88cd131ae74a22c58507c38db5f2564beb 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicateMulti.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/ExecuteOperationByPredicateMulti.java
@@ -2,10 +2,11 @@ package de.bmotionstudio.gef.editor.scheduler;
 
 import java.util.ArrayList;
 
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.BindingObject;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 import de.bmotionstudio.gef.editor.scheduler.wizard.WizardExecuteOperationByPredicateMulti;
+import de.bmotionstudio.gef.editor.util.BMSUtil;
 
 public class ExecuteOperationByPredicateMulti extends SchedulerEvent {
 
@@ -27,8 +28,8 @@ public class ExecuteOperationByPredicateMulti extends SchedulerEvent {
 					.getExecutePredicate();
 
 			if (executePredicate.length() > 0) {
-				bolValue = parsePredicate(executePredicate, control, animation,
-						null);
+				bolValue = BMSUtil.parsePredicate(executePredicate, control,
+						animation);
 			}
 
 			if (Boolean.valueOf(bolValue)) { // If true
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerEvent.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerEvent.java
index 1ab4d5c9f15eafeaf03b46780b189720530b93be..acc22a77cfb4ce228782038c422420071bde5da9 100644
--- a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerEvent.java
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/scheduler/SchedulerEvent.java
@@ -9,8 +9,8 @@ package de.bmotionstudio.gef.editor.scheduler;
 import org.eclipse.core.runtime.IConfigurationElement;
 
 import de.bmotionstudio.gef.editor.AbstractExpressionControl;
+import de.bmotionstudio.gef.editor.Animation;
 import de.bmotionstudio.gef.editor.BMotionEditorPlugin;
-import de.bmotionstudio.gef.editor.internal.Animation;
 import de.bmotionstudio.gef.editor.model.BControl;
 
 /**
diff --git a/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/util/BMSUtil.java b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/util/BMSUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed487db0020ca2b9fa7657c1866e35b2a0159489
--- /dev/null
+++ b/de.bmotionstudio.gef.editor/src/de/bmotionstudio/gef/editor/util/BMSUtil.java
@@ -0,0 +1,223 @@
+package de.bmotionstudio.gef.editor.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import de.be4.classicalb.core.parser.exceptions.BException;
+import de.bmotionstudio.gef.editor.Animation;
+import de.bmotionstudio.gef.editor.AttributeConstants;
+import de.bmotionstudio.gef.editor.model.BControl;
+import de.prob.core.command.EvaluationGetValuesCommand;
+import de.prob.core.command.GetOperationByPredicateCommand;
+import de.prob.core.domainobjects.EvaluationElement;
+import de.prob.core.domainobjects.EvaluationStateElement;
+import de.prob.core.domainobjects.Operation;
+import de.prob.core.domainobjects.State;
+import de.prob.exceptions.ProBException;
+import de.prob.parserbase.ProBParseException;
+
+public class BMSUtil {
+
+	private static final Pattern PATTERN = Pattern.compile("\\$(.+?)\\$");
+
+	// private static Boolean hasError = false;
+	private static final String DEFAULT_PREDICATE = "1=1";
+	private static final String DEFAULT_BOOLVAL = "true";
+
+	public static String parseExpression(String expressionString,
+			BControl control, Animation animation) {
+		return parseExpression(expressionString, control, animation, false,
+				true);
+	}
+
+	public static String parseExpression(final String expressionString,
+			final BControl control, final Animation animation,
+			boolean parseControls) {
+		return parseExpression(expressionString, control, animation, false,
+				parseControls);
+	}
+
+	public static String parsePredicate(String expressionString,
+			BControl control, Animation animation) {
+		return parsePredicate(expressionString, control, animation, true);
+	}
+	
+	public static String parsePredicate(String expressionString,
+			BControl control, Animation animation, boolean parseControls) {
+		if (expressionString == null || expressionString.trim().length() == 0)
+			return DEFAULT_BOOLVAL;
+		return parseExpression(expressionString, control, animation, true,
+				parseControls);
+	}
+
+	private static String parseExpression(String expressionString,
+			BControl control, Animation animation, boolean isPredicate,
+			boolean parseControls) {
+
+		boolean hasError = false;
+
+		boolean hasSubExpressions = false;
+
+		Map<EvaluationElement, String> evaluationKeys = new HashMap<EvaluationElement, String>();
+
+		// Find expressions and collect ExpressionEvalElements
+		final Matcher matcher = PATTERN.matcher(expressionString);
+		while (matcher.find()) {
+			final String subExpr = matcher.group(1);
+			collectEvalElements(subExpr, "$" + subExpr + "$", isPredicate,
+					animation, control, evaluationKeys, parseControls);
+			hasSubExpressions = true;
+		}
+
+		// We have only one expression (without "$$")
+		if (!hasSubExpressions) {
+			collectEvalElements(expressionString, expressionString,
+					isPredicate, animation, control, evaluationKeys,
+					parseControls);
+		}
+
+		// Try to get expression results and parse expression string
+		Collection<EvaluationStateElement> resultList;
+		try {
+			resultList = getExpressionValues(control, animation,
+					new ArrayList<EvaluationElement>(evaluationKeys.keySet()));
+		} catch (ProBException e) {
+			resultList = Collections.emptyList();
+			hasError = true;
+		}
+
+		// If getting ExpressionEvalElement throws no error, try to get
+		// expression results
+		String result = expressionString;
+		if (!hasError) {
+			for (EvaluationStateElement stateElement : resultList) {
+				final EvaluationElement evalElement = stateElement.getElement();
+				final String text;
+				if (isPredicate) {
+					text = stateElement.getResult().isPredicateTrue() ? "true"
+							: "false";
+				} else {
+					text = stateElement.getText();
+				}
+				final String subExpression = evaluationKeys.get(evalElement);
+				result = result.replace(subExpression, text);
+			}
+		} else {
+			// if (obj != null)
+			// obj.setHasError(true);
+			// addError(control, animation,
+			// "An error occurred while evaluating expression\\predicate value: \""
+			// + expressionString
+			// + "\". Please check your expression\\predicate.");
+		}
+
+		return result;
+
+	}
+
+	private static boolean collectEvalElements(final String subexpression,
+			final String key, final boolean isPredicate,
+			final Animation animation, final BControl control,
+			final Map<EvaluationElement, String> evaluationKeys,
+			final boolean parseControls) {
+
+		String parsedSubexpr = subexpression;
+
+		if(parseControls)
+			parsedSubexpr = parseControls(parsedSubexpr, control);
+		EvaluationElement evalElement;
+		try {
+			evalElement = animation.getCachedEvalElement(parsedSubexpr,
+					isPredicate);
+			evaluationKeys.put(evalElement, key);
+			return true;
+		} catch (UnsupportedOperationException e) {
+			return false;
+		} catch (ProBException e) {
+			return false;
+		} catch (ProBParseException e) {
+			// addError(control, animation, e.getMessage());
+			return false;
+		}
+
+	}
+
+	public static String parseControls(String expressionString,
+			BControl control) {
+
+		List<String> allControlIDs = control.getVisualization()
+				.getAllBControlNames();
+
+		// Search for control ids
+		Pattern cPattern = Pattern.compile("(\\w+)");
+		Matcher cMatcher = cPattern.matcher(expressionString);
+
+		while (cMatcher.find()) {
+
+			String controlID = cMatcher.group(1);
+
+			if (controlID.equals("this")) {
+
+				expressionString = expressionString.replace(controlID, control
+						.getAttributeValue(AttributeConstants.ATTRIBUTE_CUSTOM)
+						.toString());
+
+			} else if (allControlIDs.contains(controlID)) {
+
+				expressionString = expressionString.replace(controlID, control
+						.getVisualization().getBControl(controlID)
+						.getValueOfData());
+
+			} else {
+				// TODO: Return error if no control exists
+			}
+		}
+
+		return expressionString;
+
+	}
+
+	private static Collection<EvaluationStateElement> getExpressionValues(
+			final BControl control, final Animation animation,
+			final Collection<EvaluationElement> evalElements)
+			throws ProBException {
+		final State state = animation.getAnimator().getCurrentState();
+		// TODO[DP, 11.04.2011] Add an animator to the parameters!
+		final Collection<EvaluationStateElement> values = EvaluationGetValuesCommand
+				.getValuesForExpressionsCached(state, evalElements);
+		return values;
+	}
+
+	public static List<Operation> parseOperation(final String opName,
+			String opPredicate, int opRandom, final Animation animation,
+			final String currentState, final BControl control) {
+
+		try {
+
+			if (opPredicate != null && opPredicate.length() > 0)
+				opPredicate = parseControls(opPredicate, control);
+			else
+				opPredicate = DEFAULT_PREDICATE;
+
+			if (opRandom < 1)
+				opRandom = 1;
+
+			return GetOperationByPredicateCommand.getOperations(
+					animation.getAnimator(), currentState, opName, opPredicate,
+					opRandom);
+
+		} catch (ProBException e) {
+		} catch (BException e) {
+		}
+
+		return null;
+
+	}
+
+}