public void clearMessages() {
    messages.clear();
    getRootStyleNode().removeChildrenAll();

    rootMessageStyleNodes.clear();

    endMarginNode = null;
    newMessageSeparatorNode = null;
  }
 public List<AnalyzedMessage> getMessages(int offset, int length) {
   List<AnalyzedMessage> list = new ArrayList<>();
   for (int i = 0; i < rootMessageStyleNodes.size(); i++) {
     StyleNode node = rootMessageStyleNodes.get(i);
     if (JUtils.intersects(offset, length, node.getOffset(), node.getLength())) {
       list.add(messages.get(i));
     }
   }
   return list;
 }
  public void appendMessages(List<AnalyzedMessage> newMessages) {
    if (newMessages.size() == 0) return;

    List<AnalyzedMessage> oldMessages = new ArrayList<>(messages);

    if (messageFilter != null) newMessages = CUtils.filter(newMessages, messageFilter);

    messages.addAll(newMessages);

    List<StyleNode> msgNodes =
        CUtils.map(
            newMessages,
            m -> {
              StyleNode n = builder.buildMessage(m);
              n.updateTree(NStyleUtils.getTemplateManager());
              return n;
            });
    rootMessageStyleNodes.addAll(msgNodes);

    List<StyleNode> appendNodes = new ArrayList<>();
    List<StyleNode> removeNodes = new ArrayList<>();

    if (oldMessages.size() > 0) {
      appendNodes.add(builder.buildTemplate("message_separator"));

      if (newMessages.size() > 0) {
        if (newMessageSeparatorNode != null) removeNodes.add(newMessageSeparatorNode);
        newMessageSeparatorNode = builder.buildTemplate("new_message_separator");
        if (newMessageSeparatorNode != null) appendNodes.add(newMessageSeparatorNode);
      }
    }

    for (int i = 0; i < msgNodes.size(); i++) {
      StyleNode n = msgNodes.get(i);
      appendNodes.add(n);

      if (i < msgNodes.size() - 1) appendNodes.add(builder.buildTemplate("message_separator"));
    }

    if (endMarginTemplateId != null) {
      if (endMarginNode != null) removeNodes.add(endMarginNode);
      endMarginNode = builder.buildTemplate(endMarginTemplateId);
      appendNodes.add(endMarginNode);
    }

    runWithNoRedraw(
        () -> {
          CUtils.forEach(removeNodes, node -> node.getParent().removeChild(node));

          getRootStyleNode().addChildAll(appendNodes);

          try {
            getRootStyleNode().updateTree(NStyleUtils.getTemplateManager());
          } catch (RuntimeException e) {
            DialogUtils.openError(null, "Script error", e.toString());
          }
        });
  }
 public StyleNode getMessageStyleNode(AnalyzedMessage msg) {
   int index = messages.indexOf(msg);
   if (index >= 0) return rootMessageStyleNodes.get(index);
   return null;
 }