class BackendUtils {

    public static TArtifactTemplate synchronizeReferences(IRepository repository, ArtifactTemplateId id) throws IOException {
        TArtifactTemplate template = repository.getElement(id);
        List<TArtifactReference> toRemove = new ArrayList<>();
        List<RepositoryFileReference> toAdd = new ArrayList<>();
        TArtifactTemplate.ArtifactReferences artifactReferences = template.getArtifactReferences();
        DirectoryId fileDir = new ArtifactTemplateFilesDirectoryId(id);
        SortedSet<RepositoryFileReference> files = repository.getContainedFiles(fileDir);

        if (artifactReferences == null) {
            artifactReferences = new TArtifactTemplate.ArtifactReferences();
            template.setArtifactReferences(artifactReferences);
        }

        List<TArtifactReference> artRefList = artifactReferences.getArtifactReference();
        determineChanges(artRefList, files, toRemove, toAdd);

        if (toAdd.size() > 0 || toRemove.size() > 0) {
            // apply removal list
            toRemove.forEach(artRefList::remove);

            // apply addition list
            artRefList.addAll(toAdd.stream().map(fileRef -> {
                String path = Util.getUrlPath(fileRef);

                // put path into data structure
                // we do not use Include/Exclude as we directly reference a concrete file
                TArtifactReference artRef = new TArtifactReference();
                artRef.setReference(path);

                return artRef;
            }).collect(Collectors.toList()));

            // finally, persist only if something changed
            BackendUtils.persist(repository, id, template);
        }

        return template;
    }

}