private void assertAtLeastOne(final IDescription desc, final String facet) {
   final IDescription sd = desc.getEnclosingDescription();
   if (!(sd instanceof SpeciesDescription)) {
     return;
   }
   for (final IDescription child : ((SpeciesDescription) sd).getBehaviors()) {
     String s = child.getKeyword();
     if (s.equals(STATE) || s.equals(USER_PANEL)) {
       final IExpression expr = child.getFacets().getExpr(facet);
       if (expr == null) {
         continue;
       }
       if (IExpressionFactory.TRUE_EXPR.equals(expr)) {
         return;
       }
     }
   }
   final String error = "No " + facet + " state defined";
   sd.error(
       error,
       IGamlIssue.MISSING_DEFINITION,
       sd.getUnderlyingElement(null),
       desc.getKeyword(),
       facet,
       TRUE);
 }
 private void assertNoOther(final IDescription desc, final String facet) {
   final IDescription sd = desc.getEnclosingDescription();
   if (!(sd instanceof SpeciesDescription)) {
     return;
   }
   for (final IDescription child : ((SpeciesDescription) sd).getBehaviors()) {
     if (child.equals(desc) || !child.getKeyword().equals(STATE)) {
       continue;
     }
     IExpression expr = child.getFacets().getExpr(facet);
     if (IExpressionFactory.TRUE_EXPR.equals(expr)) {
       final String error = "Only one " + facet + " state is allowed.";
       child.error(error, IGamlIssue.DUPLICATE_DEFINITION, facet, TRUE);
     }
   }
 }
 /**
  * Method validate()
  *
  * @see msi.gaml.compilation.IDescriptionValidator#validate(msi.gaml.descriptions.IDescription)
  */
 @Override
 public void validate(final IDescription description) {
   // Verify that the state is inside a species with fsm control
   SpeciesDescription species = description.getSpeciesContext();
   String keyword = description.getKeyword();
   IArchitecture control = species.getControl();
   // String control = species.getControlName();
   if (!(control instanceof FsmArchitecture)) {
     if (keyword.equals(STATE)) {
       description.error(
           "A state can only be defined in an fsm-controlled or user-controlled species",
           IGamlIssue.WRONG_CONTEXT);
       return;
     } else if (control.getClass() == FsmArchitecture.class) {
       description.error(
           "A "
               + description.getKeyword()
               + " can only be defined in a user-controlled species (one of"
               + AllowedArchitectures
               + ")",
           IGamlIssue.WRONG_CONTEXT);
       return;
     }
   }
   if (!Assert.nameIsValid(description)) {
     return;
   }
   Facets ff = description.getFacets();
   IExpression expr = ff.getExpr(INITIAL);
   if (IExpressionFactory.TRUE_EXPR.equals(expr)) {
     assertNoOther(description, INITIAL);
   } else {
     expr = ff.getExpr(FINAL);
     if (IExpressionFactory.TRUE_EXPR.equals(expr)) {
       assertNoOther(description, FINAL);
     } else {
       assertAtLeastOne(description, INITIAL);
     }
   }
 }