docs: private MemoEntry parseProduction(Production production, int position, int line)
  	    throws TreeException, ParserException {
  	ParseTreeNode node = new ParseTreeNode(production);
  	MemoEntry progress = MemoEntry.success(0, 0, node);
  	for (Construction construction : production.getConstructions()) {
  	    processIgnoredLeadingTokens(node, position, line, progress);
  	    if (construction.isNonTerminal()) {
  		MemoEntry newProgress = applyRule(construction.getName(), position + progress.getDeltaPosition(),
  			line + progress.getDeltaLine());
  		if (newProgress.getAnswer() instanceof ParseTreeNode) {
  		    ParseTreeNode child = (ParseTreeNode) newProgress.getAnswer();
  		    if (child.isNode()) {
  			if (child.isStackingAllowed()) {
  			    node.addChild(child);
  			} else {
  			    if (node.getName().equals(child.getName())) {
  				node.addChildren(child.getChildren());
  			    } else {
  				node.addChild(child);
  			    }
  			}
  		    } else {
  			node.addChildren(child.getChildren());
  		    }
  		    progress.add(newProgress);
  		} else if (newProgress.getAnswer().equals(Status.FAILED))
  		    return MemoEntry.failed();
  	    } else {
  		MemoEntry newProgress = processTerminal(node, (Terminal) construction,
  			position + progress.getDeltaPosition(), line + progress.getDeltaLine());
  		if (newProgress.getAnswer() instanceof ParseTreeNode) {
  		    progress.add(newProgress);
  		} else {
  		    return MemoEntry.failed();
  		}
  	    }
  	    processIgnoredTrailingTokens(node, position, line, progress);
  	}
  	if (logger.isTraceEnabled()) {
  	    logger.trace("Parsed: " + production);
  	}
  	return progress;
      }