/// <exception cref="Javax.Servlet.ServletException"/>
        /// <exception cref="System.IO.IOException"/>
        public virtual void OutputVisualise(PrintWriter @out, Annotation annotation)
        {
            // Note: A lot of the HTML generation in this method could/should be
            // done at a templating level, but as-of-yet I am not entirely sure how
            // this should be done in jsp. Also, a lot of the HTML is unnecessary
            // for the other outputs such as pretty print and XML.
            // Div for potential error messages when fetching the configuration.
            @out.Println("<div id=\"config_error\">");
            @out.Println("</div>");
            // Insert divs that will be used for each visualisation type.
            int visualiserDivPxWidth = 700;
            IDictionary <string, string> nameByAbbrv = new LinkedHashMap <string, string>();

            nameByAbbrv["pos"]       = "Part-of-Speech";
            nameByAbbrv["ner"]       = "Named Entity Recognition";
            nameByAbbrv["coref"]     = "Coreference";
            nameByAbbrv["basic_dep"] = "Basic Dependencies";
            //nameByAbbrv.put("collapsed_dep", "Collapsed dependencies");
            nameByAbbrv["collapsed_ccproc_dep"] = "Enhanced Dependencies";
            foreach (KeyValuePair <string, string> entry in nameByAbbrv)
            {
                @out.Println("<h2>" + entry.Value + ":</h2>");
                @out.Println("<div id=\"" + entry.Key + "\" style=\"width:" + visualiserDivPxWidth + "px\">");
                @out.Println("    <div id=\"" + entry.Key + "_loading\">");
                @out.Println("        <p>Loading...</p>");
                @out.Println("    </div>");
                @out.Println("</div>");
                @out.Println(string.Empty);
            }
            // Time to get the XML data into HTML.
            StringWriter xmlOutput = new StringWriter();

            pipeline.XmlPrint(annotation, xmlOutput);
            xmlOutput.Flush();
            // Escape the XML to be embeddable into a Javascript string.
            string escapedXml = xmlOutput.ToString().ReplaceAll("\\r\\n|\\r|\\n", string.Empty).Replace("\"", "\\\"");

            // Inject the XML results into the HTML to be retrieved by the Javascript.
            @out.Println("<script type=\"text/javascript\">");
            @out.Println("// <![CDATA[");
            @out.Println("    stanfordXML = \"" + escapedXml + "\";");
            @out.Println("// ]]>");
            @out.Println("</script>");
            // Relative brat installation location to CoreNLP.
            string bratLocation = "../brat";

            // Inject the location variable, we need it in Javascript mode.
            @out.Println("<script type=\"text/javascript\">");
            @out.Println("// <![CDATA[");
            @out.Println("    bratLocation = \"" + bratLocation + "\";");
            @out.Println("    webFontURLs = [\n" + "        '" + bratLocation + "/static/fonts/Astloch-Bold.ttf',\n" + "        '" + bratLocation + "/static/fonts/PT_Sans-Caption-Web-Regular.ttf',\n" + "        '" + bratLocation + "/static/fonts/Liberation_Sans-Regular.ttf'];"
                         );
            @out.Println("// ]]>");
            @out.Println("</script>");
            // Inject the brat stylesheet (removing this line breaks visualisation).
            @out.Println("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + bratLocation + "/style-vis.css\"/>");
            // Include the Javascript libraries necessary to run brat.
            @out.Println("<script type=\"text/javascript\" src=\"" + bratLocation + "/client/lib/head.load.min.js\"></script>");
            // Main Javascript that hooks into all that we have introduced so far.
            @out.Println("<script type=\"text/javascript\" src=\"brat.js\"></script>");
            // Link to brat, I hope this is okay to have here...
            @out.Println("<h>Visualisation provided using the " + "<a href=\"http://brat.nlplab.org/\">brat " + "visualisation/annotation software</a>.</h>");
            @out.Println("<br/>");
        }
        /// <summary>Usage: java -cp "*" StanfordCoreNlpDemo [inputFile [outputTextFile [outputXmlFile]]]</summary>
        /// <exception cref="System.IO.IOException"/>
        public static void Main(string[] args)
        {
            // set up optional output files
            PrintWriter @out;

            if (args.Length > 1)
            {
                @out = new PrintWriter(args[1]);
            }
            else
            {
                @out = new PrintWriter(System.Console.Out);
            }
            PrintWriter xmlOut = null;

            if (args.Length > 2)
            {
                xmlOut = new PrintWriter(args[2]);
            }
            // Create a CoreNLP pipeline. To build the default pipeline, you can just use:
            //   StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
            // Here's a more complex setup example:
            //   Properties props = new Properties();
            //   props.put("annotators", "tokenize, ssplit, pos, lemma, ner, depparse");
            //   props.put("ner.model", "edu/stanford/nlp/models/ner/english.all.3class.distsim.crf.ser.gz");
            //   props.put("ner.applyNumericClassifiers", "false");
            //   StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
            // Add in sentiment
            Properties props = new Properties();

            props.SetProperty("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref, sentiment");
            StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
            // Initialize an Annotation with some text to be annotated. The text is the argument to the constructor.
            Annotation annotation;

            if (args.Length > 0)
            {
                annotation = new Annotation(IOUtils.SlurpFileNoExceptions(args[0]));
            }
            else
            {
                annotation = new Annotation("Kosgi Santosh sent an email to Stanford University. He didn't get a reply.");
            }
            // run all the selected Annotators on this text
            pipeline.Annotate(annotation);
            // this prints out the results of sentence analysis to file(s) in good formats
            pipeline.PrettyPrint(annotation, @out);
            if (xmlOut != null)
            {
                pipeline.XmlPrint(annotation, xmlOut);
            }
            // Access the Annotation in code
            // The toString() method on an Annotation just prints the text of the Annotation
            // But you can see what is in it with other methods like toShorterString()
            @out.Println();
            @out.Println("The top level annotation");
            @out.Println(annotation.ToShorterString());
            @out.Println();
            // An Annotation is a Map with Class keys for the linguistic analysis types.
            // You can get and use the various analyses individually.
            // For instance, this gets the parse tree of the first sentence in the text.
            IList <ICoreMap> sentences = annotation.Get(typeof(CoreAnnotations.SentencesAnnotation));

            if (sentences != null && !sentences.IsEmpty())
            {
                ICoreMap sentence = sentences[0];
                @out.Println("The keys of the first sentence's CoreMap are:");
                @out.Println(sentence.KeySet());
                @out.Println();
                @out.Println("The first sentence is:");
                @out.Println(sentence.ToShorterString());
                @out.Println();
                @out.Println("The first sentence tokens are:");
                foreach (ICoreMap token in sentence.Get(typeof(CoreAnnotations.TokensAnnotation)))
                {
                    @out.Println(token.ToShorterString());
                }
                Tree tree = sentence.Get(typeof(TreeCoreAnnotations.TreeAnnotation));
                @out.Println();
                @out.Println("The first sentence parse tree is:");
                tree.PennPrint(@out);
                @out.Println();
                @out.Println("The first sentence basic dependencies are:");
                @out.Println(sentence.Get(typeof(SemanticGraphCoreAnnotations.BasicDependenciesAnnotation)).ToString(SemanticGraph.OutputFormat.List));
                @out.Println("The first sentence collapsed, CC-processed dependencies are:");
                SemanticGraph graph = sentence.Get(typeof(SemanticGraphCoreAnnotations.CollapsedCCProcessedDependenciesAnnotation));
                @out.Println(graph.ToString(SemanticGraph.OutputFormat.List));
                // Access coreference. In the coreference link graph,
                // each chain stores a set of mentions that co-refer with each other,
                // along with a method for getting the most representative mention.
                // Both sentence and token offsets start at 1!
                @out.Println("Coreference information");
                IDictionary <int, CorefChain> corefChains = annotation.Get(typeof(CorefCoreAnnotations.CorefChainAnnotation));
                if (corefChains == null)
                {
                    return;
                }
                foreach (KeyValuePair <int, CorefChain> entry in corefChains)
                {
                    @out.Println("Chain " + entry.Key);
                    foreach (CorefChain.CorefMention m in entry.Value.GetMentionsInTextualOrder())
                    {
                        // We need to subtract one since the indices count from 1 but the Lists start from 0
                        IList <CoreLabel> tokens = sentences[m.sentNum - 1].Get(typeof(CoreAnnotations.TokensAnnotation));
                        // We subtract two for end: one for 0-based indexing, and one because we want last token of mention not one following.
                        @out.Println("  " + m + ", i.e., 0-based character offsets [" + tokens[m.startIndex - 1].BeginPosition() + ", " + tokens[m.endIndex - 2].EndPosition() + ")");
                    }
                }
                @out.Println();
                @out.Println("The first sentence overall sentiment rating is " + sentence.Get(typeof(SentimentCoreAnnotations.SentimentClass)));
            }
            IOUtils.CloseIgnoringExceptions(@out);
            IOUtils.CloseIgnoringExceptions(xmlOut);
        }