/**
   * Get Journal Entries.
   *
   * @param userId The ID of the user whose e-journal entries are being retrieved.
   * @return all of the user's notary e-journal entries.
   */
  public List<com.silanis.esl.sdk.NotaryJournalEntry> getJournalEntries(String userId) {
    List<com.silanis.esl.sdk.NotaryJournalEntry> result =
        new ArrayList<com.silanis.esl.sdk.NotaryJournalEntry>();
    String path =
        template.urlFor(UrlTemplate.NOTARY_JOURNAL_PATH).replace("{userId}", userId).build();

    try {
      String stringResponse = client.get(path);
      Result<com.silanis.esl.api.model.NotaryJournalEntry> apiResponse =
          JacksonUtil.deserialize(
              stringResponse,
              new TypeReference<Result<com.silanis.esl.api.model.NotaryJournalEntry>>() {});
      for (com.silanis.esl.api.model.NotaryJournalEntry apiNotaryJournalEntry :
          apiResponse.getResults()) {
        result.add(
            new NotaryJournalEntryConverter(apiNotaryJournalEntry).toSDKNotaryJournalEntry());
      }
      return result;

    } catch (RequestException e) {
      throw new EslException("Could not get Journal Entries.", e);
    } catch (Exception e) {
      throw new EslException("Could not get Journal Entries." + " Exception: " + e.getMessage());
    }
  }
  /**
   * Create Fast Track Package.
   *
   * @param packageId The id of the package to start FastTrack
   * @param signers The signers to get the signing url
   * @return The signing url
   */
  public String startFastTrack(PackageId packageId, List<FastTrackSigner> signers) {
    String token = getFastTrackToken(packageId, true);
    String path =
        template.urlFor(UrlTemplate.START_FAST_TRACK_PATH).replace("{token}", token).build();

    List<FastTrackRole> roles = new ArrayList<FastTrackRole>();
    for (FastTrackSigner signer : signers) {
      FastTrackRole role =
          FastTrackRoleBuilder.newRoleWithId(signer.getId())
              .withName(signer.getId())
              .withSigner(signer)
              .build();
      roles.add(role);
    }

    String json = Serialization.toJson(roles);
    try {
      String response = client.post(path, json);
      SigningUrl signingUrl = Serialization.fromJson(response, SigningUrl.class);
      return signingUrl.getUrl();
    } catch (RequestException e) {
      throw new EslException("Could not start fast track.", e);
    } catch (Exception e) {
      throw new EslException("Could not start fast track." + " Exception: " + e.getMessage());
    }
  }
  private Page<DocumentPackage> convertToPage(Result<Package> results, PageRequest request) {
    List<DocumentPackage> converted = new ArrayList<DocumentPackage>();

    for (Package aPackage : results.getResults()) {
      DocumentPackage dp = new DocumentPackageConverter(aPackage).toSDKPackage();
      converted.add(dp);
    }

    return new Page<DocumentPackage>(converted, results.getCount(), request);
  }
  /**
   * Gets the documents from the history list
   *
   * @return
   */
  public List<com.silanis.esl.sdk.Document> getDocuments() {
    String path = template.urlFor(UrlTemplate.PROVIDER_DOCUMENTS).build();

    try {
      String stringResponse = client.get(path);
      List<Document> apiResponse =
          JacksonUtil.deserialize(stringResponse, new TypeReference<List<Document>>() {});
      List<com.silanis.esl.sdk.Document> documents = new ArrayList<com.silanis.esl.sdk.Document>();
      for (Document document : apiResponse) {
        documents.add(new DocumentConverter(document, null).toSDKDocument());
      }
      return documents;
    } catch (RequestException e) {
      throw new EslServerException("Failed to retrieve documents from history List.", e);
    } catch (Exception e) {
      throw new EslException("Failed to retrieve documents from history list.", e);
    }
  }
  /**
   * Upload documents with external content to the package.
   *
   * @param packageId
   */
  public void addDocumentWithExternalContent(
      String packageId, List<com.silanis.esl.sdk.Document> providerDocuments) {
    String path =
        template.urlFor(UrlTemplate.DOCUMENT_PATH).replace("{packageId}", packageId).build();

    List<Document> apiDocuments = new ArrayList<Document>();
    for (com.silanis.esl.sdk.Document document : providerDocuments) {
      apiDocuments.add(new DocumentConverter(document).toAPIDocumentMetadata());
    }
    try {
      String json = Serialization.toJson(apiDocuments);
      client.post(path, json);
    } catch (RequestException e) {
      throw new EslServerException("Could not upload the documents.", e);
    } catch (Exception e) {
      throw new EslException("Could not upload the documents." + " Exception: " + e.getMessage());
    }
  }
  /**
   * Updates the documents signing order
   *
   * @param documentPackage
   */
  public void orderDocuments(DocumentPackage documentPackage) {
    String path =
        template
            .urlFor(UrlTemplate.DOCUMENT_PATH)
            .replace("{packageId}", documentPackage.getId().getId())
            .build();

    List<Document> documents = new ArrayList<Document>();
    for (com.silanis.esl.sdk.Document document : documentPackage.getDocuments()) {
      documents.add(new DocumentConverter(document).toAPIDocumentMetadata());
    }
    try {
      String json = Serialization.toJson(documents);

      client.put(path, json);
    } catch (RequestException e) {
      throw new EslServerException("Could not order the documents.", e);
    } catch (Exception e) {
      throw new EslException("Could not order the documents." + " Exception: " + e.getMessage());
    }
  }
  /**
   * Updates the signer order in a package.
   *
   * @param documentPackage The id of the package to update signer order
   */
  public void orderSigners(DocumentPackage documentPackage) {
    String path =
        template
            .urlFor(UrlTemplate.ROLE_PATH)
            .replace("{packageId}", documentPackage.getId().getId())
            .build();

    List<Role> roles = new ArrayList<Role>();
    for (com.silanis.esl.sdk.Signer signer : documentPackage.getSigners()) {
      roles.add(new SignerConverter(signer).toAPIRole(signer.getId()));
    }

    try {
      String json = Serialization.toJson(roles);
      client.put(path, json);
    } catch (RequestException e) {
      throw new EslServerException("Could not order signers.", e);
    } catch (Exception e) {
      throw new EslException("Could not order signers." + " Exception: " + e.getMessage());
    }
  }