瀏覽代碼

Added validation for entry points and entry point specs.

markus.muehlbrandt@gmail.com 12 年之前
父節點
當前提交
2c92299f07

+ 201 - 56
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextJavaValidator.java

@@ -11,6 +11,7 @@
  */
 package org.yakindu.sct.model.stext.validation;
 
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -31,6 +32,7 @@ import org.eclipse.xtext.validation.Check;
 import org.eclipse.xtext.validation.CheckType;
 import org.eclipse.xtext.validation.ComposedChecks;
 import org.eclipse.xtext.validation.ValidationMessageAcceptor;
+import org.yakindu.base.base.NamedElement;
 import org.yakindu.base.types.Event;
 import org.yakindu.base.types.Feature;
 import org.yakindu.base.types.ITypeSystem.InferenceIssue;
@@ -39,6 +41,9 @@ import org.yakindu.base.types.Operation;
 import org.yakindu.base.types.Parameter;
 import org.yakindu.base.types.Property;
 import org.yakindu.sct.model.sgraph.Choice;
+import org.yakindu.sct.model.sgraph.Entry;
+import org.yakindu.sct.model.sgraph.ReactionProperty;
+import org.yakindu.sct.model.sgraph.Region;
 import org.yakindu.sct.model.sgraph.SGraphPackage;
 import org.yakindu.sct.model.sgraph.Scope;
 import org.yakindu.sct.model.sgraph.ScopedElement;
@@ -53,6 +58,7 @@ import org.yakindu.sct.model.stext.stext.DefaultTrigger;
 import org.yakindu.sct.model.stext.stext.Direction;
 import org.yakindu.sct.model.stext.stext.ElementReferenceExpression;
 import org.yakindu.sct.model.stext.stext.EntryEvent;
+import org.yakindu.sct.model.stext.stext.EntryPointSpec;
 import org.yakindu.sct.model.stext.stext.EventDefinition;
 import org.yakindu.sct.model.stext.stext.EventRaisingExpression;
 import org.yakindu.sct.model.stext.stext.EventSpec;
@@ -82,7 +88,8 @@ import com.google.inject.name.Named;
  * @auhor muelder
  * 
  */
-@ComposedChecks(validators = { SGraphJavaValidator.class, SCTResourceValidator.class })
+@ComposedChecks(validators = { SGraphJavaValidator.class,
+		SCTResourceValidator.class })
 public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 	public static final String CHOICE_ONE_OUTGOING_DEFAULT_TRANSITION = "A choice should have one outgoing default transition";
@@ -97,6 +104,9 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public static final String GUARD_EXPRESSION = "The evaluation result of a guard expression must be of type boolean";
 	public static final String ASSIGNMENT_EXPRESSION = "No nested assignment of the same variable allowed (different behavior in various programming languages)";
 	public static final String VARIABLE_VOID_TYPE = "'void' is an invalid type for variables";
+	public static final String TRANSITION_ENTRY_SPEC_NOT_COMPOSITE = "Target state isn't composite";
+	public static final String TRANSITION_UNBOUND_ENTRY_POINT = "Target state has regions without 'default' entries.";
+	public static final String REGION_UNBOUND_ENTRY_POINT = "Region must have a 'default' entry.";
 
 	@Inject
 	private ISTextTypeInferrer typeInferrer;
@@ -110,11 +120,100 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	@Named(Constants.LANGUAGE_NAME)
 	private String languageName;
 
+	@Check(CheckType.FAST)
+	public void checkEntrySpecOnAtomicState(final Transition transition) {
+		for (ReactionProperty property : transition.getProperties()) {
+			if (property instanceof EntryPointSpec) {
+				if (transition.getTarget() instanceof org.yakindu.sct.model.sgraph.State) {
+					org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) transition
+							.getTarget();
+					if (!state.isComposite()) {
+						warning(TRANSITION_ENTRY_SPEC_NOT_COMPOSITE,
+								transition, null, -1);
+					}
+				}
+			}
+		}
+	}
+	
+	@Check(CheckType.FAST)
+	public void checkUnboundEntryPoints(
+			final org.yakindu.sct.model.sgraph.State state) {
+
+		final List<Transition> transitions = getTransitionsWithoutEntrySpec(state
+				.getIncomingTransitions());
+
+		if (!transitions.isEmpty()) {
+			final List<Region> regions = getRegionsWithoutDefaultEntry(state
+					.getRegions());
+			if (!regions.isEmpty()) {
+				for (Transition transition : transitions) {
+					error(TRANSITION_UNBOUND_ENTRY_POINT, transition, null, -1);
+				}
+				for (Region region : regions) {
+					error(REGION_UNBOUND_ENTRY_POINT, region, null, -1);
+				}
+			}
+		}
+	}
+
+	private List<Transition> getTransitionsWithoutEntrySpec(
+			List<Transition> elements) {
+		final List<Transition> transitions = new ArrayList<Transition>();
+		for (Transition transition : elements) {
+			boolean hasEntrySpec = false;
+			for (ReactionProperty property : transition.getProperties()) {
+				if (property instanceof EntryPointSpec) {
+					hasEntrySpec = true;
+					break;
+				}
+			}
+			if (!hasEntrySpec) {
+				transitions.add(transition);
+			}
+		}
+		return transitions;
+	}
+
+	private List<Region> getRegionsWithoutDefaultEntry(List<Region> elements) {
+		List<Region> regions = new ArrayList<Region>();
+		for (Region region : elements) {
+			boolean hasDefaultEntry = false;
+			for (Entry entry : getEntries(region.eContents())) {
+				if (isDefault(entry)) {
+					hasDefaultEntry = true;
+					break;
+				}
+			}
+			if (!hasDefaultEntry) {
+				regions.add(region);
+			}
+		}
+		return regions;
+	}
+
+	private boolean isDefault(final NamedElement element) {
+		return element.getName() == null
+				|| (element.getName() != null && (element.getName().isEmpty() || element
+						.getName().equalsIgnoreCase("default")));
+	}
+
+	private List<Entry> getEntries(List<EObject> elements) {
+		List<Entry> entries = new ArrayList<Entry>();
+		for (EObject element : elements) {
+			if (element instanceof Entry) {
+				entries.add((Entry) element);
+			}
+		}
+		return entries;
+	}
+
 	@Check(CheckType.FAST)
 	public void checkVariableDefinition(final VariableDefinition definition) {
 		try {
 			InferenceResult result = typeInferrer.inferType(definition);
-			if (result.getType() != null && typeSystem.isVoidType(result.getType())) {
+			if (result.getType() != null
+					&& typeSystem.isVoidType(result.getType())) {
 				error(VARIABLE_VOID_TYPE, null);
 			} else {
 				report(result, null);
@@ -138,7 +237,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	}
 
 	@Check(CheckType.FAST)
-	public void checkOperationArguments_TypedElementReferenceExpression(final ElementReferenceExpression call) {
+	public void checkOperationArguments_TypedElementReferenceExpression(
+			final ElementReferenceExpression call) {
 		if (call.getReference() instanceof Operation) {
 			Operation operation = (Operation) call.getReference();
 			EList<Parameter> parameters = operation.getParameters();
@@ -154,16 +254,18 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 		final String name = getVariableName(exp);
 
-		List<AssignmentExpression> contents = EcoreUtil2.eAllOfType(exp, AssignmentExpression.class);
+		List<AssignmentExpression> contents = EcoreUtil2.eAllOfType(exp,
+				AssignmentExpression.class);
 		contents.remove(exp);
 
-		Iterable<AssignmentExpression> filter = Iterables.filter(contents, new Predicate<AssignmentExpression>() {
-			public boolean apply(final AssignmentExpression ex) {
-				String variableName = getVariableName(ex);
-				return variableName.equals(name);
+		Iterable<AssignmentExpression> filter = Iterables.filter(contents,
+				new Predicate<AssignmentExpression>() {
+					public boolean apply(final AssignmentExpression ex) {
+						String variableName = getVariableName(ex);
+						return variableName.equals(name);
 
-			}
-		});
+					}
+				});
 		if (Iterables.size(filter) > 0) {
 			error(ASSIGNMENT_EXPRESSION, null);
 		}
@@ -173,9 +275,11 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		Expression varRef = exp.getVarRef();
 		if (varRef instanceof ElementReferenceExpression
 				&& ((ElementReferenceExpression) varRef).getReference() instanceof Property) {
-			Property reference = (Property) ((ElementReferenceExpression) varRef).getReference();
+			Property reference = (Property) ((ElementReferenceExpression) varRef)
+					.getReference();
 			return reference.getName();
-		} else if (varRef instanceof FeatureCall && ((FeatureCall) varRef).getFeature() instanceof Property) {
+		} else if (varRef instanceof FeatureCall
+				&& ((FeatureCall) varRef).getFeature() instanceof Property) {
 			Property reference = (Property) ((FeatureCall) varRef).getFeature();
 			return reference.getName();
 		}
@@ -188,7 +292,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			return;
 		}
 		if (call.getFeature() instanceof Scope) {
-			error("A variable, event or operation is required", StextPackage.Literals.FEATURE_CALL__FEATURE,
+			error("A variable, event or operation is required",
+					StextPackage.Literals.FEATURE_CALL__FEATURE,
 					INSIGNIFICANT_INDEX, FEATURE_CALL_TO_SCOPE);
 		}
 	}
@@ -200,8 +305,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		}
 		if (call.getReference() instanceof Scope) {
 			error("A variable, event or operation is required",
-					StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE, INSIGNIFICANT_INDEX,
-					FEATURE_CALL_TO_SCOPE);
+					StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
+					INSIGNIFICANT_INDEX, FEATURE_CALL_TO_SCOPE);
 		}
 	}
 
@@ -211,9 +316,12 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			return;
 		}
 		try {
-			InferenceResult result = typeInferrer.inferType(trigger.getGuardExpression());
-			if (result.getType() == null || !typeSystem.isBooleanType(result.getType())) {
-				error(GUARD_EXPRESSION, StextPackage.Literals.REACTION_TRIGGER__GUARD_EXPRESSION);
+			InferenceResult result = typeInferrer.inferType(trigger
+					.getGuardExpression());
+			if (result.getType() == null
+					|| !typeSystem.isBooleanType(result.getType())) {
+				error(GUARD_EXPRESSION,
+						StextPackage.Literals.REACTION_TRIGGER__GUARD_EXPRESSION);
 			}
 			report(result, null);
 		} catch (IllegalArgumentException e) {
@@ -226,7 +334,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public void checkTimeEventSpecValueExpression(TimeEventSpec spec) {
 		try {
 			InferenceResult result = typeInferrer.inferType(spec.getValue());
-			if (result.getType() == null || !typeSystem.isIntegerType(result.getType())) {
+			if (result.getType() == null
+					|| !typeSystem.isIntegerType(result.getType())) {
 				error(TIME_EXPRESSION, null);
 			}
 			report(result, StextPackage.Literals.TIME_EVENT_SPEC__VALUE);
@@ -242,8 +351,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			if (!(reactionTrigger.eContainer() instanceof LocalReaction)
 					&& (eventSpec instanceof EntryEvent || eventSpec instanceof ExitEvent)) {
 				error("entry and exit events are allowed as local reactions only.",
-						StextPackage.Literals.REACTION_TRIGGER__TRIGGERS, INSIGNIFICANT_INDEX,
-						LOCAL_REACTIONS_NOT_ALLOWED);
+						StextPackage.Literals.REACTION_TRIGGER__TRIGGERS,
+						INSIGNIFICANT_INDEX, LOCAL_REACTIONS_NOT_ALLOWED);
 			}
 		}
 	}
@@ -270,15 +379,18 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	public void checkReactionEffectActions(ReactionEffect effect) {
 		for (Expression exp : effect.getActions()) {
 
-			if (!(exp instanceof AssignmentExpression) && !(exp instanceof EventRaisingExpression)) {
+			if (!(exp instanceof AssignmentExpression)
+					&& !(exp instanceof EventRaisingExpression)) {
 
 				if (exp instanceof FeatureCall) {
 					checkFeatureCallEffect((FeatureCall) exp);
 				} else if (exp instanceof ElementReferenceExpression) {
 					checkElementReferenceEffect((ElementReferenceExpression) exp);
 				} else {
-					error("Action has no effect.", StextPackage.Literals.REACTION_EFFECT__ACTIONS, effect.getActions()
-							.indexOf(exp), FEATURE_CALL_HAS_NO_EFFECT);
+					error("Action has no effect.",
+							StextPackage.Literals.REACTION_EFFECT__ACTIONS,
+							effect.getActions().indexOf(exp),
+							FEATURE_CALL_HAS_NO_EFFECT);
 				}
 
 			}
@@ -289,17 +401,23 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		if (call.getFeature() != null && call.getFeature() instanceof Feature
 				&& !(call.getFeature() instanceof Operation)) {
 			if (call.getFeature() instanceof Property) {
-				error("Access to property '" + nameProvider.getFullyQualifiedName(call.getFeature())
-						+ "' has no effect.", call, StextPackage.Literals.FEATURE_CALL__FEATURE, INSIGNIFICANT_INDEX,
-						FEATURE_CALL_HAS_NO_EFFECT);
+				error("Access to property '"
+						+ nameProvider.getFullyQualifiedName(call.getFeature())
+						+ "' has no effect.", call,
+						StextPackage.Literals.FEATURE_CALL__FEATURE,
+						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			} else if (call.getFeature() instanceof Event) {
-				error("Access to event '" + nameProvider.getFullyQualifiedName(call.getFeature()) + "' has no effect.",
-						call, StextPackage.Literals.FEATURE_CALL__FEATURE, INSIGNIFICANT_INDEX,
-						FEATURE_CALL_HAS_NO_EFFECT);
+				error("Access to event '"
+						+ nameProvider.getFullyQualifiedName(call.getFeature())
+						+ "' has no effect.", call,
+						StextPackage.Literals.FEATURE_CALL__FEATURE,
+						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			} else {
-				error("Access to feature '" + nameProvider.getFullyQualifiedName(call.getFeature())
-						+ "' has no effect.", call, StextPackage.Literals.FEATURE_CALL__FEATURE, INSIGNIFICANT_INDEX,
-						FEATURE_CALL_HAS_NO_EFFECT);
+				error("Access to feature '"
+						+ nameProvider.getFullyQualifiedName(call.getFeature())
+						+ "' has no effect.", call,
+						StextPackage.Literals.FEATURE_CALL__FEATURE,
+						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			}
 		}
 	}
@@ -307,16 +425,25 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 	protected void checkElementReferenceEffect(ElementReferenceExpression refExp) {
 		if (!(refExp.getReference() instanceof Operation)) {
 			if (refExp.getReference() instanceof Property) {
-				error("Access to property '" + nameProvider.getFullyQualifiedName(refExp.getReference())
-						+ "' has no effect.", refExp, StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
+				error("Access to property '"
+						+ nameProvider.getFullyQualifiedName(refExp
+								.getReference()) + "' has no effect.",
+						refExp,
+						StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
 						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			} else if (refExp.getReference() instanceof Event) {
-				error("Access to event '" + nameProvider.getFullyQualifiedName(refExp.getReference())
-						+ "' has no effect.", refExp, StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
+				error("Access to event '"
+						+ nameProvider.getFullyQualifiedName(refExp
+								.getReference()) + "' has no effect.",
+						refExp,
+						StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
 						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			} else {
-				error("Access to feature '" + nameProvider.getFullyQualifiedName(refExp.getReference())
-						+ "' has no effect.", refExp, StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
+				error("Access to feature '"
+						+ nameProvider.getFullyQualifiedName(refExp
+								.getReference()) + "' has no effect.",
+						refExp,
+						StextPackage.Literals.ELEMENT_REFERENCE_EXPRESSION__REFERENCE,
 						INSIGNIFICANT_INDEX, FEATURE_CALL_HAS_NO_EFFECT);
 			}
 		}
@@ -324,11 +451,15 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 	@Check(CheckType.FAST)
 	public void checkEventDefinition(EventDefinition event) {
-		if (event.eContainer() instanceof InterfaceScope && event.getDirection() == Direction.LOCAL) {
-			error(LOCAL_DECLARATIONS, StextPackage.Literals.EVENT_DEFINITION__DIRECTION);
+		if (event.eContainer() instanceof InterfaceScope
+				&& event.getDirection() == Direction.LOCAL) {
+			error(LOCAL_DECLARATIONS,
+					StextPackage.Literals.EVENT_DEFINITION__DIRECTION);
 		}
-		if (event.eContainer() instanceof InternalScope && event.getDirection() != Direction.LOCAL) {
-			error(IN_OUT_DECLARATIONS, StextPackage.Literals.EVENT_DEFINITION__DIRECTION);
+		if (event.eContainer() instanceof InternalScope
+				&& event.getDirection() != Direction.LOCAL) {
+			error(IN_OUT_DECLARATIONS,
+					StextPackage.Literals.EVENT_DEFINITION__DIRECTION);
 		}
 	}
 
@@ -337,14 +468,17 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		List<InterfaceScope> defaultInterfaces = new LinkedList<InterfaceScope>();
 
 		for (Scope scope : statechart.getScopes()) {
-			if (scope instanceof InterfaceScope && ((InterfaceScope) scope).getName() == null) {
+			if (scope instanceof InterfaceScope
+					&& ((InterfaceScope) scope).getName() == null) {
 				defaultInterfaces.add((InterfaceScope) scope);
 			}
 		}
 		if (defaultInterfaces.size() > 1) {
 			for (InterfaceScope scope : defaultInterfaces) {
-				error(ONLY_ONE_INTERFACE, scope, grammarAccess.getInterfaceScopeAccess().getInterfaceKeyword_1(),
-						ValidationMessageAcceptor.INSIGNIFICANT_INDEX, ONLY_ONE_INTERFACE);
+				error(ONLY_ONE_INTERFACE, scope, grammarAccess
+						.getInterfaceScopeAccess().getInterfaceKeyword_1(),
+						ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
+						ONLY_ONE_INTERFACE);
 			}
 		}
 	}
@@ -359,19 +493,22 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 			}
 		}
 		if (!found)
-			warning(CHOICE_ONE_OUTGOING_DEFAULT_TRANSITION, SGraphPackage.Literals.VERTEX__OUTGOING_TRANSITIONS);
+			warning(CHOICE_ONE_OUTGOING_DEFAULT_TRANSITION,
+					SGraphPackage.Literals.VERTEX__OUTGOING_TRANSITIONS);
 	}
 
 	protected boolean isDefault(Trigger trigger) {
 
 		return trigger == null
 				|| trigger instanceof DefaultTrigger
-				|| ((trigger instanceof ReactionTrigger) && ((ReactionTrigger) trigger).getTriggers().size() == 0 && ((ReactionTrigger) trigger)
+				|| ((trigger instanceof ReactionTrigger)
+						&& ((ReactionTrigger) trigger).getTriggers().size() == 0 && ((ReactionTrigger) trigger)
 						.getGuardExpression() == null);
 	}
 
 	@Override
-	protected String getCurrentLanguage(Map<Object, Object> context, EObject eObject) {
+	protected String getCurrentLanguage(Map<Object, Object> context,
+			EObject eObject) {
 		Resource eResource = eObject.eResource();
 		if (eResource instanceof XtextResource) {
 			return super.getCurrentLanguage(context, eObject);
@@ -381,19 +518,23 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		return "";
 	}
 
-	protected void error(String message, EObject source, Keyword keyword, int index, String code) {
+	protected void error(String message, EObject source, Keyword keyword,
+			int index, String code) {
 		final String[] issueData = null;
 		ICompositeNode rootNode = NodeModelUtils.findActualNodeFor(source);
 		if (rootNode != null) {
-			INode child = findNode(source, false, rootNode, keyword, new int[] { index });
+			INode child = findNode(source, false, rootNode, keyword,
+					new int[] { index });
 			if (child != null) {
 				int offset = child.getTotalOffset();
 				int length = child.getTotalLength();
-				getMessageAcceptor().acceptError(message, source, offset, length, code, issueData);
+				getMessageAcceptor().acceptError(message, source, offset,
+						length, code, issueData);
 				return;
 			}
 		}
-		error(message, source, (EStructuralFeature) null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, code);
+		error(message, source, (EStructuralFeature) null,
+				ValidationMessageAcceptor.INSIGNIFICANT_INDEX, code);
 	}
 
 	protected void report(InferenceResult result, EStructuralFeature feature) {
@@ -405,7 +546,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 
 	}
 
-	private INode findNode(EObject source, boolean sourceFound, INode root, Keyword keyword, int[] index) {
+	private INode findNode(EObject source, boolean sourceFound, INode root,
+			Keyword keyword, int[] index) {
 		if (sourceFound && root.getSemanticElement() != source) {
 			return null;
 		}
@@ -416,7 +558,9 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		// .equals or == does not work because sub grammars use their own
 		// Modules with custom
 		// grammarAccess instance and .equals is not overwritten.
-		if (grammarElement instanceof Keyword && keyword.getValue().equals(((Keyword) grammarElement).getValue())) {
+		if (grammarElement instanceof Keyword
+				&& keyword.getValue().equals(
+						((Keyword) grammarElement).getValue())) {
 			if (index[0] != INSIGNIFICANT_INDEX) {
 				index[0]--;
 			}
@@ -427,7 +571,8 @@ public class STextJavaValidator extends AbstractSTextJavaValidator {
 		if (root instanceof ICompositeNode) {
 			ICompositeNode node = (ICompositeNode) root;
 			for (INode child : node.getChildren()) {
-				INode result = findNode(source, sourceFound, child, keyword, index);
+				INode result = findNode(source, sourceFound, child, keyword,
+						index);
 				if (result != null) {
 					return result;
 				}

+ 2 - 1
test-plugins/org.yakindu.sct.model.stext.test/META-INF/MANIFEST.MF

@@ -15,7 +15,8 @@ Require-Bundle: org.eclipse.xtext.junit4;bundle-version="2.0.1",
  org.eclipse.core.runtime,
  org.eclipse.ui.workbench;resolution:=optional,
  org.yakindu.sct.model.stext.resource;bundle-version="1.0.0",
- org.eclipse.gmf.runtime.emf.core;bundle-version="1.4.1"
+ org.eclipse.gmf.runtime.emf.core;bundle-version="1.4.1",
+ org.yakindu.sct.test.models;bundle-version="2.1.0"
 Export-Package: org.yakindu.sct.model.stext.test,
  org.yakindu.sct.model.stext.test.util,
  org.yakindu.sct.model.stext

+ 90 - 6
test-plugins/org.yakindu.sct.model.stext.test/src/org/yakindu/sct/model/stext/test/STextJavaValidatorTest.java

@@ -12,16 +12,26 @@
 package org.yakindu.sct.model.stext.test;
 
 import static org.eclipse.xtext.junit4.validation.AssertableDiagnostics.errorCode;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.yakindu.sct.model.stext.validation.STextJavaValidator.FEATURE_CALL_HAS_NO_EFFECT;
 import static org.yakindu.sct.model.stext.validation.STextJavaValidator.FEATURE_CALL_TO_SCOPE;
 import static org.yakindu.sct.model.stext.validation.STextJavaValidator.IN_OUT_DECLARATIONS;
 import static org.yakindu.sct.model.stext.validation.STextJavaValidator.LOCAL_DECLARATIONS;
 import static org.yakindu.sct.model.stext.validation.STextJavaValidator.LOCAL_REACTIONS_NOT_ALLOWED;
 import static org.yakindu.sct.model.stext.validation.STextJavaValidator.ONLY_ONE_INTERFACE;
+import static org.yakindu.sct.model.stext.validation.STextJavaValidator.TRANSITION_ENTRY_SPEC_NOT_COMPOSITE;
+import static org.yakindu.sct.model.stext.validation.STextJavaValidator.TRANSITION_UNBOUND_ENTRY_POINT;
+import static org.yakindu.sct.model.stext.validation.STextJavaValidator.REGION_UNBOUND_ENTRY_POINT;
 
 import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
 
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.xtext.junit4.InjectWith;
 import org.eclipse.xtext.junit4.XtextRunner;
@@ -33,7 +43,10 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.yakindu.sct.model.sgraph.Scope;
+import org.yakindu.sct.model.sgraph.State;
 import org.yakindu.sct.model.sgraph.Statechart;
+import org.yakindu.sct.model.sgraph.Synchronization;
+import org.yakindu.sct.model.sgraph.Transition;
 import org.yakindu.sct.model.stext.stext.Expression;
 import org.yakindu.sct.model.stext.stext.InterfaceScope;
 import org.yakindu.sct.model.stext.stext.InternalScope;
@@ -44,6 +57,7 @@ import org.yakindu.sct.model.stext.stext.TransitionSpecification;
 import org.yakindu.sct.model.stext.test.util.AbstractSTextTest;
 import org.yakindu.sct.model.stext.test.util.STextInjectorProvider;
 import org.yakindu.sct.model.stext.validation.STextJavaValidator;
+import org.yakindu.sct.test.models.AbstractTestModelsUtil;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
@@ -52,7 +66,8 @@ import com.google.inject.Inject;
 import com.google.inject.Injector;
 
 /**
- * @author andreas muelder - Initial contribution and API
+ * @author andreas muelder - Initial contribution and APIimport
+ *         org.yakindu.sct.model.sgraph.test.util.SGraphTestModelUtil;
  * 
  */
 @RunWith(XtextRunner.class)
@@ -63,7 +78,6 @@ public class STextJavaValidatorTest extends AbstractSTextTest {
 	private STextJavaValidator validator;
 	@Inject
 	private Injector injector;
-
 	private ValidatorTester<STextJavaValidator> tester;
 
 	@Before
@@ -109,18 +123,18 @@ public class STextJavaValidatorTest extends AbstractSTextTest {
 		validationResult = tester.validate(expression);
 		validationResult.assertOK();
 	}
-	
+
 	@Test
-	public void checkTimeEventSpecValueExpression(){
+	public void checkTimeEventSpecValueExpression() {
 		EObject expression = super.parseExpression("after true s",
 				ReactionTrigger.class.getSimpleName());
 		AssertableDiagnostics validationResult = tester.validate(expression);
 		validationResult
 				.assertErrorContains(STextJavaValidator.TIME_EXPRESSION);
 	}
-	
+
 	@Test
-	public void checkReactionEffectActionExpression(){
+	public void checkReactionEffectActionExpression() {
 		// covered by inferrer tests
 	}
 
@@ -365,4 +379,74 @@ public class STextJavaValidatorTest extends AbstractSTextTest {
 		}
 	}
 
+	@Test
+	public void checkEntrySpecOnAtomicState() {
+		BasicDiagnostic diagnostics = new BasicDiagnostic();
+		Statechart statechart = AbstractTestModelsUtil
+				.loadStatechart("UnboundEntryPoints01.sct");
+		Iterator<EObject> iter = statechart.eAllContents();
+		while (iter.hasNext()) {
+			EObject element = iter.next();
+			if (element instanceof Transition) {
+				assertTrue(validator.validate(element, diagnostics,
+						new HashMap<Object, Object>()));
+			}
+		}
+
+		assertIssueCount(diagnostics, 1);
+		assertWarning(diagnostics, TRANSITION_ENTRY_SPEC_NOT_COMPOSITE);
+	}
+
+	@Test
+	public void checkUnboundEntryPoints() {
+		BasicDiagnostic diagnostics = new BasicDiagnostic();
+		Statechart statechart = AbstractTestModelsUtil
+				.loadStatechart("UnboundEntryPoints02.sct");
+		Iterator<EObject> iter = statechart.eAllContents();
+		while (iter.hasNext()) {
+			EObject element = iter.next();
+			if (element instanceof Transition) {
+				validator.validate(element, diagnostics,
+						new HashMap<Object, Object>());
+			}
+			if (element instanceof State) {
+				validator.validate(element, diagnostics,
+						new HashMap<Object, Object>());
+			}
+		}
+
+		assertIssueCount(diagnostics, 4);
+		assertError(diagnostics, TRANSITION_UNBOUND_ENTRY_POINT);
+		assertError(diagnostics, REGION_UNBOUND_ENTRY_POINT);
+	}
+
+	protected void assertError(BasicDiagnostic diag, String message) {
+		Diagnostic d = issueByName(diag, message);
+		assertNotNull("Issue '" + message + "' does not exist.",
+				issueByName(diag, message));
+		assertEquals("Issue '" + message + "' is no error.", Diagnostic.ERROR,
+				d.getSeverity());
+	}
+
+	protected void assertWarning(BasicDiagnostic diag, String message) {
+		Diagnostic d = issueByName(diag, message);
+		assertNotNull("Issue '" + message + "' does not exist.",
+				issueByName(diag, message));
+		assertEquals("Issue '" + message + "' is no warning.",
+				Diagnostic.WARNING, d.getSeverity());
+	}
+
+	protected void assertIssueCount(BasicDiagnostic diag, int count) {
+		int c = diag.getChildren().size();
+		assertEquals("expected " + count + " issue(s) but were " + c + " ["
+				+ diag.toString() + "]", count, c);
+	}
+
+	protected Diagnostic issueByName(BasicDiagnostic diag, String message) {
+		for (Diagnostic issue : diag.getChildren()) {
+			if (message.equals(issue.getMessage()))
+				return issue;
+		}
+		return null;
+	}
 }

+ 101 - 0
test-plugins/org.yakindu.sct.test.models/testmodels/validation/UnboundEntryPoints01.sct

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:sgraph="http://www.yakindu.org/sct/sgraph/2.0.0">
+  <sgraph:Statechart xmi:id="_x651cKsyEeKkYoDxSIY5_A" name="UnboundEntryPoints">
+    <regions xmi:id="_x67DkqsyEeKkYoDxSIY5_A" name="main region">
+      <vertices xsi:type="sgraph:Entry" xmi:id="_x6_VA6syEeKkYoDxSIY5_A">
+        <outgoingTransitions xmi:id="_x7C_YasyEeKkYoDxSIY5_A" target="_N-dcMKv2EeKJqNG1GG2jEA"/>
+      </vertices>
+      <vertices xsi:type="sgraph:State" xmi:id="_ttT-MKszEeKkYoDxSIY5_A" specification="" name="B" incomingTransitions="_QhMesKv2EeKJqNG1GG2jEA"/>
+      <vertices xsi:type="sgraph:State" xmi:id="_N-dcMKv2EeKJqNG1GG2jEA" name="C" incomingTransitions="_x7C_YasyEeKkYoDxSIY5_A">
+        <outgoingTransitions xmi:id="_QhMesKv2EeKJqNG1GG2jEA" specification="# > enter" target="_ttT-MKszEeKkYoDxSIY5_A"/>
+      </vertices>
+    </regions>
+  </sgraph:Statechart>
+  <notation:Diagram xmi:id="_x67DkKsyEeKkYoDxSIY5_A" type="org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor" element="_x651cKsyEeKkYoDxSIY5_A" measurementUnit="Pixel">
+    <children xmi:id="_x684wKsyEeKkYoDxSIY5_A" type="Region" element="_x67DkqsyEeKkYoDxSIY5_A">
+      <children xsi:type="notation:DecorationNode" xmi:id="_x6-t8KsyEeKkYoDxSIY5_A" type="RegionName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_x6-t8asyEeKkYoDxSIY5_A"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_x6-t8qsyEeKkYoDxSIY5_A"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_x6_VAKsyEeKkYoDxSIY5_A" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
+        <children xmi:id="_x6_8EKsyEeKkYoDxSIY5_A" type="Entry" element="_x6_VA6syEeKkYoDxSIY5_A">
+          <children xmi:id="_x6_8E6syEeKkYoDxSIY5_A" type="BorderItemLabelContainer">
+            <children xsi:type="notation:DecorationNode" xmi:id="_x7AjIKsyEeKkYoDxSIY5_A" type="BorderItemLabel">
+              <styles xsi:type="notation:ShapeStyle" xmi:id="_x7AjIasyEeKkYoDxSIY5_A"/>
+              <layoutConstraint xsi:type="notation:Location" xmi:id="_x7AjIqsyEeKkYoDxSIY5_A"/>
+            </children>
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_x6_8FKsyEeKkYoDxSIY5_A" fontName="Verdana" lineColor="4210752"/>
+            <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x6_8FasyEeKkYoDxSIY5_A"/>
+          </children>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_x6_8EasyEeKkYoDxSIY5_A" fontName="Verdana" lineColor="4210752"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x7AjI6syEeKkYoDxSIY5_A" x="94" y="37" width="15" height="15"/>
+        </children>
+        <children xmi:id="_ttXBgKszEeKkYoDxSIY5_A" type="State" element="_ttT-MKszEeKkYoDxSIY5_A">
+          <children xsi:type="notation:DecorationNode" xmi:id="_ttY2sKszEeKkYoDxSIY5_A" type="StateName">
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_ttY2saszEeKkYoDxSIY5_A"/>
+            <layoutConstraint xsi:type="notation:Location" xmi:id="_ttY2sqszEeKkYoDxSIY5_A"/>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_ttY2s6szEeKkYoDxSIY5_A" type="StateTextCompartment">
+            <children xsi:type="notation:Shape" xmi:id="_ttY2tKszEeKkYoDxSIY5_A" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_ttY2taszEeKkYoDxSIY5_A"/>
+            </children>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_ttZdwKszEeKkYoDxSIY5_A" type="StateFigureCompartment"/>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_ttXBgaszEeKkYoDxSIY5_A" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
+          <styles xsi:type="notation:FontStyle" xmi:id="_ttXBgqszEeKkYoDxSIY5_A"/>
+          <styles xsi:type="notation:BooleanValueStyle" xmi:id="_ttZdwaszEeKkYoDxSIY5_A" name="isHorizontal" booleanValue="true"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_ttXokKszEeKkYoDxSIY5_A" x="219" y="102" width="40" height="53"/>
+        </children>
+        <children xmi:id="_N-hGkKv2EeKJqNG1GG2jEA" type="State" element="_N-dcMKv2EeKJqNG1GG2jEA">
+          <children xsi:type="notation:DecorationNode" xmi:id="_N-htoKv2EeKJqNG1GG2jEA" type="StateName">
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_N-htoav2EeKJqNG1GG2jEA"/>
+            <layoutConstraint xsi:type="notation:Location" xmi:id="_N-htoqv2EeKJqNG1GG2jEA"/>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_N-iUsKv2EeKJqNG1GG2jEA" type="StateTextCompartment">
+            <children xsi:type="notation:Shape" xmi:id="_N-iUsav2EeKJqNG1GG2jEA" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_N-iUsqv2EeKJqNG1GG2jEA"/>
+            </children>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_N-iUs6v2EeKJqNG1GG2jEA" type="StateFigureCompartment"/>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_N-hGkav2EeKJqNG1GG2jEA" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
+          <styles xsi:type="notation:FontStyle" xmi:id="_N-hGkqv2EeKJqNG1GG2jEA"/>
+          <styles xsi:type="notation:BooleanValueStyle" xmi:id="_N-i7wKv2EeKJqNG1GG2jEA" name="isHorizontal" booleanValue="true"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_N-hGk6v2EeKJqNG1GG2jEA" x="84" y="102" width="40" height="53"/>
+        </children>
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x6_VAasyEeKkYoDxSIY5_A"/>
+      </children>
+      <styles xsi:type="notation:ShapeStyle" xmi:id="_x684wasyEeKkYoDxSIY5_A" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x6_VAqsyEeKkYoDxSIY5_A" x="220" y="10" width="516" height="400"/>
+    </children>
+    <children xsi:type="notation:Shape" xmi:id="_x7E0kasyEeKkYoDxSIY5_A" type="StatechartText" fontName="Verdana" lineColor="4210752">
+      <children xsi:type="notation:DecorationNode" xmi:id="_x7FboKsyEeKkYoDxSIY5_A" type="StatechartName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_x7FboasyEeKkYoDxSIY5_A"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_x7FboqsyEeKkYoDxSIY5_A"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_x7Fbo6syEeKkYoDxSIY5_A" type="StatechartTextExpression" fontName="Verdana" lineColor="4210752">
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x7FbpKsyEeKkYoDxSIY5_A"/>
+      </children>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x7FbpasyEeKkYoDxSIY5_A" x="10" y="10" width="200" height="400"/>
+    </children>
+    <styles xsi:type="notation:DiagramStyle" xmi:id="_x67DkasyEeKkYoDxSIY5_A"/>
+    <edges xmi:id="_x7ENgKsyEeKkYoDxSIY5_A" type="Transition" element="_x7C_YasyEeKkYoDxSIY5_A" source="_x6_8EKsyEeKkYoDxSIY5_A" target="_N-hGkKv2EeKJqNG1GG2jEA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_x7ENhKsyEeKkYoDxSIY5_A" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_x7ENhasyEeKkYoDxSIY5_A"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_x7E0kKsyEeKkYoDxSIY5_A" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_x7ENgasyEeKkYoDxSIY5_A" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_x7ENg6syEeKkYoDxSIY5_A" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_x7ENgqsyEeKkYoDxSIY5_A" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
+    </edges>
+    <edges xmi:id="_QhO68Kv2EeKJqNG1GG2jEA" type="Transition" element="_QhMesKv2EeKJqNG1GG2jEA" source="_N-hGkKv2EeKJqNG1GG2jEA" target="_ttXBgKszEeKkYoDxSIY5_A">
+      <children xsi:type="notation:DecorationNode" xmi:id="_QhPiAqv2EeKJqNG1GG2jEA" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_QhPiA6v2EeKJqNG1GG2jEA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_QhPiBKv2EeKJqNG1GG2jEA" x="5" y="23"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_QhO68av2EeKJqNG1GG2jEA" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_QhPiAav2EeKJqNG1GG2jEA" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_QhPiAKv2EeKJqNG1GG2jEA" points="[18, -3, -178, 3]$[197, 97, 1, 103]"/>
+      <targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_QhRXMKv2EeKJqNG1GG2jEA" id="(0.013761467889908258,0.5992366412213741)"/>
+    </edges>
+  </notation:Diagram>
+</xmi:XMI>

+ 166 - 0
test-plugins/org.yakindu.sct.test.models/testmodels/validation/UnboundEntryPoints02.sct

@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:sgraph="http://www.yakindu.org/sct/sgraph/2.0.0">
+  <sgraph:Statechart xmi:id="_x651cKsyEeKkYoDxSIY5_A" name="UnboundEntryPoints">
+    <regions xmi:id="_x67DkqsyEeKkYoDxSIY5_A" name="main region">
+      <vertices xsi:type="sgraph:Entry" xmi:id="_x6_VA6syEeKkYoDxSIY5_A">
+        <outgoingTransitions xmi:id="_x7C_YasyEeKkYoDxSIY5_A" target="_N-dcMKv2EeKJqNG1GG2jEA"/>
+      </vertices>
+      <vertices xsi:type="sgraph:State" xmi:id="_ttT-MKszEeKkYoDxSIY5_A" specification="" name="B" incomingTransitions="_QhMesKv2EeKJqNG1GG2jEA _NaQ2EKwOEeKDK5u47htxww">
+        <regions xmi:id="_Ixvy0KwOEeKDK5u47htxww"/>
+        <regions xmi:id="_JE2VAKwOEeKDK5u47htxww"/>
+      </vertices>
+      <vertices xsi:type="sgraph:State" xmi:id="_N-dcMKv2EeKJqNG1GG2jEA" name="C" incomingTransitions="_x7C_YasyEeKkYoDxSIY5_A">
+        <outgoingTransitions xmi:id="_QhMesKv2EeKJqNG1GG2jEA" specification="" target="_ttT-MKszEeKkYoDxSIY5_A"/>
+        <outgoingTransitions xmi:id="_PCxsAKwOEeKDK5u47htxww" specification="" target="_ME3wcKwOEeKDK5u47htxww"/>
+      </vertices>
+      <vertices xsi:type="sgraph:State" xmi:id="_ME3wcKwOEeKDK5u47htxww" name="A" incomingTransitions="_PCxsAKwOEeKDK5u47htxww">
+        <outgoingTransitions xmi:id="_NaQ2EKwOEeKDK5u47htxww" specification="default" target="_ttT-MKszEeKkYoDxSIY5_A"/>
+      </vertices>
+    </regions>
+  </sgraph:Statechart>
+  <notation:Diagram xmi:id="_x67DkKsyEeKkYoDxSIY5_A" type="org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor" element="_x651cKsyEeKkYoDxSIY5_A" measurementUnit="Pixel">
+    <children xmi:id="_x684wKsyEeKkYoDxSIY5_A" type="Region" element="_x67DkqsyEeKkYoDxSIY5_A">
+      <children xsi:type="notation:DecorationNode" xmi:id="_x6-t8KsyEeKkYoDxSIY5_A" type="RegionName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_x6-t8asyEeKkYoDxSIY5_A"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_x6-t8qsyEeKkYoDxSIY5_A"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_x6_VAKsyEeKkYoDxSIY5_A" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
+        <children xmi:id="_x6_8EKsyEeKkYoDxSIY5_A" type="Entry" element="_x6_VA6syEeKkYoDxSIY5_A">
+          <children xmi:id="_x6_8E6syEeKkYoDxSIY5_A" type="BorderItemLabelContainer">
+            <children xsi:type="notation:DecorationNode" xmi:id="_x7AjIKsyEeKkYoDxSIY5_A" type="BorderItemLabel">
+              <styles xsi:type="notation:ShapeStyle" xmi:id="_x7AjIasyEeKkYoDxSIY5_A"/>
+              <layoutConstraint xsi:type="notation:Location" xmi:id="_x7AjIqsyEeKkYoDxSIY5_A"/>
+            </children>
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_x6_8FKsyEeKkYoDxSIY5_A" fontName="Verdana" lineColor="4210752"/>
+            <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x6_8FasyEeKkYoDxSIY5_A"/>
+          </children>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_x6_8EasyEeKkYoDxSIY5_A" fontName="Verdana" lineColor="4210752"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x7AjI6syEeKkYoDxSIY5_A" x="29" y="102" width="15" height="15"/>
+        </children>
+        <children xmi:id="_ttXBgKszEeKkYoDxSIY5_A" type="State" element="_ttT-MKszEeKkYoDxSIY5_A">
+          <children xsi:type="notation:DecorationNode" xmi:id="_ttY2sKszEeKkYoDxSIY5_A" type="StateName">
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_ttY2saszEeKkYoDxSIY5_A"/>
+            <layoutConstraint xsi:type="notation:Location" xmi:id="_ttY2sqszEeKkYoDxSIY5_A"/>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_ttY2s6szEeKkYoDxSIY5_A" type="StateTextCompartment">
+            <children xsi:type="notation:Shape" xmi:id="_ttY2tKszEeKkYoDxSIY5_A" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_ttY2taszEeKkYoDxSIY5_A"/>
+            </children>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_ttZdwKszEeKkYoDxSIY5_A" type="StateFigureCompartment">
+            <children xmi:id="_Ixy2IKwOEeKDK5u47htxww" type="Region" element="_Ixvy0KwOEeKDK5u47htxww">
+              <children xsi:type="notation:DecorationNode" xmi:id="_Ix0EQKwOEeKDK5u47htxww" type="RegionName">
+                <styles xsi:type="notation:ShapeStyle" xmi:id="_Ix0EQawOEeKDK5u47htxww"/>
+                <layoutConstraint xsi:type="notation:Location" xmi:id="_Ix0rUKwOEeKDK5u47htxww"/>
+              </children>
+              <children xsi:type="notation:Shape" xmi:id="_Ix0rUawOEeKDK5u47htxww" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
+                <layoutConstraint xsi:type="notation:Bounds" xmi:id="_Ix0rUqwOEeKDK5u47htxww"/>
+              </children>
+              <styles xsi:type="notation:ShapeStyle" xmi:id="_Ixy2IawOEeKDK5u47htxww" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_Ixy2IqwOEeKDK5u47htxww"/>
+            </children>
+            <children xmi:id="_JE4xQKwOEeKDK5u47htxww" type="Region" element="_JE2VAKwOEeKDK5u47htxww">
+              <children xsi:type="notation:DecorationNode" xmi:id="_JE4xQ6wOEeKDK5u47htxww" type="RegionName">
+                <styles xsi:type="notation:ShapeStyle" xmi:id="_JE4xRKwOEeKDK5u47htxww"/>
+                <layoutConstraint xsi:type="notation:Location" xmi:id="_JE5YUKwOEeKDK5u47htxww"/>
+              </children>
+              <children xsi:type="notation:Shape" xmi:id="_JE5YUawOEeKDK5u47htxww" type="RegionCompartment" fontName="Verdana" lineColor="4210752">
+                <layoutConstraint xsi:type="notation:Bounds" xmi:id="_JE5YUqwOEeKDK5u47htxww"/>
+              </children>
+              <styles xsi:type="notation:ShapeStyle" xmi:id="_JE4xQawOEeKDK5u47htxww" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_JE4xQqwOEeKDK5u47htxww"/>
+            </children>
+          </children>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_ttXBgaszEeKkYoDxSIY5_A" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
+          <styles xsi:type="notation:FontStyle" xmi:id="_ttXBgqszEeKkYoDxSIY5_A"/>
+          <styles xsi:type="notation:BooleanValueStyle" xmi:id="_ttZdwaszEeKkYoDxSIY5_A" name="isHorizontal" booleanValue="true"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_ttXokKszEeKkYoDxSIY5_A" x="214" y="57" width="266" height="246"/>
+        </children>
+        <children xmi:id="_N-hGkKv2EeKJqNG1GG2jEA" type="State" element="_N-dcMKv2EeKJqNG1GG2jEA">
+          <children xsi:type="notation:DecorationNode" xmi:id="_N-htoKv2EeKJqNG1GG2jEA" type="StateName">
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_N-htoav2EeKJqNG1GG2jEA"/>
+            <layoutConstraint xsi:type="notation:Location" xmi:id="_N-htoqv2EeKJqNG1GG2jEA"/>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_N-iUsKv2EeKJqNG1GG2jEA" type="StateTextCompartment">
+            <children xsi:type="notation:Shape" xmi:id="_N-iUsav2EeKJqNG1GG2jEA" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_N-iUsqv2EeKJqNG1GG2jEA"/>
+            </children>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_N-iUs6v2EeKJqNG1GG2jEA" type="StateFigureCompartment"/>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_N-hGkav2EeKJqNG1GG2jEA" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
+          <styles xsi:type="notation:FontStyle" xmi:id="_N-hGkqv2EeKJqNG1GG2jEA"/>
+          <styles xsi:type="notation:BooleanValueStyle" xmi:id="_N-i7wKv2EeKJqNG1GG2jEA" name="isHorizontal" booleanValue="true"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_N-hGk6v2EeKJqNG1GG2jEA" x="19" y="167" width="40" height="53"/>
+        </children>
+        <children xmi:id="_ME93EKwOEeKDK5u47htxww" type="State" element="_ME3wcKwOEeKDK5u47htxww">
+          <children xsi:type="notation:DecorationNode" xmi:id="_ME_sQKwOEeKDK5u47htxww" type="StateName">
+            <styles xsi:type="notation:ShapeStyle" xmi:id="_ME_sQawOEeKDK5u47htxww"/>
+            <layoutConstraint xsi:type="notation:Location" xmi:id="_ME_sQqwOEeKDK5u47htxww"/>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_MFA6YKwOEeKDK5u47htxww" type="StateTextCompartment">
+            <children xsi:type="notation:Shape" xmi:id="_MFBhcKwOEeKDK5u47htxww" type="StateTextCompartmentExpression" fontName="Verdana" lineColor="4210752">
+              <layoutConstraint xsi:type="notation:Bounds" xmi:id="_MFBhcawOEeKDK5u47htxww"/>
+            </children>
+          </children>
+          <children xsi:type="notation:Compartment" xmi:id="_MFCIgKwOEeKDK5u47htxww" type="StateFigureCompartment"/>
+          <styles xsi:type="notation:ShapeStyle" xmi:id="_ME93EawOEeKDK5u47htxww" fontName="Verdana" fillColor="15981773" lineColor="12632256"/>
+          <styles xsi:type="notation:FontStyle" xmi:id="_ME93EqwOEeKDK5u47htxww"/>
+          <styles xsi:type="notation:BooleanValueStyle" xmi:id="_MFCIgawOEeKDK5u47htxww" name="isHorizontal" booleanValue="true"/>
+          <layoutConstraint xsi:type="notation:Bounds" xmi:id="_ME93E6wOEeKDK5u47htxww" x="19" y="250"/>
+        </children>
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x6_VAasyEeKkYoDxSIY5_A"/>
+      </children>
+      <styles xsi:type="notation:ShapeStyle" xmi:id="_x684wasyEeKkYoDxSIY5_A" fontName="Verdana" fillColor="15790320" lineColor="12632256"/>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x6_VAqsyEeKkYoDxSIY5_A" x="220" y="10" width="521" height="400"/>
+    </children>
+    <children xsi:type="notation:Shape" xmi:id="_x7E0kasyEeKkYoDxSIY5_A" type="StatechartText" fontName="Verdana" lineColor="4210752">
+      <children xsi:type="notation:DecorationNode" xmi:id="_x7FboKsyEeKkYoDxSIY5_A" type="StatechartName">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_x7FboasyEeKkYoDxSIY5_A"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_x7FboqsyEeKkYoDxSIY5_A"/>
+      </children>
+      <children xsi:type="notation:Shape" xmi:id="_x7Fbo6syEeKkYoDxSIY5_A" type="StatechartTextExpression" fontName="Verdana" lineColor="4210752">
+        <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x7FbpKsyEeKkYoDxSIY5_A"/>
+      </children>
+      <layoutConstraint xsi:type="notation:Bounds" xmi:id="_x7FbpasyEeKkYoDxSIY5_A" x="10" y="10" width="200" height="400"/>
+    </children>
+    <styles xsi:type="notation:DiagramStyle" xmi:id="_x67DkasyEeKkYoDxSIY5_A"/>
+    <edges xmi:id="_x7ENgKsyEeKkYoDxSIY5_A" type="Transition" element="_x7C_YasyEeKkYoDxSIY5_A" source="_x6_8EKsyEeKkYoDxSIY5_A" target="_N-hGkKv2EeKJqNG1GG2jEA">
+      <children xsi:type="notation:DecorationNode" xmi:id="_x7ENhKsyEeKkYoDxSIY5_A" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_x7ENhasyEeKkYoDxSIY5_A"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_x7E0kKsyEeKkYoDxSIY5_A" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_x7ENgasyEeKkYoDxSIY5_A" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_x7ENg6syEeKkYoDxSIY5_A" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_x7ENgqsyEeKkYoDxSIY5_A" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
+    </edges>
+    <edges xmi:id="_QhO68Kv2EeKJqNG1GG2jEA" type="Transition" element="_QhMesKv2EeKJqNG1GG2jEA" source="_N-hGkKv2EeKJqNG1GG2jEA" target="_ttXBgKszEeKkYoDxSIY5_A">
+      <children xsi:type="notation:DecorationNode" xmi:id="_QhPiAqv2EeKJqNG1GG2jEA" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_QhPiA6v2EeKJqNG1GG2jEA"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_QhPiBKv2EeKJqNG1GG2jEA" x="5" y="23"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_QhO68av2EeKJqNG1GG2jEA" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_QhPiAav2EeKJqNG1GG2jEA" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_QhPiAKv2EeKJqNG1GG2jEA" points="[18, -3, -178, 3]$[197, 97, 1, 103]"/>
+      <targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_QhRXMKv2EeKJqNG1GG2jEA" id="(0.013761467889908258,0.5992366412213741)"/>
+    </edges>
+    <edges xmi:id="_NaT5YKwOEeKDK5u47htxww" type="Transition" element="_NaQ2EKwOEeKDK5u47htxww" source="_ME93EKwOEeKDK5u47htxww" target="_ttXBgKszEeKkYoDxSIY5_A">
+      <children xsi:type="notation:DecorationNode" xmi:id="_NaUgcKwOEeKDK5u47htxww" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_NaUgcawOEeKDK5u47htxww"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_NaUgcqwOEeKDK5u47htxww" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_NaT5YawOEeKDK5u47htxww" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_NaT5Y6wOEeKDK5u47htxww" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_NaT5YqwOEeKDK5u47htxww" points="[18, -7, -162, 5]$[181, 24, 1, 36]"/>
+      <targetAnchor xsi:type="notation:IdentityAnchor" xmi:id="_NaW8sKwOEeKDK5u47htxww" id="(0.011278195488721804,0.8821138211382114)"/>
+    </edges>
+    <edges xmi:id="_PC3yoKwOEeKDK5u47htxww" type="Transition" element="_PCxsAKwOEeKDK5u47htxww" source="_N-hGkKv2EeKJqNG1GG2jEA" target="_ME93EKwOEeKDK5u47htxww">
+      <children xsi:type="notation:DecorationNode" xmi:id="_PC5AwKwOEeKDK5u47htxww" type="TransitionExpression">
+        <styles xsi:type="notation:ShapeStyle" xmi:id="_PC5AwawOEeKDK5u47htxww"/>
+        <layoutConstraint xsi:type="notation:Location" xmi:id="_PC5AwqwOEeKDK5u47htxww" y="10"/>
+      </children>
+      <styles xsi:type="notation:ConnectorStyle" xmi:id="_PC3yoawOEeKDK5u47htxww" lineColor="4210752"/>
+      <styles xsi:type="notation:FontStyle" xmi:id="_PC4ZsKwOEeKDK5u47htxww" fontName="Verdana"/>
+      <bendpoints xsi:type="notation:RelativeBendpoints" xmi:id="_PC3yoqwOEeKDK5u47htxww" points="[-2, 24, -2, -59]$[-2, 59, -2, -24]"/>
+    </edges>
+  </notation:Diagram>
+</xmi:XMI>