@Override
  public byte @NotNull [] contentsToByteArray(@NotNull VirtualFile file, boolean mayCacheContent) throws IOException {

    int fileId = getFileId(file);

    long length;
    int contentRecordId;

    //MAYBE RC: we could reduce contention on this lock by utilising FileIdLock inside the vfsPeer.
    myInputLock.readLock().lock();
    try {
      int flags = vfsPeer.getFlags(fileId);
      boolean mustReloadLength = BitUtil.isSet(flags, Flags.MUST_RELOAD_LENGTH);
      boolean mustReloadContent = BitUtil.isSet(flags, Flags.MUST_RELOAD_CONTENT);
      length = mustReloadLength ? -1 : vfsPeer.getLength(fileId);
      boolean contentOutdated = (length == -1) || mustReloadContent;
      if (contentOutdated) {
        contentRecordId = -1;
      }
      else {
        // As soon as we got a contentId -- there is no need for locking anymore,
        // since VFSContentStorage is a thread-safe append-only storage
        contentRecordId = vfsPeer.getContentRecordId(fileId);
      }
    }
    finally {
      myInputLock.readLock().unlock();
    }

    if (contentRecordId <= 0) {
      NewVirtualFileSystem fs = getFileSystem(file);

      byte[] content = fs.contentsToByteArray(file);

      if (mayCacheContent && shouldCache(content.length)) {
        updateContentForFile(fileId, new ByteArraySequence(content));
      }
      else {
        myInputLock.writeLock().lock();
        try {
          setLength(fileId, content.length);
        }
        finally {
          myInputLock.writeLock().unlock();
        }
      }

      return content;
    }

    //VFS content storage is append-only, hence doesn't need lock for reading:
    InputStream contentStream = vfsPeer.readContentById(contentRecordId);
    try {
      assert length >= 0 : file;
      return contentStream.readNBytes((int)length);
    }
    catch (IOException e) {
      throw vfsPeer.handleError(e);
    }
  }
@Override
  public byte @NotNull [] contentsToByteArray(@NotNull VirtualFile file, boolean mayCacheContent)