docs: private String renderTemplate(Run<?, ?> build, FilePath workspace, TaskListener listener, InputStream templateStream)
              throws IOException {
          
          String result;
          
          final Map<String, Object> binding = new HashMap<>();
          ExtendedEmailPublisherDescriptor descriptor = Jenkins.getActiveInstance().getDescriptorByType(ExtendedEmailPublisherDescriptor.class);
          binding.put("build", build);
          binding.put("listener", listener);
          binding.put("it", new ScriptContentBuildWrapper(build));
          binding.put("rooturl", descriptor.getHudsonUrl());
          binding.put("project", build.getParent());
          binding.put("workspace", workspace);
  
          try {
              String text = IOUtils.toString(templateStream);
              boolean approvedScript = false;
              if (templateStream instanceof UserProvidedContentInputStream && !AbstractEvalContent.isApprovedScript(text, GroovyLanguage.get())) {
                  approvedScript = false;
                  ScriptApproval.get().configuring(text, GroovyLanguage.get(), ApprovalContext.create().withItem(build.getParent()));
              } else {
                  approvedScript = true;
              }
              // we add the binding to the SimpleTemplateEngine instead of the shell
              GroovyShell shell = createEngine(descriptor, Collections.<String, Object>emptyMap(), !approvedScript);
              SimpleTemplateEngine engine = new SimpleTemplateEngine(shell);
              Template tmpl;
              synchronized (templateCache) {
                  Reference<Template> templateR = templateCache.get(text);
                  tmpl = templateR == null ? null : templateR.get();
                  if (tmpl == null) {
                      tmpl = engine.createTemplate(text);
                      templateCache.put(text, new SoftReference<>(tmpl));
                  }
              }
              final Template tmplR = tmpl;
              if (approvedScript) {
                  //The script has been approved by an admin, so run it as is
                  result = tmplR.make(binding).toString();
              } else {
                  //unapproved script, so run in sandbox
                  StaticProxyInstanceWhitelist whitelist = new StaticProxyInstanceWhitelist(build, "templates-instances.whitelist");
                  result = GroovySandbox.runInSandbox(new Callable<String>() {
                      @Override
                      public String call() throws Exception {
                          return tmplR.make(binding).toString(); //TODO there is a PrintWriter instance created in make and bound to out
                      }
                  }, new ProxyWhitelist(
                          Whitelist.all(),
                          new TaskListenerInstanceWhitelist(listener),
                          new PrintStreamInstanceWhitelist(listener.getLogger()),
                          new EmailExtScriptTokenMacroWhitelist(),
                          whitelist));
              }
  
          } catch(Exception e) {
              StringWriter sw = new StringWriter();
              PrintWriter pw = new PrintWriter(sw);
              e.printStackTrace(pw);
              result = "Exception raised during template rendering: " + e.getMessage() + "\n\n" + sw.toString();
          }
          return result;
      }