private Asset getOrCreateAsset(
      AssetContainer assetContainer,
      MemoizedFile dir,
      String requirePrefix,
      AssetRegistry assetDiscoveryInitiator,
      List<Asset> implicitDependencies,
      Asset parent) {
    String requirePath = DirectoryAsset.getRequirePath(requirePrefix, dir);

    if (!assetDiscoveryInitiator.hasRegisteredAsset(requirePath)) {
      List<Asset> furtherAssetImplicitDependencies = new ArrayList<>();
      furtherAssetImplicitDependencies.addAll(implicitDependencies);
      furtherAssetImplicitDependencies.add(parent);
      Asset asset =
          new DirectoryAsset(assetContainer, dir, requirePrefix, furtherAssetImplicitDependencies);
      assetDiscoveryInitiator.registerAsset(asset);
      return asset;
    } else {
      return assetDiscoveryInitiator.getRegisteredAsset(requirePath);
    }
  }
  private List<Asset> discoverFurtherAssetsForChild(
      AssetContainer assetContainer,
      MemoizedFile dir,
      String requirePrefix,
      List<Asset> implicitDependencies,
      AssetRegistry assetDiscoveryInitiator,
      Asset parent) {
    List<Asset> furtherAssetImplicitDependencies = new ArrayList<>();
    furtherAssetImplicitDependencies.addAll(implicitDependencies);
    furtherAssetImplicitDependencies.add(parent);

    List<Asset> discoveredAssets =
        assetDiscoveryInitiator.discoverFurtherAssets(
            dir, requirePrefix, furtherAssetImplicitDependencies);
    List<Asset> dependentAssets = new ArrayList<>();
    if (parent instanceof LinkedAsset) {
      for (Asset dependentAsset : discoveredAssets) {
        if (dependentAsset instanceof SourceModule) {
          continue;
        }
        dependentAssets.add(dependentAsset);
      }
      ((LinkedAsset) parent).addImplicitDependencies(dependentAssets);
    }

    for (MemoizedFile childDir : dir.dirs()) {
      discoveredAssets.addAll(
          createAssetsForChildDir(
              assetContainer,
              childDir,
              requirePrefix,
              implicitDependencies,
              assetDiscoveryInitiator,
              parent));
    }
    return discoveredAssets;
  }
  @Override
  public void discoverAssets(
      AssetContainer assetContainer,
      MemoizedFile dir,
      String requirePrefix,
      List<Asset> implicitDependencies,
      AssetRegistry assetDiscoveryInitiator) {
    // only create assets if we're at the root of the asset container *and* its not a default
    // bladeset
    if (assetContainer instanceof DefaultBladeset
        || !neccessaryChildDirsArePresent(assetContainer)
        || assetContainer.dir() != dir
        || assetDiscoveryInitiator.hasRegisteredAsset(
            BRJSConformantRootDirectoryLinkedAsset.calculateRequirePath(assetContainer))) {
      return;
    }

    List<Asset> assets = new ArrayList<>();

    LinkedAsset rootAsset = new BRJSConformantRootDirectoryLinkedAsset(assetContainer);
    assetDiscoveryInitiator.registerAsset(rootAsset);
    assets.add(rootAsset);

    for (MemoizedFile srcDir : getSrcDirs(assetContainer)) {
      if (useImpliedRequirePrefix(assetContainer)) {
        discoverFurtherAssetsForChild(
            assetContainer,
            srcDir,
            requirePrefix,
            implicitDependencies,
            assetDiscoveryInitiator,
            rootAsset);
      } else {
        discoverFurtherAssetsForChild(
            assetContainer, srcDir, "", implicitDependencies, assetDiscoveryInitiator, rootAsset);
      }
    }

    List<Asset> implicitResourcesDependencies = new ArrayList<>();
    implicitResourcesDependencies.addAll(implicitDependencies);
    implicitResourcesDependencies.add(rootAsset);
    for (MemoizedFile resourceDir : getResourceDirs(assetContainer)) {
      List<Asset> discoveredAssets =
          createAssetsForChildDir(
              assetContainer,
              resourceDir,
              requirePrefix,
              implicitResourcesDependencies,
              assetDiscoveryInitiator,
              rootAsset);
      rootAsset.addImplicitDependencies(discoveredAssets);
    }

    for (MemoizedFile testDir : getTestDirs(assetContainer)) {
      discoverFurtherAssetsForChild(
          assetContainer,
          testDir,
          "test/" + requirePrefix,
          implicitDependencies,
          assetDiscoveryInitiator,
          rootAsset);
    }

    for (MemoizedFile themeDir : getThemeDirs(assetContainer)) {
      String themeRequirePrefix = "theme!" + themeDir.getName() + ":" + requirePrefix;
      List<Asset> discoveredAssets =
          createAssetsForChildDir(
              assetContainer,
              themeDir,
              themeRequirePrefix,
              implicitDependencies,
              assetDiscoveryInitiator,
              rootAsset);
      rootAsset.addImplicitDependencies(discoveredAssets);
    }
  }