/**
  * 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;
 }
  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);
  }
  @Check(CheckType.FAST)
  public void checkUnusedEntry(final Entry entry) {
    if (entry.getParentRegion().getComposite() instanceof org.yakindu.sct.model.sgraph.State
        && entry.getIncomingTransitions().isEmpty()) {
      org.yakindu.sct.model.sgraph.State state =
          (org.yakindu.sct.model.sgraph.State) entry.getParentRegion().getComposite();

      if (!STextValidationModelUtils.isDefault(entry)) {

        boolean hasIncomingTransition = false;
        Iterator<Transition> transitionIt = state.getIncomingTransitions().iterator();

        while (transitionIt.hasNext() && !hasIncomingTransition) {

          Iterator<ReactionProperty> propertyIt = transitionIt.next().getProperties().iterator();

          while (propertyIt.hasNext() && !hasIncomingTransition) {

            ReactionProperty property = propertyIt.next();

            if (property instanceof EntryPointSpec) {

              hasIncomingTransition =
                  entry.getName().equals(((EntryPointSpec) property).getEntrypoint());
            }
          }
        }
        if (!hasIncomingTransition) {
          warning(ENTRY_UNUSED, entry, null, -1);
        }
      }
    }
  }
 public static Entry _createEntry(EntryKind kind, String name, Region r) {
   Entry entry = SGraphFactory.eINSTANCE.createEntry();
   if (kind != null) entry.setKind(kind);
   else entry.setKind(EntryKind.INITIAL);
   entry.setName(name);
   if (r != null) r.getVertices().add(entry);
   return entry;
 }
  @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);
              }
            }
          }
        }
      }
    }
  }
 @Check(CheckType.FAST)
 public void initialEntryWithoutOutgoingTransition(Entry entry) {
   if (entry.getOutgoingTransitions().size() == 0
       && ((Entry) entry).getKind().equals(EntryKind.INITIAL)) {
     warning(ISSUE_INITIAL_ENTRY_WITHOUT_OUT_TRANS, entry, null, -1);
   }
 }
 @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);
     }
   }
 }
  /**
   * Checks if all composite states that are siblings of a shallow history can enter their regions.
   *
   * @param e
   */
  @Check(CheckType.FAST)
  public void regionCantBeEnteredUsingShallowHistory(Entry e) {

    if (e.getKind() == EntryKind.SHALLOW_HISTORY) {

      // get all regions off all sibling states
      List<Region> regions = new ArrayList<Region>();
      for (Vertex v : e.getParentRegion().getVertices()) {
        if (v instanceof org.yakindu.sct.model.sgraph.State) {
          org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) v;
          regions.addAll(state.getRegions());
        }
      }

      // check each region
      for (Region r : regions) {

        // first determine if the region contains a default entry
        Entry defaultEntry = null;
        for (Vertex v : r.getVertices()) {
          if (v instanceof Entry) {
            String name = v.getName().trim().toLowerCase();
            if (name != null || "".equals(name) || "default".equals(name)) {
              defaultEntry = (Entry) v;
              break;
            }
          }
        }

        // now check error conditions
        if (defaultEntry == null) {
          error(ISSUE_REGION_CANT_BE_ENTERED_USING_SHALLOW_HISTORY_NO_DEFAULT_ENTRY, r, null, -1);
        } else if (defaultEntry.getOutgoingTransitions().size() != 1) {
          error(
              ISSUE_REGION_CANT_BE_ENTERED_USING_SHALLOW_HISTORY_NON_CONNECTED_DEFAULT_ENTRY,
              r,
              null,
              -1);
        }
      }
    }
  }
 private void addEntryPointSpec(Transition transition, Entry entryPoint) {
   EList<ReactionProperty> properties = transition.getProperties();
   EntryPointSpec entryPointSpec = StextFactory.eINSTANCE.createEntryPointSpec();
   // A transition can only have one entry point so alter the existing
   for (ReactionProperty reactionProperty : properties) {
     if (reactionProperty instanceof EntryPointSpec) {
       entryPointSpec = (EntryPointSpec) reactionProperty;
     }
   }
   entryPointSpec.setEntrypoint(entryPoint.getName());
   properties.add(entryPointSpec);
 }
  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;
  }
 @Check(CheckType.FAST)
 public void initialEntryWithMultipleOutgoingTransition(Entry entry) {
   if (entry.getOutgoingTransitions().size() > 1) {
     error(ISSUE_ENTRY_WITH_MULTIPLE_OUT_TRANS, entry, null, -1);
   }
 }
 @Check(CheckType.FAST)
 public void initialEntryWithoutIncomingTransitions(Entry entry) {
   if (entry.getIncomingTransitions().size() > 0 && entry.getKind().equals(EntryKind.INITIAL)) {
     warning(ISSUE_INITIAL_ENTRY_WITH_IN_TRANS, entry, null, -1);
   }
 }