/**
   * save the EMF Model's parameters to Element
   *
   * @param elem
   * @param pType
   */
  public static void saveElementParameters(Element elem, ParametersType pType) {
    EList listParamType = pType.getElementParameter();
    listParamType.clear();

    List<IElementParameter> paramList =
        (List<IElementParameter>) elem.getElementParametersWithChildrens();
    for (IElementParameter param : paramList) {
      ElementParameterType type = getElemeterParameterType(param);
      listParamType.add(type);
    }
  }
Exemple #2
0
  public static void resolve(Context context, EList<BodyElement> elements) {
    List<BodyElement> resolved = new ArrayList<BodyElement>();
    for (int i = 0; i < elements.size(); i++) {
      BodyElement element = elements.get(i);
      if (element instanceof UnresolvedBodyElement) {
        UnresolvedBodyElement unresolved = (UnresolvedBodyElement) element;
        resolved.addAll(unresolved.resolve(context));
      } else {
        resolved.add(element);
      }
    }

    elements.clear();
    elements.addAll(resolved);
  }
Exemple #3
0
  /** Tests support for attributes of ELong type. */
  public void test_supportForELongAttributes_198451() {
    helper.setContext(thingType);

    long maxInt = Integer.MAX_VALUE;
    long maxIntMinusOne = (long) Integer.MAX_VALUE - 1;
    long maxIntSquared = ((long) Integer.MAX_VALUE) * ((long) Integer.MAX_VALUE);
    double quotient = (double) maxIntSquared / (double) maxIntMinusOne;

    Numero maxIntN = new Numero(maxInt);
    Numero maxIntMinusOneN = new Numero(maxIntMinusOne);
    Numero maxIntSquaredN = new Numero(maxIntSquared);

    @SuppressWarnings("unchecked")
    EList<Numero> list = (EList<Numero>) thing.eGet(enumeros);
    list.clear();
    list.add(maxIntN);
    list.add(maxIntMinusOneN);
    list.add(maxIntSquaredN);
    list.add(new Numero(1));

    try {
      // this should be OK because both values can be represented as integers
      assertEquals(1, evaluate(helper, thing, "numeros->at(1).asLong() - numeros->at(2).asLong()"));

      // same number represented in different precision
      assertTrue(check(helper, thing, "numeros->at(4).asLong() = 1"));

      // different numbers represented in different precision
      assertTrue(check(helper, thing, "numeros->at(4).asLong() <> 2"));

      // this is also OK, because we compute in high precision and coerce
      // the result to lower precision
      assertEquals(
          quotient, evaluate(helper, thing, "numeros->at(3).asLong() / numeros->at(2).asLong()"));

      // this is another case where the intermediate result is high-precision but
      // the result is low
      assertEquals(
          (int) maxIntMinusOne,
          evaluate(helper, thing, String.format("(%d + %d).div(2) - 1", maxInt, maxInt)));

      // finally, a case where the result is in high precision (new capability)
      assertEquals(
          maxIntSquared, evaluate(helper, thing, String.format("%d * %d", maxInt, maxInt)));
    } catch (Exception e) {
      fail("Failed to parse or evaluate: " + e.getLocalizedMessage());
    }
  }
 public void clear() {
   copy.clear();
   original.clear();
 }
  /**
   *
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated NOT
   */
  @Override
  public EList<HistoricalValues> updateHistoryExtensions(SnapshotCollection snapshotCollection) {
    // long start = System.currentTimeMillis();
    // String typeName = ((EClass)getSEType()).getName();
    EList<HistoricalValues> histValsList = new BasicEList<HistoricalValues>();
    RepositoryRegistry rg = RepositoryRegistry.vmtMANAGER;
    // long start4 = System.currentTimeMillis();
    Set<VMTRootObject> vObj = rg.getInstances(getSEType());
    // logger.info("getting SE instances fo SE type "+typeName +" took:
    // "+(System.currentTimeMillis()-start4));

    EList<EObject> attrList = getAttribute();
    EList<ENamedElement> nes = new BasicEList<ENamedElement>();
    ServiceEntityHistoryExt histExt;

    // long start5 = System.currentTimeMillis();
    for (VMTRootObject obj : vObj) {
      // long start3 = System.currentTimeMillis();
      boolean constraintFailed = false;
      ServiceEntity se = (ServiceEntity) obj;
      // Check constraints + that the se participates in the main market and not a template
      if ((se.getServiceEntityOf() != null)
          && se.getServiceEntityOf().isMainMarket()
          && (se.getTemplateForMarket() == null)) {

        for (Constraint constraint : getMatchingCriteria()) {
          if (!constraint.match(obj)) {
            constraintFailed = true;
            break;
          }
        }
      } else {
        constraintFailed = true;
      }

      // and skip if any of the constraints do not match
      if (constraintFailed) continue;

      histExt =
          (ServiceEntityHistoryExt)
              se.createExtension(ReportingExtensionsPackage.eINSTANCE.getServiceEntityHistoryExt());
      histExt.setSnapshotCollection(snapshotCollection);
      if (scLogger.isTraceEnabled())
        scLogger.trace(String.format("%s: Updating ServiceEntityHistoryExt", se.toVMTString()));

      // Get the attribute value and create/add to the historical values
      if (attrList.size() == 1) {
        EStructuralFeature attribute = (EStructuralFeature) attrList.get(0);

        HistoricalValues vals;
        EList<HistoricalValues> valuesList = histExt.getHistoricalValues(attribute.getName());
        // if the attribute was not added to the extension yet create it
        if (valuesList == null || valuesList.isEmpty()) {
          vals = ReportingFactory.eINSTANCE.createHistoricalValues();
          vals.initValues(snapshotCollection);
          histExt.addHistoricalValues(attribute.getName(), vals);
          if (scLogger.isTraceEnabled())
            scLogger.trace(
                String.format(
                    "%s: Adding historicalValues for attribute %s",
                    se.toVMTString(), attribute.getName()));
        } else {
          // There cannot be more than 1 value for an attribute.
          vals = histExt.getHistoricalValues(attribute.getName()).get(0);
        }

        // Only add a value if the attribute has been set already - otherwise add no value
        if (obj.eIsSet(attribute)) {
          Object attributeValue = obj.eGet(attribute);
          vals.addValue((Float) attributeValue);
          histValsList.add(vals);
          if (scLogger.isTraceEnabled())
            scLogger.trace(
                String.format(
                    "%s: Adding value %f to historicalValues for attribute %s",
                    se.toVMTString(), attributeValue, attribute.getName()));
        } else {
          vals.addValue(HistoricalValuesImpl.NO_VALUE);
          if (scLogger.isTraceEnabled())
            scLogger.trace(
                String.format(
                    "%s: Adding no value to historicalValues for attribute %s",
                    se.toVMTString(), attribute.getName()));
        }
      }
      // Or get the list of attribute values and create/add to historical values for each
      else {
        nes.clear();
        /* previously we assumed a list of size 3 [reference, commodity, attribute], now we assume
         * the last entry is the attribute and the third to last entry is the commodity. */
        EStructuralFeature attribute = (EStructuralFeature) attrList.get(attrList.size() - 1);
        EReference reference = (EReference) attrList.get(attrList.size() - 3);

        // instead of: nes.addAll((Collection<? extends ENamedElement>) attrList.subList(0,
        // attrList.size()-1));
        for (int i = 0; i < attrList.size() - 1; i++) nes.add((ENamedElement) attrList.get(i));

        List<Object> matchedCommodities = obj.getValues(nes);
        for (Object commObj : matchedCommodities) {

          // long start2 = System.currentTimeMillis();

          if (commObj instanceof Commodity) {
            Commodity comm = (Commodity) commObj;

            // if a history extension already exists use it, otherwise create a new one and
            // initialize it.
            if (comm.getHistoryExtension() == null) {
              CommodityHistoryExt commHistExt =
                  (CommodityHistoryExt)
                      comm.createExtension(
                          ReportingExtensionsPackage.eINSTANCE.getCommodityHistoryExt());
              commHistExt.init(snapshotCollection, histExt);
              if (scLogger.isTraceEnabled())
                scLogger.trace(
                    String.format(
                        "%s: Updating CommodityHistoryExt for %s",
                        se.toVMTString(), comm.toVMTString()));
            }

            // update the snapshot collection accumulated used values
            snapshotCollection.updateOverallCommodityUsage(comm);

            try {
              // add the value to the historical ext - insert to the proper historical values
              HistoricalValues vals =
                  comm.getHistoryExtension().getFeatureHistory(attribute, reference);

              // Only add a value for the attributes that have been set already
              if (comm.eIsSet(attribute)) {
                vals.addValue((Float) comm.eGet(attribute));
                histValsList.add(vals);
                if (scLogger.isTraceEnabled())
                  scLogger.trace(
                      String.format(
                          "%s: Adding value %f to historicalValues of commodity %s for attribute %s",
                          se.toVMTString(),
                          comm.eGet(attribute),
                          comm.toVMTString(),
                          attribute.getName()));
              }
              // otherwise - set to NO VALUE
              else {
                vals.addValue(HistoricalValuesImpl.NO_VALUE);
                if (scLogger.isTraceEnabled())
                  scLogger.trace(
                      String.format(
                          "%s: Adding no value to historicalValues of commodity %s for attribute %s",
                          se.toVMTString(), comm.toVMTString(), attribute.getName()));
              }
            } catch (Exception e) {
              logger.error(
                  "Exception trying to update history extension for "
                      + comm.getName()
                      + "::"
                      + attribute.getName(),
                  e);
            }
          } else {
            logger.error(
                "Missconfigured MetaReacord. Penultimate argument should be a Commodity: "
                    + commObj);
          }

          // logger.info("updating a single commodity for SE type "+typeName +" took:
          // "+(System.currentTimeMillis()-start2));
        }
      }
      // logger.info("updating a single entity for SE type "+typeName +" took:
      // "+(System.currentTimeMillis()-start3));
    }
    // logger.info("iterating over all entities of type "+typeName +" took:
    // "+(System.currentTimeMillis()-start5));

    // logger.info("update history extension for SE type "+typeName +" took:
    // "+(System.currentTimeMillis()-start));
    return histValsList;
  }
  /**
   *
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   *
   * @generated NOT
   */
  @Override
  public EList<Record> getRecords() {
    EList<Record> recordList = new BasicEList<Record>();
    RepositoryRegistry rg = RepositoryRegistry.vmtMANAGER;
    Set<VMTRootObject> vObj = rg.getInstances(getSEType());

    EList<EObject> attrList = getAttribute();
    EList<ENamedElement> nes = new BasicEList<ENamedElement>();

    for (VMTRootObject obj : vObj) {
      boolean constraintfailed = false;
      ServiceEntity se = (ServiceEntity) obj;
      // Check constraints + that the se participates in the main market and not a template
      if ((se.getServiceEntityOf() != null)
          && se.getServiceEntityOf().isMainMarket()
          && (se.getTemplateForMarket() == null)) {

        for (Constraint constraint : getMatchingCriteria()) {
          if (!constraint.match(obj)) {
            constraintfailed = true;
            break;
          }
        }
      } else {
        constraintfailed = true;
      }

      // and skip if any of the constraints do not match
      if (constraintfailed) continue;

      // Get the attribute value and create a single record
      if (attrList.size() == 1) {
        EStructuralFeature attribute = (EStructuralFeature) attrList.get(0);
        // Only create a record if the attribute has been set already
        if (obj.eIsSet(attribute)) {
          Object attributeValue = obj.eGet(attribute);
          RecordFromMetaRecord rec = ReportingFactory.eINSTANCE.createRecordFromMetaRecord();
          rec.setObject(obj);
          rec.setFeature(attribute);
          if (trackSize && attributeValue instanceof List<?>) {
            rec.setValueObject(((List<?>) attributeValue).size());
          } else if (trackSize) {
            rec.setValueObject(1);
          } else {
            rec.setValueObject(attributeValue);
          }
          recordList.add(rec);
        }
        // Or get the list of attribute values and create a record for each
      } else {
        nes.clear();
        EReference reference = (EReference) attrList.get(attrList.size() - 3);
        ENamedElement commodity = (ENamedElement) attrList.get(attrList.size() - 2);
        EStructuralFeature attribute = (EStructuralFeature) attrList.get(attrList.size() - 1);

        for (EObject attrib : attrList) {
          nes.add((ENamedElement) attrib);
        }
        // Only creating a record for the attributes that has been set already, otherwise getValues
        // returns no elements in the list
        List<Object> attributeValueList = obj.getValues(nes);
        for (Object attributeValue : attributeValueList) {
          RecordFromMetaRecord2 rec = ReportingFactory.eINSTANCE.createRecordFromMetaRecord2();
          rec.setObject(obj);
          rec.setFeature(attribute);
          rec.setCommodity(commodity);
          rec.setReference(reference);
          if (trackSize && attributeValue instanceof List<?>) {
            rec.setValueObject(((List<?>) attributeValue).size());
          } else if (trackSize) {
            rec.setValueObject(1);
          } else {
            rec.setValueObject(attributeValue);
          }
          recordList.add(rec);
        }
      }
    }
    return recordList;
  }
  /**
   * Validate the model. All checks are performed for all automata in the file. This method checks
   * that
   *
   * <ul>
   *   <li>only allowed extension are used. Allowed extension are {@link
   *       org.ect.ea.extensions.clocks.AutomatonClocksProvider}, {@link
   *       org.ect.ea.extensions.clocks.TCADataConstraintsProvider}, {@link
   *       org.ect.ea.extensions.constraints.ConstraintExtensionProvider}, {@link
   *       org.ect.ea.extensions.startstates.StartStateExtensionProvider}, {@link
   *       org.ect.ea.extensions.portnames.AutomatonPortNamesProvider}, {@link
   *       org.ect.ea.extensions.portnames.TransitionPortNamesProvider}, {@link
   *       org.ect.ea.extensions.clocks.TransitionUpdateProvider}, {@link
   *       org.ect.ea.extensions.clocks.TransitionGuardProvider}, {@link
   *       org.ect.ea.extension.stateMemory.StateMemoryExtensionProvider} and {@link
   *       org.ect.ea.extensions.clocks.StateInvariantProvider}.
   *   <li>all required extensions are used. Required extensions are {@link
   *       org.ect.ea.extensions.startstates.StartStateExtensionProvider}, {@link
   *       org.ect.ea.extensions.portnames.AutomatonPortNamesProvider} and {@link
   *       org.ect.ea.extensions.portnames.TransitionPortNamesProvider}.
   *   <li>depending on whether the automaton is a CA or a TCA, some other extensions are required
   *       and forbidden:
   *       <ul>
   *         <li>Required extensions of TCA are {@link
   *             org.ect.ea.extensions.clocks.TCADataConstraintsProvider}, {@link
   *             org.ect.ea.extensions.clocks.AutomatonClocksProvider}, {@link
   *             org.ect.ea.extensions.clocks.TransitionGuardProvider}, {@link
   *             org.ect.ea.extensions.clocks.TransitionUpdateProvider} and {@link
   *             org.ect.ea.extensions.clocks.StateInvariantProvider}. These are also the forbidden
   *             extensions for CA.
   *         <li>Forbidden extensions of TCA are {@link
   *             org.ect.ea.extensions.constraints.ConstraintExtensionProvider}. These are also the
   *             required extensions for CA.
   *       </ul>
   *   <li>all names (except for memory cells and ports) are unique within the system.
   *   <li>memory cell names may occur more than once in one automaton, but must be unique between
   *       different automata, and must not equal any other name.
   *   <li>port names may be shared between automata, but must be different from all other names
   *   <li>there exists exactly one start state per automaton.
   *   <li>untimed CA (that means without clock extensions) do not have transitions with empty name
   *       set
   *   <li>TCA transition with empty name set do not have an associated data constraint
   *   <li>there exist no names {@link org.ect.ea.extensions.clocks.ClockUtils#GLOBAL_CLOCK} or
   *       {@link org.ect.ea.extensions.clocks.ClockUtils#NO_FLOW_NAME}
   *   <li>the range of data values is well-formed, i.e. either on the form
   *       <tt>lowerBound..upperBound</tt>, with <tt>lowerBound=0</tt>, <tt>upperBound>=1</tt>, or
   *       empty (for infinite data domain)
   *   <li>integer values in the data constraints lie within the given range
   *   <li>unfolding depth is at least 1
   *   <li>the target language is one of [mathsat,msat]
   *   <li>the output file name is not empty
   * </ul>
   */
  public IStatus validateGenModel(IGenModel genModel) {

    EList<Automaton> automata = ((Automaton) genModel.getTarget()).getModule().getAutomata();

    String projectName = genModel.getProperty(IGenModel.PROJECT_NAME);
    if (projectName == null || projectName.equals("")) {
      return new Status(IStatus.ERROR, PLUGIN_ID, "Project name cannot be empty.");
    }

    String rng = genModel.getProperty(CodegenUtils.PROPERTY_RANGE);
    // rng = rng.replace("..", ",");

    String targetlang = genModel.getProperty("targetlang");

    // for temporary usage
    // String tempS = "";
    EList<String> tempL = new BasicEList<String>();
    boolean tempB;

    /* check extensions */
    /* Every automaton must support the automaton port names, transition
     * port names, and start state extension, and may support the state
     * memory extension.
     * If the automaton is a CA (untimed), it must support the constraint
     * extension, and must not support the TCA data constraint,
     * automaton clocks, transition guard, transition update and
     * invariant extension.
     * If the automaton is a TCA (timed), it must support the TCA data
     * constraint, automaton clocks, transition guard, transition update and
     * invariant extension, and must not support the constraint extension.
     * */

    // check that only allowed extensions are used
    // note that not all these extensions can be used at the same time
    final EList<String> allowedExtensions = new BasicEList<String>();
    allowedExtensions.add(ClockUtils.STATE_MEMORY_ID);
    allowedExtensions.add(ClockUtils.AUTOMATON_CLOCKS_ID);
    allowedExtensions.add(ClockUtils.TRANSITION_GUARD_ID);
    allowedExtensions.add(ClockUtils.TRANSITION_UPDATE_ID);
    allowedExtensions.add(ClockUtils.INVARIANT_ID);
    allowedExtensions.add(ClockUtils.DATA_CONSTRAINT_ID);
    allowedExtensions.add(ClockUtils.CONSTRAINT_ID);
    allowedExtensions.add(ClockUtils.AUTOMATON_PORT_NAMES_ID);
    allowedExtensions.add(ClockUtils.TRANSITION_PORT_NAMES_ID);
    allowedExtensions.add(ClockUtils.START_STATE_ID);

    final EList<String> requiredExtensions = new BasicEList<String>();
    requiredExtensions.add(ClockUtils.START_STATE_ID);
    requiredExtensions.add(ClockUtils.AUTOMATON_PORT_NAMES_ID);
    requiredExtensions.add(ClockUtils.TRANSITION_PORT_NAMES_ID);

    final EList<String> requiredCAExtensions = new BasicEList<String>();
    requiredCAExtensions.add(ClockUtils.CONSTRAINT_ID);

    final EList<String> forbiddenCAExtensions = new BasicEList<String>();
    forbiddenCAExtensions.add(ClockUtils.DATA_CONSTRAINT_ID);
    forbiddenCAExtensions.add(ClockUtils.AUTOMATON_CLOCKS_ID);
    forbiddenCAExtensions.add(ClockUtils.TRANSITION_GUARD_ID);
    forbiddenCAExtensions.add(ClockUtils.TRANSITION_UPDATE_ID);
    forbiddenCAExtensions.add(ClockUtils.INVARIANT_ID);

    final EList<String> requiredTCAExtensions = new BasicEList<String>(forbiddenCAExtensions);
    final EList<String> forbiddenTCAExtensions = new BasicEList<String>(requiredCAExtensions);

    EList<String> names = new BasicEList<String>(); // to check uniqueness of names
    Set<String> portNames =
        new HashSet<
            String>(); // port names can be shared, but must be different from other names, use set
                       // to automatically remove duplicates

    boolean timed = false;
    boolean untimed = false;
    boolean allMem = false;
    boolean noMem = false;

    for (Automaton automaton : automata) {

      // add automaton name to global name set name
      names.add(automaton.getName());

      // check that only allowed extensions are used
      final EList<String> usedExtensions = automaton.getUsedExtensionIds();
      if (!allowedExtensions.containsAll(usedExtensions)) {
        tempL.clear();
        tempL.addAll(usedExtensions);
        tempL.removeAll(allowedExtensions);
        return new Status(
            IStatus.ERROR, PLUGIN_ID, "Extension(s) used but not supported: " + tempL);
      }

      // check that all required extensions are used
      if (!usedExtensions.containsAll(requiredExtensions)) {
        tempL.clear();
        tempL.addAll(requiredExtensions);
        tempL.removeAll(usedExtensions);
        return new Status(
            IStatus.ERROR, PLUGIN_ID, automaton.getName() + "must support extension(s): " + tempL);
      }

      // check that exactly one of the constraint extensions is used, infer CA or TCA from that
      if (usedExtensions.contains(ClockUtils.DATA_CONSTRAINT_ID)) {
        timed = true;
        if (untimed == true) {
          return new Status(
              IStatus.ERROR,
              PLUGIN_ID,
              "All automata must support same constraint extension, either "
                  + ClockUtils.DATA_CONSTRAINT_ID
                  + " or "
                  + ClockUtils.CONSTRAINT_ID);
        }
      }
      if (usedExtensions.contains(ClockUtils.CONSTRAINT_ID)) {
        untimed = true;
        if (timed == true) {
          return new Status(
              IStatus.ERROR,
              PLUGIN_ID,
              "All automata must support same constraint extension, either "
                  + ClockUtils.DATA_CONSTRAINT_ID
                  + " or "
                  + ClockUtils.CONSTRAINT_ID);
        }
      }
      if (!(timed || untimed)) { // no constraint extension is used
        return new Status(
            IStatus.ERROR,
            PLUGIN_ID,
            "All automata must support same constraint extension, either "
                + ClockUtils.DATA_CONSTRAINT_ID
                + " or "
                + ClockUtils.CONSTRAINT_ID);
      }

      // if CA: check for required and forbidden extensions
      if (untimed) {
        if (!usedExtensions.containsAll(requiredCAExtensions)) {
          tempL.clear();
          tempL.addAll(requiredCAExtensions);
          tempL.removeAll(usedExtensions);
          return new Status(
              IStatus.ERROR, PLUGIN_ID, "Untimed CA must support extension(s): " + tempL);
        }
        tempL.clear();
        tempL.addAll(usedExtensions);
        tempL.addAll(forbiddenCAExtensions);
        tempL = new StringListExtension(tempL).getDuplicateEntries();
        if (!tempL.isEmpty()) {
          return new Status(
              IStatus.ERROR, PLUGIN_ID, "Untimed CA must not support extension(s): " + tempL);
        }
      }
      // if TCA: check for required and forbidden extensions
      if (timed) {

        if (!usedExtensions.containsAll(requiredTCAExtensions)) {
          tempL.clear();
          tempL.addAll(requiredTCAExtensions);
          tempL.removeAll(usedExtensions);
          return new Status(IStatus.ERROR, PLUGIN_ID, "TCA must support extension(s): " + tempL);
        }
        tempL.clear();
        tempL.addAll(usedExtensions);
        tempL.addAll(forbiddenTCAExtensions);
        tempL = new StringListExtension(tempL).getDuplicateEntries();
        if (!tempL.isEmpty()) {
          return new Status(
              IStatus.ERROR, PLUGIN_ID, "TCA must not support extension(s): " + tempL);
        }
      }

      // check that the automaton has states (otherwise, code generation does not make sense)
      if (automaton.getStates().isEmpty()) {
        return new Status(
            IStatus.ERROR,
            PLUGIN_ID,
            "Automaton does not have states, code generation does not make sense.");
      }

      // check that the automaton has transitions (otherwise, code generation does not make sense)
      if (automaton.getTransitions().isEmpty()) {
        return new Status(
            IStatus.ERROR,
            PLUGIN_ID,
            "Automaton does not have transitions, code generation does not make sense.");
      }

      // check for state memory extension
      if (usedExtensions.contains(ClockUtils.STATE_MEMORY_ID)) {
        allMem = true;
        if (noMem) {
          return new Status(
              IStatus.ERROR,
              PLUGIN_ID,
              "State memory must be support by all automata or not at all.");
        }
      } else {
        noMem = true;
        if (allMem) {
          return new Status(
              IStatus.ERROR,
              PLUGIN_ID,
              "State memory must be support by all automata or not at all.");
        }
      }

      // create EList of memory cell names (if memory cells are used)
      if (allMem) {
        EList<String> thisAutoMemCells = new BasicEList<String>();
        for (State s : automaton.getStates()) {
          try {
            tempL =
                StringListExtension.parse(s.findExtension(ClockUtils.STATE_MEMORY_ID).toString())
                    .getValues(); // memory cells of current state
            if (!tempL.isEmpty()) { // empty if state does not have memory cells
              thisAutoMemCells.addAll(tempL);
            }
          } catch (ParseException pe) {
            return new Status(
                IStatus.ERROR,
                PLUGIN_ID,
                "Unexpected error while trying to parse memory cells of " + s.getName());
          }
        }
        // remove duplicate cells from current automaton
        StringListExtension sle = new StringListExtension(thisAutoMemCells);
        sle.removeDuplicateEntries();
        // add names to global EList (checked later)
        tempL = sle.getValues();
        for (String s : tempL) {
          names.add(s);
        }
      }

      // add state names to global name set (checked later), and check for initial states
      tempB = false; // for initial states
      for (State s : automaton.getStates()) {
        if (s.getName() == null || s.getName().equals("")) {
          return new Status(IStatus.ERROR, PLUGIN_ID, "States must have a name.");
        }
        names.add(s.getName());
        if (CA.isStartState(s)) {
          if (tempB == true) {
            return new Status(
                IStatus.ERROR, PLUGIN_ID, "Each automaton must have exactly one initial location");
          }
          tempB = true;
        }
        if (!tempB) {
          return new Status(
              IStatus.ERROR, PLUGIN_ID, "Each automaton must have exactly one initial location");
        }
      }

      // untimed CA transitions must not have empty name set
      if (untimed) {
        for (Transition t : automaton.getTransitions()) {
          if (((StringListExtension) t.findExtension(ClockUtils.TRANSITION_PORT_NAMES_ID))
              .getValues()
              .isEmpty()) {
            return new Status(
                IStatus.ERROR, PLUGIN_ID, "Transitions of untimed CA must not have empty name set");
          }
        }
      }

      // TCA transitions with the empty name set must not have a data
      // constraint on ports (only memory cells)
      // actually this check should not be necessary, it is checked during editing (by the parser)
      // already
      if (timed) {
        for (Transition t : automaton.getTransitions()) {
          if (((StringListExtension) t.findExtension(ClockUtils.TRANSITION_PORT_NAMES_ID))
              .getValues()
              .isEmpty()) { // found transition with empty port set
            // get the constraint
            String cons = t.findExtension(ClockUtils.DATA_CONSTRAINT_ID).toString();
            TCADataParser parser = new TCADataParser(cons);
            try {
              tempL = parser.get_port_names();
              if (!tempL.isEmpty()) {
                return new Status(
                    IStatus.ERROR,
                    PLUGIN_ID,
                    "Invisible transitions (with empty port set) must not have a data constraint on ports.");
              }
            } catch (RecognitionException pe) {
              return new Status(
                  IStatus.ERROR, PLUGIN_ID, "Unexpected error while trying to parse " + cons);
            }
          }
        }
      }

      // add clock names to global name set (checked later)
      if (timed) {
        for (String c : ClockUtils.getClocks(automaton)) {
          names.add(c);
        }
      }

      // add port names to global port name set (checked later)
      for (String p :
          ((StringListExtension) automaton.findExtension(ClockUtils.AUTOMATON_PORT_NAMES_ID))
              .getValues()) {
        portNames.add(p);
      }
    }

    // check range of data values
    // either 'lowerBound..upperBound' or empty (=infinite)
    if (rng.trim().equals("")) {
      infinite = true;
    } else {
      infinite = false;
      if (!rng.contains("..")) {
        return new Status(
            IStatus.ERROR,
            PLUGIN_ID,
            "Finite range must be given in the form '0..upperBound'.\nupperBound must be an integer value strictly greater than 0.");
      }
      try {
        lowerBound = Integer.parseInt(rng.substring(0, rng.indexOf(".")));
        if (lowerBound != 0) {
          return new Status(
              IStatus.ERROR,
              PLUGIN_ID,
              "Finite range must be given in the form '0..upperBound'.\nLower bounds other than 0 are not (yet) supported.");
        }
      } catch (NumberFormatException nfe) {
        return new Status(
            IStatus.ERROR,
            PLUGIN_ID,
            "Finite range must be given in the form '0..upperBound'.\nLower bounds other than 0 are not (yet) supported.");
      }
      try {
        upperBound = Integer.parseInt(rng.substring(rng.lastIndexOf(".") + 1, rng.length()));
        if (upperBound < 1) {
          return new Status(
              IStatus.ERROR,
              PLUGIN_ID,
              "Finite range must be given in the form '0..upperBound'.\nupperBound must be an integer value strictly greater than 0.");
        }
      } catch (NumberFormatException nfe) {
        return new Status(
            IStatus.ERROR,
            PLUGIN_ID,
            "Finite range must be given in the form '0..upperBound'.\nupperBound must be an integer value strictly greater than 0.");
      }
    }

    // check that integer values used in data constraints are within the range (if finite)
    if (!infinite) {
      int min = -1;
      int max = 0;
      for (Automaton automaton : automata) {
        for (Transition t : automaton.getTransitions()) {
          String cons = t.findExtension(ClockUtils.DATA_CONSTRAINT_ID).toString();
          TCADataParser parser = new TCADataParser(cons);
          try {
            tempL = parser.get_minmax_int_values();
            min = Math.min(min, Integer.parseInt(tempL.get(0)));
            max = Math.max(max, Integer.parseInt(tempL.get(1)));
          } catch (RecognitionException re) {
            return new Status(
                IStatus.ERROR, PLUGIN_ID, "Unexpected error while trying to parse " + cons);
          }
        }
        if ((min < -1) || (max > this.upperBound)) {
          return new Status(
              IStatus.ERROR,
              PLUGIN_ID,
              "Integer values in data constraints are outside declared range.");
        }
      }
    }

    // check for spaces in all but port names
    for (String s : names) {
      if (s.contains(" ")) {
        return new Status(IStatus.ERROR, PLUGIN_ID, "Names must not contain spaces: '" + s + "'");
      }
    }

    // check for duplicate names in all but port names
    tempL = new StringListExtension(names).getDuplicateEntries();
    if (!tempL.isEmpty()) {
      return new Status(
          IStatus.ERROR,
          PLUGIN_ID,
          "Names (except for port names) must not be shared between automata: "
              + tempL.toString().replace("[", "").replace("]", ""));
    }

    // check for spaces in port names
    for (String p : portNames) {
      if (p.contains(" ")) {
        return new Status(IStatus.ERROR, PLUGIN_ID, "Names must not contain spaces: '" + p + "'");
      }
    }

    // compare port names with all other names, check for duplicates between the two sets
    StringListExtension sle = new StringListExtension(portNames);
    sle.removeDuplicateEntries();
    tempL = sle.getValues();
    tempL.addAll(names);
    tempL = new StringListExtension(tempL).getDuplicateEntries();
    if (!tempL.isEmpty()) {
      return new Status(
          IStatus.ERROR,
          PLUGIN_ID,
          "Names must be unique: " + tempL.toString().replace("[", "").replace("]", ""));
    }

    // check for reserved names CodegenUtils.NO_FLOW_NAME and CodegenUtils.GLOBAL_CLOCK
    if (names.contains(CodegenUtils.NO_FLOW_NAME)
        || portNames.contains(CodegenUtils.NO_FLOW_NAME)) {
      return new Status(
          IStatus.ERROR, PLUGIN_ID, "'" + CodegenUtils.NO_FLOW_NAME + "' is a reserved name. ");
    }
    if (names.contains(CodegenUtils.GLOBAL_CLOCK)
        || portNames.contains(CodegenUtils.GLOBAL_CLOCK)) {
      return new Status(
          IStatus.ERROR, PLUGIN_ID, "'" + CodegenUtils.GLOBAL_CLOCK + "' is a reserved name. ");
    }

    // check that the unfolding depth is at least 1
    try {
      unfoldingDepth = Integer.valueOf(genModel.getProperty(CodegenUtils.PROPERTY_DEPTH));
    } catch (NumberFormatException nfe) {
      return new Status(
          IStatus.ERROR, PLUGIN_ID, "Not a valid unfolding depth: chose an integer > 0");
    }
    if (!(unfoldingDepth > 0)) {
      return new Status(
          IStatus.ERROR, PLUGIN_ID, "Not a valid unfolding depth: chose an integer > 0");
    }

    // check that target language is one of the supported languages, hard code for the moment
    if (!targetlang.equalsIgnoreCase("mathsat") && !targetlang.equalsIgnoreCase("msat")) {
      return new Status(IStatus.ERROR, PLUGIN_ID, "Target language must be one of [mathsat|msat]");
    } else { // to standardise the property contents
      genModel.setProperty("targetlang", mathsat);
    }

    // check that output file name is not empty
    if (genModel.getProperty(CodegenUtils.PROPERTY_FILENAME).isEmpty()) {
      return new Status(IStatus.ERROR, PLUGIN_ID, "Output file name cannot be empty");
    }

    /* If none of the above occurs, the model is ok */
    return Status.OK_STATUS;
  }