コード例 #1
0
 /**
  * Retrieves the target from an entry. TODO: validation of preconditions for entry targets e.g
  * every region needs an entry with appropriate target
  */
 public State target(final Entry entry) {
   State _xifexpression = null;
   EList<Transition> _outgoingTransitions =
       entry == null ? (EList<Transition>) null : entry.getOutgoingTransitions();
   boolean _notEquals = (!Objects.equal(_outgoingTransitions, null));
   if (_notEquals) {
     State _xifexpression_1 = null;
     EList<Transition> _outgoingTransitions_1 = entry.getOutgoingTransitions();
     int _size = _outgoingTransitions_1.size();
     boolean _greaterThan = (_size > 0);
     if (_greaterThan) {
       State _xblockexpression = null;
       {
         EList<Transition> _outgoingTransitions_2 = entry.getOutgoingTransitions();
         Transition _get = _outgoingTransitions_2.get(0);
         final Vertex target = _get.getTarget();
         State _xifexpression_2 = null;
         if ((target instanceof State)) {
           _xifexpression_2 = ((State) target);
         }
         _xblockexpression = (_xifexpression_2);
       }
       _xifexpression_1 = _xblockexpression;
     }
     _xifexpression = _xifexpression_1;
   }
   return _xifexpression;
 }
コード例 #2
0
  protected void createEntryPoint(Edge edge, Diagram subdiagram) {
    Transition transition = (Transition) edge.getElement();
    Region entryPointContainer = getEntryPointContainer(transition);
    Entry entryPoint = createSemanticEntryPoint(transition);

    // re-wire old transition to targeting the selected state
    transition.setTarget((State) subdiagram.getElement());
    View oldTarget = edge.getTarget();
    edge.setTarget(getContextObject());

    // create node for entry point
    View entryPointContainerView =
        helper.getViewForSemanticElement(entryPointContainer, subdiagram);
    View entryPointRegionCompartment =
        ViewUtil.getChildBySemanticHint(entryPointContainerView, SemanticHints.REGION_COMPARTMENT);
    Node entryNode =
        ViewService.createNode(
            entryPointRegionCompartment, entryPoint, SemanticHints.ENTRY, preferencesHint);
    ViewService.createEdge(
        entryNode,
        oldTarget,
        entryPoint.getOutgoingTransitions().get(0),
        SemanticHints.TRANSITION,
        preferencesHint);

    addEntryPointSpec(transition, entryPoint);
  }
コード例 #3
0
 @Check(CheckType.FAST)
 public void disallowTrigger(Entry entry) {
   for (Transition transition : entry.getOutgoingTransitions()) {
     if (transition.getTrigger() != null) {
       error(ISSUE_ENTRY_WITH_TRIGGER, entry, null, -1);
     }
   }
 }
コード例 #4
0
 @Check(CheckType.FAST)
 public void checkExitPointSpecWithTrigger(Transition t) {
   if (!STextValidationModelUtils.getExitPointSpecs(t.getProperties()).isEmpty()
       && t.getTrigger() != null
       && t.getSource() instanceof org.yakindu.sct.model.sgraph.State) {
     error(EXITPOINTSPEC_WITH_TRIGGER, t, null, -1);
   }
 }
コード例 #5
0
 protected String getExitPointName(Transition transition) {
   StringBuilder stringBuilder = new StringBuilder();
   stringBuilder.append("exit_");
   stringBuilder.append(transition.getSource().getName());
   int index = transition.getSource().getOutgoingTransitions().indexOf(transition);
   stringBuilder.append(index);
   return stringBuilder.toString();
 }
コード例 #6
0
  /**
   * If a time trigger is defined for a transition then an event must be introduced into the
   * execution flow.
   */
  @Test
  public void testSingleTransitionTimeTrigger() {

    Statechart sc = _createStatechart("test");
    Scope scope = _createInterfaceScope("interface", sc);
    VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER, scope);
    Region r = _createRegion("main", sc);
    State s = _createState("s", r);

    Transition t = _createTransition(s, s);
    ReactionTrigger tr1 = _createReactionTrigger(t);
    _createTimeEventSpec(TimeEventType.AFTER, _createValue(1), TimeUnit.SECOND, tr1);

    AssignmentExpression assign =
        _createVariableAssignment(
            v1, AssignmentOperator.ASSIGN, _createValue(42), (ReactionEffect) t.getEffect());

    ExecutionFlow flow = sequencer.transform(sc);

    // assert definition of time event
    Scope timerScope = flow.getScopes().get(1);
    assertTrue(timerScope.getDeclarations().get(0) instanceof TimeEvent);

    TimeEvent te = (TimeEvent) timerScope.getDeclarations().get(0);

    // assert that the reaction check checks the time event
    assertEquals(1, flow.getStates().size());
    ExecutionState _s = flow.getStates().get(0);
    assertEquals(s.getName(), _s.getSimpleName());
    If _if =
        (If)
            SCTTestUtil.flattenSequenceStepsAsList(flow.getStates().get(0).getReactSequence())
                .get(0);

    ElementReferenceExpression _ere = (ElementReferenceExpression) _if.getCheck().getCondition();
    assertSame(te, _ere.getReference());

    // assert the scheduling of the time event during state entry
    assertNotNull(_s.getEntryAction());
    Sequence entryAction = (Sequence) _s.getEntryAction();
    ScheduleTimeEvent ste = (ScheduleTimeEvent) entryAction.getSteps().get(0);
    assertSame(te, ste.getTimeEvent());
    NumericalMultiplyDivideExpression multiply =
        (NumericalMultiplyDivideExpression) ste.getTimeValue();
    assertIntLiteral(1, ((PrimitiveValueExpression) multiply.getLeftOperand()).getValue());
    assertIntLiteral(1000, ((PrimitiveValueExpression) multiply.getRightOperand()).getValue());
    assertEquals(MultiplicativeOperator.MUL, multiply.getOperator());

    // assert the unscheduling of the time events during state exit
    assertNotNull(_s.getExitAction());
    Sequence exitAction = (Sequence) _s.getExitAction();
    UnscheduleTimeEvent ute = (UnscheduleTimeEvent) exitAction.getSteps().get(0);
    assertSame(te, ute.getTimeEvent());
  }
コード例 #7
0
  @Check(CheckType.FAST)
  public void checkUnboundEntryPoints(final org.yakindu.sct.model.sgraph.State state) {
    if (state.isComposite()) {
      final List<Transition>[] transitions =
          STextValidationModelUtils.getEntrySpecSortedTransitions(state.getIncomingTransitions());
      Map<Region, List<Entry>> regions = null;

      // first list contains Transitions without entry spec
      if (!transitions[0].isEmpty()) {
        regions = STextValidationModelUtils.getRegionsWithoutDefaultEntry(state.getRegions());
        if (!regions.isEmpty()) {
          for (Transition transition : transitions[0]) {
            error(TRANSITION_UNBOUND_DEFAULT_ENTRY_POINT, transition, null, -1);
          }
          for (Region region : regions.keySet()) {
            error(REGION_UNBOUND_DEFAULT_ENTRY_POINT, region, null, -1);
          }
        }
      }

      // second list contains Transitions with entry spec
      if (!transitions[1].isEmpty()) {
        if (regions == null) {
          regions = STextValidationModelUtils.getRegionsWithoutDefaultEntry(state.getRegions());
        }
        for (Transition transition : transitions[1]) {
          boolean hasTargetEntry = true;
          for (ReactionProperty property : transition.getProperties()) {
            if (property instanceof EntryPointSpec) {
              EntryPointSpec spec = (EntryPointSpec) property;
              String specName = "'" + spec.getEntrypoint() + "'";
              for (Region region : regions.keySet()) {
                boolean hasEntry = false;
                for (Entry entry : regions.get(region)) {
                  if (entry.getName().equals(spec.getEntrypoint())) {
                    hasEntry = true;
                    break;
                  }
                }
                if (!hasEntry) {
                  error(REGION_UNBOUND_NAMED_ENTRY_POINT + specName, region, null, -1);
                  hasTargetEntry = false;
                }
              }
              if (!hasTargetEntry) {
                error(TRANSITION_UNBOUND_NAMED_ENTRY_POINT + specName, transition, null, -1);
              }
            }
          }
        }
      }
    }
  }
コード例 #8
0
  @Check(CheckType.FAST)
  public void checkTransitionPropertySpec(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);
          }
        }
      } else if (property instanceof ExitPointSpec) {
        final ExitPointSpec exitPointSpec = (ExitPointSpec) property;
        if (transition.getSource() instanceof org.yakindu.sct.model.sgraph.State) {
          org.yakindu.sct.model.sgraph.State state =
              (org.yakindu.sct.model.sgraph.State) transition.getSource();
          if (!state.isComposite()) {
            warning(TRANSITION_EXIT_SPEC_NOT_COMPOSITE, transition, null, -1);
          } else {
            // Validate an exit point is continued on one transition
            // only.
            for (Transition t : state.getOutgoingTransitions()) {
              if (transition != t
                  && STextValidationModelUtils.isNamedExitTransition(
                      t, exitPointSpec.getExitpoint())) {
                warning(TRANSITION_EXIT_SPEC_ON_MULTIPLE_SIBLINGS, transition, null, -1);
              }
            }

            // Validate the state has minimally one named exit
            // region

            boolean hasExit = false;
            Iterator<Region> regionIter = state.getRegions().iterator();
            while (regionIter.hasNext() && !hasExit) {

              Iterator<Exit> exitIter =
                  STextValidationModelUtils.getExits(regionIter.next().eContents()).iterator();
              while (exitIter.hasNext() && !hasExit) {
                Exit exit = exitIter.next();
                hasExit = exitPointSpec.getExitpoint().equals(exit.getName());
              }
            }
            if (!hasExit) {
              error(TRANSITION_NOT_EXISTING_NAMED_EXIT_POINT, transition, null, -1);
            }
          }
        }
      }
    }
  }
コード例 #9
0
 @Check
 public void checkChoiceWithoutDefaultTransition(final Choice choice) {
   boolean found = false;
   for (Transition transition : choice.getOutgoingTransitions()) {
     Trigger trigger = transition.getTrigger();
     if (isDefault(trigger)) {
       found = true;
     }
   }
   if (!found)
     warning(
         CHOICE_ONE_OUTGOING_DEFAULT_TRANSITION,
         SGraphPackage.Literals.VERTEX__OUTGOING_TRANSITIONS);
 }
コード例 #10
0
  @Check
  public void orthogonalTransition(Transition transition) {

    Vertex source = transition.getSource();
    Vertex target = transition.getTarget();

    if ((source instanceof Synchronization) || (target instanceof Synchronization))
      return; // ... the check does not apply.

    EObject commonAncestor = commonAncestor(source, target);

    if (commonAncestor instanceof CompositeElement) {

      error(ISSUE_TRANSITION_ORTHOGONAL, transition, null, -1);
    }
  }
コード例 #11
0
 @Override
 protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info)
     throws ExecutionException {
   if (!canExecute()) {
     throw new ExecutionException("Invalid arguments in create link command");
   }
   if (getSource() != null && getTarget() != null) {
     Transition transition = SGraphFactory.eINSTANCE.createTransition();
     source.getOutgoingTransitions().add(transition);
     transition.setSource(source);
     transition.setTarget(target);
     source.getOutgoingTransitions().add(transition);
     target.getIncomingTransitions().add(transition);
     ((CreateElementRequest) getRequest()).setNewElement(transition);
   }
   return CommandResult.newOKCommandResult();
 }
コード例 #12
0
  @Test
  public void testTransitionCheckSequenceWithGuard() {

    EventDefinition e1 = _createEventDefinition("e1", null);
    EventDefinition e2 = _createEventDefinition("e2", null);

    ReactionTrigger tr1 = _createReactionTrigger(null);
    _createRegularEventSpec(e1, tr1);
    _createRegularEventSpec(e2, tr1);

    PrimitiveValueExpression exp = _createValue(false);
    tr1.setGuard(createGuardExpression(exp));

    Transition t = SGraphFactory.eINSTANCE.createTransition();
    t.setTrigger(tr1);

    Statechart sc = _createStatechart("test");
    Region region = _createRegion("r1", sc);
    t.setSource(_createState("A", region));
    t.setTarget(_createState("B", region));

    Reaction reaction = behaviorMapping.mapTransition(t);

    // now check the expression structure ...

    // the root is an and condition with the trigger check as the first
    // (left) part and the guard as the right (second) part.
    LogicalAndExpression and = (LogicalAndExpression) reaction.getCheck().getCondition();
    LogicalOrExpression triggerCheck = (LogicalOrExpression) and.getLeftOperand();
    PrimitiveValueExpression guardCheck = (PrimitiveValueExpression) and.getRightOperand();

    assertClass(ElementReferenceExpression.class, triggerCheck.getLeftOperand());
    assertClass(ElementReferenceExpression.class, triggerCheck.getRightOperand());
    assertEquals(
        e1.getName(),
        ((NamedElement) ((ElementReferenceExpression) triggerCheck.getLeftOperand()).getReference())
            .getName());
    assertEquals(
        e2.getName(),
        ((NamedElement)
                ((ElementReferenceExpression) triggerCheck.getRightOperand()).getReference())
            .getName());

    assertBoolLiteral(false, guardCheck.getValue());
  }
コード例 #13
0
  @Test
  public void testTransitionCheckSequenceWithoutGuard() {

    EventDefinition e1 = _createEventDefinition("e1", null);
    EventDefinition e2 = _createEventDefinition("e2", null);

    ReactionTrigger tr1 = _createReactionTrigger(null);
    _createRegularEventSpec(e1, tr1);
    _createRegularEventSpec(e2, tr1);

    Transition t = SGraphFactory.eINSTANCE.createTransition();
    t.setTrigger(tr1);

    Statechart sc = _createStatechart("test");
    Region region = _createRegion("r1", sc);
    t.setSource(_createState("A", region));
    t.setTarget(_createState("B", region));

    Reaction reaction = behaviorMapping.mapTransition(t);

    assertTrue(reaction.getCheck().getCondition() instanceof LogicalOrExpression);
    assertClass(
        ElementReferenceExpression.class,
        ((LogicalOrExpression) reaction.getCheck().getCondition()).getLeftOperand());
    assertClass(
        ElementReferenceExpression.class,
        ((LogicalOrExpression) reaction.getCheck().getCondition()).getRightOperand());

    assertEquals(
        e1.getName(),
        ((NamedElement)
                ((ElementReferenceExpression)
                        ((LogicalOrExpression) reaction.getCheck().getCondition()).getLeftOperand())
                    .getReference())
            .getName());
    assertEquals(
        e2.getName(),
        ((NamedElement)
                ((ElementReferenceExpression)
                        ((LogicalOrExpression) reaction.getCheck().getCondition())
                            .getRightOperand())
                    .getReference())
            .getName());
  }
コード例 #14
0
  /** The enter sequence must be called withnin incoming transitions. */
  @SuppressWarnings("unused")
  @Test
  public void testFinalStateEnterSequenceCall() {

    Statechart sc = _createStatechart("sc");
    {
      InterfaceScope s_scope = _createInterfaceScope("Interface", sc);
      VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER, s_scope);
      EventDefinition e1 = _createEventDefinition("e1", s_scope);

      Region r = _createRegion("r", sc);
      {
        State s1 = _createState("s1", r);

        FinalState fs = _createFinalState(r);

        Transition t_s1_fs = _createTransition(s1, fs);
        _createReactionTrigger(t_s1_fs);
        _createRegularEventSpec(e1, (ReactionTrigger) t_s1_fs.getTrigger());
      }
    }

    ExecutionFlow flow = sequencer.transform(sc);

    ExecutionState _s1 = flow.getStates().get(0);
    assertEquals("sc.r.s1", _s1.getName());

    ExecutionState _fs = flow.getStates().get(1);
    assertEquals("sc.r._final_", _fs.getName());

    assertNull(_fs.getEntryAction());
    assertNull(_fs.getExitAction());

    // the transition s1 -> fs must includes the fs exit sequence call
    Sequence cycle = _s1.getReactSequence();
    If _if = (If) SCTTestUtil.flattenSequenceStepsAsList(cycle).get(0);
    assertCall(_if.getThenStep(), _s1.getReactions().get(0).getEffect());

    Sequence _seq = (Sequence) _s1.getReactions().get(0).getEffect();
    assertCall(_seq, 1, _fs.getEnterSequences().get(0));
  }
コード例 #15
0
 private void addExitPointSpec(Transition transition, Exit exitPoint) {
   EList<ReactionProperty> properties = transition.getProperties();
   ExitPointSpec exitPointSpec = StextFactory.eINSTANCE.createExitPointSpec();
   // A transition can only have one exit point so alter the existing
   for (ReactionProperty reactionProperty : properties) {
     if (reactionProperty instanceof ExitPointSpec) {
       exitPointSpec = (ExitPointSpec) reactionProperty;
     }
   }
   exitPointSpec.setExitpoint(exitPoint.getName());
   properties.add(exitPointSpec);
 }
コード例 #16
0
  protected void createExitPoint(Edge edge, Diagram subdiagram) {
    Transition transition = (Transition) edge.getElement();
    // create semantic exit point
    Region exitPointContainer = getExitPointContainer(transition);
    Exit exitPoint = createSemanticExitPoint(transition);

    // create node for exit point
    View exitPointContainerView = helper.getViewForSemanticElement(exitPointContainer, subdiagram);
    View exitPointRegionCompartment =
        ViewUtil.getChildBySemanticHint(exitPointContainerView, SemanticHints.REGION_COMPARTMENT);
    Node exitNode =
        ViewService.createNode(
            exitPointRegionCompartment, exitPoint, SemanticHints.EXIT, preferencesHint);

    // re-wire existing transition to new exit point
    Vertex oldTarget = transition.getTarget();
    transition.setTarget(exitPoint);
    ViewService.createEdge(
        edge.getSource(), exitNode, transition, SemanticHints.TRANSITION, preferencesHint);

    // create transition from selected state to former transition target
    Transition exitPointTransition = SGraphFactory.eINSTANCE.createTransition();
    exitPointTransition.setSource((State) subdiagram.getElement());
    exitPointTransition.setTarget(oldTarget);
    ViewService.createEdge(
        getContextObject(),
        edge.getTarget(),
        exitPointTransition,
        SemanticHints.TRANSITION,
        preferencesHint);

    addExitPointSpec(exitPointTransition, exitPoint);
  }
コード例 #17
0
  @Check(CheckType.FAST)
  public void transitionsWithNoTrigger(Transition trans) {
    if (trans.getSource() instanceof Entry
        || trans.getSource() instanceof Choice
        || trans.getSource() instanceof Synchronization) {
      return;
    }
    if (trans.getSource() instanceof org.yakindu.sct.model.sgraph.State) {
      org.yakindu.sct.model.sgraph.State state =
          (org.yakindu.sct.model.sgraph.State) trans.getSource();
      if (state.isComposite()) {
        for (Region r : state.getRegions()) {
          for (Vertex v : r.getVertices()) {
            if (v instanceof Exit) {
              return;
            }
          }
        }
      }
    }

    if (!STextValidationModelUtils.getExitPointSpecs(trans.getProperties()).isEmpty()) {
      return;
    }

    if (trans.getTrigger() == null) {
      warning(ISSUE_TRANSITION_WITHOUT_TRIGGER, trans, null, -1);
    }
  }
コード例 #18
0
  @Check
  public void orthogonalSynchronizedTransition(Synchronization sync) {

    List<Transition> incoming = sync.getIncomingTransitions();
    List<List<EObject>> inAncestorsList = new ArrayList<List<EObject>>();
    for (Transition trans : incoming) {
      inAncestorsList.add(collectAncestors(trans.getSource(), new ArrayList<EObject>()));
    }

    List<Transition> outgoing = sync.getOutgoingTransitions();
    List<List<EObject>> outAncestorsList = new ArrayList<List<EObject>>();
    for (Transition trans : outgoing) {
      outAncestorsList.add(collectAncestors(trans.getTarget(), new ArrayList<EObject>()));
    }

    Set<Transition> inOrthogonal = new HashSet<Transition>(incoming);
    Set<Transition> outOrthogonal = new HashSet<Transition>(outgoing);

    for (int i = 0; i < incoming.size(); i++) {
      for (int j = 0; j < outgoing.size(); j++) {

        EObject commonAncestor =
            findCommonAncestor(inAncestorsList.get(i), outAncestorsList.get(j));

        if (commonAncestor instanceof Region) {
          inOrthogonal.remove(incoming.get(i));
          outOrthogonal.remove(outgoing.get(j));
        }
      }
    }

    for (Transition trans : inOrthogonal) {
      error(ISSUE_SYNCHRONIZATION_SOURCE_STATES_NOT_WITHIN_SAME_PARENTSTATE, trans, null, -1);
    }

    for (Transition trans : outOrthogonal) {
      error(ISSUE_SYNCHRONIZATION_TARGET_STATES_NOT_WITHIN_SAME_PARENTSTATE, trans, null, -1);
    }
  }
コード例 #19
0
  protected Entry createSemanticEntryPoint(Transition transition) {
    Region entryPointTarget = getEntryPointContainer(transition);
    String name = getEntryPointName(transition);
    Entry entryPoint = null;
    Iterator<Vertex> iterator = entryPointTarget.getVertices().iterator();
    while (iterator.hasNext()) {
      Vertex next = iterator.next();
      if (next instanceof Entry) {
        Entry current = (Entry) next;
        if (name.equals(current.getName())) {
          // Do nothing, there already exists an entry point
          return current;
        }
      }
    }
    entryPoint = SGraphFactory.eINSTANCE.createEntry();
    entryPoint.setName(name);
    entryPointTarget.getVertices().add(entryPoint);
    Transition entryPointTransition = SGraphFactory.eINSTANCE.createTransition();
    entryPointTransition.setSource(entryPoint);
    entryPointTransition.setTarget(transition.getTarget());

    return entryPoint;
  }
コード例 #20
0
  @Test
  public void testTransitionCheckSequenceWithoutTrigger() {

    ReactionTrigger tr1 = _createReactionTrigger(null);
    PrimitiveValueExpression exp = _createValue(false);
    tr1.setGuard(createGuardExpression(exp));

    Transition t = SGraphFactory.eINSTANCE.createTransition();
    t.setTrigger(tr1);

    Statechart sc = _createStatechart("test");
    Region region = _createRegion("r1", sc);
    t.setSource(_createState("A", region));
    t.setTarget(_createState("B", region));

    Reaction reaction = behaviorMapping.mapTransition(t);

    // now check the expression structure ...

    // the root is an and condition with the trigger check as the first
    // (left) part and the guard as the right (second) part.
    PrimitiveValueExpression guard = (PrimitiveValueExpression) reaction.getCheck().getCondition();
    assertBoolLiteral(false, guard.getValue());
  }
コード例 #21
0
 public static Transition _createTransition(Vertex source, Vertex target) {
   Transition t = SGraphFactory.eINSTANCE.createTransition();
   t.setSource(source);
   t.setTarget(target);
   return t;
 }
コード例 #22
0
 private Region getExitPointContainer(Transition transition) {
   // exit point container is the subdiagram's state's region which
   // contains the transition source
   EObject firstParentRegion = transition.getSource().getParentRegion();
   return getOutermostParentRegion(firstParentRegion);
 }
コード例 #23
0
 private Region getEntryPointContainer(Transition transition) {
   // entry point container is the subdiagram's state's region which
   // contains the transition target
   EObject firstParentRegion = transition.getTarget().getParentRegion();
   return getOutermostParentRegion(firstParentRegion);
 }
コード例 #24
0
 @Check(CheckType.FAST)
 public void initialEntryWithTransitionToContainer(Transition t) {
   if (t.getSource() instanceof Entry && !isChildOrSibling(t.getSource(), t.getTarget())) {
     error(ISSUE_INITIAL_ENTRY_WITH_TRANSITION_TO_CONTAINER, t, null, -1);
   }
 }
コード例 #25
0
  /** The state cycle must contain all reactions of parent states. */
  @SuppressWarnings("unused")
  @Test
  public void testStateCycle_WithParent() {

    Statechart sc = _createStatechart("sc");
    {
      InterfaceScope s_scope = _createInterfaceScope("Interface", sc);
      VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER, s_scope);
      EventDefinition e1 = _createEventDefinition("e1", s_scope);

      Region r = _createRegion("r", sc);
      {
        State s1 = _createState("s1", r);
        {
          // a local reaction: "e1 / x=42;"
          LocalReaction lr1 = _createLocalReaction(s1, null);
          _createRegularEventSpec(e1, (ReactionTrigger) lr1.getTrigger());
          ReactionEffect lr1_eff = _createReactionEffect(lr1);
          AssignmentExpression assign1 =
              _createVariableAssignment(v1, AssignmentOperator.ASSIGN, _createValue(42), lr1_eff);

          Region r_s1 = _createRegion("r", s1);
          {
            State s3 = _createState("s3", r_s1);
            {
              _createEntryAssignment(v1, s3, 2);

              Region r_s3 = _createRegion("r", s3);
              {
                State s4 = _createState("s4", r_s3);
                _createEntryAssignment(v1, s4, 3);

                State s5 = _createState("s5", r_s3);
              }
            }
          }
        }
        State s2 = _createState("s2", r);
        {
          Region r_s1 = _createRegion("r", s2);
          {
            _createState("s6", r_s1);
          }
        }
      }

      Transition t_s4_s5 = _createTransition(findState(sc, "s4"), findState(sc, "s5"));
      _createReactionTrigger(t_s4_s5);
      _createRegularEventSpec(e1, (ReactionTrigger) t_s4_s5.getTrigger());

      Transition t_s3_s6 = _createTransition(findState(sc, "s3"), findState(sc, "s6"));
      _createReactionTrigger(t_s3_s6);
      _createRegularEventSpec(e1, (ReactionTrigger) t_s3_s6.getTrigger());
    }

    ExecutionFlow flow = sequencer.transform(sc);

    ExecutionState _s1 = flow.getStates().get(0);
    assertEquals("sc.r.s1", _s1.getName());

    ExecutionState _s3 = flow.getStates().get(1);
    assertEquals("sc.r.s1.r.s3", _s3.getName());

    ExecutionState _s4 = flow.getStates().get(2);
    assertEquals("sc.r.s1.r.s3.r.s4", _s4.getName());

    ExecutionState _s6 = flow.getStates().get(5);
    assertEquals("sc.r.s2.r.s6", _s6.getName());

    Sequence cycle = _s4.getReactSequence();

    Sequence _seq = (Sequence) cycle.getSteps().get(0);

    // first entry is the s1 local reaction
    List<Step> steps = SCTTestUtil.flattenSequenceStepsAsList(_seq);
    If _if = (If) steps.get(0);
    assertCall(_if.getThenStep(), _s1.getReactions().get(0).getEffect());

    // second entry is the s3 cycle with the transition reaction
    _if = (If) steps.get(1);
    assertCall(_if.getThenStep(), _s3.getReactions().get(0).getEffect());
    assertTrue(_s3.getReactions().get(0).isTransition());

    // third is the s4 cycle with the transition reaction
    _seq = (Sequence) _if.getElseStep();
    cycle = (Sequence) _seq.getSteps().get(0);
    _if = (If) cycle.getSteps().get(0);
    assertCall(_if.getThenStep(), _s4.getReactions().get(0).getEffect());
    assertTrue(_s4.getReactions().get(0).isTransition());
    assertNull(_if.getElseStep());
    assertEquals(1, cycle.getSteps().size());
  }