private String calculateImplicitOrExplicitRequirePrefixDirectory(
      AssetContainer assetContainer, String srcDirName) {
    MemoizedFile brjsDir = assetContainer.root().dir();
    String rootPath = srcDirName;

    MemoizedFile srcDir = assetContainer.file(srcDirName);
    if (!srcDir.isDirectory()) {
      return srcDirName;
    }

    String rootRequirePrefix = StringUtils.substringBefore(assetContainer.requirePrefix(), "/");
    MemoizedFile rootRequirePrefixDir = srcDir.file(rootRequirePrefix);

    String nestedRequirePrefixPath = srcDirName + "/" + assetContainer.requirePrefix();
    MemoizedFile nestedRequirePrefixDir = assetContainer.file(nestedRequirePrefixPath);

    MemoizedFile rootPathDir = assetContainer.file(rootPath);
    boolean explicitRequirePrefixDirsExist = nestedRequirePrefixDir.isDirectory();

    if (rootRequirePrefixDir.exists() && !explicitRequirePrefixDirsExist) {
      InvalidRequirePathException wrappedRequirePathException =
          new InvalidRequirePathException(
              String.format(
                  "The location '%s' contains a directory with the same name as the root require prefix ('%s') which suggests it's require prefix is explicitly defined"
                      + " but no folder exists that corresponds to the require prefix for this location ('%s'). Either move all source files and package folders into the directory '%s'"
                      + " to use an explicit directory structure or move all files and package folders into '%s' to allow the require prefix to be calculated automatically.",
                  brjsDir.getRelativePath(assetContainer.file(srcDirName)),
                  rootRequirePrefix,
                  assetContainer.requirePrefix(),
                  brjsDir.getRelativePath(nestedRequirePrefixDir),
                  brjsDir.getRelativePath(rootPathDir)));
      throw new RuntimeException(wrappedRequirePathException);
    }

    BRJS brjs = assetContainer.root();
    Logger logger = brjs.logger(this.getClass());
    if (explicitRequirePrefixDirsExist && useImpliedRequirePrefix(assetContainer)) {
      return nestedRequirePrefixPath;
    }
    logger.debug(
        IMPLICIT_PACKAGE_USED,
        assetContainer.root().dir().getRelativePath(srcDir),
        assetContainer.requirePrefix(),
        assetContainer.requirePrefix());
    return rootPath;
  }
 private List<MemoizedFile> filterNonExistantDirs(List<MemoizedFile> dirs) {
   List<MemoizedFile> existingDirs = new ArrayList<>();
   for (MemoizedFile dir : dirs) {
     if (dir.isDirectory()) {
       existingDirs.add(dir);
     }
   }
   return existingDirs;
 }
 private boolean neccessaryChildDirsArePresent(AssetContainer assetContainer) {
   List<MemoizedFile> expectedDirs = getSrcDirs(assetContainer);
   expectedDirs.addAll(getResourceDirs(assetContainer));
   expectedDirs.addAll(getTestDirs(assetContainer));
   expectedDirs.addAll(getThemeDirs(assetContainer));
   for (MemoizedFile dir : expectedDirs) {
     if (dir.isDirectory()) {
       return true;
     }
   }
   return false;
 }