@NotNull
  private static DirEntry findOrCreateNextDirEntry(@NotNull DirEntry lastEntry, @NotNull String name,
                                                   int prevIndex,
                                                   int nameEnd,
                                                   int nameHash) {
    DirEntry nextEntry = null;
    DirEntry[] directories = lastEntry.childrenDirectories; // volatile read

    if (directories != null) {
      //noinspection ForLoopReplaceableByForEach
      for (int index = 0, len = directories.length; index < len; ++index) {
        DirEntry previouslyScannedDir = directories[index];
        if (previouslyScannedDir.nameHash == nameHash &&
            previouslyScannedDir.name.regionMatches(0, name, prevIndex, nameEnd - prevIndex)) {
          nextEntry = previouslyScannedDir;
          break;
        }
      }
    }

    if (nextEntry == null) {
      nextEntry = new DirEntry(nameHash, name.substring(prevIndex, nameEnd));
      DirEntry[] newChildrenDirectories;
      if (directories != null) {
        newChildrenDirectories = Arrays.copyOf(directories, directories.length + 1);
        newChildrenDirectories[directories.length] = nextEntry;
      }
      else {
        newChildrenDirectories = new DirEntry[]{nextEntry};
      }
      lastEntry.childrenDirectories = newChildrenDirectories; // volatile write with new copy of data
    }

    lastEntry = nextEntry;
    return lastEntry;
  }
@NotNull
  private static DirEntry findOrCreateNextDirEntry(@NotNull DirEntry lastEntry, @NotNull String name,
                                                   int prevIndex,
                                                   int nameEnd,
                                                   int nameHash)