code: private static IVarDef asVarDef( String varName, String varType, Annotated groupAnnotations, JsonObject json)
      {
      try
        {
        validIdentifier( varName);
  
        AbstractVarDef varDef =
          json.containsKey( MEMBERS_KEY)
          ? new VarSet( varName)
          : new VarDef( varName);
  
        varDef.setType( varType);
      
        // Get annotations for this variable
        Optional.ofNullable( json.getJsonObject( HAS_KEY))
          .ifPresent( has -> has.keySet().stream().forEach( key -> varDef.setAnnotation( key, has.getString( key))));
      
        // Get the condition for this variable
        Optional.ofNullable( json.getJsonObject( WHEN_KEY))
          .ifPresent( object -> varDef.setCondition( asValidCondition( object)));
  
        if( json.containsKey( MEMBERS_KEY))
          {
          VarSet varSet = (VarSet) varDef;
          getVarDefs( varType, json.getJsonObject( MEMBERS_KEY))
            .forEach( member -> varSet.addMember( member));
  
          if( !varSet.getMembers().hasNext())
            {
            throw new SystemInputException( String.format( "No members defined for VarSet=%s", varName));
            }
          }
        else
          {
          VarDef var = (VarDef) varDef;
          getValueDefs( json.getJsonObject( VALUES_KEY))
            .forEach( valueDef -> var.addValue( valueDef));
  
          if( !var.getValidValues().hasNext())
            {
            throw new SystemInputException( String.format( "No valid values defined for Var=%s", varName));
            }
          }
  
        // Add any group annotations
        varDef.addAnnotations( groupAnnotations);
  
        return varDef;
        }
      catch( SystemInputException e)
        {
        throw new SystemInputException( String.format( "Error defining variable=%s", varName), e);
        }
      }
docs: Returns the variable definition represented by the given JSON object.