/**
   * Merge the newly processed data with an (possible) existing data already present, also convert
   * the completed JSON merge into a Stream for storage.
   *
   * @param dataJson an instantiated JSON object containing data to store
   * @param metaJson an instantiated JSON object containing metadata to store
   * @param existing an instantiated JsonSimple object with any existing data
   * @throws IOException if any character encoding issues effect the Stream
   */
  private InputStream streamMergedJson(
      JsonObject dataJson, JsonObject metaJson, JsonSimple existing) throws IOException {
    // Overwrite and/or create only nodes we consider new data
    existing.getJsonObject().put("recordIDPrefix", idPrefix);
    JsonObject existingData = existing.writeObject("data");
    existingData.putAll(dataJson);
    JsonObject existingMeta = existing.writeObject("metadata");
    existingMeta.putAll(metaJson);

    // Turn into a stream to return
    String jsonString = existing.toString(true);
    return IOUtils.toInputStream(jsonString, "UTF-8");
  }
  /**
   * Main render method to send the file to ICE service
   *
   * @param sourceFile : File to be rendered
   * @return file returned by ICE service
   * @throws TransformerException
   */
  private File render(File sourceFile) throws TransformerException {
    log.info("Converting {}...", sourceFile);
    String filename = sourceFile.getName();
    String basename = FilenameUtils.getBaseName(filename);
    String ext = FilenameUtils.getExtension(filename);
    int status = HttpStatus.SC_OK;

    // Grab our config
    JsonObject object = itemConfig.getObject("resize");
    Map<String, JsonSimple> resizeConfig = JsonSimple.toJavaMap(object);

    if (resizeConfig == null || resizeConfig.isEmpty()) {
      // Try system config instead
      object = config.getObject("resize");
      resizeConfig = JsonSimple.toJavaMap(object);
      if (resizeConfig == null || resizeConfig.isEmpty()) {
        throw new TransformerException("No resizing configuration found.");
      }
    }

    String resizeJson = "";
    for (String key : resizeConfig.keySet()) {
      JsonSimple j = resizeConfig.get(key);
      resizeJson += "\"" + key + "\":" + j.toString() + ",";
    }

    PostMethod post = new PostMethod(convertUrl);
    try {
      Part[] parts = {
        new StringPart("zip", "on"),
        new StringPart("dc", "on"),
        new StringPart("toc", "on"),
        new StringPart("pdflink", "on"),
        new StringPart("addThumbnail", "on"),
        new StringPart("pathext", ext),
        new StringPart("template", getTemplate()),
        new StringPart(
            "multipleImageOptions", "{" + StringUtils.substringBeforeLast(resizeJson, ",") + "}"),
        new StringPart("mode", "download"),
        new FilePart("file", sourceFile)
      };
      post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
      BasicHttpClient client = new BasicHttpClient(convertUrl);
      log.debug("Using conversion URL: {}", convertUrl);
      status = client.executeMethod(post);
      log.debug("HTTP status: {} {}", status, HttpStatus.getStatusText(status));
    } catch (IOException ioe) {
      throw new TransformerException("Failed to send ICE conversion request", ioe);
    }
    try {
      if (status != HttpStatus.SC_OK) {
        String xmlError = post.getResponseBodyAsString();
        log.debug("Error: {}", xmlError);
        throw new TransformerException(xmlError);
      }
      String type = post.getResponseHeader("Content-Type").getValue();
      if ("application/zip".equals(type)) {
        filename = basename + ".zip";
      } else if (type.startsWith("image/")) {
        filename = basename + "_thumbnail.jpg";
      } else if ("video/x-flv".equals(type)) {
        filename = basename + ".flv";
      } else if ("audio/mpeg".equals(type)) {
        filename = basename + ".mp3";
      }
      File outputFile = new File(outputDir, filename);
      if (outputFile.exists()) {
        outputFile.delete();
      }
      InputStream in = post.getResponseBodyAsStream();
      FileOutputStream out = new FileOutputStream(outputFile);
      IOUtils.copy(in, out);
      in.close();
      out.close();
      log.debug("ICE output file: {}", outputFile);
      return outputFile;
    } catch (IOException ioe) {
      throw new TransformerException("Failed to process ICE output", ioe);
    }
  }