Dictionary<char, NamedCharacter> LiteralsCollection; // literals collection

        /// <summary>
        /// Translate ABNF grammar to ANTLR grammar
        /// </summary>
        /// <param name="input">TextReader which reads the ABNF grammar</param>
        /// <param name="output">TextWriter which writes the ANTLR grammar</param>
        public void Translate(TextReader input, TextWriter writer, bool performDirectTranslation)
        {
            // force single threaded operation
            lock (SyncLock)
            {
                this.LiteralsCollection = new Dictionary<char, NamedCharacter>();

                // open input stream
                var stream = new Antlr.Runtime.ANTLRReaderStream(input);

                // create lexer
                var lexer = new AbnfAstLexer(stream);

                // get token stream from input stream
                var tokens = new CommonTokenStream(lexer);

                // create parser
                var parser = new AbnfAstParser(tokens);

                // parse token stream
                var results = parser.start();

                if (parser.RecognitionExceptions.Count > 0 || lexer.RecognitionExceptions.Count > 0)
                {
                    var message =
                        AntlrHelper.GetErrorMessages(parser.RecognitionExceptions)
                        + AntlrHelper.GetErrorMessages(lexer.RecognitionExceptions)
                        ;

                    throw new TranslationException(message, parser.RecognitionExceptions, lexer.RecognitionExceptions);
                }

                // get parse tree
                var tree = results.Tree;

                // Use simplified named characters for indirect translation
                var lookup = new NamedCharacterLookupSimple();

                // enable this line to use Unicode named characters for indirect translation
                // var lookup = new NamedCharacterLookupUnicode();

                var ruleStatistics = new RuleStatistics();
                var statisticsVisitor = new TreeVisitor_GatherRuleStatistics(ruleStatistics);
                statisticsVisitor.Visit(tree);

                // output translated grammar
                if (performDirectTranslation)
                {
                    OutputDirectTranslation(writer, tokens, tree, lookup, ruleStatistics);
                }
                else
                {
                    OutputIndirectTranslation(writer, tokens, tree, lookup, ruleStatistics);
                }
            }
        }
        Dictionary<char, NamedCharacter> LiteralsCollection; // literals collection

        /// <summary>
        /// Translate ABNF grammar to ANTLR grammar
        /// </summary>
        /// <param name="input">TextReader which reads the ABNF grammar</param>
        /// <param name="output">TextWriter which writes the ANTLR grammar</param>
        public void Translate(TextReader input, TextWriter writer, bool performDirectTranslation)
        {
            // force single threaded operation
            lock (SyncLock)
            {
                this.LiteralsCollection = new Dictionary<char, NamedCharacter>();

                // open input stream
                var stream = new Antlr.Runtime.ANTLRReaderStream(input);

                // create lexer
                var lexer = new AbnfAstLexer(stream);

                // get token stream from input stream
                var tokens = new CommonTokenStream(lexer);

                // create parser
                var parser = new AbnfAstParser(tokens);

                // parse token stream
                var results = parser.start();

                // get parse tree
                var tree = results.Tree;

                // give lexer rules unicode standard names
                INamedCharacterLookup lookup = new NamedCharacterLookupUnicode();

                // enable the next line to give lexer rules simple names
                lookup = new NamedCharacterLookupSimple();

                // output translated grammar
                if (performDirectTranslation)
                {
                    OutputDirectTranslation(writer, tokens, tree, lookup);
                }
                else
                {
                    OutputIndirectTranslation(writer, tokens, tree, lookup);
                }
            }
        }