@Cached
public Rule ListItem(Rule itemStart, SuperNodeCreator itemNodeCreator) {
// for a simpler parser design we use a recursive parsing strategy for list items:
// we collect a number of markdown source blocks for an item, run complete parsing cycle on these and attach
// the roots of the inner parsing results AST to the outer AST tree
StringBuilderVar block = new StringBuilderVar();
StringBuilderVar temp = new StringBuilderVar();
Var<Boolean> tight = new Var<Boolean>(false);
Var<SuperNode> tightFirstItem = new Var<SuperNode>();
return Sequence(
push(getContext().getCurrentIndex()),
FirstOf(CrossedOut(BlankLine(), block), tight.set(true)),
CrossedOut(itemStart, block), Line(block),
ZeroOrMore(
Optional(CrossedOut(Indent(), temp)),
NotItem(),
Line(temp),
block.append(temp.getString()) && temp.clearContents()
),
tight.get() ? push(tightFirstItem.setAndGet(itemNodeCreator.create(parseListBlock(block)))) :
fixFirstItem((SuperNode) peek(1)) &&
push(itemNodeCreator.create(parseListBlock(block.appended("\n\n")))),
ZeroOrMore(