docs: protected boolean parse(ParsingContext context) {
  		try {
  			context.getParserInterceptor().openContext(context);
  			boolean specialTagFound = false;
  			final String lineSeparator = getLineSeparator();
  			while (context.getMatcher().find()) {
  				int groupIndex = findFirstGroup(context.getMatcher(), 0);
  				final String tagName = context.getMatcher().group(groupIndex);
  				if (lineSeparator.equals(tagName)) {
  					context.incrementLineNo();
  					continue;
  				}
  				final Tag tag = getTagForPattern(tagName);
  				if (tag != null) {
  					if (tag.isActive(context)) {
  						final String tagDynamicName;
  						if (tag.hasDynamicName()) {
  							final OutParameter<String> dname = new OutParameter<>();
  							extractDynamicName(tag, tagName, dname);
  							tagDynamicName = dname.get();
  						} else {
  							tagDynamicName = null;
  						}
  						final String parameterValue;
  						if (tag.hasParameter()) {
  							groupIndex = findFirstGroup(context.getMatcher(), groupIndex);
  							final String parameter = Strings.nullToEmpty(context.getMatcher().group(groupIndex));
  							final ContentParserInterceptor subInterceptor = new ContentParserInterceptor(context.getParserInterceptor());
  							final boolean inBlock = context.setInBlock(false);
  							final boolean inParam = context.setInParameter(true);
  							parse(parameter, context.getCurrentFile(),
  									context.getMatcher().start(groupIndex) + context.getStartIndex(),
  									context.getStage(),
  									context,
  									subInterceptor);
  							context.setInParameter(inParam);
  							context.setInBlock(inBlock);
  							parameterValue = Strings.emptyToNull(subInterceptor.getResult());
  						} else {
  							parameterValue = null;
  						}
  						final String blockContent;
  						if (tag.isOpeningTag()) {
  							groupIndex = findFirstGroup(context.getMatcher(), groupIndex);
  							final String tagContent = context.getMatcher().group(groupIndex);
  							final ContentParserInterceptor subInterceptor = new ContentParserInterceptor(context.getParserInterceptor());
  							final boolean inBlock = context.setInBlock(true);
  							final boolean inParam = context.setInParameter(false);
  							context.setVisibleInBlock(false);
  							parse(Strings.nullToEmpty(tagContent), context.getCurrentFile(),
  									context.getMatcher().start(groupIndex) + context.getStartIndex(),
  									context.getStage(),
  									context,
  									subInterceptor);
  							context.setInParameter(inParam);
  							context.setInBlock(inBlock);
  							blockContent = Strings.nullToEmpty(subInterceptor.getResult());
  						} else {
  							blockContent = null;
  						}
  						specialTagFound = true;
  						try {
  							context.getParserInterceptor().tag(context, tag, tagDynamicName, parameterValue, blockContent);
  						} catch (Throwable exception) {
  							reportError(context, Messages.SarlDocumentationParser_6, tagName, exception);
  							return false;
  						}
  					} else {
  						// Ignore the tag for this stage.
  					}
  				} else {
  					reportError(context, Messages.SarlDocumentationParser_1, tagName);
  					return false;
  				}
  			}
  			context.getParserInterceptor().closeContext(context);
  			return specialTagFound;
  		} catch (ParsingException exception) {
  			throw exception;
  		} catch (Throwable exception) {
  			final Throwable rootException = Throwables.getRootCause(exception);
  			throw new ParsingException(
  					rootException.getClass().getName() + " - " + rootException.getLocalizedMessage(), //$NON-NLS-1$
  					context.getCurrentFile(),
  					context.getLineNo(),
  					rootException);
  		}
  	}