@Override
 public void ignoreProblem(RefEntity refEntity, CommonProblemDescriptor problem, int idx) {
   if (refEntity == null) return;
   final Set<QuickFix> localQuickFixes = getQuickFixActions().get(refEntity);
   final QuickFix[] fixes = problem.getFixes();
   if (isIgnoreProblem(fixes, localQuickFixes, idx)) {
     getProblemToElements().remove(problem);
     Map<RefEntity, CommonProblemDescriptor[]> problemElements = getProblemElements();
     synchronized (lock) {
       CommonProblemDescriptor[] descriptors = problemElements.get(refEntity);
       if (descriptors != null) {
         ArrayList<CommonProblemDescriptor> newDescriptors =
             new ArrayList<CommonProblemDescriptor>(Arrays.asList(descriptors));
         newDescriptors.remove(problem);
         getQuickFixActions().put(refEntity, null);
         if (!newDescriptors.isEmpty()) {
           problemElements.put(
               refEntity,
               newDescriptors.toArray(new CommonProblemDescriptor[newDescriptors.size()]));
           for (CommonProblemDescriptor descriptor : newDescriptors) {
             collectQuickFixes(descriptor.getFixes(), refEntity);
           }
         } else {
           ignoreProblemElement(refEntity);
         }
       }
     }
   }
 }
  @Override
  @SuppressWarnings({"HardCodedStringLiteral"})
  public void loadState(Element element) {
    Element entryPointsElement = element.getChild("entry_points");
    if (entryPointsElement != null) {
      final String version = entryPointsElement.getAttributeValue(VERSION_ATTR);
      if (!Comparing.strEqual(version, VERSION)) {
        convert(entryPointsElement, myPersistentEntryPoints);
      } else {
        List content = entryPointsElement.getChildren();
        for (final Object aContent : content) {
          Element entryElement = (Element) aContent;
          if (ENTRY_POINT_ATTR.equals(entryElement.getName())) {
            SmartRefElementPointerImpl entryPoint = new SmartRefElementPointerImpl(entryElement);
            myPersistentEntryPoints.put(entryPoint.getFQName(), entryPoint);
          }
        }
      }
    }
    try {
      ADDITIONAL_ANNOTATIONS.readExternal(element);
    } catch (Throwable ignored) {
    }

    getPatterns().clear();
    for (Element pattern : element.getChildren("pattern")) {
      final ClassPattern classPattern = new ClassPattern();
      XmlSerializer.deserializeInto(classPattern, pattern);
      getPatterns().add(classPattern);
    }
  }
  @Override
  public void addEntryPoint(@NotNull RefElement newEntryPoint, boolean isPersistent) {
    if (!newEntryPoint.isValid()) return;
    if (isPersistent) {
      if (newEntryPoint instanceof RefMethod && ((RefMethod) newEntryPoint).isConstructor()
          || newEntryPoint instanceof RefClass) {
        final ClassPattern classPattern = new ClassPattern();
        classPattern.pattern = new SmartRefElementPointerImpl(newEntryPoint, true).getFQName();
        getPatterns().add(classPattern);

        final EntryPointsManager entryPointsManager =
            getInstance(newEntryPoint.getElement().getProject());
        if (this != entryPointsManager) {
          entryPointsManager.addEntryPoint(newEntryPoint, true);
        }

        return;
      }
    }

    if (newEntryPoint instanceof RefClass) {
      RefClass refClass = (RefClass) newEntryPoint;

      if (refClass.isAnonymous()) {
        // Anonymous class cannot be an entry point.
        return;
      }

      List<RefMethod> refConstructors = refClass.getConstructors();
      if (refConstructors.size() == 1) {
        addEntryPoint(refConstructors.get(0), isPersistent);
      } else if (refConstructors.size() > 1) {
        // Many constructors here. Need to ask user which ones are used
        for (RefMethod refConstructor : refConstructors) {
          addEntryPoint(refConstructor, isPersistent);
        }
      }
    }

    if (!isPersistent) {
      myTemporaryEntryPoints.add(newEntryPoint);
      ((RefElementImpl) newEntryPoint).setEntry(true);
    } else {
      if (myPersistentEntryPoints.get(newEntryPoint.getExternalName()) == null) {
        final SmartRefElementPointerImpl entry =
            new SmartRefElementPointerImpl(newEntryPoint, true);
        myPersistentEntryPoints.put(entry.getFQName(), entry);
        ((RefElementImpl) newEntryPoint).setEntry(true);
        ((RefElementImpl) newEntryPoint).setPermanentEntry(true);
        if (entry.isPersistent()) { // do save entry points
          final EntryPointsManager entryPointsManager =
              getInstance(newEntryPoint.getElement().getProject());
          if (this != entryPointsManager) {
            entryPointsManager.addEntryPoint(newEntryPoint, true);
          }
        }
      }
    }
  }
  public static void convert(
      Element element, final Map<String, SmartRefElementPointer> persistentEntryPoints) {
    List content = element.getChildren();
    for (final Object aContent : content) {
      Element entryElement = (Element) aContent;
      if (ENTRY_POINT_ATTR.equals(entryElement.getName())) {
        String fqName = entryElement.getAttributeValue(SmartRefElementPointerImpl.FQNAME_ATTR);
        final String type = entryElement.getAttributeValue(SmartRefElementPointerImpl.TYPE_ATTR);
        if (Comparing.strEqual(type, RefJavaManager.METHOD)) {

          int spaceIdx = fqName.indexOf(' ');
          int lastDotIdx = fqName.lastIndexOf('.');

          int parenIndex = fqName.indexOf('(');

          while (lastDotIdx > parenIndex) lastDotIdx = fqName.lastIndexOf('.', lastDotIdx - 1);

          boolean notype = false;
          if (spaceIdx < 0 || spaceIdx + 1 > lastDotIdx || spaceIdx > parenIndex) {
            notype = true;
          }

          final String className = fqName.substring(notype ? 0 : spaceIdx + 1, lastDotIdx);
          final String methodSignature =
              notype
                  ? fqName.substring(lastDotIdx + 1)
                  : fqName.substring(0, spaceIdx) + ' ' + fqName.substring(lastDotIdx + 1);

          fqName = className + " " + methodSignature;
        } else if (Comparing.strEqual(type, RefJavaManager.FIELD)) {
          final int lastDotIdx = fqName.lastIndexOf('.');
          if (lastDotIdx > 0 && lastDotIdx < fqName.length() - 2) {
            String className = fqName.substring(0, lastDotIdx);
            String fieldName = fqName.substring(lastDotIdx + 1);
            fqName = className + " " + fieldName;
          } else {
            continue;
          }
        }
        SmartRefElementPointerImpl entryPoint = new SmartRefElementPointerImpl(type, fqName);
        persistentEntryPoints.put(entryPoint.getFQName(), entryPoint);
      }
    }
  }
 @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()]);
 }
 @SuppressWarnings({"HardCodedStringLiteral"})
 public void loadState(Element element) {
   Element entryPointsElement = element.getChild("entry_points");
   if (entryPointsElement != null) {
     final String version = entryPointsElement.getAttributeValue(VERSION_ATTR);
     if (!Comparing.strEqual(version, VERSION)) {
       convert(entryPointsElement, myPersistentEntryPoints);
     } else {
       List content = entryPointsElement.getChildren();
       for (final Object aContent : content) {
         Element entryElement = (Element) aContent;
         if (ENTRY_POINT_ATTR.equals(entryElement.getName())) {
           SmartRefElementPointerImpl entryPoint = new SmartRefElementPointerImpl(entryElement);
           myPersistentEntryPoints.put(entryPoint.getFQName(), entryPoint);
         }
       }
     }
   }
   try {
     ADDITIONAL_ANNOTATIONS.readExternal(element);
   } catch (InvalidDataException ignored) {
   }
 }
  @Override
  public void addProblemElement(
      final RefEntity refElement,
      boolean filterSuppressed,
      @NotNull final CommonProblemDescriptor... descriptors) {
    if (refElement == null) return;
    if (descriptors.length == 0) return;
    if (filterSuppressed) {
      if (!isOutputPathSet() || !(myToolWrapper instanceof LocalInspectionToolWrapper)) {
        synchronized (lock) {
          Map<RefEntity, CommonProblemDescriptor[]> problemElements = getProblemElements();
          CommonProblemDescriptor[] problems = problemElements.get(refElement);
          problems = problems == null ? descriptors : mergeDescriptors(problems, descriptors);
          problemElements.put(refElement, problems);
        }
        for (CommonProblemDescriptor description : descriptors) {
          getProblemToElements().put(description, refElement);
          collectQuickFixes(description.getFixes(), refElement);
        }
      } else {
        writeOutput(descriptors, refElement);
      }
    } else { // just need to collect problems
      for (CommonProblemDescriptor descriptor : descriptors) {
        getProblemToElements().put(descriptor, refElement);
      }
    }

    final GlobalInspectionContextImpl context = getContext();
    if (myToolWrapper instanceof LocalInspectionToolWrapper) {
      final InspectionResultsView view = context.getView();
      if (view == null || !(refElement instanceof RefElement)) {
        return;
      }
      UIUtil.invokeLaterIfNeeded(
          new Runnable() {
            @Override
            public void run() {
              if (!isDisposed()) {
                final InspectionNode toolNode;
                synchronized (myToolLock) {
                  if (myToolNode == null) {
                    final HighlightSeverity currentSeverity = getSeverity((RefElement) refElement);
                    toolNode =
                        view.addTool(
                            myToolWrapper,
                            HighlightDisplayLevel.find(currentSeverity),
                            context.getUIOptions().GROUP_BY_SEVERITY);
                  } else {
                    toolNode = myToolNode;
                    if (toolNode.isTooBigForOnlineRefresh()) {
                      return;
                    }
                  }
                }
                final Map<RefEntity, CommonProblemDescriptor[]> problems =
                    new HashMap<RefEntity, CommonProblemDescriptor[]>();
                problems.put(refElement, descriptors);
                final Map<String, Set<RefEntity>> contents = new HashMap<String, Set<RefEntity>>();
                final String groupName =
                    refElement.getRefManager().getGroupName((RefElement) refElement);
                Set<RefEntity> content = contents.get(groupName);
                if (content == null) {
                  content = new HashSet<RefEntity>();
                  contents.put(groupName, content);
                }
                content.add(refElement);

                view.getProvider()
                    .appendToolNodeContent(
                        context,
                        toolNode,
                        (InspectionTreeNode) toolNode.getParent(),
                        context.getUIOptions().SHOW_STRUCTURE,
                        contents,
                        problems,
                        (DefaultTreeModel) view.getTree().getModel());
                context.addView(view);
              }
            }
          });
    }
  }