public static LocationInfo parse(String fullInfo) {
    if (fullInfo == null) {
      return null;
    }
    fullInfo = removeLambdas(fullInfo);
    fullInfo = fullInfo.trim();
    fullInfo = StringUtils.removeStart(fullInfo, "at ");
    int lastClosingBrace = fullInfo.indexOf(')');
    int lastColon = fullInfo.lastIndexOf(':', lastClosingBrace);
    int lastOpeningBrace = fullInfo.lastIndexOf('(', lastColon);
    if (lastOpeningBrace == -1 || lastClosingBrace == -1 || lastColon == -1) {
      return null;
    }
    String packageName;
    String className;
    String methodName;
    String fileName;
    Optional<Integer> lineNumber;
    final String lineNumberString = fullInfo.substring(lastColon + 1, lastClosingBrace);
    lineNumber = Optional.of(Integer.parseInt(lineNumberString));
    fileName = fullInfo.substring(lastOpeningBrace + 1, lastColon);
    // packageName
    fullInfo = fullInfo.substring(0, lastOpeningBrace);
    int lastDot = fullInfo.lastIndexOf('.');
    if (lastDot == -1) {
      return null;
    } else {
      methodName = fullInfo.substring(lastDot + 1);
      className = fullInfo.substring(0, lastDot);
      lastDot = className.lastIndexOf(".");
      if (lastDot == -1) {
        packageName = ""; // the default package
      } else {
        packageName = className.substring(0, lastDot);
      }
    }
    return new LocationInfo(
      Optional.of(packageName),
      Optional.of(className),
      Optional.of(methodName),
      Optional.of(fileName),
      lineNumber,
      Optional.empty());
  }
build a LocationInfo instance from one line of a stackTrace

@param fullInfo one line from a stacktrace)
@return a LocationInfo based on the input (or null if input could not be parsed)
olv-api/src/main/java/pl/otros/logview/api/model/LocationInfo.java