class BlockFactory extends AbstractBlockParserFactory {
        private Patterns myPatterns = null;
        final private boolean myHtmlCommentBlocksInterruptParagraph;
        final private boolean myHtmlBlockDeepParser;
        final private boolean myHtmlBlockDeepParseNonBlock;
        final private boolean myHtmlBlockDeepParseFirstOpenTagOnOneLine;
        final private boolean myHtmlBlockCommentOnlyFullLine;
        final private boolean myHtmlBlockStartOnlyOnBlockTags;

        private BlockFactory(DataHolder options) {
            super(options);
            myHtmlCommentBlocksInterruptParagraph = Parser.HTML_COMMENT_BLOCKS_INTERRUPT_PARAGRAPH.get(options);
            this.myHtmlBlockDeepParser = Parser.HTML_BLOCK_DEEP_PARSER.get(options);
            this.myHtmlBlockDeepParseNonBlock = Parser.HTML_BLOCK_DEEP_PARSE_NON_BLOCK.get(options);
            this.myHtmlBlockDeepParseFirstOpenTagOnOneLine = Parser.HTML_BLOCK_DEEP_PARSE_FIRST_OPEN_TAG_ON_ONE_LINE.get(options);
            this.myHtmlBlockCommentOnlyFullLine = Parser.HTML_BLOCK_COMMENT_ONLY_FULL_LINE.get(options);
            this.myHtmlBlockStartOnlyOnBlockTags = Parser.HTML_BLOCK_START_ONLY_ON_BLOCK_TAGS.get(options);
        }

        @Override
        public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) {<FILL_FUNCTION_BODY>}
    }

            int nextNonSpace = state.getNextNonSpaceIndex();
            BasedSequence line = state.getLine();

            if (state.getIndent() < 4 && line.charAt(nextNonSpace) == '<' && !(matchedBlockParser.getBlockParser() instanceof HtmlBlockParser)) {
                if (myHtmlBlockDeepParser) {
                    HtmlDeepParser deepParser = new HtmlDeepParser(Parser.HTML_BLOCK_TAGS.get(state.getProperties()));
                    deepParser.parseHtmlChunk(line.subSequence(nextNonSpace, line.length()), myHtmlBlockStartOnlyOnBlockTags, myHtmlBlockDeepParseNonBlock, myHtmlBlockDeepParseFirstOpenTagOnOneLine);
                    if (deepParser.hadHtml()) {
                        // have our html block start
                        if ((deepParser.getHtmlMatch() == OPEN_TAG || (!myHtmlCommentBlocksInterruptParagraph && deepParser.getHtmlMatch() == COMMENT))
                                && (!deepParser.isFirstBlockTag() && matchedBlockParser.getBlockParser().getBlock() instanceof Paragraph)) {
                        } else {
                            // not paragraph or can interrupt paragraph
                            return BlockStart.of(new HtmlBlockParser(state.getProperties(), null, deepParser.getHtmlMatch() == COMMENT, deepParser)).atIndex(state.getIndex());
                        }
                    }
                } else {
                    for (int blockType = 1; blockType <= 7; blockType++) {
                        // Type 7 cannot interrupt a paragraph or may not start a block altogether
                        if (blockType == 7 && (myHtmlBlockStartOnlyOnBlockTags || matchedBlockParser.getBlockParser().getBlock() instanceof Paragraph)) {
                            continue;
                        }

                        if (myPatterns == null) {
                            myPatterns = new Patterns(state.getParsing(), state.getProperties());
                        }

                        Pattern opener = myPatterns.BLOCK_PATTERNS[blockType][0];
                        Pattern closer = myPatterns.BLOCK_PATTERNS[blockType][1];
                        Matcher matcher = opener.matcher(line.subSequence(nextNonSpace, line.length()));
                        boolean matches = matcher.find();

                        // TEST: non-interrupting of paragraphs by HTML comments
                        if (matches && (myHtmlCommentBlocksInterruptParagraph || blockType != myPatterns.COMMENT_PATTERN_INDEX || !(matchedBlockParser.getBlockParser() instanceof ParagraphParser))) {
                            // Issue #158, HTML Comment followed by text
                            if (blockType == myPatterns.COMMENT_PATTERN_INDEX && myHtmlBlockCommentOnlyFullLine) {
                                Matcher endMatcher = myPatterns.BLOCK_PATTERNS[myPatterns.COMMENT_PATTERN_INDEX][1].matcher(line.subSequence(matcher.end(), line.length()));
                                if (endMatcher.find()) {
                                    // see if nothing follows
                                    BasedSequence trailing = line.subSequence(endMatcher.end(), line.length()).trim();
                                    if (!trailing.equals("-->")) {
                                        return BlockStart.none();
                                    }
                                }
                            }
                            return BlockStart.of(new HtmlBlockParser(state.getProperties(), closer, blockType == myPatterns.COMMENT_PATTERN_INDEX, null)).atIndex(state.getIndex());
                        }
                    }
                }
            }
            return BlockStart.none();
        
<methods>public non-sealed void <init>() ,public void addLine(com.vladsch.flexmark.parser.block.ParserState, com.vladsch.flexmark.util.sequence.BasedSequence) ,public boolean breakOutOnDoubleBlankLine() ,public boolean canContain(com.vladsch.flexmark.parser.block.ParserState, com.vladsch.flexmark.parser.block.BlockParser, com.vladsch.flexmark.util.ast.Block) ,public boolean canInterruptBy(com.vladsch.flexmark.parser.block.BlockParserFactory) ,public final void finalizeClosedBlock() ,public com.vladsch.flexmark.util.ast.BlockContent getBlockContent() ,public com.vladsch.flexmark.util.data.MutableDataHolder getDataHolder() ,public boolean isClosed() ,public boolean isContainer() ,public boolean isInterruptible() ,public boolean isParagraphParser() ,public boolean isPropagatingLastBlankLine(com.vladsch.flexmark.parser.block.BlockParser) ,public boolean isRawText() ,public void parseInlines(com.vladsch.flexmark.parser.InlineParser) ,public void removeBlankLines() <variables>private boolean isClosed,private com.vladsch.flexmark.util.data.MutableDataSet mutableData