code: @Override
      protected void doProcess(ITemplateContext context, IProcessableElementTag tag, IElementTagStructureHandler structureHandler) {
          checkPreconditions(context, tag, structureHandler);
  
          final WebEngineContext webEngineContext = (WebEngineContext) context;
          final IModelFactory modelFactory = context.getModelFactory();
          final IModel model = modelFactory.createModel();
          final HttpServletRequest request = webEngineContext.getRequest();
          final Context flashMessagesContext = context(request);
  
          for (Level level : flashMessagesContext.levels()) {
              final Collection<Message> messages = flashMessagesContext.levelMessages(level, request);
              if (!messages.isEmpty()) {
                  model.addModel(levelMessages(level, messages, request, modelFactory));
              }
          }
  
          /*
           * Instruct the engine to replace this entire element with the specified model.
           */
          structureHandler.replaceWith(model, false);
      }
docs: <pre>
  <div data-level="${level}" class="alert alert-${level}">
  <c:choose>
  <c:when test="${fn:length(messages) gt 1}">
  <ul>
  <c:forEach var="message" items="${messages}">
  <li data-timestamp="${message.timestamp}"><c:out value="${message.text}" escapeXml="false"/></li>
  </c:forEach>
  </ul>
  </c:when>
  <c:otherwise>
  <c:forEach var="message" items="${messages}">
  <span data-timestamp="${message.timestamp}"><c:out value="${message.text}" escapeXml="false"/></span>
  </c:forEach>
  </c:otherwise>
  </c:choose>
  </div>
  </pre>
  
  @param context
  @param tag
  @param structureHandler