class SourceTagsReport extends Report {

    @Override
    public void write(PrintWriter writer, StatisticsTracker stats) {<FILL_FUNCTION_BODY>}

    @Override
    public String getFilename() {
        return "source-report.txt";
    }
}


        Set<String> sourceTags = stats.sourceHostDistribution.keySet();
        
        if(sourceTags.isEmpty()) {
            writer.println("No source tag information. (Is 'sourceTagSeeds' enabled?)");
            return; 
        }
        
        writer.print("[source] [host] [#urls]\n");
        // for each source
        for (String sourceKey : sourceTags) {
            Map<String,AtomicLong> hostCounts = 
                (Map<String,AtomicLong>)stats.sourceHostDistribution.get(sourceKey);
            // sort hosts by #urls
            DisposableStoredSortedMap<Long,String> sortedHostCounts = 
                stats.getReverseSortedHostCounts(hostCounts);
            // for each host
            for (Map.Entry<Long, String> entry : sortedHostCounts.entrySet()) {
                writer.print(sourceKey.toString());
                writer.print(" ");
                writer.print(entry.getValue());
                writer.print(" ");
                writer.print(Math.abs(entry.getKey()));
                writer.print("\n");
            }
            sortedHostCounts.dispose();
        }
    
<methods>public void <init>() ,public abstract java.lang.String getFilename() ,public boolean getShouldReportAtEndOfCrawl() ,public boolean getShouldReportDuringCrawl() ,public void setShouldReportAtEndOfCrawl(boolean) ,public void setShouldReportDuringCrawl(boolean) ,public abstract void write(java.io.PrintWriter, org.archive.crawler.reporting.StatisticsTracker) <variables>private boolean shouldReportAtEndOfCrawl,private boolean shouldReportDuringCrawl