@Override
  public void processNull(
      TemplateExecutionEnvironment environment,
      SNodeReference templateSwitch,
      TemplateContext context) {

    SNode generatorMessage = RuleUtil.getSwitch_NullInputMessage(mySwitch);
    if (generatorMessage != null) {
      GeneratorUtilEx.processGeneratorMessage(
          generatorMessage,
          context.getInput(),
          templateSwitch.resolve(MPSModuleRepository.getInstance()),
          null,
          environment.getGenerator());
    }
  }
  @Override
  public Collection<SNode> applyDefault(
      TemplateExecutionEnvironment environment,
      SNodeReference templateSwitch,
      String mappingName,
      TemplateContext context)
      throws GenerationException {
    SNode defaultConsequence = RuleUtil.getSwitchDefaultConsequence(mySwitch);
    if (defaultConsequence == null) {
      SNodeReference modifies = getModifiesSwitch();
      if (modifies == null) {
        return null;
      }
      TemplateSwitchMapping switchMapping = environment.getGenerator().getSwitch(modifies);
      if (switchMapping == null) {
        return null;
      }
      return switchMapping.applyDefault(environment, templateSwitch, mappingName, context);
    }

    List<SNode> collection = new ArrayList<SNode>();
    try {
      List<Pair<SNode, String>> nodeAndMappingNamePairs =
          GeneratorUtilEx.getTemplateNodesFromRuleConsequence(
              defaultConsequence,
              context.getInput(),
              templateSwitch.resolve(MPSModuleRepository.getInstance()),
              environment.getReductionContext(),
              environment.getGenerator());
      if (nodeAndMappingNamePairs == null) {
        environment
            .getGenerator()
            .showErrorMessage(
                context.getInput(),
                templateSwitch.resolve(MPSModuleRepository.getInstance()),
                defaultConsequence,
                "error processing $SWITCH$/default");
        return null;
      }

      for (Pair<SNode, String> nodeAndMappingNamePair : nodeAndMappingNamePairs) {
        SNode altTemplateNode = nodeAndMappingNamePair.o1;
        String innerMappingName =
            nodeAndMappingNamePair.o2 != null ? nodeAndMappingNamePair.o2 : mappingName;
        try {
          TemplateProcessor templateProcessor =
              new TemplateProcessor(environment.getGenerator(), environment.getReductionContext());
          collection.addAll(templateProcessor.apply(innerMappingName, altTemplateNode, context));
        } catch (TemplateProcessingFailureException e) {
          environment
              .getGenerator()
              .showErrorMessage(
                  context.getInput(),
                  templateSwitch.resolve(MPSModuleRepository.getInstance()),
                  "error processing template fragment");
        }
      }
    } catch (AbandonRuleInputException e) {
      // it's ok. just ignore
    }
    return collection;
  }