class Fetcher {

    public boolean fetchData() {
        Date snapshotDate = from(now());

        logger.info("Starting fetching data. Snapshot date: {} {}, IP and MAC Address: {}.",
                snapshotDate, snapshotDate.getTime(), getIpAndMacAddress());

        List<Future<Snapshot>> futures = new ArrayList<>();

        try {
            for (String organizationName : organizations) {
                futures.add(snapshotProvider.takeSnapshot(organizationName, snapshotDate));
                logger.info("Enqueued task TakeSnapshotTask for organization '{}'.", organizationName);
            }
        } catch (IOException e) {
            logger.error("Unable to fetch data from GitHub API. Missing GitHub API credentials?.", e);
            throw new CrawlerRetryException(e);
        }
        logger.info("Submitted {} TakeSnapshotTasks.", futures.size());

        for (Future<Snapshot> future : futures) {
            try {
                Snapshot snapshot = future.get();

                statisticsRepository.save(snapshot.getStatistics());
                projectRepository.save(snapshot.getProjects());
                contributorRepository.save(snapshot.getContributors());
                // TODO languagesRepository.save(snapshot.getLanguages());

                logger.info("Successfully saved data for organization '{}'.", snapshot.getStatistics()
                        .getOrganizationName());
            } catch (InterruptedException | ExecutionException e) {
                logger.error("Error occurred while processing organization.", e);
                throw new CrawlerRetryException(e);
            }
        }
        logger.info("Finished fetching data.");
        return true;
    }

    @Autowired public  Fetcher(ProjectRepository projectRepository,
                   StatisticsRepository statisticsRepository,
                   ContributorRepository contributorRepository,
                   SnapshotProvider snapshotProvider,
                   @Value("#{'${organization.list}'.split(',')}") String[] organizations);

}