@Override
  protected void processData(
      @NotNull Collection<DataNode<TaskData>> nodes, @NotNull Project project) {
    if (nodes.isEmpty()) {
      return;
    }
    ProjectSystemId externalSystemId = nodes.iterator().next().getData().getOwner();
    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(externalSystemId);
    assert manager != null;

    ExternalSystemKeymapExtension.updateActions(project, nodes);

    MultiMap<ExternalConfigPathAware, DataNode<TaskData>> grouped =
        ContainerUtil.groupBy(nodes, TASK_HOLDER_RETRIEVAL_STRATEGY);
    Map<String, Collection<ExternalTaskPojo>> data = ContainerUtilRt.newHashMap();
    for (Map.Entry<ExternalConfigPathAware, Collection<DataNode<TaskData>>> entry :
        grouped.entrySet()) {
      data.put(
          entry.getKey().getLinkedExternalProjectPath(),
          ContainerUtilRt.map2List(entry.getValue(), MAPPER));
    }

    AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
    Map<String, Collection<ExternalTaskPojo>> availableTasks =
        ContainerUtilRt.newHashMap(settings.getAvailableTasks());
    availableTasks.putAll(data);
    settings.setAvailableTasks(availableTasks);
  }
  @Override
  protected void processData(
      @NotNull final Collection<DataNode<ModuleData>> nodes, @NotNull Project project) {
    if (nodes.isEmpty()) {
      return;
    }
    ProjectSystemId externalSystemId = nodes.iterator().next().getData().getOwner();
    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(externalSystemId);
    assert manager != null;

    final MultiMap<DataNode<ProjectData>, DataNode<ModuleData>> grouped =
        ExternalSystemApiUtil.groupBy(nodes, ProjectKeys.PROJECT);
    Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> data = ContainerUtilRt.newHashMap();
    for (Map.Entry<DataNode<ProjectData>, Collection<DataNode<ModuleData>>> entry :
        grouped.entrySet()) {
      data.put(
          ExternalProjectPojo.from(entry.getKey().getData()),
          ContainerUtilRt.map2List(entry.getValue(), MAPPER));
    }

    AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);
    Set<String> pathsToForget = detectRenamedProjects(data, settings.getAvailableProjects());
    if (!pathsToForget.isEmpty()) {
      settings.forgetExternalProjects(pathsToForget);
    }
    Map<ExternalProjectPojo, Collection<ExternalProjectPojo>> projects =
        ContainerUtilRt.newHashMap(settings.getAvailableProjects());
    projects.putAll(data);
    settings.setAvailableProjects(projects);
  }
  @Override
  public void importData(
      @NotNull final Collection<DataNode<BuildScriptClasspathData>> toImport,
      @NotNull final Project project,
      boolean synchronous) {
    if (toImport.isEmpty()) {
      return;
    }
    if (!project.isInitialized()) {
      return;
    }

    final GradleInstallationManager gradleInstallationManager =
        ServiceManager.getService(GradleInstallationManager.class);

    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(GradleConstants.SYSTEM_ID);
    assert manager != null;
    AbstractExternalSystemLocalSettings localSettings =
        manager.getLocalSettingsProvider().fun(project);

    //noinspection MismatchedQueryAndUpdateOfCollection
    Map<String /* externalProjectPath */, Set<String>> externalProjectGradleSdkLibs =
        new FactoryMap<String, Set<String>>() {
          @Nullable
          @Override
          protected Set<String> create(String externalProjectPath) {
            GradleProjectSettings settings =
                GradleSettings.getInstance(project).getLinkedProjectSettings(externalProjectPath);
            if (settings == null || settings.getDistributionType() == null) return null;

            final Set<String> gradleSdkLibraries = ContainerUtil.newLinkedHashSet();
            File gradleHome =
                gradleInstallationManager.getGradleHome(
                    settings.getDistributionType(), externalProjectPath, settings.getGradleHome());
            if (gradleHome != null && gradleHome.isDirectory()) {

              final Collection<File> libraries =
                  gradleInstallationManager.getClassRoots(project, externalProjectPath);
              if (libraries != null) {
                for (File library : libraries) {
                  gradleSdkLibraries.add(FileUtil.toCanonicalPath(library.getPath()));
                }
              }
            }
            return gradleSdkLibraries;
          }
        };

    for (final DataNode<BuildScriptClasspathData> node : toImport) {
      if (GradleConstants.SYSTEM_ID.equals(node.getData().getOwner())) {

        DataNode<ProjectData> projectDataNode =
            ExternalSystemApiUtil.findParent(node, ProjectKeys.PROJECT);
        assert projectDataNode != null;

        String linkedExternalProjectPath = projectDataNode.getData().getLinkedExternalProjectPath();
        DataNode<ModuleData> moduleDataNode =
            ExternalSystemApiUtil.findParent(node, ProjectKeys.MODULE);
        if (moduleDataNode == null) continue;

        String externalModulePath = moduleDataNode.getData().getLinkedExternalProjectPath();
        GradleProjectSettings settings =
            GradleSettings.getInstance(project).getLinkedProjectSettings(linkedExternalProjectPath);
        if (settings == null || settings.getDistributionType() == null) continue;

        final Set<String> buildClasspath = ContainerUtil.newLinkedHashSet();
        BuildScriptClasspathData buildScriptClasspathData = node.getData();
        for (BuildScriptClasspathData.ClasspathEntry classpathEntry :
            buildScriptClasspathData.getClasspathEntries()) {
          for (String path : classpathEntry.getSourcesFile()) {
            buildClasspath.add(FileUtil.toCanonicalPath(path));
          }

          for (String path : classpathEntry.getClassesFile()) {
            buildClasspath.add(FileUtil.toCanonicalPath(path));
          }
        }

        ExternalProjectBuildClasspathPojo projectBuildClasspathPojo =
            localSettings.getProjectBuildClasspath().get(linkedExternalProjectPath);
        if (projectBuildClasspathPojo == null) {
          projectBuildClasspathPojo =
              new ExternalProjectBuildClasspathPojo(
                  moduleDataNode.getData().getExternalName(),
                  ContainerUtil.<String>newArrayList(),
                  ContainerUtil.<String, ExternalModuleBuildClasspathPojo>newHashMap());
          localSettings
              .getProjectBuildClasspath()
              .put(linkedExternalProjectPath, projectBuildClasspathPojo);
        }

        List<String> projectBuildClasspath =
            ContainerUtil.newArrayList(externalProjectGradleSdkLibs.get(linkedExternalProjectPath));
        // add main java root of buildSrc project
        projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/java");
        // add main groovy root of buildSrc project
        projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/groovy");

        projectBuildClasspathPojo.setProjectBuildClasspath(projectBuildClasspath);
        projectBuildClasspathPojo
            .getModulesBuildClasspath()
            .put(
                externalModulePath,
                new ExternalModuleBuildClasspathPojo(
                    externalModulePath, ContainerUtil.newArrayList(buildClasspath)));
      }
    }

    GradleBuildClasspathManager.getInstance(project).reload();
  }
  public ExternalSystemTasksPanel(
      @NotNull Project project,
      @NotNull ProjectSystemId externalSystemId,
      @NotNull NotificationGroup notificationGroup) {
    super(true);
    myExternalSystemId = externalSystemId;
    myNotificationGroup = notificationGroup;
    myProject = project;

    ExternalSystemManager<?, ?, ?, ?, ?> manager =
        ExternalSystemApiUtil.getManager(externalSystemId);
    assert manager != null;
    AbstractExternalSystemLocalSettings settings = manager.getLocalSettingsProvider().fun(project);

    ExternalSystemRecentTaskListModel recentTasksModel =
        new ExternalSystemRecentTaskListModel(externalSystemId, project);
    recentTasksModel.setTasks(settings.getRecentTasks());
    myRecentTasksList =
        new ExternalSystemRecentTasksList(recentTasksModel, externalSystemId, project) {
          @Override
          protected void processMouseEvent(MouseEvent e) {
            if (e.getClickCount() > 0) {
              mySelectedTaskProvider = myRecentTasksList;
              myAllTasksTree.getSelectionModel().clearSelection();
            }
            super.processMouseEvent(e);
          }
        };

    myAllTasksModel = new ExternalSystemTasksTreeModel(externalSystemId);
    myAllTasksTree =
        new ExternalSystemTasksTree(
            myAllTasksModel, settings.getExpandStates(), project, externalSystemId) {
          @Override
          protected void processMouseEvent(MouseEvent e) {
            if (e.getClickCount() > 0) {
              mySelectedTaskProvider = myAllTasksTree;
              myRecentTasksList.getSelectionModel().clearSelection();
            }
            super.processMouseEvent(e);
          }
        };
    final String actionIdToUseForDoubleClick =
        DefaultRunExecutor.getRunExecutorInstance().getContextActionId();
    myAllTasksTree.addMouseListener(
        new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() >= 2 && !e.isPopupTrigger()) {
              ExternalSystemUiUtil.executeAction(actionIdToUseForDoubleClick, e);
            }
          }
        });
    ExternalSystemUiUtil.apply(settings, myAllTasksModel);
    CustomizationUtil.installPopupHandler(
        myAllTasksTree, TREE_ACTIONS_GROUP_ID, TREE_CONTEXT_MENU_PLACE);

    ActionManager actionManager = ActionManager.getInstance();
    ActionGroup group = (ActionGroup) actionManager.getAction(TOOL_WINDOW_TOOLBAR_ACTIONS_GROUP_ID);
    ActionToolbar toolbar = actionManager.createActionToolbar(TOOL_WINDOW_PLACE, group, true);
    toolbar.setTargetComponent(this);
    setToolbar(toolbar.getComponent());

    JPanel content = new JPanel(new GridBagLayout());
    content.setOpaque(true);
    content.setBackground(UIUtil.getListBackground());
    JComponent recentTasksWithTitle =
        wrap(myRecentTasksList, ExternalSystemBundle.message("tasks.recent.title"));
    content.add(recentTasksWithTitle, ExternalSystemUiUtil.getFillLineConstraints(0));
    JBScrollPane scrollPane = new JBScrollPane(myAllTasksTree);
    scrollPane.setBorder(null);
    JComponent allTasksWithTitle =
        wrap(scrollPane, ExternalSystemBundle.message("tasks.all.title"));
    content.add(
        allTasksWithTitle, ExternalSystemUiUtil.getFillLineConstraints(0).weighty(1).fillCell());
    setContent(content);
  }