private boolean executePresendScript(
      AbstractBuild<?, ?> build,
      BuildListener listener,
      MimeMessage msg,
      EmailTrigger trigger,
      Map<String, EmailTrigger> triggered)
      throws RuntimeException {
    boolean cancel = false;
    presendScript = new ContentBuilder().transformText(presendScript, this, build, listener);
    if (StringUtils.isNotBlank(presendScript)) {
      listener.getLogger().println("Executing pre-send script");
      ClassLoader cl = Jenkins.getInstance().getPluginManager().uberClassLoader;
      ScriptSandbox sandbox = null;
      CompilerConfiguration cc = new CompilerConfiguration();
      cc.addCompilationCustomizers(
          new ImportCustomizer()
              .addStarImports("jenkins", "jenkins.model", "hudson", "hudson.model"));

      if (ExtendedEmailPublisher.DESCRIPTOR.isSecurityEnabled()) {
        debug(listener.getLogger(), "Setting up sandbox for pre-send script");
        cc.addCompilationCustomizers(new SandboxTransformer());
        sandbox = new ScriptSandbox();
      }

      Binding binding = new Binding();
      binding.setVariable("build", build);
      binding.setVariable("msg", msg);
      binding.setVariable("logger", listener.getLogger());
      binding.setVariable("cancel", cancel);
      binding.setVariable("trigger", trigger);
      binding.setVariable("triggered", Collections.unmodifiableMap(triggered));

      GroovyShell shell = new GroovyShell(cl, binding, cc);
      StringWriter out = new StringWriter();
      PrintWriter pw = new PrintWriter(out);

      if (sandbox != null) {
        sandbox.register();
      }

      try {
        Object output = shell.evaluate(presendScript);
        if (output != null) {
          pw.println("Result: " + output);
          cancel = ((Boolean) shell.getVariable("cancel")).booleanValue();
          debug(listener.getLogger(), "Pre-send script set cancel to %b", cancel);
        }
      } catch (SecurityException e) {
        listener
            .getLogger()
            .println("Pre-send script tried to access secured objects: " + e.getMessage());
      } catch (Throwable t) {
        t.printStackTrace(pw);
        listener.getLogger().println(out.toString());
        // should we cancel the sending of the email???
      }
      debug(listener.getLogger(), out.toString());
    }
    return !cancel;
  }
  private MimeMessage createMail(
      EmailType type, AbstractBuild<?, ?> build, BuildListener listener, EmailTrigger trigger)
      throws MessagingException, IOException, InterruptedException {
    boolean overrideGlobalSettings = ExtendedEmailPublisher.DESCRIPTOR.getOverrideGlobalSettings();

    MimeMessage msg;

    // If not overriding global settings, use the Mailer class to create a session and set the from
    // address
    // Else we'll do it ourselves
    if (!overrideGlobalSettings) {
      debug(
          listener.getLogger(),
          "NOT overriding default server settings, using Mailer to create session");
      msg = new MimeMessage(Mailer.descriptor().createSession());
      msg.setFrom(new InternetAddress(Mailer.descriptor().getAdminAddress()));
    } else {
      debug(listener.getLogger(), "Overriding default server settings, creating our own session");
      msg = new MimeMessage(ExtendedEmailPublisher.DESCRIPTOR.createSession());
      msg.setFrom(new InternetAddress(ExtendedEmailPublisher.DESCRIPTOR.getAdminAddress()));
    }

    String charset = Mailer.descriptor().getCharset();
    if (overrideGlobalSettings) {
      String overrideCharset = ExtendedEmailPublisher.DESCRIPTOR.getCharset();
      if (StringUtils.isNotBlank(overrideCharset)) {
        debug(listener.getLogger(), "Overriding charset %s", overrideCharset);
        charset = overrideCharset;
      }
    }

    // Set the contents of the email
    msg.addHeader("X-Jenkins-Job", build.getProject().getDisplayName());
    if (build.getResult() != null) {
      msg.addHeader("X-Jenkins-Result", build.getResult().toString());
    }
    msg.setSentDate(new Date());
    setSubject(type, build, msg, listener, charset);

    Multipart multipart = new MimeMultipart();
    multipart.addBodyPart(getContent(type, build, listener, charset, trigger));

    AttachmentUtils attachments = new AttachmentUtils(attachmentsPattern);
    attachments.attach(multipart, this, build, listener);

    // add attachments from the email type if they are setup
    if (StringUtils.isNotBlank(type.getAttachmentsPattern())) {
      AttachmentUtils typeAttachments = new AttachmentUtils(type.getAttachmentsPattern());
      typeAttachments.attach(multipart, this, build, listener);
    }

    if (attachBuildLog || type.getAttachBuildLog()) {
      debug(listener.getLogger(), "Request made to attach build log");
      AttachmentUtils.attachBuildLog(
          multipart, build, listener, compressBuildLog || type.getCompressBuildLog());
    }

    msg.setContent(multipart);

    EnvVars env = null;
    try {
      env = build.getEnvironment(listener);
    } catch (Exception e) {
      listener.getLogger().println("Error retrieving environment vars: " + e.getMessage());
      // create an empty set of env vars
      env = new EnvVars();
    }

    // Get the recipients from the global list of addresses
    Set<InternetAddress> recipientAddresses = new LinkedHashSet<InternetAddress>();
    Set<InternetAddress> ccAddresses = new LinkedHashSet<InternetAddress>();
    if (type.getSendToRecipientList()) {
      debug(listener.getLogger(), "Adding recipients from recipient list");
      addAddressesFromRecipientList(
          recipientAddresses,
          ccAddresses,
          getRecipientList(type, build, recipientList, listener, charset),
          env,
          listener);
    }
    // Get the list of developers who made changes between this build and the last
    // if this mail type is configured that way
    if (type.getSendToDevelopers()) {
      debug(listener.getLogger(), "Adding developers");
      Set<User> users;
      if (type.getIncludeCulprits()) {
        users = build.getCulprits();
      } else {
        users = new HashSet<User>();
        for (Entry change : build.getChangeSet()) {
          users.add(change.getAuthor());
        }
      }

      for (User user : users) {
        if (!isExcludedCommitter(user.getFullName())) {
          String userAddress = EmailRecipientUtils.getUserConfiguredEmail(user);
          if (userAddress != null) {
            addAddressesFromRecipientList(
                recipientAddresses, ccAddresses, userAddress, env, listener);
          } else {
            listener
                .getLogger()
                .println(
                    "Failed to send e-mail to "
                        + user.getFullName()
                        + " because no e-mail address is known, and no default e-mail domain is configured");
          }
        }
      }
    }

    if (type.isSendToRequester()) {
      debug(listener.getLogger(), "Sending to requester");
      // looking for Upstream build.
      AbstractBuild<?, ?> cur = build;
      Cause.UpstreamCause upc = build.getCause(Cause.UpstreamCause.class);
      while (upc != null) {
        // UpstreamCause.getUpStreamProject() returns the full name, so use getItemByFullName
        AbstractProject<?, ?> p =
            (AbstractProject<?, ?>)
                Hudson.getInstance().getItemByFullName(upc.getUpstreamProject());
        cur = p.getBuildByNumber(upc.getUpstreamBuild());
        upc = cur.getCause(Cause.UpstreamCause.class);
      }
      addUserTriggeringTheBuild(cur, recipientAddresses, ccAddresses, env, listener);
    }

    // Get the list of recipients that are uniquely specified for this type of email
    if (StringUtils.isNotBlank(type.getRecipientList())) {
      addAddressesFromRecipientList(
          recipientAddresses,
          ccAddresses,
          getRecipientList(type, build, type.getRecipientList(), listener, charset),
          env,
          listener);
    }

    String emergencyReroute = ExtendedEmailPublisher.DESCRIPTOR.getEmergencyReroute();
    boolean isEmergencyReroute = StringUtils.isNotBlank(emergencyReroute);

    if (isEmergencyReroute) {
      debug(listener.getLogger(), "Emergency reroute turned on");
      recipientAddresses.clear();
      addAddressesFromRecipientList(
          recipientAddresses, ccAddresses, emergencyReroute, env, listener);
      listener.getLogger().println("Emergency reroute is set to: " + emergencyReroute);
    }

    msg.setRecipients(
        Message.RecipientType.TO,
        recipientAddresses.toArray(new InternetAddress[recipientAddresses.size()]));
    if (ccAddresses.size() > 0) {
      msg.setRecipients(
          Message.RecipientType.CC, ccAddresses.toArray(new InternetAddress[ccAddresses.size()]));
    }

    Set<InternetAddress> replyToAddresses = new LinkedHashSet<InternetAddress>();
    if (StringUtils.isNotBlank(replyTo)) {
      addAddressesFromRecipientList(
          replyToAddresses,
          null,
          getRecipientList(type, build, replyTo, listener, charset),
          env,
          listener);
    }

    if (StringUtils.isNotBlank(type.getReplyTo())) {
      addAddressesFromRecipientList(
          replyToAddresses,
          null,
          getRecipientList(type, build, type.getReplyTo(), listener, charset),
          env,
          listener);
    }

    if (replyToAddresses.size() > 0) {
      msg.setReplyTo(replyToAddresses.toArray(new InternetAddress[replyToAddresses.size()]));
    }

    AbstractBuild<?, ?> pb = build.getPreviousBuild();
    if (pb != null) {
      // Send mails as replies until next successful build
      MailMessageIdAction b = pb.getAction(MailMessageIdAction.class);
      if (b != null && pb.getResult() != Result.SUCCESS) {
        debug(listener.getLogger(), "Setting In-Reply-To since last build was not successful");
        msg.setHeader("In-Reply-To", b.messageId);
        msg.setHeader("References", b.messageId);
      }
    }

    if (CONTENT_TRANSFER_ENCODING != null) {
      msg.setHeader("Content-Transfer-Encoding", CONTENT_TRANSFER_ENCODING);
    }

    String listId = ExtendedEmailPublisher.DESCRIPTOR.getListId();
    if (listId != null) {
      msg.setHeader("List-ID", listId);
    }

    if (ExtendedEmailPublisher.DESCRIPTOR.getPrecedenceBulk()) {
      msg.setHeader("Precedence", "bulk");
    }

    return msg;
  }
 public void debug(PrintStream p, String format, Object... args) {
   ExtendedEmailPublisher.DESCRIPTOR.debug(p, format, args);
 }