public static FSRecordsImpl connect(@NotNull Path storagesDirectoryPath,
                                      @NotNull List<ConnectionInterceptor> connectionInterceptors,
                                      boolean enableVfsLog,
                                      @NotNull ErrorHandler errorHandler) throws UncheckedIOException {
    if (IOUtil.isSharedCachesEnabled()) {
      IOUtil.OVERRIDE_BYTE_BUFFERS_USE_NATIVE_BYTE_ORDER_PROP.set(false);
    }
    try {
      int currentVersion = currentImplementationVersion();
      VFSInitializationResult initializationResult = PersistentFSConnector.connect(
        storagesDirectoryPath,
        currentVersion,
        enableVfsLog,
        connectionInterceptors
      );

      PersistentFSConnection connection = initializationResult.connection;

      Supplier<InvertedNameIndex> invertedNameIndexLazy = asyncFillInvertedNameIndex(connection.getRecords());

      LOG.info("VFS initialized: " + NANOSECONDS.toMillis(initializationResult.totalInitializationDurationNs) + " ms, " +
               initializationResult.attemptsFailures.size() + " failed attempts, " +
               initializationResult.connection.recoveryInfo().recoveredErrors.size() + " error(s) were recovered");

      PersistentFSContentAccessor contentAccessor = new PersistentFSContentAccessor(connection);
      PersistentFSAttributeAccessor attributeAccessor = new PersistentFSAttributeAccessor(connection);
      PersistentFSRecordAccessor recordAccessor = new PersistentFSRecordAccessor(contentAccessor, attributeAccessor, connection);
      PersistentFSTreeAccessor treeAccessor = attributeAccessor.supportsRawAccess() && USE_RAW_ACCESS_TO_READ_CHILDREN ?
                                              new PersistentFSTreeRawAccessor(attributeAccessor, recordAccessor, connection) :
                                              new PersistentFSTreeAccessor(attributeAccessor, recordAccessor, connection);

      try {
        treeAccessor.ensureLoaded();

        return new FSRecordsImpl(
          connection,
          contentAccessor, attributeAccessor, treeAccessor, recordAccessor,
          invertedNameIndexLazy,
          currentVersion,
          errorHandler,
          initializationResult
        );
      }
      catch (Throwable e) {
        try {
          //ensure async task is finished:
          invertedNameIndexLazy.get();
        }
        catch (Throwable scanningEx) {
          e.addSuppressed(scanningEx);
        }

        try {
          connection.close();
        }
        catch (Throwable closingEx) {
          e.addSuppressed(closingEx);
        }
        LOG.error(e);//because we need more details
        //FIXME throw handleError(e) ?

        //noinspection InstanceofCatchParameter
        if (e instanceof Error) {
          throw (Error)e;
        }
        //noinspection InstanceofCatchParameter
        if (e instanceof RuntimeException) {
          throw (RuntimeException)e;
        }
        throw new UncheckedIOException((IOException)e);
      }
    }
    finally {
      IOUtil.OVERRIDE_BYTE_BUFFERS_USE_NATIVE_BYTE_ORDER_PROP.remove();
    }
  }
public static FSRecordsImpl connect(@NotNull Path storagesDirectoryPath,
                                      @NotNull List<ConnectionInterceptor> connectionInterceptors,
                                      boolean enableVfsLog,
                                      @NotNull ErrorHandler errorHandler)