@Override
 public Map<String, Set<RefEntity>> getOldContent() {
   if (myOldProblemElements == null) return null;
   final Map<String, Set<RefEntity>> oldContents =
       new com.intellij.util.containers.HashMap<String, Set<RefEntity>>();
   final Set<RefEntity> elements = myOldProblemElements.keySet();
   for (RefEntity element : elements) {
     String groupName =
         element instanceof RefElement
             ? element.getRefManager().getGroupName((RefElement) element)
             : element.getName();
     final Set<RefEntity> collection = myContents.get(groupName);
     if (collection != null) {
       final Set<RefEntity> currentElements = new HashSet<RefEntity>(collection);
       if (RefUtil.contains(element, currentElements)) continue;
     }
     Set<RefEntity> oldContent = oldContents.get(groupName);
     if (oldContent == null) {
       oldContent = new HashSet<RefEntity>();
       oldContents.put(groupName, oldContent);
     }
     oldContent.add(element);
   }
   return oldContents;
 }
  public void removeEntryPoint(RefElement anEntryPoint) {
    if (anEntryPoint instanceof RefClass) {
      RefClass refClass = (RefClass) anEntryPoint;
      if (!refClass.isInterface()) {
        anEntryPoint = refClass.getDefaultConstructor();
      }
    }

    if (anEntryPoint == null) return;

    myTemporaryEntryPoints.remove(anEntryPoint);

    Set<Map.Entry<String, SmartRefElementPointer>> set = myPersistentEntryPoints.entrySet();
    String key = null;
    for (Map.Entry<String, SmartRefElementPointer> entry : set) {
      SmartRefElementPointer value = entry.getValue();
      if (value.getRefElement() == anEntryPoint) {
        key = entry.getKey();
        break;
      }
    }

    if (key != null) {
      myPersistentEntryPoints.remove(key);
      ((RefElementImpl) anEntryPoint).setEntry(false);
    }

    if (anEntryPoint.isPermanentEntry() && anEntryPoint.isValid()) {
      final Project project = anEntryPoint.getElement().getProject();
      final EntryPointsManagerImpl entryPointsManager = getInstance(project);
      if (this != entryPointsManager) {
        entryPointsManager.removeEntryPoint(anEntryPoint);
      }
    }
  }
  private void purgeTemporaryEntryPoints() {
    for (RefElement entryPoint : myTemporaryEntryPoints) {
      ((RefElementImpl) entryPoint).setEntry(false);
    }

    myTemporaryEntryPoints.clear();
  }
  private static boolean isAcceptedByPattern(
      @NotNull PsiClass element,
      String qualifiedName,
      ClassPattern pattern,
      Set<PsiClass> visited) {
    if (qualifiedName == null) {
      return false;
    }

    if (qualifiedName.equals(pattern.pattern)) {
      return true;
    }

    if (pattern.pattern.endsWith(PATTERN_SUFFIX)
        && qualifiedName.startsWith(StringUtil.trimEnd(pattern.pattern, PATTERN_SUFFIX))) {
      return true;
    }

    if (pattern.hierarchically) {
      for (PsiClass superClass : element.getSupers()) {
        final String superClassQualifiedName = superClass.getQualifiedName();
        if (visited.add(superClass)
            && isAcceptedByPattern(superClass, superClassQualifiedName, pattern, visited)) {
          return true;
        }
      }
    }
    return false;
  }
  @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);
          }
        }
      }
    }
  }
 private static boolean isIgnoreProblem(QuickFix[] problemFixes, Set<QuickFix> fixes, int idx) {
   if (problemFixes == null || fixes == null) {
     return true;
   }
   if (problemFixes.length <= idx) {
     return true;
   }
   for (QuickFix fix : problemFixes) {
     if (fix != problemFixes[idx] && !fixes.contains(fix)) {
       return false;
     }
   }
   return true;
 }
 @Override
 public void updateContent() {
   myContents.clear();
   myModulesProblems.clear();
   final Set<RefEntity> elements = getProblemElements().keySet();
   for (RefEntity element : elements) {
     if (getContext().getUIOptions().FILTER_RESOLVED_ITEMS
         && getIgnoredElements().containsKey(element)) continue;
     if (element instanceof RefModule) {
       myModulesProblems.add((RefModule) element);
     } else {
       String groupName =
           element instanceof RefElement
               ? element.getRefManager().getGroupName((RefElement) element)
               : null;
       Set<RefEntity> content = myContents.get(groupName);
       if (content == null) {
         content = new HashSet<RefEntity>();
         myContents.put(groupName, content);
       }
       content.add(element);
     }
   }
 }
  @Override
  public void cleanup() {
    myOldProblemElements = null;

    synchronized (lock) {
      myProblemElements.clear();
      myProblemToElements.clear();
      myQuickFixActions.clear();
      myIgnoredElements.clear();
      myContents.clear();
      myModulesProblems.clear();
    }

    isDisposed = true;
  }
  @Override
  public void removeEntryPoint(@NotNull RefElement anEntryPoint) {
    myTemporaryEntryPoints.remove(anEntryPoint);

    Set<Map.Entry<String, SmartRefElementPointer>> set = myPersistentEntryPoints.entrySet();
    String key = null;
    for (Map.Entry<String, SmartRefElementPointer> entry : set) {
      SmartRefElementPointer value = entry.getValue();
      if (value.getRefElement() == anEntryPoint) {
        key = entry.getKey();
        break;
      }
    }

    if (key != null) {
      myPersistentEntryPoints.remove(key);
    }
    ((RefElementImpl) anEntryPoint).setEntry(false);

    if (anEntryPoint.isPermanentEntry() && anEntryPoint.isValid()) {
      final Project project = anEntryPoint.getElement().getProject();
      final EntryPointsManager entryPointsManager = getInstance(project);
      if (this != entryPointsManager) {
        entryPointsManager.removeEntryPoint(anEntryPoint);
      }
    }

    if (anEntryPoint instanceof RefMethod && ((RefMethod) anEntryPoint).isConstructor()
        || anEntryPoint instanceof RefClass) {
      final RefClass aClass =
          anEntryPoint instanceof RefClass
              ? (RefClass) anEntryPoint
              : ((RefMethod) anEntryPoint).getOwnerClass();
      final String qualifiedName = aClass.getQualifiedName();
      for (Iterator<ClassPattern> iterator = getPatterns().iterator(); iterator.hasNext(); ) {
        if (Comparing.equal(iterator.next().pattern, qualifiedName)) {
          // todo if inheritance or pattern?
          iterator.remove();
        }
      }
    }
  }
  private void validateEntryPoints() {
    long count = PsiManager.getInstance(myProject).getModificationTracker().getModificationCount();
    if (count != myLastModificationCount) {
      myLastModificationCount = count;
      Collection<SmartRefElementPointer> collection = myPersistentEntryPoints.values();
      SmartRefElementPointer[] entries =
          collection.toArray(new SmartRefElementPointer[collection.size()]);
      for (SmartRefElementPointer entry : entries) {
        RefElement refElement = (RefElement) entry.getRefElement();
        if (refElement != null && !refElement.isValid()) {
          myPersistentEntryPoints.remove(entry.getFQName());
        }
      }

      final Iterator<RefElement> it = myTemporaryEntryPoints.iterator();
      while (it.hasNext()) {
        RefElement refElement = it.next();
        if (!refElement.isValid()) {
          it.remove();
        }
      }
    }
  }