@Override
  public String findMailAddressFor(User u) {
    String username = u.getId();

    for (JiraSite site : JiraProjectProperty.DESCRIPTOR.getSites()) {
      try {
        JiraSession session = site.createSession();
        if (session != null) {
          RemoteUser user = session.service.getUser(session.token, username);
          if (user != null) {
            String email = user.getEmail();
            if (email != null) {
              email = unmaskEmail(email);
              return email;
            }
          }
        }
      } catch (IOException ex) {
        LOGGER.log(Level.WARNING, "Unable to create session with " + site.getName(), ex);
      } catch (ServiceException ex) {
        LOGGER.log(Level.WARNING, "Unable to create session with " + site.getName(), ex);
      }
    }
    return null;
  }
  /**
   * Gets the {@link JiraSite} that this project belongs to.
   *
   * @return null if the configuration becomes out of sync.
   */
  public JiraSite getSite() {
    JiraSite[] sites = DESCRIPTOR.getSites();
    if (siteName == null && sites.length > 0)
      // default
      return sites[0];

    for (JiraSite site : sites) {
      if (site.getName().equals(siteName)) return site;
    }
    return null;
  }
  /** Performs the actual update based on job configuration. */
  @Override
  public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
      throws InterruptedException, IOException {
    String realComment = Util.fixEmptyAndTrim(build.getEnvironment(listener).expand(comment));
    String realJql = Util.fixEmptyAndTrim(build.getEnvironment(listener).expand(jqlSearch));
    String realWorkflowActionName =
        Util.fixEmptyAndTrim(build.getEnvironment(listener).expand(workflowActionName));

    JiraSite site = JiraSite.get(build.getProject());

    if (site == null) {
      listener.getLogger().println(Messages.Updater_NoJiraSite());
      build.setResult(Result.FAILURE);
      return true;
    }

    if (StringUtils.isNotEmpty(realWorkflowActionName)) {
      listener
          .getLogger()
          .println(Messages.JiraIssueUpdateBuilder_UpdatingWithAction(realWorkflowActionName));
    }

    listener.getLogger().println("[JIRA] JQL: " + realJql);

    try {
      if (!site.progressMatchingIssues(
          realJql, realWorkflowActionName, realComment, listener.getLogger())) {
        listener.getLogger().println(Messages.JiraIssueUpdateBuilder_SomeIssuesFailed());
        build.setResult(Result.UNSTABLE);
      }
    } catch (ServiceException e) {
      listener.getLogger().println(Messages.JiraIssueUpdateBuilder_Failed());
      e.printStackTrace(listener.getLogger());
      return false;
    }

    return true;
  }