/**
   * Returns an updated object where the object content input stream contains the decrypted
   * contents.
   *
   * @param object The object whose contents are to be decrypted.
   * @param instruction The instruction that will be used to decrypt the object data.
   * @return The updated object where the object content input stream contains the decrypted
   *     contents.
   * @deprecated no longer used and will be removed in the future
   */
  @Deprecated
  public static S3Object decryptObjectUsingInstruction(
      S3Object object, EncryptionInstruction instruction) {
    S3ObjectInputStream objectContent = object.getObjectContent();

    InputStream decryptedInputStream =
        new RepeatableCipherInputStream(objectContent, instruction.getCipherFactory());
    object.setObjectContent(
        new S3ObjectInputStream(decryptedInputStream, objectContent.getHttpRequest()));
    return object;
  }
  /**
   * Returns an updated request where the input stream contains the encrypted object contents. The
   * specified instruction will be used to encrypt data.
   *
   * @param request The request whose contents are to be encrypted.
   * @param instruction The instruction that will be used to encrypt the object data.
   * @return The updated request where the input stream contains the encrypted contents.
   * @deprecated no longer used and will be removed in the future
   */
  @Deprecated
  public static PutObjectRequest encryptRequestUsingInstruction(
      PutObjectRequest request, EncryptionInstruction instruction) {
    // Create a new metadata object if there is no metadata already.
    ObjectMetadata metadata = request.getMetadata();
    if (metadata == null) {
      metadata = new ObjectMetadata();
    }

    // Record the original Content MD5, if present, for the unencrypted data
    if (metadata.getContentMD5() != null) {
      metadata.addUserMetadata(Headers.UNENCRYPTED_CONTENT_MD5, metadata.getContentMD5());
    }

    // Removes the original content MD5 if present from the meta data.
    metadata.setContentMD5(null);

    // Record the original, unencrypted content-length so it can be accessed later
    final long plaintextLength = getUnencryptedContentLength(request, metadata);
    if (plaintextLength >= 0) {
      metadata.addUserMetadata(Headers.UNENCRYPTED_CONTENT_LENGTH, Long.toString(plaintextLength));
    }

    // Put the calculated length of the encrypted contents in the metadata
    long cryptoContentLength =
        calculateCryptoContentLength(instruction.getSymmetricCipher(), request, metadata);
    if (cryptoContentLength >= 0) {
      metadata.setContentLength(cryptoContentLength);
    }

    request.setMetadata(metadata);

    // Create encrypted input stream
    request.setInputStream(
        getEncryptedInputStream(request, instruction.getCipherFactory(), plaintextLength));

    // Treat all encryption requests as input stream upload requests, not as file upload requests.
    request.setFile(null);

    return request;
  }