public void update(AnActionEvent e) {
   boolean enabled = true;
   for (DependenciesBuilder builder : myBuilders) {
     enabled &= builder.getScope().isValid();
   }
   e.getPresentation().setEnabled(enabled);
 }
 private void processDependencies(
     final Set<PsiFile> searchIn,
     final Set<PsiFile> searchFor,
     Processor<List<PsiFile>> processor) {
   if (myTransitiveBorder == 0) return;
   Set<PsiFile> initialSearchFor = new HashSet<PsiFile>(searchFor);
   for (DependenciesBuilder builder : myBuilders) {
     for (PsiFile from : searchIn) {
       for (PsiFile to : initialSearchFor) {
         final List<List<PsiFile>> paths = builder.findPaths(from, to);
         Collections.sort(
             paths,
             new Comparator<List<PsiFile>>() {
               public int compare(final List<PsiFile> p1, final List<PsiFile> p2) {
                 return p1.size() - p2.size();
               }
             });
         for (List<PsiFile> path : paths) {
           if (!path.isEmpty()) {
             path.add(0, from);
             path.add(to);
             if (!processor.process(path)) return;
           }
         }
       }
     }
   }
 }
 private void rebuild() {
   myIllegalDependencies = new HashMap<PsiFile, Map<DependencyRule, Set<PsiFile>>>();
   for (DependenciesBuilder builder : myBuilders) {
     myIllegalDependencies.putAll(builder.getIllegalDependencies());
   }
   updateLeftTreeModel();
   updateRightTreeModel();
 }
 public void actionPerformed(AnActionEvent e) {
   final PackageDependenciesNode leftNode = myLeftTree.getSelectedNode();
   final PackageDependenciesNode rightNode = myRightTree.getSelectedNode();
   if (leftNode != null && rightNode != null) {
     boolean hasDirectDependencies = myTransitiveBorder == 0;
     if (myTransitiveBorder > 0) {
       final Set<PsiFile> searchIn = getSelectedScope(myLeftTree);
       final Set<PsiFile> searchFor = getSelectedScope(myRightTree);
       for (DependenciesBuilder builder : myBuilders) {
         if (hasDirectDependencies) break;
         for (PsiFile from : searchIn) {
           if (hasDirectDependencies) break;
           for (PsiFile to : searchFor) {
             if (hasDirectDependencies) break;
             final List<List<PsiFile>> paths = builder.findPaths(from, to);
             for (List<PsiFile> path : paths) {
               if (path.isEmpty()) {
                 hasDirectDependencies = true;
                 break;
               }
             }
           }
         }
       }
     }
     final PatternDialectProvider provider =
         PatternDialectProvider.getInstance(mySettings.SCOPE_TYPE);
     PackageSet leftPackageSet = provider.createPackageSet(leftNode, true);
     if (leftPackageSet == null) {
       leftPackageSet = provider.createPackageSet(leftNode, false);
     }
     LOG.assertTrue(leftPackageSet != null);
     PackageSet rightPackageSet = provider.createPackageSet(rightNode, true);
     if (rightPackageSet == null) {
       rightPackageSet = provider.createPackageSet(rightNode, false);
     }
     LOG.assertTrue(rightPackageSet != null);
     if (hasDirectDependencies) {
       DependencyValidationManager.getInstance(myProject)
           .addRule(
               new DependencyRule(
                   new NamedScope.UnnamedScope(leftPackageSet),
                   new NamedScope.UnnamedScope(rightPackageSet),
                   true));
       rebuild();
     } else {
       Messages.showErrorDialog(
           DependenciesPanel.this,
           "Rule was not added.\n There is no direct dependency between \'"
               + leftPackageSet.getText()
               + "\' and \'"
               + rightPackageSet.getText()
               + "\'",
           AnalysisScopeBundle.message("mark.dependency.illegal.text"));
     }
   }
 }
  public DependenciesPanel(
      Project project, final List<DependenciesBuilder> builders, final Set<PsiFile> excluded) {
    super(new BorderLayout());
    myBuilders = builders;
    myExcluded = excluded;
    final DependenciesBuilder main = myBuilders.get(0);
    myForward = !main.isBackward();
    myScopeOfInterest = main.getScopeOfInterest();
    myTransitiveBorder = main.getTransitiveBorder();
    myDependencies = new HashMap<PsiFile, Set<PsiFile>>();
    myIllegalDependencies = new HashMap<PsiFile, Map<DependencyRule, Set<PsiFile>>>();
    for (DependenciesBuilder builder : builders) {
      myDependencies.putAll(builder.getDependencies());
      myIllegalDependencies.putAll(builder.getIllegalDependencies());
    }
    exclude(excluded);
    myProject = project;
    myUsagesPanel = new DependenciesUsagesPanel(myProject, myBuilders);
    Disposer.register(this, myUsagesPanel);

    final Splitter treeSplitter = new Splitter();
    Disposer.register(
        this,
        new Disposable() {
          public void dispose() {
            treeSplitter.dispose();
          }
        });
    treeSplitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myLeftTree));
    treeSplitter.setSecondComponent(ScrollPaneFactory.createScrollPane(myRightTree));

    final Splitter splitter = new Splitter(true);
    Disposer.register(
        this,
        new Disposable() {
          public void dispose() {
            splitter.dispose();
          }
        });
    splitter.setFirstComponent(treeSplitter);
    splitter.setSecondComponent(myUsagesPanel);
    add(splitter, BorderLayout.CENTER);
    add(createToolbar(), BorderLayout.NORTH);

    myRightTreeExpansionMonitor = PackageTreeExpansionMonitor.install(myRightTree, myProject);
    myLeftTreeExpansionMonitor = PackageTreeExpansionMonitor.install(myLeftTree, myProject);

    myRightTreeMarker =
        new Marker() {
          public boolean isMarked(VirtualFile file) {
            return myIllegalsInRightTree.contains(file);
          }
        };

    myLeftTreeMarker =
        new Marker() {
          public boolean isMarked(VirtualFile file) {
            return myIllegalDependencies.containsKey(file);
          }
        };

    updateLeftTreeModel();
    updateRightTreeModel();

    myLeftTree
        .getSelectionModel()
        .addTreeSelectionListener(
            new TreeSelectionListener() {
              public void valueChanged(TreeSelectionEvent e) {
                updateRightTreeModel();
                final StringBuffer denyRules = new StringBuffer();
                final StringBuffer allowRules = new StringBuffer();
                final TreePath[] paths = myLeftTree.getSelectionPaths();
                if (paths == null) {
                  return;
                }
                for (TreePath path : paths) {
                  PackageDependenciesNode selectedNode =
                      (PackageDependenciesNode) path.getLastPathComponent();
                  traverseToLeaves(selectedNode, denyRules, allowRules);
                }
                if (denyRules.length() + allowRules.length() > 0) {
                  StatusBar.Info.set(
                      AnalysisScopeBundle.message(
                          "status.bar.rule.violation.message",
                          ((denyRules.length() == 0 || allowRules.length() == 0) ? 1 : 2),
                          (denyRules.length() > 0
                                  ? denyRules.toString() + (allowRules.length() > 0 ? "; " : "")
                                  : " ")
                              + (allowRules.length() > 0 ? allowRules.toString() : " ")),
                      myProject);
                } else {
                  StatusBar.Info.set(
                      AnalysisScopeBundle.message("status.bar.no.rule.violation.message"),
                      myProject);
                }
              }
            });

    myRightTree
        .getSelectionModel()
        .addTreeSelectionListener(
            new TreeSelectionListener() {
              public void valueChanged(TreeSelectionEvent e) {
                SwingUtilities.invokeLater(
                    new Runnable() {
                      public void run() {
                        final Set<PsiFile> searchIn = getSelectedScope(myLeftTree);
                        final Set<PsiFile> searchFor = getSelectedScope(myRightTree);
                        if (searchIn.isEmpty() || searchFor.isEmpty()) {
                          myUsagesPanel.setToInitialPosition();
                          processDependencies(
                              searchIn,
                              searchFor,
                              new Processor<List<PsiFile>>() { // todo do not show too many usages
                                public boolean process(final List<PsiFile> path) {
                                  searchFor.add(path.get(1));
                                  return true;
                                }
                              });
                        } else {
                          myUsagesPanel.findUsages(searchIn, searchFor);
                        }
                      }
                    });
              }
            });

    initTree(myLeftTree, false);
    initTree(myRightTree, true);

    if (builders.size() == 1) {
      AnalysisScope scope = builders.get(0).getScope();
      if (scope.getScopeType() == AnalysisScope.FILE) {
        Set<PsiFile> oneFileSet = myDependencies.keySet();
        if (oneFileSet.size() == 1) {
          selectElementInLeftTree(oneFileSet.iterator().next());
          return;
        }
      }
    }
    TreeUtil.selectFirstNode(myLeftTree);
  }