public void testPantsIdeaPluginGoal() throws Throwable {
    assertEmpty(ModuleManager.getInstance(myProject).getModules());

    /** Check whether Pants supports `idea-plugin` goal. */
    PantsUtil.findPantsExecutable(getProjectFolder().getPath());
    final GeneralCommandLine commandLinePantsGoals =
        PantsUtil.defaultCommandLine(getProjectFolder().getPath());
    commandLinePantsGoals.addParameter("goals");
    final ProcessOutput cmdOutputGoals =
        PantsUtil.getCmdOutput(commandLinePantsGoals.withWorkDirectory(getProjectFolder()), null);
    assertEquals(commandLinePantsGoals.toString() + " failed", 0, cmdOutputGoals.getExitCode());
    if (!cmdOutputGoals.getStdout().contains("idea-plugin")) {
      return;
    }

    /** Generate idea project via `idea-plugin` goal. */
    final GeneralCommandLine commandLine =
        PantsUtil.defaultCommandLine(getProjectFolder().getPath());
    final File outputFile = FileUtil.createTempFile("project_dir_location", ".out");
    commandLine.addParameters(
        "idea-plugin",
        "--no-open",
        "--output-file=" + outputFile.getPath(),
        "testprojects/tests/java/org/pantsbuild/testproject/::");
    final ProcessOutput cmdOutput =
        PantsUtil.getCmdOutput(commandLine.withWorkDirectory(getProjectFolder()), null);
    assertEquals(commandLine.toString() + " failed", 0, cmdOutput.getExitCode());
    String projectDir = FileUtil.loadFile(outputFile);

    myProject = ProjectUtil.openProject(projectDir + "/project.ipr", myProject, false);
    // Invoke post startup activities.
    UIUtil.dispatchAllInvocationEvents();
    /**
     * Under unit test mode, {@link com.intellij.ide.impl.ProjectUtil#openProject} will force open a
     * project in a new window, so Project SDK has to be reset. In practice, this is not needed.
     */
    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              @Override
              public void run() {
                final JavaSdk javaSdk = JavaSdk.getInstance();
                ProjectRootManager.getInstance(myProject)
                    .setProjectSdk(
                        ProjectJdkTable.getInstance().getSdksOfType(javaSdk).iterator().next());
              }
            });

    JUnitConfiguration runConfiguration =
        generateJUnitConfiguration(
            "testprojects_tests_java_org_pantsbuild_testproject_matcher_matcher",
            "org.pantsbuild.testproject.matcher.MatcherTest",
            null);

    assertAndRunPantsMake(runConfiguration);
    assertSuccessfulJUnitTest(runConfiguration);
  }
  @NotNull
  @Override
  public Collection<AbstractTreeNode> modify(
      @NotNull final AbstractTreeNode node,
      @NotNull Collection<AbstractTreeNode> collection,
      ViewSettings settings) {
    final Project project = node.getProject();
    if (node instanceof PsiDirectoryNode && project != null) {
      final Module module =
          ModuleUtil.findModuleForPsiElement(((PsiDirectoryNode) node).getValue());
      final Optional<String> buildPath =
          module != null
              ? PantsUtil.getPathFromAddress(
                  module, ExternalSystemConstants.LINKED_PROJECT_PATH_KEY)
              : Optional.empty();
      if (buildPath.isPresent()) {
        final Optional<VirtualFile> buildFile =
            PantsUtil.findFileRelativeToBuildRoot(project, buildPath.get());

        boolean isModuleRoot =
            ArrayUtil.indexOf(
                    ModuleRootManager.getInstance(module).getContentRoots(),
                    ((PsiDirectoryNode) node).getVirtualFile())
                >= 0;
        if (buildFile.isPresent() && isModuleRoot) {
          // Check if there's already a BUILD file in the directory; if so, we don't add another
          final AbstractTreeNode existingBuildFile =
              ContainerUtil.find(
                  collection.iterator(),
                  new Condition<AbstractTreeNode>() {
                    @Override
                    public boolean value(AbstractTreeNode node) {
                      return node instanceof PsiFileNode
                          && buildFile.get().equals(((PsiFileNode) node).getVirtualFile());
                    }
                  });
          if (existingBuildFile == null) {
            final PsiFile buildPsiFile = PsiManager.getInstance(project).findFile(buildFile.get());
            final PsiFileNode buildNode =
                new PsiFileNode(project, buildPsiFile, settings) {
                  @Override
                  protected void updateImpl(PresentationData data) {
                    super.updateImpl(data);
                    data.setIcon(PantsIcons.Icon);
                  }
                };
            final List<AbstractTreeNode> modifiedCollection =
                new ArrayList<AbstractTreeNode>(collection);
            modifiedCollection.add(buildNode);
            return modifiedCollection;
          }
        }
      }
    }
    return collection;
  }
  @NotNull
  private DataNode<ModuleData> createModuleData(
      @NotNull DataNode<ProjectData> projectInfoDataNode,
      @NotNull String targetName,
      @NotNull TargetInfo targetInfo,
      @NotNull PantsCompileOptionsExecutor executor) {
    final Collection<SourceRoot> roots = targetInfo.getRoots();
    final PantsSourceType rootType = targetInfo.getSourcesType();
    final String moduleName = PantsUtil.getCanonicalModuleName(targetName);

    final ModuleData moduleData =
        new ModuleData(
            targetName,
            PantsConstants.SYSTEM_ID,
            ModuleTypeId.JAVA_MODULE,
            moduleName,
            projectInfoDataNode.getData().getIdeProjectFileDirectoryPath() + "/" + moduleName,
            new File(executor.getWorkingDir(), targetName).getAbsolutePath());

    final DataNode<ModuleData> moduleDataNode =
        projectInfoDataNode.createChild(ProjectKeys.MODULE, moduleData);

    final TargetMetadata metadata = new TargetMetadata(PantsConstants.SYSTEM_ID, moduleName);
    metadata.setTargetAddresses(
        ContainerUtil.map(
            targetInfo.getAddressInfos(),
            new Function<TargetAddressInfo, String>() {
              @Override
              public String fun(TargetAddressInfo info) {
                return info.getTargetAddress();
              }
            }));
    metadata.setLibraryExcludes(targetInfo.getExcludes());
    moduleDataNode.createChild(TargetMetadata.KEY, metadata);

    return moduleDataNode;
  }