public static byte @NotNull [] calculateIndexedHash(@NotNull IndexedFile indexedFile, byte @NotNull [] contentHash) {
    Hasher hasher = INDEXED_FILE_CONTENT_HASHER.newHasher();
    hasher.putBytes(contentHash);

    if (!FileContentImpl.getFileTypeWithoutSubstitution(indexedFile).isBinary()) {
      // we don't need charset if it depends only on content
      if (!SKIP_CONTENT_DEPENDENT_CHARSETS) {
        Charset charset = getCharsetFromIndexedFile(indexedFile);
        hasher.putString(charset.name(), StandardCharsets.UTF_8);
      }
      else {
        Charset charset = EncodingRegistry.getInstance().getEncoding(indexedFile.getFile(), true);
        if (charset != null) {
          hasher.putString(charset.name(), StandardCharsets.UTF_8);
        }
        else {
          // do nothing; charset is not required and depends only on content
        }
      }
    }

    hasher.putString(indexedFile.getFileName(), StandardCharsets.UTF_8);

    FileType fileType = indexedFile.getFileType();
    hasher.putString(fileType.getName(), StandardCharsets.UTF_8);

    @Nullable
    FileIndexingFlavorProvider<?> provider = FileIndexingFlavorProvider.INSTANCE.forFileType(fileType);
    if (provider != null) {
      buildFlavorHash(indexedFile, provider, new HashBuilder() {
        @Override
        public @NotNull HashBuilder putInt(int val) {
          hasher.putInt(val);
          return this;
        }

        @Override
        public @NotNull HashBuilder putBoolean(boolean val) {
          hasher.putBoolean(val);
          return this;
        }

        @Override
        public @NotNull HashBuilder putString(@NotNull CharSequence charSequence) {
          hasher.putString(charSequence, StandardCharsets.UTF_8);
          return this;
        }
      });
    }

    return hasher.hash().asBytes();
  }
public static byte @NotNull [] calculateIndexedHash(@NotNull IndexedFile indexedFile, byte @NotNull [] contentHash)