code: static RemoteImageManifest createImageManifest(
        Collection<RemoteImageManifest> resps) throws IOException {
      // found valid images (with md5 hash)
      Map<Long, RemoteImage> images = Maps.newHashMap();
  
      for (RemoteImageManifest rm : resps) {
        for (RemoteImage ri : rm.getImages()) {
          if (ri.getDigest() == null) {
            LOG.info("Skipping: " + ri + " as it does not have md5 digest");
            continue;
          }
          if (images.containsKey(ri.getTxId())) {
            // we already have seen this image
            // two images from different nodes should be the same
            if (!images.get(ri.getTxId()).equals(ri)) {
              throw new IOException(
                  "Images received from different nodes do not match: "
                      + images.get(ri.getTxId()) + " vs: " + ri);
            }
          } else {
            // store image
            images.put(ri.getTxId(), ri);
          }
        }
      }
      List<RemoteImage> result = Lists.newArrayList();
      for (RemoteImage ri : images.values()) {
        result.add(ri);
      }
      // we need to sort the images
      Collections.sort(result);
  
      return new RemoteImageManifest(result);
    }
docs: Concatenate manifests obtained from the underlying journalnodes. The final
  manifest will contain only the images committed to the majority of the
  nodes. Images with no md5 associated are ignored. Also, the md5 must match
  between images from different journal nodes.