class DdlParsers {

    public AstNode parse( final String ddl,
                          final String fileName ) throws ParsingException {
        CheckArg.isNotEmpty(ddl, "ddl");
        RuntimeException firstException = null;

        // Go through each parser and score the DDL content
        final Map<DdlParser, Integer> scoreMap = new HashMap<DdlParser, Integer>(this.parsers.size());
        final DdlParserScorer scorer = new DdlParserScorer();

        for (final DdlParser parser : this.parsers) {
            try {
                parser.score(ddl, fileName, scorer);
                scoreMap.put(parser, scorer.getScore());
            } catch (RuntimeException e) {
                if (firstException == null) {
                    firstException = e;
                }
            } finally {
                scorer.reset();
            }
        }

        if (scoreMap.isEmpty()) {
            if (firstException == null) {
                throw new ParsingException(Position.EMPTY_CONTENT_POSITION,
                                           DdlSequencerI18n.errorParsingDdlContent.text(this.parsers.size()));
            }

            throw firstException;
        }

        // sort the scores
        final List<Entry<DdlParser, Integer>> scoredParsers = new ArrayList<Entry<DdlParser, Integer>>(scoreMap.entrySet());
        Collections.sort(scoredParsers, SORTER);

        firstException = null;
        AstNode astRoot = null;

        for (final Entry<DdlParser, Integer> scoredParser : scoredParsers) {
            try {
                final DdlParser parser = scoredParser.getKey();

                // create DDL root node
                astRoot = createDdlStatementsContainer(parser.getId());

                // parse
                parser.parse(ddl, astRoot, null);
                return astRoot; // successfully parsed
            } catch (final RuntimeException e) {
                if (astRoot != null) {
                    astRoot.removeFromParent();
                }

                if (firstException == null) {
                    firstException = e;
                }
            }
        }

        if (firstException == null) {
            throw new ParsingException(Position.EMPTY_CONTENT_POSITION, DdlSequencerI18n.errorParsingDdlContent.text());
        }

        throw firstException;
    }

    public  DdlParsers();
    public  DdlParsers( List<DdlParser> parsers );

}