code: protected final <R extends AbstractPutObjectRequest> R wrapWithCipher(
          final R request, ContentCryptoMaterial cekMaterial) {
          // 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 = plaintextLength(request, metadata);
          if (plaintextLength >= 0) {
              metadata.addUserMetadata(Headers.UNENCRYPTED_CONTENT_LENGTH,
                                       Long.toString(plaintextLength));
              // Put the ciphertext length in the metadata
              metadata.setContentLength(ciphertextLength(plaintextLength));
          }
          request.setMetadata(metadata);
          request.setInputStream(newS3CipherLiteInputStream(
              request, cekMaterial, plaintextLength));
          // Treat all encryption requests as input stream upload requests, not as
          // file upload requests.
          request.setFile(null);
          return request;
      }
docs: Returns the given <code>PutObjectRequest</code> but has the content as
  input stream wrapped with a cipher, and configured with some meta data
  and user metadata.