docs: protected void run(Scanner scanner) {
          String currentProfileName = null;
  
          try {
              while(scanner.hasNextLine()) {
                  String line = scanner.nextLine().trim();
  
                  // Empty or comment lines
                  if (line.isEmpty() || line.startsWith("#")) {
                      onEmptyOrCommentLine(currentProfileName, line);
                      continue;
                  }
  
                  // parseGroupName returns null if this line does not
                  // indicate a new property group.
                  String newProfileName = parseProfileName(line);
                  boolean atNewProfileStartingLine = newProfileName != null;
  
                  if (atNewProfileStartingLine) {
                      if (currentProfileName != null) {
                          onProfileEndingLine(currentProfileName);
                      }
                      onProfileStartingLine(newProfileName, line);
  
                      // Start the new profile
                      currentProfileName = newProfileName;
                  } else {
                      // Parse the property line
                      Entry<String, String> property = parsePropertyLine(line);
  
                      if (currentProfileName == null) {
                          throw new IllegalArgumentException(
                                  "Property is defined without a preceding profile name. "
                                  + "Current line: " + line);
                      }
  
                      onProfileProperty(currentProfileName,
                                        property.getKey(),
                                        property.getValue(),
                                        isSupportedProperty(property.getKey()),
                                        line);
                  }
              }
  
              // EOF
              if (currentProfileName != null) {
                  onProfileEndingLine(currentProfileName);
              }
  
              onEndOfFile();
  
          } finally {
              scanner.close();
          }
      }