private Role getRole(Package apiPackage, String sigenrId) {
   for (Role role : apiPackage.getRoles()) {
     for (Signer signer : role.getSigners()) {
       if (signer.getId().equals(sigenrId)) {
         return role;
       }
     }
   }
   return new Role();
 }
  private String findRoleUidByName(List<Role> roles, String roleName) {
    if (roleName == null || roleName.trim().isEmpty()) {
      return null;
    }

    for (Role role : roles) {
      if (roleName.equalsIgnoreCase(role.getName())) {
        return role.getId();
      }
    }

    return null;
  }
  private Role findRoleForGroup(PackageId packageId, String groupId) {
    List<Role> roles = getRoles(packageId);

    for (Role role : roles) {
      if (!role.getSigners().isEmpty()) {
        Signer signer = role.getSigners().get(0);
        if (signer.getGroup() != null) {
          if (signer.getGroup().getId().equals(groupId)) {
            return role;
          }
        }
      }
    }
    return null;
  }
  /**
   * Adds a signer to the specified package
   *
   * @param packageId The id of the package in which the signer will be added
   * @param signer The signer to be added
   * @return The role id of the signer
   */
  public String addSigner(PackageId packageId, com.silanis.esl.sdk.Signer signer) {
    Role apiPayload =
        new SignerConverter(signer).toAPIRole(UUID.randomUUID().toString().replace("-", ""));

    String path =
        template
            .urlFor(UrlTemplate.ADD_SIGNER_PATH)
            .replace("{packageId}", packageId.getId())
            .build();

    try {
      String json = Serialization.toJson(apiPayload);
      String response = client.post(path, json);
      Role apiRole = Serialization.fromJson(response, Role.class);
      return apiRole.getId();

    } catch (RequestException e) {
      throw new EslServerException("Could not add signer.", e);
    } catch (Exception e) {
      throw new EslException("Could not add signer." + " Exception: " + e.getMessage());
    }
  }
  /**
   * Create a new package based on an existing template.
   *
   * @param packageId
   * @param aPackage
   * @return PackageId
   */
  public PackageId createPackageFromTemplate(PackageId packageId, Package aPackage) {
    String path =
        template
            .urlFor(UrlTemplate.TEMPLATE_PATH)
            .replace("{packageId}", packageId.getId())
            .build();

    List<Role> roles = aPackage.getRoles();

    aPackage.setRoles(Collections.<Role>emptyList());

    String packageJson = Serialization.toJson(aPackage);
    PackageId newPackageId = null;
    try {

      String response = client.post(path, packageJson);

      newPackageId = Serialization.fromJson(response, PackageId.class);
    } catch (RequestException e) {
      throw new EslServerException("Could not create a new package", e);
    } catch (Exception e) {
      throw new EslException("Could not create a new package", e);
    }

    Package createdPackage = getApiPackage(newPackageId.getId());

    for (Role role : roles) {
      String roleUid = findRoleUidByName(createdPackage.getRoles(), role.getName());

      if (roleUid == null) {
        continue;
      }

      role.setId(roleUid);
      updateRole(newPackageId, role);
    }

    return newPackageId;
  }
 /**
  * Deletes a role from the package.
  *
  * @param packageId
  * @param role
  * @throws EslException
  */
 public void deleteRole(PackageId packageId, Role role) throws EslException {
   String path =
       template
           .urlFor(UrlTemplate.ROLE_ID_PATH)
           .replace("{packageId}", packageId.getId())
           .replace("{roleId}", role.getId())
           .build();
   try {
     client.delete(path);
   } catch (RequestException e) {
     throw new EslServerException("Could not delete role", e);
   } catch (Exception e) {
     throw new EslException("Could not delete role", e);
   }
 }
  private void sendSmsToSigner(PackageId packageId, Role role) {
    String path =
        template
            .urlFor(UrlTemplate.SEND_SMS_TO_SIGNER_PATH)
            .replace("{packageId}", packageId.getId())
            .replace("{roleId}", role.getId())
            .build();

    try {
      client.post(path, null);
    } catch (RequestException e) {
      throw new EslException("Could not send SMS to the signer.", e);
    } catch (Exception e) {
      throw new EslException("Could not send SMS to the signer." + " Exception: " + e.getMessage());
    }
  }
  /**
   * Updates a role from the package.
   *
   * @param packageId
   * @param role
   * @return The updated role
   * @throws EslException
   */
  public Role updateRole(PackageId packageId, Role role) throws EslException {
    String path =
        template
            .urlFor(UrlTemplate.ROLE_ID_PATH)
            .replace("{packageId}", packageId.getId())
            .replace("{roleId}", role.getId())
            .build();

    String roleJson = JacksonUtil.serializeDirty(role);
    String stringResponse;
    try {
      stringResponse = client.put(path, roleJson);
    } catch (RequestException e) {
      throw new EslServerException("Could not update role", e);
    } catch (Exception e) {
      throw new EslException("Could not update role", e);
    }
    return Serialization.fromJson(stringResponse, Role.class);
  }
  private String getSigningUrl(PackageId packageId, Role role) {

    String path =
        template
            .urlFor(UrlTemplate.SIGNER_URL_PATH)
            .replace("{packageId}", packageId.getId())
            .replace("{roleId}", role.getId())
            .build();

    try {
      String response = client.get(path);
      SigningUrl signingUrl = Serialization.fromJson(response, SigningUrl.class);
      return signingUrl.getUrl();
    } catch (RequestException e) {
      throw new EslException("Could not get a signing url.", e);
    } catch (Exception e) {
      throw new EslException("Could not get a signing url." + " Exception: " + e.getMessage());
    }
  }
 public void notifySigner(PackageId packageId, GroupId groupId) {
   Role role = findRoleForGroup(packageId, groupId.getId());
   notifySigner(packageId, role.getId());
 }