/**
   * Converts a document and returns an {@link InputStream}.
   *
   * @param document The file to convert
   * @param mediaType Internet media type of the file
   * @param conversionTarget The conversion target to use
   * @param customConfig The additional config params to use
   * @return Converted document in the specified format
   * @see {@link HttpMediaType} for available media types
   */
  private InputStream convertDocument(
      final File document,
      final String mediaType,
      final ConversionTarget conversionTarget,
      final JsonObject customConfig) {

    if (document == null || !document.exists())
      throw new IllegalArgumentException("document cannot be null and must exist");

    if (customConfig == null) throw new NullPointerException("custom config must not be null");

    final String type =
        mediaType != null ? mediaType : ConversionUtils.getMediaTypeFromFile(document);
    if (type == null) {
      throw new RuntimeException("mediaType cannot be null or empty");
    } else if (!ConversionUtils.isValidMediaType(type)) {
      throw new IllegalArgumentException("file with the given media type is not supported");
    }

    final JsonObject configJson = new JsonObject();
    // Do this since we shouldn't mutate customConfig
    for (Map.Entry<String, JsonElement> entry : customConfig.entrySet()) {
      configJson.add(entry.getKey(), entry.getValue());
    }
    // Add or override the conversion target
    configJson.addProperty(CONVERSION_TARGET, conversionTarget.toString());

    final MediaType mType = MediaType.parse(type);
    final RequestBody body =
        new MultipartBuilder()
            .type(MultipartBuilder.FORM)
            .addPart(
                Headers.of(HttpHeaders.CONTENT_DISPOSITION, "form-data; name=\"config\""),
                RequestBody.create(HttpMediaType.JSON, configJson.toString()))
            .addPart(
                Headers.of(HttpHeaders.CONTENT_DISPOSITION, "form-data; name=\"file\""),
                RequestBody.create(mType, document))
            .build();

    final Request request =
        RequestBuilder.post(CONVERT_DOCUMENT_PATH)
            .withQuery(VERSION, versionDate)
            .withBody(body)
            .build();

    final Response response = execute(request);
    return ResponseUtil.getInputStream(response);
  }
 /** Consumes the InputStream, converting it into a String. */
 private String responseToString(InputStream is) {
   try {
     return ConversionUtils.writeInputStreamToString(is);
   } finally {
     try {
       is.close();
     } catch (final IOException e) {
       LOG.log(Level.WARNING, "Unable to close document input stream", e);
     }
   }
 }