public RerunAction(JComponent comp) {
   super(
       InspectionsBundle.message("inspection.action.rerun"),
       InspectionsBundle.message("inspection.action.rerun"),
       AllIcons.Actions.Rerun);
   registerCustomShortcutSet(CommonShortcuts.getRerun(), comp);
 }
  public void showDescription(InspectionTool tool) {
    if (tool.getShortName().length() == 0) {
      showEmpty();
      return;
    }
    @NonNls StringBuffer page = new StringBuffer();
    page.append("<table border='0' cellspacing='0' cellpadding='0' width='100%'>");
    page.append("<tr><td colspan='2'>");
    HTMLComposer.appendHeading(
        page, InspectionsBundle.message("inspection.tool.in.browser.id.title"));
    page.append("</td></tr>");
    page.append("<tr><td width='37'></td>" + "<td>");
    page.append(tool.getShortName());
    page.append("</td></tr>");
    page.append("<tr height='10'></tr>");
    page.append("<tr><td colspan='2'>");
    HTMLComposer.appendHeading(
        page, InspectionsBundle.message("inspection.tool.in.browser.description.title"));
    page.append("</td></tr>");
    page.append("<tr><td width='37'></td>" + "<td>");
    @NonNls final String underConstruction = "<b>" + UNDER_CONSTRUCTION + "</b></html>";
    try {
      @NonNls String description = tool.loadDescription();
      if (description == null) {
        description = underConstruction;
      }
      page.append(UIUtil.getHtmlBody(description));

      page.append("</td></tr></table>");
      myHTMLViewer.setText(XmlStringUtil.wrapInHtml(page));
      setupStyle();
    } finally {
      myCurrentEntity = null;
    }
  }
  private synchronized void writeOutput(
      @NotNull final CommonProblemDescriptor[] descriptions, @NotNull RefEntity refElement) {
    final Element parentNode = new Element(InspectionsBundle.message("inspection.problems"));
    exportResults(descriptions, refElement, parentNode);
    final List list = parentNode.getChildren();

    @NonNls final String ext = ".xml";
    final String fileName = ourOutputPath + File.separator + myToolWrapper.getShortName() + ext;
    final PathMacroManager pathMacroManager =
        PathMacroManager.getInstance(getContext().getProject());
    PrintWriter printWriter = null;
    try {
      new File(ourOutputPath).mkdirs();
      final File file = new File(fileName);
      final CharArrayWriter writer = new CharArrayWriter();
      if (!file.exists()) {
        writer
            .append("<")
            .append(InspectionsBundle.message("inspection.problems"))
            .append(" " + GlobalInspectionContextBase.LOCAL_TOOL_ATTRIBUTE + "=\"")
            .append(Boolean.toString(myToolWrapper instanceof LocalInspectionToolWrapper))
            .append("\">\n");
      }
      for (Object o : list) {
        final Element element = (Element) o;
        pathMacroManager.collapsePaths(element);
        JDOMUtil.writeElement(element, writer, "\n");
      }
      printWriter =
          new PrintWriter(
              new BufferedWriter(
                  new OutputStreamWriter(
                      new FileOutputStream(fileName, true), CharsetToolkit.UTF8_CHARSET)));
      printWriter.append("\n");
      printWriter.append(writer.toString());
    } catch (IOException e) {
      LOG.error(e);
    } finally {
      if (printWriter != null) {
        printWriter.close();
      }
    }
  }
 @Override
 @Nullable
 public QuickFixAction[] extractActiveFixes(
     @NotNull RefEntity[] refElements, @NotNull Map<RefEntity, Set<QuickFix>> actions) {
   Map<Class, QuickFixAction> result =
       new com.intellij.util.containers.HashMap<Class, QuickFixAction>();
   for (RefEntity refElement : refElements) {
     final Set<QuickFix> localQuickFixes = actions.get(refElement);
     if (localQuickFixes == null) continue;
     for (QuickFix fix : localQuickFixes) {
       if (fix == null) continue;
       final Class klass =
           fix instanceof ActionClassHolder
               ? ((ActionClassHolder) fix).getActionClass()
               : fix.getClass();
       final QuickFixAction quickFixAction = result.get(klass);
       if (quickFixAction != null) {
         try {
           String familyName = fix.getFamilyName();
           familyName = !familyName.isEmpty() ? "\'" + familyName + "\'" : familyName;
           ((LocalQuickFixWrapper) quickFixAction)
               .setText(
                   InspectionsBundle.message(
                       "inspection.descriptor.provider.apply.fix", familyName));
         } catch (AbstractMethodError e) {
           // for plugin compatibility
           ((LocalQuickFixWrapper) quickFixAction)
               .setText(InspectionsBundle.message("inspection.descriptor.provider.apply.fix", ""));
         }
       } else {
         LocalQuickFixWrapper quickFixWrapper = new LocalQuickFixWrapper(fix, myToolWrapper);
         result.put(klass, quickFixWrapper);
       }
     }
   }
   return result.values().isEmpty()
       ? null
       : result.values().toArray(new QuickFixAction[result.size()]);
 }
 private void appendSuppressSection(final StringBuffer buf) {
   final InspectionTool tool = getTool();
   if (tool != null) {
     final HighlightDisplayKey key = HighlightDisplayKey.find(tool.getShortName());
     if (key != null) { // dummy entry points
       final SuppressActionWrapper.SuppressTreeAction[] suppressActions =
           new SuppressActionWrapper(
                   myView.getProject(), tool, myView.getTree().getSelectionPaths())
               .getChildren(null);
       if (suppressActions.length > 0) {
         final List<AnAction> activeSuppressActions = new ArrayList<AnAction>();
         for (SuppressActionWrapper.SuppressTreeAction suppressAction : suppressActions) {
           if (suppressAction.isAvailable()) {
             activeSuppressActions.add(suppressAction);
           }
         }
         if (!activeSuppressActions.isEmpty()) {
           int idx = 0;
           @NonNls final String br = "<br>";
           buf.append(br);
           HTMLComposerImpl.appendHeading(
               buf, InspectionsBundle.message("inspection.export.results.suppress"));
           for (AnAction suppressAction : activeSuppressActions) {
             buf.append(br);
             if (idx == activeSuppressActions.size() - 1) {
               buf.append(br);
             }
             HTMLComposer.appendAfterHeaderIndention(buf);
             @NonNls
             final String href =
                 "<a HREF=\"file://bred.txt#suppress:"
                     + idx
                     + "\">"
                     + suppressAction.getTemplatePresentation().getText()
                     + "</a>";
             buf.append(href);
             idx++;
           }
         }
       }
     }
   }
 }
 private EditSettingsAction() {
   super(
       InspectionsBundle.message("inspection.action.edit.settings"),
       InspectionsBundle.message("inspection.action.edit.settings"),
       AllIcons.General.Settings);
 }
  @SuppressWarnings({"NonStaticInitializer"})
  private JComponent createRightActionsToolbar() {
    myIncludeAction =
        new AnAction(InspectionsBundle.message("inspections.result.view.include.action.text")) {
          {
            registerCustomShortcutSet(CommonShortcuts.INSERT, myTree);
          }

          @Override
          public void actionPerformed(AnActionEvent e) {
            final TreePath[] paths = myTree.getSelectionPaths();
            if (paths != null) {
              for (TreePath path : paths) {
                ((InspectionTreeNode) path.getLastPathComponent()).amnesty();
              }
            }
            updateView(false);
          }

          @Override
          public void update(final AnActionEvent e) {
            final TreePath[] paths = myTree.getSelectionPaths();
            e.getPresentation()
                .setEnabled(
                    paths != null
                        && paths.length > 0
                        && !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS);
          }
        };

    myExcludeAction =
        new AnAction(InspectionsBundle.message("inspections.result.view.exclude.action.text")) {
          {
            registerCustomShortcutSet(CommonShortcuts.getDelete(), myTree);
          }

          @Override
          public void actionPerformed(final AnActionEvent e) {
            final TreePath[] paths = myTree.getSelectionPaths();
            if (paths != null) {
              for (TreePath path : paths) {
                ((InspectionTreeNode) path.getLastPathComponent()).ignoreElement();
              }
            }
            updateView(false);
          }

          @Override
          public void update(final AnActionEvent e) {
            final TreePath[] path = myTree.getSelectionPaths();
            e.getPresentation().setEnabled(path != null && path.length > 0);
          }
        };

    DefaultActionGroup specialGroup = new DefaultActionGroup();
    specialGroup.add(myGlobalInspectionContext.getUIOptions().createGroupBySeverityAction(this));
    specialGroup.add(myGlobalInspectionContext.getUIOptions().createGroupByDirectoryAction(this));
    specialGroup.add(
        myGlobalInspectionContext.getUIOptions().createFilterResolvedItemsAction(this));
    specialGroup.add(
        myGlobalInspectionContext.getUIOptions().createShowOutdatedProblemsAction(this));
    specialGroup.add(myGlobalInspectionContext.getUIOptions().createShowDiffOnlyAction(this));
    specialGroup.add(new EditSettingsAction());
    specialGroup.add(new InvokeQuickFixAction(this));
    specialGroup.add(new InspectionsOptionsToolbarAction(this));
    return createToolbar(specialGroup);
  }
class Browser extends JPanel {
  private static final String UNDER_CONSTRUCTION =
      InspectionsBundle.message("inspection.tool.description.under.construction.text");
  private final List<ClickListener> myClickListeners =
      ContainerUtil.createLockFreeCopyOnWriteList();
  private RefEntity myCurrentEntity;
  private JEditorPane myHTMLViewer;
  private final InspectionResultsView myView;
  private final HyperlinkListener myHyperLinkListener;
  private CommonProblemDescriptor myCurrentDescriptor;

  public static class ClickEvent {
    public static final int REF_ELEMENT = 1;
    public static final int FILE_OFFSET = 2;
    private final VirtualFile myFile;
    private final int myStartPosition;
    private final int myEndPosition;
    private final RefElement refElement;
    private final int myEventType;

    public ClickEvent(VirtualFile myFile, int myStartPosition, int myEndPosition) {
      this.myFile = myFile;
      this.myStartPosition = myStartPosition;
      this.myEndPosition = myEndPosition;
      myEventType = FILE_OFFSET;
      refElement = null;
    }

    public int getEventType() {
      return myEventType;
    }

    public VirtualFile getFile() {
      return myFile;
    }

    public int getStartOffset() {
      return myStartPosition;
    }

    public int getEndOffset() {
      return myEndPosition;
    }

    public RefElement getClickedElement() {
      return refElement;
    }
  }

  public void dispose() {
    removeAll();
    if (myHTMLViewer != null) {
      myHTMLViewer.removeHyperlinkListener(myHyperLinkListener);
      myHTMLViewer = null;
    }
    myClickListeners.clear();
  }

  public interface ClickListener {
    void referenceClicked(ClickEvent e);
  }

  private void showPageFromHistory(RefEntity newEntity) {
    InspectionTool tool = getTool(newEntity);
    try {
      if (tool instanceof DescriptorProviderInspection
          && !(tool instanceof CommonInspectionToolWrapper)) {
        showEmpty();
      } else {
        try {
          String html = generateHTML(newEntity, tool);
          myHTMLViewer.read(new StringReader(html), null);
          setupStyle();
          myHTMLViewer.setCaretPosition(0);
        } catch (Exception e) {
          showEmpty();
        }
      }
    } finally {
      myCurrentEntity = newEntity;
      myCurrentDescriptor = null;
    }
  }

  public void showPageFor(RefEntity refEntity, CommonProblemDescriptor descriptor) {
    try {
      String html = generateHTML(refEntity, descriptor);
      myHTMLViewer.read(new StringReader(html), null);
      setupStyle();
      myHTMLViewer.setCaretPosition(0);
    } catch (Exception e) {
      showEmpty();
    } finally {
      myCurrentEntity = refEntity;
      myCurrentDescriptor = descriptor;
    }
  }

  public void showPageFor(RefEntity newEntity) {
    if (newEntity == null) {
      showEmpty();
      return;
    }
    // multiple problems for one entity -> refresh browser
    showPageFromHistory(newEntity.getRefManager().getRefinedElement(newEntity));
  }

  public Browser(InspectionResultsView view) {
    super(new BorderLayout());
    myView = view;

    myCurrentEntity = null;
    myCurrentDescriptor = null;

    myHTMLViewer =
        new JEditorPane(
            UIUtil.HTML_MIME,
            InspectionsBundle.message("inspection.offline.view.empty.browser.text"));
    myHTMLViewer.setEditable(false);
    myHyperLinkListener =
        new HyperlinkListener() {
          @Override
          public void hyperlinkUpdate(HyperlinkEvent e) {
            if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
              JEditorPane pane = (JEditorPane) e.getSource();
              if (e instanceof HTMLFrameHyperlinkEvent) {
                HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e;
                HTMLDocument doc = (HTMLDocument) pane.getDocument();
                doc.processHTMLFrameHyperlinkEvent(evt);
              } else {
                try {
                  URL url = e.getURL();
                  @NonNls String ref = url.getRef();
                  if (ref.startsWith("pos:")) {
                    int delimeterPos = ref.indexOf(':', "pos:".length() + 1);
                    String startPosition = ref.substring("pos:".length(), delimeterPos);
                    String endPosition = ref.substring(delimeterPos + 1);
                    Integer textStartOffset = new Integer(startPosition);
                    Integer textEndOffset = new Integer(endPosition);
                    String fileURL = url.toExternalForm();
                    fileURL = fileURL.substring(0, fileURL.indexOf('#'));
                    VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
                    if (vFile != null) {
                      fireClickEvent(vFile, textStartOffset.intValue(), textEndOffset.intValue());
                    }
                  } else if (ref.startsWith("descr:")) {
                    if (myCurrentDescriptor instanceof ProblemDescriptor) {
                      PsiElement psiElement =
                          ((ProblemDescriptor) myCurrentDescriptor).getPsiElement();
                      if (psiElement == null) return;
                      VirtualFile vFile = psiElement.getContainingFile().getVirtualFile();
                      if (vFile != null) {
                        TextRange range =
                            ((ProblemDescriptorBase) myCurrentDescriptor).getTextRange();
                        fireClickEvent(vFile, range.getStartOffset(), range.getEndOffset());
                      }
                    }
                  } else if (ref.startsWith("invoke:")) {
                    int actionNumber = Integer.parseInt(ref.substring("invoke:".length()));
                    getTool()
                        .getQuickFixes(new RefElement[] {(RefElement) myCurrentEntity})[
                        actionNumber]
                        .doApplyFix(new RefElement[] {(RefElement) myCurrentEntity}, myView);
                  } else if (ref.startsWith("invokelocal:")) {
                    int actionNumber = Integer.parseInt(ref.substring("invokelocal:".length()));
                    if (actionNumber > -1) {
                      invokeLocalFix(actionNumber);
                    }
                  } else if (ref.startsWith("suppress:")) {
                    final SuppressActionWrapper.SuppressTreeAction[] suppressTreeActions =
                        new SuppressActionWrapper(
                                myView.getProject(),
                                getTool(),
                                myView.getTree().getSelectionPaths())
                            .getChildren(null);
                    final List<AnAction> activeActions = new ArrayList<AnAction>();
                    for (SuppressActionWrapper.SuppressTreeAction suppressTreeAction :
                        suppressTreeActions) {
                      if (suppressTreeAction.isAvailable()) activeActions.add(suppressTreeAction);
                    }
                    if (!activeActions.isEmpty()) {
                      int actionNumber = Integer.parseInt(ref.substring("suppress:".length()));
                      if (actionNumber > -1 && activeActions.size() > actionNumber) {
                        activeActions.get(actionNumber).actionPerformed(null);
                      }
                    }
                  } else {
                    int offset = Integer.parseInt(ref);
                    String fileURL = url.toExternalForm();
                    fileURL = fileURL.substring(0, fileURL.indexOf('#'));
                    VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
                    if (vFile == null) {
                      vFile = VfsUtil.findFileByURL(url);
                    }
                    if (vFile != null) {
                      fireClickEvent(vFile, offset, offset);
                    }
                  }
                } catch (Throwable t) {
                  // ???
                }
              }
            }
          }
        };
    myHTMLViewer.addHyperlinkListener(myHyperLinkListener);

    final JScrollPane pane = ScrollPaneFactory.createScrollPane(myHTMLViewer);
    pane.setBorder(null);
    add(pane, BorderLayout.CENTER);
    setupStyle();
  }

  private void setupStyle() {
    Document document = myHTMLViewer.getDocument();
    if (!(document instanceof StyledDocument)) {
      return;
    }

    StyledDocument styledDocument = (StyledDocument) document;

    EditorColorsManager colorsManager = EditorColorsManager.getInstance();
    EditorColorsScheme scheme = colorsManager.getGlobalScheme();

    Style style = styledDocument.addStyle("active", null);
    StyleConstants.setFontFamily(style, scheme.getEditorFontName());
    StyleConstants.setFontSize(style, scheme.getEditorFontSize());
    styledDocument.setCharacterAttributes(0, document.getLength(), style, false);
  }

  public void addClickListener(ClickListener listener) {
    myClickListeners.add(listener);
  }

  private void fireClickEvent(VirtualFile file, int startPosition, int endPosition) {
    ClickEvent e = new ClickEvent(file, startPosition, endPosition);

    for (ClickListener listener : myClickListeners) {
      listener.referenceClicked(e);
    }
  }

  private String generateHTML(final RefEntity refEntity, final InspectionTool tool) {
    final StringBuffer buf = new StringBuffer();
    if (refEntity instanceof RefElement) {
      final Runnable action =
          new Runnable() {
            @Override
            public void run() {
              tool.getComposer().compose(buf, refEntity);
            }
          };
      ApplicationManager.getApplication().runReadAction(action);
    } else {
      tool.getComposer().compose(buf, refEntity);
    }

    uppercaseFirstLetter(buf);

    if (refEntity instanceof RefElement) {
      appendSuppressSection(buf);
    }

    insertHeaderFooter(buf);

    return buf.toString();
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  private static void insertHeaderFooter(final StringBuffer buf) {
    buf.insert(0, "<HTML><BODY>");
    buf.append("</BODY></HTML>");
  }

  private String generateHTML(final RefEntity refEntity, final CommonProblemDescriptor descriptor) {
    final StringBuffer buf = new StringBuffer();
    final Runnable action =
        new Runnable() {
          @Override
          public void run() {
            InspectionTool tool = getTool(refEntity);
            tool.getComposer().compose(buf, refEntity, descriptor);
          }
        };
    ApplicationManager.getApplication().runReadAction(action);

    uppercaseFirstLetter(buf);

    if (refEntity instanceof RefElement) {
      appendSuppressSection(buf);
    }

    insertHeaderFooter(buf);
    return buf.toString();
  }

  private InspectionTool getTool(final RefEntity refEntity) {
    InspectionTool tool = getTool();
    assert tool != null;
    final GlobalInspectionContextImpl manager = tool.getContext();
    if (manager == null) return tool;
    if (refEntity instanceof RefElement) {
      PsiElement element = ((RefElement) refEntity).getElement();
      if (element == null) return tool;
      final InspectionProfileWrapper profileWrapper =
          InspectionProjectProfileManagerImpl.getInstanceImpl(manager.getProject())
              .getProfileWrapper();
      if (profileWrapper == null) return tool;
      tool = profileWrapper.getInspectionTool(tool.getShortName(), element);
    }
    return tool;
  }

  private void appendSuppressSection(final StringBuffer buf) {
    final InspectionTool tool = getTool();
    if (tool != null) {
      final HighlightDisplayKey key = HighlightDisplayKey.find(tool.getShortName());
      if (key != null) { // dummy entry points
        final SuppressActionWrapper.SuppressTreeAction[] suppressActions =
            new SuppressActionWrapper(
                    myView.getProject(), tool, myView.getTree().getSelectionPaths())
                .getChildren(null);
        if (suppressActions.length > 0) {
          final List<AnAction> activeSuppressActions = new ArrayList<AnAction>();
          for (SuppressActionWrapper.SuppressTreeAction suppressAction : suppressActions) {
            if (suppressAction.isAvailable()) {
              activeSuppressActions.add(suppressAction);
            }
          }
          if (!activeSuppressActions.isEmpty()) {
            int idx = 0;
            @NonNls final String br = "<br>";
            buf.append(br);
            HTMLComposerImpl.appendHeading(
                buf, InspectionsBundle.message("inspection.export.results.suppress"));
            for (AnAction suppressAction : activeSuppressActions) {
              buf.append(br);
              if (idx == activeSuppressActions.size() - 1) {
                buf.append(br);
              }
              HTMLComposer.appendAfterHeaderIndention(buf);
              @NonNls
              final String href =
                  "<a HREF=\"file://bred.txt#suppress:"
                      + idx
                      + "\">"
                      + suppressAction.getTemplatePresentation().getText()
                      + "</a>";
              buf.append(href);
              idx++;
            }
          }
        }
      }
    }
  }

  private static void uppercaseFirstLetter(final StringBuffer buf) {
    if (buf.length() > 1) {
      char[] firstLetter = new char[1];
      buf.getChars(0, 1, firstLetter, 0);
      buf.setCharAt(0, Character.toUpperCase(firstLetter[0]));
    }
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  public void showEmpty() {
    myCurrentEntity = null;
    try {
      myHTMLViewer.read(new StringReader("<html><body></body></html>"), null);
    } catch (IOException e) {
      // can't be
    }
  }

  public void showDescription(InspectionTool tool) {
    if (tool.getShortName().length() == 0) {
      showEmpty();
      return;
    }
    @NonNls StringBuffer page = new StringBuffer();
    page.append("<table border='0' cellspacing='0' cellpadding='0' width='100%'>");
    page.append("<tr><td colspan='2'>");
    HTMLComposer.appendHeading(
        page, InspectionsBundle.message("inspection.tool.in.browser.id.title"));
    page.append("</td></tr>");
    page.append("<tr><td width='37'></td>" + "<td>");
    page.append(tool.getShortName());
    page.append("</td></tr>");
    page.append("<tr height='10'></tr>");
    page.append("<tr><td colspan='2'>");
    HTMLComposer.appendHeading(
        page, InspectionsBundle.message("inspection.tool.in.browser.description.title"));
    page.append("</td></tr>");
    page.append("<tr><td width='37'></td>" + "<td>");
    @NonNls final String underConstruction = "<b>" + UNDER_CONSTRUCTION + "</b></html>";
    try {
      @NonNls String description = tool.loadDescription();
      if (description == null) {
        description = underConstruction;
      }
      page.append(UIUtil.getHtmlBody(description));

      page.append("</td></tr></table>");
      myHTMLViewer.setText(XmlStringUtil.wrapInHtml(page));
      setupStyle();
    } finally {
      myCurrentEntity = null;
    }
  }

  @Nullable
  private InspectionTool getTool() {
    if (myView != null) {
      return myView.getTree().getSelectedTool();
    }
    return null;
  }

  public void invokeLocalFix(int idx) {
    if (myView.getTree().getSelectionCount() != 1) return;
    final InspectionTreeNode node =
        (InspectionTreeNode) myView.getTree().getSelectionPath().getLastPathComponent();
    if (node instanceof ProblemDescriptionNode) {
      final ProblemDescriptionNode problemNode = (ProblemDescriptionNode) node;
      final CommonProblemDescriptor descriptor = problemNode.getDescriptor();
      final RefEntity element = problemNode.getElement();
      invokeFix(element, descriptor, idx);
    } else if (node instanceof RefElementNode) {
      RefElementNode elementNode = (RefElementNode) node;
      RefEntity element = elementNode.getElement();
      CommonProblemDescriptor descriptor = elementNode.getProblem();
      if (descriptor != null) {
        invokeFix(element, descriptor, idx);
      }
    }
  }

  private void invokeFix(
      final RefEntity element, final CommonProblemDescriptor descriptor, final int idx) {
    final QuickFix[] fixes = descriptor.getFixes();
    if (fixes != null && fixes.length > idx && fixes[idx] != null) {
      if (element instanceof RefElement) {
        PsiElement psiElement = ((RefElement) element).getElement();
        if (psiElement != null && psiElement.isValid()) {
          if (!FileModificationService.getInstance().preparePsiElementForWrite(psiElement)) return;
          performFix(element, descriptor, idx, fixes[idx]);
        }
      } else {
        performFix(element, descriptor, idx, fixes[idx]);
      }
    }
  }

  private void performFix(
      final RefEntity element,
      final CommonProblemDescriptor descriptor,
      final int idx,
      final QuickFix fix) {
    final Runnable command =
        new Runnable() {
          @Override
          public void run() {
            ApplicationManager.getApplication()
                .runWriteAction(
                    new Runnable() {
                      @Override
                      public void run() {
                        final PsiModificationTracker tracker =
                            PsiManager.getInstance(myView.getProject()).getModificationTracker();
                        final long startCount = tracker.getModificationCount();
                        CommandProcessor.getInstance()
                            .markCurrentCommandAsGlobal(myView.getProject());
                        // CCE here means QuickFix was incorrectly inherited
                        fix.applyFix(myView.getProject(), descriptor);
                        if (startCount != tracker.getModificationCount()) {
                          final DescriptorProviderInspection tool =
                              ((DescriptorProviderInspection) myView.getTree().getSelectedTool());
                          if (tool != null) {
                            tool.ignoreProblem(element, descriptor, idx);
                          }
                          myView.updateView(false);
                        }
                      }
                    });
          }
        };
    CommandProcessor.getInstance()
        .executeCommand(myView.getProject(), command, fix.getName(), null);
  }
}
  public Browser(InspectionResultsView view) {
    super(new BorderLayout());
    myView = view;

    myCurrentEntity = null;
    myCurrentDescriptor = null;

    myHTMLViewer =
        new JEditorPane(
            UIUtil.HTML_MIME,
            InspectionsBundle.message("inspection.offline.view.empty.browser.text"));
    myHTMLViewer.setEditable(false);
    myHyperLinkListener =
        new HyperlinkListener() {
          @Override
          public void hyperlinkUpdate(HyperlinkEvent e) {
            if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
              JEditorPane pane = (JEditorPane) e.getSource();
              if (e instanceof HTMLFrameHyperlinkEvent) {
                HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e;
                HTMLDocument doc = (HTMLDocument) pane.getDocument();
                doc.processHTMLFrameHyperlinkEvent(evt);
              } else {
                try {
                  URL url = e.getURL();
                  @NonNls String ref = url.getRef();
                  if (ref.startsWith("pos:")) {
                    int delimeterPos = ref.indexOf(':', "pos:".length() + 1);
                    String startPosition = ref.substring("pos:".length(), delimeterPos);
                    String endPosition = ref.substring(delimeterPos + 1);
                    Integer textStartOffset = new Integer(startPosition);
                    Integer textEndOffset = new Integer(endPosition);
                    String fileURL = url.toExternalForm();
                    fileURL = fileURL.substring(0, fileURL.indexOf('#'));
                    VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
                    if (vFile != null) {
                      fireClickEvent(vFile, textStartOffset.intValue(), textEndOffset.intValue());
                    }
                  } else if (ref.startsWith("descr:")) {
                    if (myCurrentDescriptor instanceof ProblemDescriptor) {
                      PsiElement psiElement =
                          ((ProblemDescriptor) myCurrentDescriptor).getPsiElement();
                      if (psiElement == null) return;
                      VirtualFile vFile = psiElement.getContainingFile().getVirtualFile();
                      if (vFile != null) {
                        TextRange range =
                            ((ProblemDescriptorBase) myCurrentDescriptor).getTextRange();
                        fireClickEvent(vFile, range.getStartOffset(), range.getEndOffset());
                      }
                    }
                  } else if (ref.startsWith("invoke:")) {
                    int actionNumber = Integer.parseInt(ref.substring("invoke:".length()));
                    getTool()
                        .getQuickFixes(new RefElement[] {(RefElement) myCurrentEntity})[
                        actionNumber]
                        .doApplyFix(new RefElement[] {(RefElement) myCurrentEntity}, myView);
                  } else if (ref.startsWith("invokelocal:")) {
                    int actionNumber = Integer.parseInt(ref.substring("invokelocal:".length()));
                    if (actionNumber > -1) {
                      invokeLocalFix(actionNumber);
                    }
                  } else if (ref.startsWith("suppress:")) {
                    final SuppressActionWrapper.SuppressTreeAction[] suppressTreeActions =
                        new SuppressActionWrapper(
                                myView.getProject(),
                                getTool(),
                                myView.getTree().getSelectionPaths())
                            .getChildren(null);
                    final List<AnAction> activeActions = new ArrayList<AnAction>();
                    for (SuppressActionWrapper.SuppressTreeAction suppressTreeAction :
                        suppressTreeActions) {
                      if (suppressTreeAction.isAvailable()) activeActions.add(suppressTreeAction);
                    }
                    if (!activeActions.isEmpty()) {
                      int actionNumber = Integer.parseInt(ref.substring("suppress:".length()));
                      if (actionNumber > -1 && activeActions.size() > actionNumber) {
                        activeActions.get(actionNumber).actionPerformed(null);
                      }
                    }
                  } else {
                    int offset = Integer.parseInt(ref);
                    String fileURL = url.toExternalForm();
                    fileURL = fileURL.substring(0, fileURL.indexOf('#'));
                    VirtualFile vFile = VirtualFileManager.getInstance().findFileByUrl(fileURL);
                    if (vFile == null) {
                      vFile = VfsUtil.findFileByURL(url);
                    }
                    if (vFile != null) {
                      fireClickEvent(vFile, offset, offset);
                    }
                  }
                } catch (Throwable t) {
                  // ???
                }
              }
            }
          }
        };
    myHTMLViewer.addHyperlinkListener(myHyperLinkListener);

    final JScrollPane pane = ScrollPaneFactory.createScrollPane(myHTMLViewer);
    pane.setBorder(null);
    add(pane, BorderLayout.CENTER);
    setupStyle();
  }
  private void exportResults(
      @NotNull final CommonProblemDescriptor[] descriptors,
      @NotNull RefEntity refEntity,
      @NotNull Element parentNode) {
    for (CommonProblemDescriptor descriptor : descriptors) {
      @NonNls final String template = descriptor.getDescriptionTemplate();
      int line =
          descriptor instanceof ProblemDescriptor
              ? ((ProblemDescriptor) descriptor).getLineNumber()
              : -1;
      final PsiElement psiElement =
          descriptor instanceof ProblemDescriptor
              ? ((ProblemDescriptor) descriptor).getPsiElement()
              : null;
      @NonNls
      String problemText =
          StringUtil.replace(
              StringUtil.replace(
                  template,
                  "#ref",
                  psiElement != null
                      ? ProblemDescriptorUtil.extractHighlightedText(descriptor, psiElement)
                      : ""),
              " #loc ",
              " ");

      Element element = refEntity.getRefManager().export(refEntity, parentNode, line);
      if (element == null) return;
      @NonNls
      Element problemClassElement =
          new Element(InspectionsBundle.message("inspection.export.results.problem.element.tag"));
      problemClassElement.addContent(myToolWrapper.getDisplayName());

      final HighlightSeverity severity;
      if (refEntity instanceof RefElement) {
        final RefElement refElement = (RefElement) refEntity;
        severity = getSeverity(refElement);
      } else {
        final InspectionProfile profile =
            InspectionProjectProfileManager.getInstance(getContext().getProject())
                .getInspectionProfile();
        final HighlightDisplayLevel level =
            profile.getErrorLevel(
                HighlightDisplayKey.find(myToolWrapper.getShortName()), psiElement);
        severity = level.getSeverity();
      }

      if (severity != null) {
        ProblemHighlightType problemHighlightType =
            descriptor instanceof ProblemDescriptor
                ? ((ProblemDescriptor) descriptor).getHighlightType()
                : ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
        final String attributeKey =
            getTextAttributeKey(getRefManager().getProject(), severity, problemHighlightType);
        problemClassElement.setAttribute("severity", severity.myName);
        problemClassElement.setAttribute("attribute_key", attributeKey);
      }

      element.addContent(problemClassElement);
      if (myToolWrapper instanceof GlobalInspectionToolWrapper) {
        final GlobalInspectionTool globalInspectionTool =
            ((GlobalInspectionToolWrapper) myToolWrapper).getTool();
        final QuickFix[] fixes = descriptor.getFixes();
        if (fixes != null) {
          @NonNls Element hintsElement = new Element("hints");
          for (QuickFix fix : fixes) {
            final String hint = globalInspectionTool.getHint(fix);
            if (hint != null) {
              @NonNls Element hintElement = new Element("hint");
              hintElement.setAttribute("value", hint);
              hintsElement.addContent(hintElement);
            }
          }
          element.addContent(hintsElement);
        }
      }
      try {
        Element descriptionElement =
            new Element(InspectionsBundle.message("inspection.export.results.description.tag"));
        descriptionElement.addContent(problemText);
        element.addContent(descriptionElement);
      } catch (IllegalDataException e) {
        //noinspection HardCodedStringLiteral,UseOfSystemOutOrSystemErr
        System.out.println(
            "Cannot save results for "
                + refEntity.getName()
                + ", inspection which caused problem: "
                + myToolWrapper.getShortName());
      }
    }
  }
 @NotNull
 public String getDisplayName() {
   return InspectionsBundle.message("inspection.redundant.suppression.name");
 }
  public CommonProblemDescriptor[] checkElement(
      @NotNull final PsiElement psiElement, InspectionManager manager, Project project) {
    final Map<PsiElement, Collection<String>> suppressedScopes =
        new THashMap<PsiElement, Collection<String>>();
    psiElement.accept(
        new JavaRecursiveElementWalkingVisitor() {
          @Override
          public void visitModifierList(PsiModifierList list) {
            super.visitModifierList(list);
            final PsiElement parent = list.getParent();
            if (parent instanceof PsiModifierListOwner && !(parent instanceof PsiClass)) {
              checkElement(parent);
            }
          }

          @Override
          public void visitComment(PsiComment comment) {
            checkElement(comment);
          }

          @Override
          public void visitClass(PsiClass aClass) {
            if (aClass == psiElement) {
              super.visitClass(aClass);
              checkElement(aClass);
            }
          }

          private void checkElement(final PsiElement owner) {
            String idsString = SuppressManager.getInstance().getSuppressedInspectionIdsIn(owner);
            if (idsString != null && idsString.length() != 0) {
              List<String> ids = StringUtil.split(idsString, ",");
              if (IGNORE_ALL
                  && (ids.contains(SuppressionUtil.ALL)
                      || ids.contains(SuppressionUtil.ALL.toLowerCase()))) return;
              Collection<String> suppressed = suppressedScopes.get(owner);
              if (suppressed == null) {
                suppressed = ids;
              } else {
                for (String id : ids) {
                  if (!suppressed.contains(id)) {
                    suppressed.add(id);
                  }
                }
              }
              suppressedScopes.put(owner, suppressed);
            }
          }
        });

    if (suppressedScopes.values().isEmpty()) return null;
    // have to visit all file from scratch since inspections can be written in any perversive way
    // including checkFile() overriding
    Collection<InspectionTool> suppressedTools = new THashSet<InspectionTool>();
    InspectionTool[] tools = getInspectionTools(psiElement, manager);
    for (Collection<String> ids : suppressedScopes.values()) {
      for (Iterator<String> iterator = ids.iterator(); iterator.hasNext(); ) {
        final String shortName = iterator.next().trim();
        for (InspectionTool tool : tools) {
          if (tool instanceof LocalInspectionToolWrapper
              && ((LocalInspectionToolWrapper) tool).getTool().getID().equals(shortName)) {
            if (!((LocalInspectionToolWrapper) tool).isUnfair()) {
              suppressedTools.add(tool);
            } else {
              iterator.remove();
              break;
            }
          } else if (tool.getShortName().equals(shortName)) {
            // ignore global unused as it won't be checked anyway
            if (!(tool instanceof LocalInspectionToolWrapper)
                && !(tool instanceof GlobalInspectionToolWrapper)) {
              iterator.remove();
              break;
            } else {
              suppressedTools.add(tool);
            }
          }
        }
      }
    }

    final AnalysisScope scope = new AnalysisScope(psiElement.getContainingFile());
    final InspectionManagerEx inspectionManagerEx =
        ((InspectionManagerEx) InspectionManager.getInstance(project));
    GlobalInspectionContextImpl globalContext = inspectionManagerEx.createNewGlobalContext(false);
    globalContext.setCurrentScope(scope);
    final RefManagerImpl refManager = ((RefManagerImpl) globalContext.getRefManager());
    refManager.inspectionReadActionStarted();
    final List<ProblemDescriptor> result;
    try {
      result = new ArrayList<ProblemDescriptor>();
      for (InspectionTool tool : suppressedTools) {
        String toolId =
            tool instanceof LocalInspectionToolWrapper
                ? ((LocalInspectionToolWrapper) tool).getTool().getID()
                : tool.getShortName();
        tool.initialize(globalContext);
        Collection<CommonProblemDescriptor> descriptors;
        if (tool instanceof LocalInspectionToolWrapper) {
          LocalInspectionToolWrapper local = (LocalInspectionToolWrapper) tool;
          if (local.isUnfair()) continue; // cant't work with passes other than LocalInspectionPass
          local.processFile(psiElement.getContainingFile(), false, manager);
          descriptors = local.getProblemDescriptors();
        } else if (tool instanceof GlobalInspectionToolWrapper) {
          GlobalInspectionToolWrapper global = (GlobalInspectionToolWrapper) tool;
          if (global.getTool().isGraphNeeded()) {
            refManager.findAllDeclarations();
          }
          global.processFile(scope, manager, globalContext, false);
          descriptors = global.getProblemDescriptors();
        } else {
          continue;
        }
        for (PsiElement suppressedScope : suppressedScopes.keySet()) {
          Collection<String> suppressedIds = suppressedScopes.get(suppressedScope);
          if (!suppressedIds.contains(toolId)) continue;
          for (CommonProblemDescriptor descriptor : descriptors) {
            if (!(descriptor instanceof ProblemDescriptor)) continue;
            PsiElement element = ((ProblemDescriptor) descriptor).getPsiElement();
            if (element == null) continue;
            PsiElement annotation =
                SuppressManager.getInstance().getElementToolSuppressedIn(element, toolId);
            if (annotation != null && PsiTreeUtil.isAncestor(suppressedScope, annotation, false)
                || annotation == null && !PsiTreeUtil.isAncestor(suppressedScope, element, false)) {
              suppressedIds.remove(toolId);
              break;
            }
          }
        }
      }
      for (PsiElement suppressedScope : suppressedScopes.keySet()) {
        Collection<String> suppressedIds = suppressedScopes.get(suppressedScope);
        for (String toolId : suppressedIds) {
          PsiMember psiMember;
          String problemLine = null;
          if (suppressedScope instanceof PsiMember) {
            psiMember = (PsiMember) suppressedScope;
          } else {
            psiMember = PsiTreeUtil.getParentOfType(suppressedScope, PsiDocCommentOwner.class);
            final PsiStatement statement =
                PsiTreeUtil.getNextSiblingOfType(suppressedScope, PsiStatement.class);
            problemLine = statement != null ? statement.getText() : null;
          }
          if (psiMember != null && psiMember.isValid()) {
            String description =
                InspectionsBundle.message("inspection.redundant.suppression.description");
            if (myQuickFixes == null) myQuickFixes = new BidirectionalMap<String, QuickFix>();
            final String key = toolId + (problemLine != null ? ";" + problemLine : "");
            QuickFix fix = myQuickFixes.get(key);
            if (fix == null) {
              fix = new RemoveSuppressWarningAction(toolId, problemLine);
              myQuickFixes.put(key, fix);
            }
            PsiElement identifier = null;
            if (psiMember instanceof PsiMethod) {
              identifier = ((PsiMethod) psiMember).getNameIdentifier();
            } else if (psiMember instanceof PsiField) {
              identifier = ((PsiField) psiMember).getNameIdentifier();
            } else if (psiMember instanceof PsiClass) {
              identifier = ((PsiClass) psiMember).getNameIdentifier();
            }
            if (identifier == null) {
              identifier = psiMember;
            }
            result.add(
                manager.createProblemDescriptor(
                    identifier,
                    description,
                    (LocalQuickFix) fix,
                    ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
                    false));
          }
        }
      }
    } finally {
      refManager.inspectionReadActionFinished();
      globalContext.close(true);
    }
    return result.toArray(new ProblemDescriptor[result.size()]);
  }