// output dir is a function of where the original file/module was located.
 @Override
 protected void write(
     @NotNull ModuleIdentifier moduleIdentifier,
     @NotNull ST code,
     @NotNull String outputFileName) {
   try {
     Writer w =
         compiler.getOutputFileWriter(
             moduleIdentifier,
             outputFileName,
             new Function<String, File>() {
               @Override
               public File apply(String s) {
                 Path p = moduleIdentifier.getPathRelativeToRootDir();
                 String outputDir = compiler.outputDirectory;
                 if (compiler.outputDirectory.equals(".")) outputDir = "out";
                 return new File(outputDir, p.getParent().toString());
               }
             });
     STWriter wr = new AutoIndentWriter(w);
     wr.setLineWidth(80);
     code.write(wr);
     w.close();
   } catch (IOException ioe) {
     compiler.errMgr.toolError(ErrorKind.CANNOT_WRITE_FILE, ioe, outputFileName);
   }
 }
 @Override
 protected int writePOJO(STWriter out, InstanceScope scope, Object o, String[] options)
     throws IOException {
   Class<?> type = o.getClass();
   String name = type.getSimpleName();
   out.write("<pojo:" + name + ">" + o.toString() + "</pojo:" + name + ">");
   evals.add("<pojo:" + name + ">" + o.toString() + "</pojo:" + name + ">");
   return super.writePOJO(out, scope, o, options);
 }
 @Override
 protected int writeObject(STWriter out, InstanceScope scope, Object o, String[] options) {
   if (o instanceof ST) {
     String name = ((ST) o).getName();
     name = name.substring(1);
     if (!name.startsWith("_sub")) {
       try {
         out.write("<ST:" + name + ">");
         evals.add("<ST:" + name + ">");
         int r = super.writeObject(out, scope, o, options);
         out.write("</ST:" + name + ">");
         evals.add("</ST:" + name + ">");
         return r;
       } catch (IOException ioe) {
         myErrMgrCopy.IOError(scope.st, ErrorType.WRITE_IO_ERROR, ioe);
       }
     }
   }
   return super.writeObject(out, scope, o, options);
 }
 public void indent(STWriter out) throws IOException {
   for (int i = 1; i <= tab; i++) {
     out.write("\t");
   }
 }