class FileJavaGenerator implements JavaGenerator {

  private static final Logger LOGGER = LoggerFactory.getLogger(FileJavaGenerator.class);

  private final Config config;
  private final File source;
  private final CRGeneratorRunner crGeneratorRunner;

  public FileJavaGenerator(Config config, File source) {
    crGeneratorRunner = new CRGeneratorRunner(config);
    this.config = config;
    this.source = source;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void run(File outputDirectory) {
    if (source.isDirectory()) {
      try (Stream<Path> walk = Files.walk(source.toPath(), FileVisitOption.FOLLOW_LINKS)) {
        walk
            .map(Path::toFile)
            .filter(f -> !f.getAbsolutePath().equals(source.getAbsolutePath()) && f.isFile())
            .filter(f -> config.getFilesSuffixes().stream().anyMatch(suffix -> f.getName().endsWith(suffix)))
            .forEach(f -> runOnSingleSource(f, outputDirectory));
      } catch (IOException e) {
        throw new JavaGeneratorException(
            "Error visiting the folder " + source.getAbsolutePath(), e);
      }
    } else {
      runOnSingleSource(source, outputDirectory);
    }
  }

  private void runOnSingleSource(File source, File basePath) {
    try (FileInputStream fis = new FileInputStream(source)) {
      List<Object> resources = new ArrayList<>();

      Object deserialized = Serialization.unmarshal(fis);
      if (deserialized instanceof List) {
        resources.addAll((List<Object>) deserialized);
      } else {
        resources.add(deserialized);
      }

      writeCRCompilationUnits(basePath, generateWritableCRCompilationUnits(resources));

    } catch (FileNotFoundException e) {
      throw new JavaGeneratorException("File " + source.getAbsolutePath() + " not found", e);
    } catch (IOException e) {
      throw new JavaGeneratorException("Exception reading " + source.getAbsolutePath(), e);
    }
  }

  private List<WritableCRCompilationUnit> generateWritableCRCompilationUnits(List<Object> resources) {<FILL_FUNCTION_BODY>}

  private void writeCRCompilationUnits(File basePath, List<WritableCRCompilationUnit> wCUs) {
    int size = wCUs.size();
    CompletableFuture<Void>[] futures = new CompletableFuture[size];

    for (int i = 0; i < size; i++) {
      WritableCRCompilationUnit w = wCUs.get(i);
      futures[i] = CompletableFuture.runAsync(() -> w.writeAllJavaClasses(basePath));
    }

    for (int j = 0; j < size; j++) {
      futures[j].join();
    }
  }
}

    return resources.parallelStream()
        .flatMap(
            rawResource -> {
              if (rawResource != null && rawResource instanceof HasMetadata) {
                final HasMetadata resource = (HasMetadata) rawResource;

                if (resource != null && resource.getKind()
                    .toLowerCase(Locale.ROOT)
                    .equals("customresourcedefinition")) {
                  CustomResourceDefinition crd = (CustomResourceDefinition) resource;

                  final String basePackage = groupToPackage(crd.getSpec().getGroup());
                  return crGeneratorRunner.generate(crd, basePackage).stream();
                } else {
                  LOGGER.warn("Not generating nothing for resource of kind: {}", resource.getKind());
                }
              } else {
                LOGGER.warn("Not generating nothing for unrecognized resource: {}", Serialization.asYaml(rawResource));
              }
              return Stream.empty();
            })
        .collect(Collectors.toList());
  
<no_super_class>