@Nullable
  @Override
  public DataNode<ProjectData> resolveProjectInfo(
      @NotNull final ExternalSystemTaskId id,
      @NotNull final String projectPath,
      final boolean isPreviewMode,
      @Nullable final GradleExecutionSettings settings,
      @NotNull final ExternalSystemTaskNotificationListener listener)
      throws ExternalSystemException, IllegalArgumentException, IllegalStateException {
    final GradleProjectResolverExtension projectResolverChain;
    if (settings != null) {
      myHelper.ensureInstalledWrapper(id, projectPath, settings, listener);
      List<ClassHolder<? extends GradleProjectResolverExtension>> extensionClasses =
          settings.getResolverExtensions();

      Deque<GradleProjectResolverExtension> extensions =
          new ArrayDeque<GradleProjectResolverExtension>();
      for (ClassHolder<? extends GradleProjectResolverExtension> holder : extensionClasses) {
        final GradleProjectResolverExtension extension;
        try {
          extension = holder.getTargetClass().newInstance();
        } catch (Throwable e) {
          throw new IllegalArgumentException(
              String.format(
                  "Can't instantiate project resolve extension for class '%s'",
                  holder.getTargetClassName()),
              e);
        }
        final GradleProjectResolverExtension previous = extensions.peekLast();
        if (previous != null) {
          previous.setNext(extension);
        }
        extensions.add(extension);
      }
      projectResolverChain = extensions.peekFirst();
    } else {
      projectResolverChain = new BaseGradleProjectResolverExtension();
    }

    return myHelper.execute(
        projectPath,
        settings,
        new Function<ProjectConnection, DataNode<ProjectData>>() {
          @Override
          public DataNode<ProjectData> fun(ProjectConnection connection) {
            try {
              return doResolveProjectInfo(
                  new ProjectResolverContext(
                      id, projectPath, settings, connection, listener, isPreviewMode),
                  projectResolverChain);
            } catch (RuntimeException e) {
              LOG.info("Gradle project resolve error", e);
              throw projectResolverChain.getUserFriendlyError(e, projectPath, null);
            }
          }
        });
  }