public static FunctionMetadataRegistry createRegistry() {
    InputStream is = FunctionMetadataReader.class.getResourceAsStream(METADATA_FILE_NAME);
    if (is == null) {
      throw new RuntimeException("resource '" + METADATA_FILE_NAME + "' not found");
    }

    FunctionDataBuilder fdb = new FunctionDataBuilder(400);

    try (BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
      while (true) {
        String line = br.readLine();
        if (line == null) {
          break;
        }
        if (line.length() < 1 || line.charAt(0) == '#') {
          continue;
        }
        String trimLine = line.trim();
        if (trimLine.length() < 1) {
          continue;
        }
        processLine(fdb, line);
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

    return fdb.build();
  }
  private static void processLine(FunctionDataBuilder fdb, String line) {

    String[] parts = TAB_DELIM_PATTERN.split(line, -2);
    if (parts.length != 8) {
      throw new RuntimeException("Bad line format '" + line + "' - expected 8 data fields");
    }
    int functionIndex = parseInt(parts[0]);
    String functionName = parts[1];
    int minParams = parseInt(parts[2]);
    int maxParams = parseInt(parts[3]);
    byte returnClassCode = parseReturnTypeCode(parts[4]);
    byte[] parameterClassCodes = parseOperandTypeCodes(parts[5]);
    // 6 isVolatile
    boolean hasNote = parts[7].length() > 0;

    validateFunctionName(functionName);
    // TODO - make POI use isVolatile
    fdb.add(
        functionIndex,
        functionName,
        minParams,
        maxParams,
        returnClassCode,
        parameterClassCodes,
        hasNote);
  }