class GenericReportUnitResourceConverter extends DataSourceHolderResourceConverter<ServerReportUnitType, ClientReportUnitType> {

    protected List<ResourceReference> convertResourcesToServer(Map<String, ClientReferenceableFile> clientResources,
            List<ResourceReference> serverReferencesToUpdate, ToServerConversionOptions options) throws IllegalParameterValueException, MandatoryParameterNotFoundException {
        List<ResourceReference> result = new ArrayList<ResourceReference>();
        if (clientResources != null && !clientResources.isEmpty()) {
            Map<String, ResourceReference> serverResourcesMap = getServerResourcesAsMap(serverReferencesToUpdate);
            for (String currentResourceName : clientResources.keySet()) {
                final ClientReferenceableFile clientObject = clientResources.get(currentResourceName);
                ResourceReference serverObjectToUpdate = serverResourcesMap.get(currentResourceName);
                if (serverObjectToUpdate != null && serverObjectToUpdate.isLocal()
                        && !(serverObjectToUpdate.getLocalResource() instanceof FileResource)) {
                    // this case is invalid. Local resources should be of type FileResource only.
                    // but if wrong type comes, then let's proceed like no server object to update.
                    serverObjectToUpdate = null;
                }
                if (serverObjectToUpdate != null && serverObjectToUpdate.isLocal()
                        && serverObjectToUpdate.getLocalResource() instanceof FileResource
                        && !((FileResource) serverObjectToUpdate.getLocalResource()).isReference()
                        && clientObject instanceof ClientReference
                        && !(serverObjectToUpdate.getLocalResource().getURIString().equals(clientObject.getUri()))) {
                    // if current server resource is local non reference file but client object points to another one,
                    // then this local file should be removed and new one should be created, reference one
                    serverObjectToUpdate = null;
                }
                final ResourceReferenceConverter<ClientReferenceableFile> fileResourceReferenceConverter =
                        resourceReferenceConverterProvider.getConverterForType(ClientReferenceableFile.class);
                if (clientObject instanceof ClientReference &&
                        (serverObjectToUpdate == null || serverObjectToUpdate.isLocal())) {
                    // Server side FileResource can be a reference.
                    // It is done for ReportUnit's resources referencing in JRXML.
                    // Currently this is the only known case, where FileResource can be a reference.
                    // So, handle this tricky case here.
                    if (serverObjectToUpdate == null) {
                        // new local FileResource-reference should be created
                        // ensure, that reference points to a valid file resource
                        fileResourceReferenceConverter.toServer(clientObject, options);
                        FileResource fileResourceReference = (FileResource) objectFactory.newResource(null, FileResource.class);
                        fileResourceReference.setName(currentResourceName);
                        fileResourceReference.setLabel(currentResourceName);
                        fileResourceReference.setReferenceURI(clientObject.getUri());
                        serverObjectToUpdate = new ResourceReference(fileResourceReference);
                    } else {
                        final FileResource localResource = (FileResource) serverObjectToUpdate.getLocalResource();
                        if (localResource.isReference() && !clientObject.getUri().equals(localResource.getReferenceURI())) {
                            // reference URI is changed. Let's validate reference target
                            // ensure, that reference points to a valid file resource
                            fileResourceReferenceConverter.toServer(clientObject, options);
                            // update reference if conversion above succeed
                            ((FileResource) serverObjectToUpdate.getLocalResource()).setReferenceURI(clientObject.getUri());
                        }
                    }
                } else {
                    // normal file reference case.
                    serverObjectToUpdate = fileResourceReferenceConverter.toServer(clientObject, serverObjectToUpdate, options);
                    if (serverObjectToUpdate != null && serverObjectToUpdate.getLocalResource() != null) {
                        // explicitly set file resource name. It is required for the case if local resource should be created.
                        // In update case the name is the same, in create case original name doesn't matter,
                        // it should be overridden by currentResourceName
                        serverObjectToUpdate.getLocalResource().setName(currentResourceName);
                    }
                }
                result.add(serverObjectToUpdate);
            }
            if (serverReferencesToUpdate == null) {
                // no existing resources, let's create new ArrayList with resources
                serverReferencesToUpdate = new ArrayList<ResourceReference>(result);
            } else {
                // there was a list with resources.
                // remove all previously existing resources
                serverReferencesToUpdate.clear();
                // add all updated/created resources
                serverReferencesToUpdate.addAll(result);
            }
        } else if (serverReferencesToUpdate != null) {
            // here is no resources in incoming ClientReportUnit.
            // So, let's remove all existing resources.
            serverReferencesToUpdate.clear();
        }
        return serverReferencesToUpdate;
    }

}