public void setText(@NotNull String text) throws IllegalArgumentException {
    myResult.removeAll();
    myComponents.clear();
    List<JComponent> rowComponents = new ArrayList<>();
    RichTextProcessor metaDataProcessor = null;
    StringBuilder metaTokenData = new StringBuilder();
    boolean ignoreNext = false;
    for (String s : StringUtil.tokenize(new StringTokenizer(text, " \n", true))) {
      if (ignoreNext || s.isEmpty()) {
        ignoreNext = false;
        continue;
      }

      if (metaDataProcessor != null) {
        // Inside meta-token.
        final int i = s.indexOf(RICH_TEXT_TOKEN_END);
        if (i >= 0) {
          // Meta-token ends within the current string.
          metaTokenData.append(s, 0, i);
          final JComponent component = metaDataProcessor.process(metaTokenData.toString());
          if (component != null) {
            rowComponents.add(component);
          }
          metaTokenData.setLength(0);
          metaDataProcessor = null;
          if (i + RICH_TEXT_TOKEN_END.length() < s.length()) {
            s = s.substring(i + RICH_TEXT_TOKEN_END.length());
          }
          else {
            continue;
          } 
        }
        else {
          // Meta-token data continues here.
          metaTokenData.append(s);
          continue;
        }
      }
      
      final int start = s.indexOf(RICH_TEXT_TOKEN_START);

      // Check if meta data starts here.
      if (start >= 0) {
        if (start + RICH_TEXT_TOKEN_START.length() >= s.length()) {
          throw new IllegalArgumentException(String.format(
            "Invalid rich text detected. Meta data key is assumed to directly follow '%s' (no white spaces between them). "
            + "Given text: '%s'", RICH_TEXT_TOKEN_START, text));
        }

        // Define meta-key end offset.
        int end = s.indexOf(RICH_TEXT_TOKEN_END);
        boolean metaDataComplete = true;
        if (end < start) {
          end = s.length();
          metaDataComplete = false;
        }
        String metaKey = s.substring(start + RICH_TEXT_TOKEN_START.length(), end);
        metaDataProcessor = myProcessors.get(metaKey);
        if (metaDataProcessor == null) {
          throw new IllegalArgumentException(String.format(
            "No processor is registered for the meta-key '%s' (processors are available only for these keys - %s). Rich text: '%s'",
            metaKey, myProcessors.keySet(), text
          ));
        }

        // There is a possible case like {@key}. We can complete meta-processing here than.
        if (metaDataComplete) {
          final JComponent component = metaDataProcessor.process("");
          if (component != null) {
            rowComponents.add(component);
          }
          metaDataProcessor = null;
          // Handle situation like '{@key}text', i.e. there is no white space between the meta-data and the text that follows it.
          s = s.substring(end);
        }
        else {
          ignoreNext = true;
          continue;
        }
      }
      if (s.contains("\n")) {
        addRow(rowComponents);
        rowComponents.clear();
      }
      else {
        final JLabel label = new JLabel(s); // NON-NLS
        label.setForeground(myForegroundColor);
        label.setBackground(myBackgroundColor);
        label.setFont(myFont);
        rowComponents.add(label);
      }
    }
    if (!rowComponents.isEmpty()) {
      addRow(rowComponents);
    }
  }
public void setText(@NotNull String text)