/**
   * Get the document's metadata from the package.
   *
   * @param documentPackage The DocumentPackage we want to get document from.
   * @param documentId Id of document to get.
   * @return the document's metadata
   */
  public com.silanis.esl.sdk.Document getDocumentMetadata(
      DocumentPackage documentPackage, String documentId) {
    String path =
        template
            .urlFor(UrlTemplate.DOCUMENT_ID_PATH)
            .replace("{packageId}", documentPackage.getId().getId())
            .replace("{documentId}", documentId)
            .build();

    try {
      String response = client.get(path);
      Document apilDocument = Serialization.fromJson(response, Document.class);

      // Wipe out the members not related to the metadata
      apilDocument.setApprovals(new ArrayList<Approval>());
      apilDocument.setFields(new ArrayList<Field>());
      apilDocument.setPages(new ArrayList<com.silanis.esl.api.model.Page>());

      return new DocumentConverter(
              apilDocument, new DocumentPackageConverter(documentPackage).toAPIPackage())
          .toSDKDocument();
    } catch (RequestException e) {
      throw new EslServerException("Could not get the document's metadata.", e);
    } catch (Exception e) {
      throw new EslException(
          "Could not get the document's metadata." + " Exception: " + e.getMessage());
    }
  }
  @Override
  public void execute() {
    DocumentPackage template =
        PackageBuilder.newPackageNamed("Template " + getPackageName())
            .describedAs("first message")
            .withEmailMessage(PACKAGE_EMAIL_MESSAGE)
            .withSigner(
                newSignerWithEmail(email1)
                    .withFirstName(PACKAGE_SIGNER1_FIRST)
                    .withLastName(PACKAGE_SIGNER1_LAST)
                    .withTitle(PACKAGE_SIGNER1_TITLE)
                    .withCompany(PACKAGE_SIGNER1_COMPANY)
                    .withCustomId(PACKAGE_SIGNER1_CUSTOM_ID))
            .withDocument(
                DocumentBuilder.newDocumentWithName(DOCUMENT_NAME)
                    .fromStream(documentInputStream1, DocumentType.PDF)
                    .withId(DOCUMENT_ID)
                    .build())
            .build();

    template.setId(eslClient.getTemplateService().createTemplate(template));

    DocumentPackage newPackage =
        PackageBuilder.newPackageNamed(getPackageName())
            .describedAs(PACKAGE_DESCRIPTION)
            .withEmailMessage(PACKAGE_EMAIL_MESSAGE2)
            .withSigner(
                newSignerWithEmail(email2)
                    .withFirstName(PACKAGE_SIGNER2_FIRST)
                    .withLastName(PACKAGE_SIGNER2_LAST)
                    .withTitle(PACKAGE_SIGNER2_TITLE)
                    .withCompany(PACKAGE_SIGNER2_COMPANY)
                    .withCustomId(PACKAGE_SIGNER2_CUSTOM_ID))
            .withSettings(
                DocumentPackageSettingsBuilder.newDocumentPackageSettings()
                    .withoutInPerson()
                    .withoutDecline()
                    .withoutOptOut()
                    .withWatermark()
                    .build())
            .build();

    packageId =
        eslClient.getTemplateService().createPackageFromTemplate(template.getId(), newPackage);
    retrievedPackage = eslClient.getPackage(packageId);
  }
  @Override
  public void execute() {
    DocumentPackage template =
        PackageBuilder.newPackageNamed("Template " + getPackageName())
            .describedAs("first message")
            .withEmailMessage(PACKAGE_EMAIL_MESSAGE)
            .withSigner(SignerBuilder.newSignerPlaceholder(new Placeholder(PLACEHOLDER_ID)))
            .withDocument(
                DocumentBuilder.newDocumentWithName(DOCUMENT_NAME)
                    .fromStream(documentInputStream1, DocumentType.PDF)
                    .withId(DOCUMENT_ID)
                    .withSignature(
                        SignatureBuilder.signatureFor(new Placeholder(PLACEHOLDER_ID))
                            .onPage(0)
                            .atPosition(100, 100))
                    .build())
            .build();

    template.setId(eslClient.getTemplateService().createTemplate(template));

    DocumentPackage newPackage =
        PackageBuilder.newPackageNamed(getPackageName())
            .describedAs(PACKAGE_DESCRIPTION)
            .withEmailMessage(PACKAGE_EMAIL_MESSAGE2)
            .withSigner(
                newSignerWithEmail(email1)
                    .withFirstName(SIGNER1_FIRST)
                    .withLastName(SIGNER1_LAST)
                    .withTitle(SIGNER1_TITLE)
                    .withCompany(SIGNER1_COMPANY)
                    .withCustomId(PLACEHOLDER_ID)
                    .withAttachmentRequirement(
                        AttachmentRequirementBuilder.newAttachmentRequirementWithName(
                                ATTACHMENT_REQUIREMENT_NAME)
                            .withDescription(ATTACHMENT_REQUIREMENT_DESCRIPTION)
                            .isRequiredAttachment()
                            .build()))
            .withSettings(
                DocumentPackageSettingsBuilder.newDocumentPackageSettings().withInPerson().build())
            .build();

    packageId =
        eslClient.getTemplateService().createPackageFromTemplate(template.getId(), newPackage);
    retrievedPackage = eslClient.getPackage(packageId);
  }
  /**
   * 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());
    }
  }
  /**
   * Updates the document's metadata from the package.
   *
   * @param documentPackage
   * @param document
   */
  public void updateDocumentMetadata(
      DocumentPackage documentPackage, com.silanis.esl.sdk.Document document) {
    String path =
        template
            .urlFor(UrlTemplate.DOCUMENT_ID_PATH)
            .replace("{packageId}", documentPackage.getId().getId())
            .replace("{documentId}", document.getId().toString())
            .build();

    Document internalDoc = new DocumentConverter(document).toAPIDocumentMetadata();

    try {
      String json = Serialization.toJson(internalDoc);

      client.put(path, json);
    } catch (RequestException e) {
      throw new EslServerException("Could not update the document's metadata.", e);
    } catch (Exception e) {
      throw new EslException(
          "Could not update the document's metadata." + " Exception: " + e.getMessage());
    }
  }