@Nullable
  public static ExceptionInfo parseMessage(String line, int textEndOffset) {
    int firstSpace = line.indexOf(' ');
    int colonPos = -1;
    TextRange classRange = null;
    if (firstSpace == -1) {
      classRange = getExceptionClassFromMessage(line, 0, getLength(line));
    }
    else if (firstSpace == "Caused".length() && line.startsWith(CAUSED_BY)) {
      colonPos = line.indexOf(':', CAUSED_BY.length());
      classRange = getExceptionClassFromMessage(line, CAUSED_BY.length(), colonPos == -1 ? getLength(line) : colonPos);
    }
    else if (firstSpace == "Exception".length() && line.startsWith(EXCEPTION_IN_THREAD)) {
      int nextQuotePos = line.indexOf("\" ", EXCEPTION_IN_THREAD.length());
      if (nextQuotePos == -1) return null;
      int start = nextQuotePos + "\" ".length();
      colonPos = line.indexOf(':', start);
      classRange = getExceptionClassFromMessage(line, start, colonPos == -1 ? getLength(line) : colonPos);
    }
    else if (firstSpace > 2 && line.charAt(firstSpace - 1) == ':') {
      colonPos = firstSpace - 1;
      classRange = getExceptionClassFromMessage(line, 0, firstSpace - 1);
    }
    else if (firstSpace > 3 && line.charAt(0) == '[' && line.charAt(firstSpace - 1) == ':' && line.charAt(firstSpace - 2) == ']') {
      colonPos = line.indexOf(':', firstSpace);
      classRange = getExceptionClassFromMessage(line, firstSpace + 1, colonPos == -1 ? getLength(line) : colonPos);
    }
    if (classRange == null) return null;
    String message = colonPos == -1 ? null : line.substring(colonPos + 1).trim();
    message = StringUtil.notNullize(message);
    int absoluteOffset = textEndOffset - line.length();
    String exceptionName = classRange.substring(line);
    int startOffset = classRange.getStartOffset() + absoluteOffset;
    return createExceptionInfo(message, exceptionName, startOffset);
  }
@Nullable
  public static ExceptionInfo parseMessage(String line, int textEndOffset)