public ScopeEditorPanel(Project project, final NamedScopesHolder holder) {
    myProject = project;
    myHolder = holder;

    myPackageTree = new Tree(new RootNode(project));

    myButtonsPanel.add(createActionsPanel());

    myTreePanel.setLayout(new BorderLayout());
    myTreePanel.add(ScrollPaneFactory.createScrollPane(myPackageTree), BorderLayout.CENTER);

    myTreeToolbar.setLayout(new BorderLayout());
    myTreeToolbar.add(createTreeToolbar(), BorderLayout.WEST);

    myTreeExpansionMonitor = PackageTreeExpansionMonitor.install(myPackageTree, myProject);

    myTreeMarker =
        new Marker() {
          public boolean isMarked(VirtualFile file) {
            return myCurrentScope != null
                && (myCurrentScope instanceof PackageSetBase
                    ? ((PackageSetBase) myCurrentScope).contains(file, myHolder)
                    : myCurrentScope.contains(PackageSetBase.getPsiFile(file, myHolder), myHolder));
          }
        };

    myPatternField.setDialogCaption("Pattern");
    myPatternField
        .getDocument()
        .addDocumentListener(
            new DocumentAdapter() {
              public void textChanged(DocumentEvent event) {
                onTextChange();
              }
            });

    myPatternField
        .getTextField()
        .addCaretListener(
            new CaretListener() {
              public void caretUpdate(CaretEvent e) {
                myCaretPosition = e.getDot();
                updateCaretPositionText();
              }
            });

    myPatternField
        .getTextField()
        .addFocusListener(
            new FocusListener() {
              public void focusGained(FocusEvent e) {
                if (myErrorMessage != null) {
                  myPositionPanel.setVisible(true);
                  myPanel.revalidate();
                }
              }

              public void focusLost(FocusEvent e) {
                myPositionPanel.setVisible(false);
                myPanel.revalidate();
              }
            });

    initTree(myPackageTree);
    new UiNotifyConnector(
        myPanel,
        new Activatable() {
          @Override
          public void showNotify() {}

          @Override
          public void hideNotify() {
            cancelCurrentProgress();
          }
        });
    myPartiallyIncluded.setBackground(MyTreeCellRenderer.PARTIAL_INCLUDED);
    myRecursivelyIncluded.setBackground(MyTreeCellRenderer.WHOLE_INCLUDED);
  }
  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);
  }