class TransactionTracer {

  public List<String> traceTransactionToFile(
      final Hash blockHash,
      final List<Transaction> transactions,
      final Optional<TransactionTraceParams> transactionTraceParams,
      final Path traceDir) {
    final List<String> traces = new ArrayList<>();
    try {
      final Optional<Hash> selectedHash =
          transactionTraceParams
              .map(TransactionTraceParams::getTransactionHash)
              .map(Hash::fromHexString);
      final boolean showMemory =
          transactionTraceParams
              .map(TransactionTraceParams::traceOptions)
              .map(TraceOptions::isMemoryEnabled)
              .orElse(true);

      if (!Files.isDirectory(traceDir) && !traceDir.toFile().mkdirs()) {
        throw new IOException(
            String.format("Trace directory '%s' does not exist and could not be made.", traceDir));
      }
      for (int i = 0; i < transactions.size(); i++) {
        final Transaction transaction = transactions.get(i);
        if (selectedHash.isEmpty()
            || selectedHash.filter(isEqual(transaction.getHash())).isPresent()) {
          final File traceFile =
              traceDir
                  .resolve(
                      String.format(
                          "block_%.10s-%d-%.10s-%s",
                          blockHash.toHexString(),
                          i,
                          transaction.getHash().toHexString(),
                          System.currentTimeMillis()))
                  .toFile();
          try (PrintStream out = new PrintStream(new FileOutputStream(traceFile))) {
            traceTransaction(
                    blockHash, transaction.getHash(), new StandardJsonTracer(out, showMemory))
                .ifPresent(
                    trace ->
                        out.println(
                            StandardJsonTracer.summaryTrace(
                                transaction, trace.getTime().orElseThrow(), trace.getResult())));
            traces.add(traceFile.getPath());
          }
        }
      }
    } catch (Exception e) {
      LOG.error("Unable to create transaction trace : {}", e.getMessage());
      throw new RuntimeException(e.getMessage(), e);
    }
    return traces;
  }

  public  TransactionTracer(final BlockReplay blockReplay);

}