class ComponentImportUtils {

    public static RequestSummary writeToDatabase(Iterable<ComponentCSVRecord> compCSVRecords,
                                                 ComponentService.Iface componentClient, VendorService.Iface vendorClient,
                                                 AttachmentService.Iface attachmentClient, User user) throws TException {

        Map<String, String> vendorNameToVendorId = getVendorNameToId(compCSVRecords, vendorClient);
        log.debug(format("Read vendors: (%d) %s ", vendorNameToVendorId.size(), vendorNameToVendorId));

        final RequestSummary componentRequestSummary = updateComponents(compCSVRecords, componentClient, user);


        Map<String, String> componentNameToId = new HashMap<>();
        final ArrayList<Release> releases = new ArrayList<>();
        for (Component component : componentClient.getComponentDetailedSummaryForExport()) {
            componentNameToId.put(component.getName(), component.getId());
            final List<Release> componentReleases = component.getReleases();
            if (componentReleases != null && componentReleases.size() > 0)
                releases.addAll(componentReleases);
        }
        Set<String> knownReleaseIdentifiers = Sets.newHashSet(getReleaseIdentifiers(releases));


        List<ComponentCSVRecord> relevantCSVRecords = new ArrayList<>();
        final HashMap<String, List<String>> releaseIdentifierToDownloadURL = new HashMap<>();


        List<AttachmentContent> attachmentContentsToUpdate = new ArrayList<>();

        filterRelevantCSVRecordsAndGetAttachmentContents(compCSVRecords, componentNameToId, knownReleaseIdentifiers, relevantCSVRecords,
                releaseIdentifierToDownloadURL, attachmentContentsToUpdate);

        attachmentContentsToUpdate = attachmentClient.makeAttachmentContents(attachmentContentsToUpdate);
        final ImmutableMap<String, AttachmentContent> URLtoAttachment = Maps.uniqueIndex(attachmentContentsToUpdate, new Function<AttachmentContent, String>() {
            @Override
            public String apply(AttachmentContent input) {
                return input.getRemoteUrl();
            }
        });

        Set<Release> releasesToUpdate = new HashSet<>();


        //I do not need so many checks here because I only iterate over the relevant CSV records
        for (ComponentCSVRecord componentCSVRecord : relevantCSVRecords) {
            String releaseIdentifier = componentCSVRecord.getReleaseIdentifier();
            String vendorName = componentCSVRecord.getVendorName();
            String vendorId = vendorNameToVendorId.get(vendorName);

            String componentId = componentNameToId.get(componentCSVRecord.getComponentName());
            List<AttachmentContent> attachmentContents = getAttachmentContents(releaseIdentifierToDownloadURL, URLtoAttachment, releaseIdentifier);

            Release releaseToAdd = componentCSVRecord.getRelease(vendorId, componentId, attachmentContents);
            knownReleaseIdentifiers.add(releaseIdentifier);
            if (releaseToAdd != null) {
                releasesToUpdate.add(releaseToAdd);
            }

        }

        final RequestSummary releaseRequestSummary = componentClient.updateReleases(releasesToUpdate, user);

        return CommonUtils.addRequestSummaries(componentRequestSummary, "component", releaseRequestSummary, "release");
    }

    private  ComponentImportUtils();

}