@Override
  public boolean parse(@NlsSafe @NotNull String line,
                       @NotNull BuildOutputInstantReader reader,
                       @NotNull Consumer<? super BuildEvent> messageConsumer) {
    int colonIndex1 = line.indexOf(COLON);
    if (colonIndex1 == 1) { // drive letter
      colonIndex1 = line.indexOf(COLON, colonIndex1 + 1);
    }

    if (colonIndex1 >= 0) { // looks like found something like a file path.
      @NlsSafe String part1 = line.substring(0, colonIndex1).trim();
      if (part1.equalsIgnoreCase("error") /* jikes */ || part1.equalsIgnoreCase("Caused by")) {
        // +1 so we don't include the colon
        String text = line.substring(colonIndex1 + 1).trim();
        messageConsumer
          .accept(new MessageEventImpl(reader.getParentEventId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP.get(), text, line));
        return true;
      }
      if (part1.equalsIgnoreCase("warning")) {
        // +1 so we don't include the colon
        String text = line.substring(colonIndex1 + 1).trim();
        messageConsumer
          .accept(new MessageEventImpl(reader.getParentEventId(), MessageEvent.Kind.WARNING, COMPILER_MESSAGES_GROUP.get(), text, line));
        return true;
      }
      if (part1.equalsIgnoreCase("javac")) {
        messageConsumer
          .accept(new MessageEventImpl(reader.getParentEventId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP.get(), line, line));
        return true;
      }
      if (part1.equalsIgnoreCase("Note")) {
        String message = line.substring(colonIndex1 + 1).trim();
        int javaFileExtensionIndex = message.indexOf(".java");
        if (javaFileExtensionIndex > 0) {
          File file = new File(message.substring(0, javaFileExtensionIndex + ".java".length()));
          if (file.isFile()) {
            message = message.substring(javaFileExtensionIndex + ".java".length() + 1);
            String detailedMessage = amendNextInfoLinesIfNeeded(file.getPath() + ":\n" + message, reader);
            messageConsumer
              .accept(new FileMessageEventImpl(reader.getParentEventId(), MessageEvent.Kind.INFO, COMPILER_MESSAGES_GROUP.get(),
                                               message, detailedMessage,
                                               new FilePosition(file, 0, 0)));
            return true;
          }
        }
      }

      int colonIndex2 = line.indexOf(COLON, colonIndex1 + 1);
      if (colonIndex2 >= 0) {
        File file = new File(part1);
        if (!file.isFile()) {
          // the part one is not a file path.
          return false;
        }
        try {
          int lineNumber = Integer.parseInt(line.substring(colonIndex1 + 1, colonIndex2).trim()); // 1-based.
          String text = line.substring(colonIndex2 + 1).trim();
          MessageEvent.Kind kind = MessageEvent.Kind.ERROR;

          if (StringUtil.startsWithIgnoreCase(text, WARNING_PREFIX)) {
            text = text.substring(WARNING_PREFIX.length()).trim();
            kind = MessageEvent.Kind.WARNING;
          }
          else if (StringUtil.startsWithIgnoreCase(text, NOTE_PREFIX)) {
            text = text.substring(NOTE_PREFIX.length()).trim();
            kind = MessageEvent.Kind.INFO;
          }
          else if (StringUtil.startsWithIgnoreCase(text, ERROR_PREFIX)) {
            text = text.substring(ERROR_PREFIX.length()).trim();
            kind = MessageEvent.Kind.ERROR;
          }

          // Only slurp up line pointer (^) information if this is required source files
          if (!isRelatedFile(file)) {
            return false;
          }

          BuildOutputCollector outputCollector = new BuildOutputCollector(reader);
          List<String> messageList = new ArrayList<>();
          messageList.add(text);
          int column; // 0-based.
          String prevLine = null;
          do {
            String nextLine = outputCollector.readLine();
            if (nextLine == null) {
              return false;
            }
            if (nextLine.trim().equals("^")) {
              column = nextLine.indexOf('^');
              String messageEnd = outputCollector.readLine();

              while (isMessageEnd(messageEnd)) {
                messageList.add(messageEnd.trim());
                messageEnd = outputCollector.readLine();
              }

              if (messageEnd != null) {
                outputCollector.pushBack();
              }
              break;
            }
            if (prevLine != null) {
              messageList.add(prevLine);
            }
            prevLine = nextLine;
          }
          while (true);

          if (column >= 0) {
            String message = StringUtil.join(convertMessages(messageList), "\n");
            String detailedMessage = line + "\n" + outputCollector.getOutput(); //NON-NLS
            messageConsumer.accept(new FileMessageEventImpl(reader.getParentEventId(), kind, COMPILER_MESSAGES_GROUP.get(),
                                                            message, detailedMessage, new FilePosition(file, lineNumber - 1, column)));
            return true;
          }
        }
        catch (NumberFormatException ignored) {
        }
      }
    }

    if (line.endsWith("java.lang.OutOfMemoryError")) {
      messageConsumer.accept(new MessageEventImpl(reader.getParentEventId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP.get(),
                                                  LangBundle.message("build.event.message.out.memory"), line));
      return true;
    }

    return false;
  }
@Override
  public boolean parse(@NlsSafe @NotNull String line,
                       @NotNull BuildOutputInstantReader reader,
                       @NotNull Consumer<? super BuildEvent> messageConsumer)