private void checkAndScheduleChildRefresh(List<VFileEvent> events,
                                            NewVirtualFileSystem fs,
                                            @Nullable NewVirtualFile parent,
                                            NewVirtualFile child,
                                            FileAttributes childAttributes,
                                            boolean enqueue) {
    boolean fileDirty = child.isDirty();
    if (LOG.isTraceEnabled()) LOG.trace("file=" + child + " dirty=" + fileDirty);
    if (!fileDirty) {
      return;
    }

    if (checkAndScheduleFileTypeChange(events, fs, parent, child, childAttributes)) {
      child.markClean();
      return;
    }

    checkWritableAttributeChange(events, child, myPersistence.isWritable(child), childAttributes.isWritable());

    if (SystemInfoRt.isWindows) {
      checkHiddenAttributeChange(events, child, child.is(VFileProperty.HIDDEN), childAttributes.isHidden());
    }

    if (childAttributes.isSymLink()) {
      var t = System.nanoTime();
      var target = fs.resolveSymLink(child);
      myIoTime.addAndGet(System.nanoTime() - t);
      checkSymbolicLinkChange(events, child, child.getCanonicalPath(), target);
    }

    if (!childAttributes.isDirectory()) {
      long oldTimestamp = myPersistence.getTimeStamp(child), newTimestamp = childAttributes.lastModified;
      long oldLength = myPersistence.getLastRecordedLength(child), newLength = childAttributes.length;
      if (oldTimestamp != newTimestamp || oldLength != newLength) {
        if (LOG.isTraceEnabled()) LOG.trace(
          "update file=" + child +
          (oldTimestamp != newTimestamp ? " TS=" + oldTimestamp + "->" + newTimestamp : "") +
          (oldLength != newLength ? " len=" + oldLength + "->" + newLength : ""));
        events.add(new VFileContentChangeEvent(myRequestor, child, child.getModificationStamp(), -1, oldTimestamp, newTimestamp, oldLength, newLength));
      }
      child.markClean();
    }
    else if (enqueue && myIsRecursive) {
      if (child instanceof VirtualDirectoryImpl) {
        mySemaphore.down();
        myRefreshQueue.add(child);
      }
      else {
        LOG.error("not a directory: " + child + " (" + child.getClass() + ')');
      }
    }
  }
private void checkAndScheduleChildRefresh(List<VFileEvent> events,
                                            NewVirtualFileSystem fs,
                                            @Nullable NewVirtualFile parent,
                                            NewVirtualFile child,
                                            FileAttributes childAttributes,
                                            boolean enqueue)