class SW360MetaDataUpdater {

    public AttachmentUploadResult<SW360Release> uploadAttachments(SW360Release sw360Release,
                                                                  Map<Path, SW360AttachmentType> attachments,
                                                                  boolean force) {
        Set<String> attachmentsToDelete = new HashSet<>();
        Map<AttachmentUploadRequest.Item, Throwable> conflictFailures = new HashMap<>();
        AttachmentUploadRequest.Builder<SW360Release> builder = AttachmentUploadRequest.builder(sw360Release);
        for (Map.Entry<Path, SW360AttachmentType> e : attachments.entrySet()) {
            String fileName = String.valueOf(e.getKey().getFileName());
            Optional<SW360SparseAttachment> optAttachment = findAttachmentByFileName(sw360Release, fileName);
            boolean shouldUpload = optAttachment.map(attachment ->
                    checkUploadCriteria(e.getKey(), attachment, attachmentsToDelete, conflictFailures, force))
                    .orElse(true);
            if (shouldUpload) {
                builder = builder.addAttachment(e.getKey(), e.getValue());
            }
        }

        deleteConflictingAttachments(sw360Release, attachmentsToDelete);

        AttachmentUploadRequest<SW360Release> uploadRequest = builder.build();
        if (!uploadRequest.getItems().isEmpty()) {
            AttachmentUploadResult<SW360Release> result = releaseClientAdapter.uploadAttachments(uploadRequest);
            LOGGER.debug("Result of attachment upload operation: {}", result);
            if (!result.isSuccess()) {
                LOGGER.error("Failed to upload attachments: {}", result.failedUploads());
            }
            return appendFailures(result, conflictFailures);
        }
        return appendFailures(new AttachmentUploadResult<>(sw360Release), conflictFailures);
    }

    public  SW360MetaDataUpdater(SW360Connection connection);

}