private boolean isAllowedNext(
     final ITranslator<?, ?, ?, ?, ?, ?> current, final ITranslator<?, ?, ?, ?, ?, ?> next) {
   // source is e.g. RcfgElement, target is e.g. BoogieASTNode
   // meaning, source is the output of the tool, target the input
   return current.getSourceExpressionClass() == next.getTargetExpressionClass()
       && current.getSourceTraceElementClass() == next.getTargetTraceElementClass();
 }
 private <SE> Stack<ITranslator<?, ?, ?, ?, ?, ?>> prepareExpressionStack(
     final SE expression, final Class<SE> clazz) {
   final Stack<ITranslator<?, ?, ?, ?, ?, ?>> current = new Stack<ITranslator<?, ?, ?, ?, ?, ?>>();
   boolean canTranslate = false;
   for (final ITranslator<?, ?, ?, ?, ?, ?> trans : mTranslationSequence) {
     current.push(trans);
     if (trans.getSourceExpressionClass().isAssignableFrom(clazz)) {
       canTranslate = true;
     }
   }
   if (!canTranslate) {
     throw new IllegalArgumentException(
         "You cannot translate "
             + expression.getClass().getName()
             + " with this backtranslation service, as there is no compatible "
             + "ITranslator available. Available translators: "
             + toString());
   }
   if (!current.peek().getSourceExpressionClass().isAssignableFrom(clazz)) {
     throw new IllegalArgumentException(
         "You cannot translate "
             + expression.getClass().getName()
             + " with this backtranslation service, as the last ITranslator in "
             + "this chain is not compatible. Available translators: "
             + toString());
   }
   return current;
 }
  @Override
  public <STE, SE> IProgramExecution<?, ?> translateProgramExecution(
      final IProgramExecution<STE, SE> programExecution) {
    final Stack<ITranslator<?, ?, ?, ?, ?, ?>> current = new Stack<ITranslator<?, ?, ?, ?, ?, ?>>();
    boolean canTranslate = false;
    for (final ITranslator<?, ?, ?, ?, ?, ?> trans : mTranslationSequence) {
      current.push(trans);
      if (trans
              .getSourceTraceElementClass()
              .isAssignableFrom(programExecution.getTraceElementClass())
          && trans
              .getSourceExpressionClass()
              .isAssignableFrom(programExecution.getExpressionClass())) {
        canTranslate = true;
      }
    }
    if (!canTranslate) {
      throw new IllegalArgumentException(
          "You cannot translate "
              + programExecution
              + " with this backtranslation service, as there is no compatible ITranslator available");
    }

    if (!current
            .peek()
            .getSourceTraceElementClass()
            .isAssignableFrom(programExecution.getTraceElementClass())
        || !current
            .peek()
            .getSourceExpressionClass()
            .isAssignableFrom(programExecution.getExpressionClass())) {
      throw new IllegalArgumentException(
          "You cannot translate "
              + programExecution
              + " with this backtranslation service, as the last ITranslator in this chain is not compatible");
    }
    return translateProgramExecution(current, programExecution);
  }