public static void main(String[] args) throws IOException {
        CommandLineParser parser = new GnuParser();
        Options options = new Options();
        options.addOption("ngram", true, "n-gram order");
        options.addOption("norm", true, "normalization: none, cosine");
        options.addOption("smooth", false, "smooth idf counts");
        options.addOption("noaddone", false, "do not add 1 to idf");
        options.addOption("help", false, "help");

        String filename = null;
        List<Integer> ns = Lists.newArrayList(1);
        TfIdf.Normalization normalization = TfIdf.Normalization.NONE;
        boolean smooth = false;
        boolean noAddOne = false;
        try {
            String s;

            HelpFormatter formatter = new HelpFormatter();
            CommandLine cmd = parser.parse(options, args);
            if (cmd.hasOption("help")) {
                formatter.printHelp("NgramTfIdf FILE", options, true);
                System.exit(0);
            }
            s = cmd.getOptionValue("ngram");
            if (null != s) {
                for (String i : StringUtils.split(s, ",")) {
                    ns.add(Integer.valueOf(i));
                }
            }
            if (cmd.hasOption("norm")) {
                s = cmd.getOptionValue("norm");
                switch (s) {
                    case "none":
                        normalization = TfIdf.Normalization.NONE;
                        break;
                    case "cosine":
                        normalization = TfIdf.Normalization.COSINE;
                        break;
                    default:
                        formatter.printHelp("NgramTfIdf FILE", "", options, "Invalid normalization " + s, true);
                        System.exit(-1);
                }
            }
            smooth = cmd.hasOption("smooth");
            noAddOne = cmd.hasOption("noaddone");
            String[] positional = cmd.getArgs();
            if (positional.length == 0) {
                formatter.printHelp("NgramTfIdf FILE", "", options, "Specify a documents file", true);
                System.exit(-1);
            }
            filename = positional[0];
        } catch (ParseException e) {
            System.err.println(e.getMessage());
            System.exit(-1);
        }

        File file = new File(filename);
        List<String> text = Files.readLines(file, Charsets.UTF_8);
        Iterable<Collection<String>> documents = ngramDocumentTerms(ns, text);

        Iterable<Map<String, Double>> tfs = TfIdf.tfs(documents);
        Map<String, Double> idf = TfIdf.idfFromTfs(tfs, smooth, !noAddOne);
        System.out.println("IDF\n" + termStatistics(idf));
        System.out.println("TF-IDF");
        for (Map<String, Double> tf : tfs) {
            Map<String, Double> tfIdf = TfIdf.tfIdf(tf, idf, normalization);
            System.out.println(termStatistics(tfIdf));
        }
    }