/**
   * Marshals the object to the given path that must represent a path to the file.
   *
   * <p>This method is capable of setting the schema version to the object being marshalled.
   *
   * @param path Path to file
   * @param object Object to marshal
   * @param noNamespaceSchemaLocation NoNamespaceSchemaLocation to set. If it's <code>null</code> no
   *     location will be set.
   * @param schemaVersion If schema version is set and object to marshall is instance of {@link
   *     ISchemaVersionAware} then the given schema version will be set to the object. Use <code>0
   *     </code> to ignore setting of schema version.
   * @throws JAXBException If {@link JAXBException} occurs.
   * @throws IOException If {@link IOException} occurs.
   */
  public void marshall(
      Path path, Object object, String noNamespaceSchemaLocation, int schemaVersion)
      throws JAXBException, IOException {
    if (Files.isDirectory(path)) {
      throw new IOException("Can not marshal object to the path that represents the directory");
    }
    Files.deleteIfExists(path);
    Files.createDirectories(path.getParent());

    JAXBContext context = JAXBContext.newInstance(object.getClass());
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    if (null != noNamespaceSchemaLocation) {
      marshaller.setProperty(
          Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, noNamespaceSchemaLocation);
    }

    // set schema version if needed
    if ((object instanceof ISchemaVersionAware) && (0 != schemaVersion)) {
      ((ISchemaVersionAware) object).setSchemaVersion(schemaVersion);
    }

    try (OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW)) {
      marshaller.marshal(object, outputStream);
    }
  }
  /**
   * Marshals the object to the bytes.
   *
   * @param object Object to marshal
   * @param noNamespaceSchemaLocation NoNamespaceSchemaLocation to set. If it's <code>null</code> no
   *     location will be set.
   * @param schemaVersion If schema version is set and object to marshall is instance of {@link
   *     ISchemaVersionAware} then the given schema version will be set to the object. Use <code>0
   *     </code> to ignore setting of schema version.
   * @return bytes representing the results of the marshall operation
   * @throws JAXBException If {@link JAXBException} occurs.
   * @throws IOException If {@link IOException} occurs.
   */
  public byte[] marshall(Object object, String noNamespaceSchemaLocation, int schemaVersion)
      throws JAXBException, IOException {
    JAXBContext context = JAXBContext.newInstance(object.getClass());
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    if (null != noNamespaceSchemaLocation) {
      marshaller.setProperty(
          Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, noNamespaceSchemaLocation);
    }

    // set schema version if needed
    if ((object instanceof ISchemaVersionAware) && (0 != schemaVersion)) {
      ((ISchemaVersionAware) object).setSchemaVersion(schemaVersion);
    }

    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
      marshaller.marshal(object, outputStream);
      return outputStream.toByteArray();
    }
  }