class LanguageStats {

    public static List<LanguageStats> buildStats(List<Project> projectList) {
        List<Project> projects = filterUniqueSnapshots(projectList);

        // For each date, we have a map of all the counts. Later we piece the
        // results together from these pieces of information.
        Map<Date, Map<String,Integer>> counts = new HashMap<>();
        TreeSet<Date> dates = new TreeSet<>();
        Set<String> languages = new HashSet<>();

        for (Project p: projects) {
            String language = p.getPrimaryLanguage();
            Date date = p.getSnapshotDate();

            if (language == null)
                language = "unknown";

            dates.add(date);
            languages.add(language);

            Map<String,Integer> hist = counts.get(date);
            if (hist == null) {
                hist = new HashMap<>();
                counts.put(date, hist);
            }

            if (hist.containsKey(language)) {
                hist.put(language, hist.get(language) + 1);
            } else {
                hist.put(language, 1);
            }
        }

        List<LanguageStats> result = new ArrayList<>();
        for (String l: languages) {
            List<Integer> projectCounts = new ArrayList<>();
            List<Date> snapshotDates = new ArrayList<>(dates);

            for(Date d: snapshotDates) {
                Integer i = counts.get(d).get(l);
                if (i == null) {
                    projectCounts.add(0);
                } else {
                    projectCounts.add(i);
                }
            }
            result.add(new LanguageStats(l, projectCounts, snapshotDates));
        }
        return result;
    }

    public  LanguageStats(String languageName, List<Integer> projectCounts, List<Date> snapshotDates);

}