public synchronized void createNewList(
     @NotNull String name, boolean readOnly, boolean allowsTree) {
   myName2FavoritesRoots.put(name, new ArrayList<TreeItem<Pair<AbstractUrl, String>>>());
   if (readOnly) {
     myReadOnlyLists.add(name);
   }
   if (allowsTree) {
     myAllowsTreeLists.add(name);
   }
   fireListeners.listAdded(name);
 }
 @Override
 public void visitReferenceExpression(final PsiReferenceExpression reference) {
   if (myLineRange.intersects(reference.getTextRange())) {
     final PsiElement psiElement = reference.resolve();
     if (psiElement instanceof PsiVariable) {
       final PsiVariable var = (PsiVariable) psiElement;
       if (var instanceof PsiField) {
         if (myCollectExpressions
             && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(
                 reference, myVisibleLocals)) {
           /*
           if (var instanceof PsiEnumConstant && reference.getQualifier() == null) {
             final PsiClass enumClass = ((PsiEnumConstant)var).getContainingClass();
             if (enumClass != null) {
               final PsiExpression expression = JavaPsiFacade.getInstance(var.getProject()).getParserFacade().createExpressionFromText(enumClass.getName() + "." + var.getName(), var);
               final PsiReference ref = expression.getReference();
               if (ref != null) {
                 ref.bindToElement(var);
                 myExpressions.add(new TextWithImportsImpl(expression));
               }
             }
           }
           else {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
           */
           final PsiModifierList modifierList = var.getModifierList();
           boolean isConstant =
               (var instanceof PsiEnumConstant)
                   || (modifierList != null
                       && modifierList.hasModifierProperty(PsiModifier.STATIC)
                       && modifierList.hasModifierProperty(PsiModifier.FINAL));
           if (!isConstant) {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
         }
       } else {
         if (myVisibleLocals.contains(var.getName())) {
           myVars.add(var.getName());
         } else {
           // fix for variables used in inner classes
           if (!Comparing.equal(
               PsiTreeUtil.getParentOfType(reference, PsiClass.class),
               PsiTreeUtil.getParentOfType(var, PsiClass.class))) {
             myExpressions.add(new TextWithImportsImpl(reference));
           }
         }
       }
     }
   }
   super.visitReferenceExpression(reference);
 }
 public static boolean filterEquals(ClassFilter[] filters1, ClassFilter[] filters2) {
   if (filters1.length != filters2.length) {
     return false;
   }
   final Set<ClassFilter> f1 =
       new HashSet<ClassFilter>(Math.max((int) (filters1.length / .75f) + 1, 16));
   final Set<ClassFilter> f2 =
       new HashSet<ClassFilter>(Math.max((int) (filters2.length / .75f) + 1, 16));
   for (ClassFilter filter : filters1) {
     f1.add(filter);
   }
   for (ClassFilter aFilters2 : filters2) {
     f2.add(aFilters2);
   }
   return f2.equals(f1);
 }
 public void bePatternConfiguration(List<PsiClass> classes, PsiMethod method) {
   myData.TEST_OBJECT = TEST_PATTERN;
   final Set<String> patterns = new HashSet<String>();
   final String methodSufiix;
   if (method != null) {
     myData.METHOD_NAME = method.getName();
     methodSufiix = "," + myData.METHOD_NAME;
   } else {
     methodSufiix = "";
   }
   for (PsiClass pattern : classes) {
     patterns.add(JavaExecutionUtil.getRuntimeQualifiedName(pattern) + methodSufiix);
   }
   myData.setPatterns(patterns);
   final Module module =
       PatternConfigurationProducer.findModule(
           this, getConfigurationModule().getModule(), patterns);
   if (module == null) {
     myData.setScope(TestSearchScope.WHOLE_PROJECT);
     setModule(null);
   } else {
     setModule(module);
   }
   setGeneratedName();
 }
  private static boolean checkDependants(
      final IdeaPluginDescriptor pluginDescriptor,
      final Function<PluginId, IdeaPluginDescriptor> pluginId2Descriptor,
      final Condition<PluginId> check,
      final Set<PluginId> processed) {
    processed.add(pluginDescriptor.getPluginId());
    final PluginId[] dependentPluginIds = pluginDescriptor.getDependentPluginIds();
    final Set<PluginId> optionalDependencies =
        new HashSet<PluginId>(Arrays.asList(pluginDescriptor.getOptionalDependentPluginIds()));
    for (final PluginId dependentPluginId : dependentPluginIds) {
      if (processed.contains(dependentPluginId)) continue;

      // TODO[yole] should this condition be a parameter?
      if (isModuleDependency(dependentPluginId)
          && (ourAvailableModules.isEmpty()
              || ourAvailableModules.contains(dependentPluginId.getIdString()))) {
        continue;
      }
      if (!optionalDependencies.contains(dependentPluginId)) {
        if (!check.value(dependentPluginId)) {
          return false;
        }
        final IdeaPluginDescriptor dependantPluginDescriptor =
            pluginId2Descriptor.fun(dependentPluginId);
        if (dependantPluginDescriptor != null
            && !checkDependants(dependantPluginDescriptor, pluginId2Descriptor, check, processed)) {
          return false;
        }
      }
    }
    return true;
  }
  @NotNull
  private VirtualFilePointerContainer registerContainer(
      @NotNull Disposable parent,
      @NotNull final VirtualFilePointerContainerImpl virtualFilePointerContainer) {
    synchronized (myContainers) {
      myContainers.add(virtualFilePointerContainer);
    }
    Disposer.register(
        parent,
        new Disposable() {
          @Override
          public void dispose() {
            Disposer.dispose(virtualFilePointerContainer);
            boolean removed;
            synchronized (myContainers) {
              removed = myContainers.remove(virtualFilePointerContainer);
            }
            if (!ApplicationManager.getApplication().isUnitTestMode()) {
              assert removed;
            }
          }

          @Override
          @NonNls
          @NotNull
          public String toString() {
            return "Disposing container " + virtualFilePointerContainer;
          }
        });
    return virtualFilePointerContainer;
  }
 @Override
 public void visitArrayAccessExpression(final PsiArrayAccessExpression expression) {
   if (myCollectExpressions
       && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(expression, myVisibleLocals)) {
     myExpressions.add(new TextWithImportsImpl(expression));
   }
   super.visitArrayAccessExpression(expression);
 }
 @Override
 public void openTestProject(@NotNull final Project project) {
   synchronized (myOpenProjects) {
     assert ApplicationManager.getApplication().isUnitTestMode();
     assert !project.isDisposed() : "Must not open already disposed project";
     myTestProjects.add(project);
   }
 }
Example #9
0
  @SuppressWarnings({"HardCodedStringLiteral"})
  public static boolean isCharOrIntegerArray(Value value) {
    if (value == null) return false;
    if (myCharOrIntegers == null) {
      myCharOrIntegers = new HashSet<String>();
      myCharOrIntegers.add("C");
      myCharOrIntegers.add("B");
      myCharOrIntegers.add("S");
      myCharOrIntegers.add("I");
      myCharOrIntegers.add("J");
    }

    String signature = value.type().signature();
    int i;
    for (i = 0; signature.charAt(i) == '['; i++) ;
    if (i == 0) return false;
    signature = signature.substring(i, signature.length());
    return myCharOrIntegers.contains(signature);
  }
 @Override
 @NotNull
 public String[] getUrls(@NotNull OrderRootType rootType) {
   Set<String> originalUrls =
       new LinkedHashSet<String>(Arrays.asList(LibraryImpl.this.getUrls(rootType)));
   for (VirtualFile file : getFiles(rootType)) { // Add those expanded with jar directories.
     originalUrls.add(file.getUrl());
   }
   return ArrayUtil.toStringArray(originalUrls);
 }
  private static Set<PsiElement> getAllParents(PsiElement element) {
    Set<PsiElement> parents = new java.util.HashSet<PsiElement>();

    while (element != null) {
      parents.add(element);
      if (element instanceof PsiFile) break;
      element = element.getParent();
    }
    return parents;
  }
 public static Set<String> getAllLookupStrings(@NotNull PsiMember member) {
   Set<String> allLookupStrings = ContainerUtil.newLinkedHashSet();
   String name = member.getName();
   allLookupStrings.add(name);
   PsiClass containingClass = member.getContainingClass();
   while (containingClass != null) {
     final String className = containingClass.getName();
     if (className == null) {
       break;
     }
     name = className + "." + name;
     allLookupStrings.add(name);
     final PsiElement parent = containingClass.getParent();
     if (!(parent instanceof PsiClass)) {
       break;
     }
     containingClass = (PsiClass) parent;
   }
   return allLookupStrings;
 }
 @Override
 public void visitMethodCallExpression(final PsiMethodCallExpression expression) {
   if (myCollectExpressions) {
     final PsiMethod psiMethod = expression.resolveMethod();
     if (psiMethod != null
         && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(expression, myVisibleLocals)) {
       myExpressions.add(new TextWithImportsImpl(expression));
     }
   }
   super.visitMethodCallExpression(expression);
 }
 private void updateFileIconLater(VirtualFile file) {
   myFilesToUpdateIconsFor.add(file);
   myIconUpdaterAlarm.cancelAllRequests();
   myIconUpdaterAlarm.addRequest(
       () -> {
         if (myManager.getProject().isDisposed()) return;
         for (VirtualFile file1 : myFilesToUpdateIconsFor) {
           updateFileIconImmediately(file1);
         }
         myFilesToUpdateIconsFor.clear();
       },
       200,
       ModalityState.stateForComponent(this));
 }
 @Nullable
 public static Set<PsiType> getExpectedTypes(final CompletionParameters parameters) {
   final PsiExpression expr =
       PsiTreeUtil.getContextOfType(parameters.getPosition(), PsiExpression.class, true);
   if (expr != null) {
     final Set<PsiType> set = new THashSet<PsiType>();
     for (final ExpectedTypeInfo expectedInfo :
         JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
       set.add(expectedInfo.getType());
     }
     return set;
   }
   return null;
 }
 @NotNull
 public VirtualFile[] getOpenFiles() {
   final Set<VirtualFile> files = new ArrayListSet<VirtualFile>();
   for (final EditorWindow myWindow : myWindows) {
     final EditorWithProviderComposite[] editors = myWindow.getEditors();
     for (final EditorWithProviderComposite editor : editors) {
       VirtualFile file = editor.getFile();
       // background thread may call this method when invalid file is being removed
       // do not return it here as it will quietly drop out soon
       if (file.isValid()) {
         files.add(file);
       }
     }
   }
   return VfsUtilCore.toVirtualFileArray(files);
 }
 @NotNull
 public FileEditor[] getSelectedEditors() {
   List<FileEditor> editors = new ArrayList<FileEditor>();
   Set<EditorWindow> windows = new THashSet<EditorWindow>(myWindows);
   final EditorWindow currentWindow = getCurrentWindow();
   if (currentWindow != null) {
     windows.add(currentWindow);
   }
   for (final EditorWindow window : windows) {
     final EditorWithProviderComposite composite = window.getSelectedEditor();
     if (composite != null) {
       editors.add(composite.getSelectedEditor());
     }
   }
   return editors.toArray(new FileEditor[editors.size()]);
 }
  private static void registerExtensionPointsAndExtensions(
      ExtensionsArea area, List<IdeaPluginDescriptorImpl> loadedPlugins) {
    for (IdeaPluginDescriptorImpl descriptor : loadedPlugins) {
      descriptor.registerExtensionPoints(area);
    }

    Set<String> epNames = ContainerUtil.newHashSet();
    for (ExtensionPoint point : area.getExtensionPoints()) {
      epNames.add(point.getName());
    }

    for (IdeaPluginDescriptorImpl descriptor : loadedPlugins) {
      for (String epName : epNames) {
        descriptor.registerExtensions(area, epName);
      }
    }
  }
 private static Set<TextWithImports> computeExtraVars(
     Pair<Set<String>, Set<TextWithImports>> usedVars,
     SourcePosition sourcePosition,
     EvaluationContextImpl evalContext) {
   Set<String> alreadyCollected = new HashSet<String>(usedVars.first);
   for (TextWithImports text : usedVars.second) {
     alreadyCollected.add(text.getText());
   }
   Set<TextWithImports> extra = new HashSet<TextWithImports>();
   for (FrameExtraVariablesProvider provider :
       FrameExtraVariablesProvider.EP_NAME.getExtensions()) {
     if (provider.isAvailable(sourcePosition, evalContext)) {
       extra.addAll(provider.collectVariables(sourcePosition, evalContext, alreadyCollected));
     }
   }
   return extra;
 }
 @NotNull
 private static GroovyResolveResult[] collapseReflectedMethods(GroovyResolveResult[] candidates) {
   Set<GrMethod> visited = ContainerUtil.newHashSet();
   List<GroovyResolveResult> collapsed = ContainerUtil.newArrayList();
   for (GroovyResolveResult result : candidates) {
     PsiElement element = result.getElement();
     if (element instanceof GrReflectedMethod) {
       GrMethod baseMethod = ((GrReflectedMethod) element).getBaseMethod();
       if (visited.add(baseMethod)) {
         collapsed.add(
             PsiImplUtil.reflectedToBase(result, baseMethod, (GrReflectedMethod) element));
       }
     } else {
       collapsed.add(result);
     }
   }
   return collapsed.toArray(new GroovyResolveResult[collapsed.size()]);
 }
  public void addEntryPoint(RefElement newEntryPoint, boolean isPersistent) {
    if (!newEntryPoint.isValid()) return;
    if (newEntryPoint instanceof RefClass) {
      RefClass refClass = (RefClass) newEntryPoint;

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

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

        return;
      }
    }

    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 EntryPointsManagerImpl entryPointsManager =
              getInstance(newEntryPoint.getElement().getProject());
          if (this != entryPointsManager) {
            entryPointsManager.addEntryPoint(newEntryPoint, true);
          }
        }
      }
    }
  }
  private void putName(
      String sourceFileName, int classQName, String relativePathToSource, String pathToClass) {
    if (LOG.isDebugEnabled()) {
      LOG.debug(
          "Registering [sourceFileName, relativePathToSource, pathToClass] = ["
              + sourceFileName
              + "; "
              + relativePathToSource
              + "; "
              + pathToClass
              + "]");
    }
    Set<CompiledClass> paths = myFileNameToSourceMap.get(sourceFileName);

    if (paths == null) {
      paths = new HashSet<CompiledClass>();
      myFileNameToSourceMap.put(sourceFileName, paths);
    }
    paths.add(new CompiledClass(classQName, relativePathToSource, pathToClass));
  }
 @NotNull
 public VirtualFile[] getSelectedFiles() {
   final Set<VirtualFile> files = new ArrayListSet<VirtualFile>();
   for (final EditorWindow window : myWindows) {
     final VirtualFile file = window.getSelectedFile();
     if (file != null) {
       files.add(file);
     }
   }
   final VirtualFile[] virtualFiles = VfsUtilCore.toVirtualFileArray(files);
   final VirtualFile currentFile = getCurrentFile();
   if (currentFile != null) {
     for (int i = 0; i != virtualFiles.length; ++i) {
       if (Comparing.equal(virtualFiles[i], currentFile)) {
         virtualFiles[i] = virtualFiles[0];
         virtualFiles[0] = currentFile;
         break;
       }
     }
   }
   return virtualFiles;
 }
  public void readExternal(final Element element) throws InvalidDataException {
    PathMacroManager.getInstance(getProject()).expandPaths(element);
    super.readExternal(element);
    JavaRunConfigurationExtensionManager.getInstance().readExternal(this, element);
    readModule(element);
    DefaultJDOMExternalizer.readExternal(this, element);
    DefaultJDOMExternalizer.readExternal(getPersistentData(), element);
    EnvironmentVariablesComponent.readExternal(element, getPersistentData().getEnvs());
    final Element patternsElement = element.getChild(PATTERNS_EL_NAME);
    if (patternsElement != null) {
      final Set<String> tests = new LinkedHashSet<String>();
      for (Object o : patternsElement.getChildren(PATTERN_EL_NAME)) {
        Element patternElement = (Element) o;
        tests.add(patternElement.getAttributeValue(TEST_CLASS_ATT_NAME));
      }
      myData.setPatterns(tests);
    }
    final Element forkModeElement = element.getChild("fork_mode");
    if (forkModeElement != null) {
      final String mode = forkModeElement.getAttributeValue("value");
      if (mode != null) {
        setForkMode(mode);
      }
    }
    final Element dirNameElement = element.getChild("dir");
    if (dirNameElement != null) {
      final String dirName = dirNameElement.getAttributeValue("value");
      getPersistentData().setDirName(FileUtil.toSystemDependentName(dirName));
    }

    final Element categoryNameElement = element.getChild("category");
    if (categoryNameElement != null) {
      final String categoryName = categoryNameElement.getAttributeValue("value");
      getPersistentData().setCategoryName(categoryName);
    }
  }
 void addWindow(EditorWindow window) {
   myWindows.add(window);
 }
  @NotNull
  private List<PostponedAction> normalizeAndReorderPostponedActions(
      @NotNull Set<PostprocessFormattingTask> rangesToProcess, @NotNull Document document) {
    final List<PostprocessFormattingTask> freeFormattingActions =
        new ArrayList<PostprocessFormattingTask>();
    final List<ReindentTask> indentActions = new ArrayList<ReindentTask>();

    PostprocessFormattingTask accumulatedTask = null;
    Iterator<PostprocessFormattingTask> iterator = rangesToProcess.iterator();
    while (iterator.hasNext()) {
      final PostprocessFormattingTask currentTask = iterator.next();
      if (accumulatedTask == null) {
        accumulatedTask = currentTask;
        iterator.remove();
      } else if (accumulatedTask.getStartOffset() > currentTask.getEndOffset()
          || accumulatedTask.getStartOffset() == currentTask.getEndOffset()
              && !canStickActionsTogether(accumulatedTask, currentTask)) {
        // action can be pushed
        if (accumulatedTask instanceof ReindentTask) {
          indentActions.add((ReindentTask) accumulatedTask);
        } else {
          freeFormattingActions.add(accumulatedTask);
        }

        accumulatedTask = currentTask;
        iterator.remove();
      } else if (accumulatedTask instanceof ReformatTask && currentTask instanceof ReindentTask) {
        // split accumulated reformat range into two
        if (accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
          final RangeMarker endOfRange =
              document.createRangeMarker(
                  accumulatedTask.getStartOffset(), currentTask.getStartOffset());
          // add heading reformat part
          rangesToProcess.add(new ReformatTask(endOfRange));
          // and manage heading whitespace because formatter does not edit it in previous action
          iterator = rangesToProcess.iterator();
          //noinspection StatementWithEmptyBody
          while (iterator.next().getRange() != currentTask.getRange()) ;
        }
        final RangeMarker rangeToProcess =
            document.createRangeMarker(currentTask.getEndOffset(), accumulatedTask.getEndOffset());
        freeFormattingActions.add(new ReformatWithHeadingWhitespaceTask(rangeToProcess));
        accumulatedTask = currentTask;
        iterator.remove();
      } else {
        if (!(accumulatedTask instanceof ReindentTask)) {
          iterator.remove();

          boolean withLeadingWhitespace =
              accumulatedTask instanceof ReformatWithHeadingWhitespaceTask;
          if (accumulatedTask instanceof ReformatTask
              && currentTask instanceof ReformatWithHeadingWhitespaceTask
              && accumulatedTask.getStartOffset() == currentTask.getStartOffset()) {
            withLeadingWhitespace = true;
          } else if (accumulatedTask instanceof ReformatWithHeadingWhitespaceTask
              && currentTask instanceof ReformatTask
              && accumulatedTask.getStartOffset() < currentTask.getStartOffset()) {
            withLeadingWhitespace = false;
          }
          int newStart = Math.min(accumulatedTask.getStartOffset(), currentTask.getStartOffset());
          int newEnd = Math.max(accumulatedTask.getEndOffset(), currentTask.getEndOffset());
          RangeMarker rangeMarker;

          if (accumulatedTask.getStartOffset() == newStart
              && accumulatedTask.getEndOffset() == newEnd) {
            rangeMarker = accumulatedTask.getRange();
          } else if (currentTask.getStartOffset() == newStart
              && currentTask.getEndOffset() == newEnd) {
            rangeMarker = currentTask.getRange();
          } else {
            rangeMarker = document.createRangeMarker(newStart, newEnd);
          }

          if (withLeadingWhitespace) {
            accumulatedTask = new ReformatWithHeadingWhitespaceTask(rangeMarker);
          } else {
            accumulatedTask = new ReformatTask(rangeMarker);
          }
        } else if (currentTask instanceof ReindentTask) {
          iterator.remove();
        } // TODO[ik]: need to be fixed to correctly process indent inside indent
      }
    }
    if (accumulatedTask != null) {
      if (accumulatedTask instanceof ReindentTask) {
        indentActions.add((ReindentTask) accumulatedTask);
      } else {
        freeFormattingActions.add(accumulatedTask);
      }
    }

    final List<PostponedAction> result = new ArrayList<PostponedAction>();
    Collections.reverse(freeFormattingActions);
    Collections.reverse(indentActions);

    if (!freeFormattingActions.isEmpty()) {
      FormatTextRanges ranges = new FormatTextRanges();
      for (PostprocessFormattingTask action : freeFormattingActions) {
        TextRange range = TextRange.create(action);
        ranges.add(range, action instanceof ReformatWithHeadingWhitespaceTask);
      }
      result.add(new ReformatRangesAction(ranges));
    }

    if (!indentActions.isEmpty()) {
      ReindentRangesAction reindentRangesAction = new ReindentRangesAction();
      for (ReindentTask action : indentActions) {
        reindentRangesAction.add(action.getRange(), action.getOldIndent());
      }
      result.add(reindentRangesAction);
    }

    return result;
  }
  @Override
  protected void collectInformationWithProgress(@NotNull final ProgressIndicator progress) {
    if (!Registry.is("editor.injected.highlighting.enabled")) return;

    final Set<HighlightInfo> gotHighlights = new THashSet<HighlightInfo>(100);

    final List<PsiElement> inside = new ArrayList<PsiElement>();
    final List<PsiElement> outside = new ArrayList<PsiElement>();
    List<ProperTextRange> insideRanges = new ArrayList<ProperTextRange>();
    List<ProperTextRange> outsideRanges = new ArrayList<ProperTextRange>();
    // TODO: this thing is just called TWICE with same arguments eating CPU on huge files :(
    Divider.divideInsideAndOutside(
        myFile,
        myRestrictRange.getStartOffset(),
        myRestrictRange.getEndOffset(),
        myPriorityRange,
        inside,
        insideRanges,
        outside,
        outsideRanges,
        false,
        SHOULD_HIGHIGHT_FILTER);

    // all infos for the "injected fragment for the host which is inside" are indeed inside
    // but some of the infos for the "injected fragment for the host which is outside" can be still
    // inside
    Set<HighlightInfo> injectedResult = new THashSet<HighlightInfo>();
    Set<PsiFile> injected = getInjectedPsiFiles(inside, outside, progress);
    setProgressLimit(injected.size());

    if (!addInjectedPsiHighlights(
        injected, progress, Collections.synchronizedSet(injectedResult))) {
      throw new ProcessCanceledException();
    }
    final List<HighlightInfo> injectionsOutside =
        new ArrayList<HighlightInfo>(gotHighlights.size());

    Set<HighlightInfo> result;
    synchronized (injectedResult) {
      // sync here because all writes happened in another thread
      result = injectedResult;
    }
    for (HighlightInfo info : result) {
      if (myRestrictRange.contains(info)) {
        gotHighlights.add(info);
      } else {
        // nonconditionally apply injected results regardless whether they are in
        // myStartOffset,myEndOffset
        injectionsOutside.add(info);
      }
    }

    if (!injectionsOutside.isEmpty()) {
      final ProperTextRange priorityIntersection = myPriorityRange.intersection(myRestrictRange);
      if ((!inside.isEmpty() || !gotHighlights.isEmpty())
          && priorityIntersection
              != null) { // do not apply when there were no elements to highlight
        // clear infos found in visible area to avoid applying them twice
        final List<HighlightInfo> toApplyInside = new ArrayList<HighlightInfo>(gotHighlights);
        myHighlights.addAll(toApplyInside);
        gotHighlights.clear();

        myHighlightInfoProcessor.highlightsInsideVisiblePartAreProduced(
            myHighlightingSession, toApplyInside, myPriorityRange, myRestrictRange, getId());
      }

      List<HighlightInfo> toApply = new ArrayList<HighlightInfo>();
      for (HighlightInfo info : gotHighlights) {
        if (!myRestrictRange.containsRange(info.getStartOffset(), info.getEndOffset())) continue;
        if (!myPriorityRange.containsRange(info.getStartOffset(), info.getEndOffset())) {
          toApply.add(info);
        }
      }
      toApply.addAll(injectionsOutside);

      myHighlightInfoProcessor.highlightsOutsideVisiblePartAreProduced(
          myHighlightingSession,
          toApply,
          myRestrictRange,
          new ProperTextRange(0, myDocument.getTextLength()),
          getId());
    } else {
      // else apply only result (by default apply command) and only within inside
      myHighlights.addAll(gotHighlights);
      myHighlightInfoProcessor.highlightsInsideVisiblePartAreProduced(
          myHighlightingSession, myHighlights, myRestrictRange, myRestrictRange, getId());
    }
  }
  private boolean shouldReloadProject(final Project project) {
    if (project.isDisposed()) return false;
    final HashSet<Pair<VirtualFile, StateStorage>> causes =
        new HashSet<Pair<VirtualFile, StateStorage>>();

    synchronized (myChangedProjectFiles) {
      final List<Pair<VirtualFile, StateStorage>> changes = myChangedProjectFiles.remove(project);
      if (changes != null) {
        causes.addAll(changes);
      }

      if (causes.isEmpty()) return false;
    }

    final boolean[] reloadOk = {false};

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              @Override
              public void run() {
                try {
                  LOG.debug("[RELOAD] Reloading project/components...");
                  reloadOk[0] = ((ProjectEx) project).getStateStore().reload(causes);
                } catch (StateStorageException e) {
                  Messages.showWarningDialog(
                      ProjectBundle.message("project.reload.failed", e.getMessage()),
                      ProjectBundle.message("project.reload.failed.title"));
                } catch (IOException e) {
                  Messages.showWarningDialog(
                      ProjectBundle.message("project.reload.failed", e.getMessage()),
                      ProjectBundle.message("project.reload.failed.title"));
                }
              }
            });
    if (reloadOk[0]) return false;

    String message;
    if (causes.size() == 1) {
      message =
          ProjectBundle.message(
              "project.reload.external.change.single",
              causes.iterator().next().first.getPresentableUrl());
    } else {
      StringBuilder filesBuilder = new StringBuilder();
      boolean first = true;
      Set<String> alreadyShown = new HashSet<String>();
      for (Pair<VirtualFile, StateStorage> cause : causes) {
        String url = cause.first.getPresentableUrl();
        if (!alreadyShown.contains(url)) {
          if (alreadyShown.size() > 10) {
            filesBuilder
                .append("\n" + "and ")
                .append(causes.size() - alreadyShown.size())
                .append(" more");
            break;
          }
          if (!first) filesBuilder.append("\n");
          first = false;
          filesBuilder.append(url);
          alreadyShown.add(url);
        }
      }
      message =
          ProjectBundle.message("project.reload.external.change.multiple", filesBuilder.toString());
    }

    return Messages.showTwoStepConfirmationDialog(
            message,
            ProjectBundle.message("project.reload.external.change.title"),
            "Reload project",
            Messages.getQuestionIcon())
        == 0;
  }
  @Override
  public void documentChanged(DocumentEvent event) {
    if (myStopTrackingDocuments) return;

    final Document document = event.getDocument();
    VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
    boolean isRelevant = virtualFile != null && isRelevant(virtualFile);

    final FileViewProvider viewProvider = getCachedViewProvider(document);
    if (viewProvider == null) {
      handleCommitWithoutPsi(document);
      return;
    }
    boolean inMyProject = viewProvider.getManager() == myPsiManager;
    if (!isRelevant || !inMyProject) {
      myLastCommittedTexts.remove(document);
      return;
    }

    ApplicationManager.getApplication().assertWriteAccessAllowed();
    final List<PsiFile> files = viewProvider.getAllFiles();
    boolean commitNecessary = true;
    for (PsiFile file : files) {

      if (mySynchronizer.isInsideAtomicChange(file)) {
        commitNecessary = false;
        continue;
      }

      assert file instanceof PsiFileImpl
              || "mock.file".equals(file.getName())
                  && ApplicationManager.getApplication().isUnitTestMode()
          : event + "; file=" + file + "; allFiles=" + files + "; viewProvider=" + viewProvider;
    }

    boolean forceCommit =
        ApplicationManager.getApplication().hasWriteAction(ExternalChangeAction.class)
            && (SystemProperties.getBooleanProperty("idea.force.commit.on.external.change", false)
                || ApplicationManager.getApplication().isHeadlessEnvironment()
                    && !ApplicationManager.getApplication().isUnitTestMode());

    // Consider that it's worth to perform complete re-parse instead of merge if the whole document
    // text is replaced and
    // current document lines number is roughly above 5000. This makes sense in situations when
    // external change is performed
    // for the huge file (that causes the whole document to be reloaded and 'merge' way takes a
    // while to complete).
    if (event.isWholeTextReplaced() && document.getTextLength() > 100000) {
      document.putUserData(BlockSupport.DO_NOT_REPARSE_INCREMENTALLY, Boolean.TRUE);
    }

    if (commitNecessary) {
      assert !(document instanceof DocumentWindow);
      myUncommittedDocuments.add(document);
      myDocumentCommitProcessor.log(
          "added uncommitted doc",
          null,
          false,
          myProject,
          document,
          ((DocumentEx) document).isInBulkUpdate());
      if (forceCommit) {
        commitDocument(document);
      } else if (!((DocumentEx) document).isInBulkUpdate() && myPerformBackgroundCommit) {
        myDocumentCommitProcessor.commitAsynchronously(myProject, document, event);
      }
    } else {
      myLastCommittedTexts.remove(document);
    }
  }
  public static Set<LookupElement> processJavaReference(
      PsiElement element,
      PsiJavaReference javaReference,
      ElementFilter elementFilter,
      JavaCompletionProcessor.Options options,
      final PrefixMatcher matcher,
      CompletionParameters parameters) {
    final Set<LookupElement> set = new LinkedHashSet<LookupElement>();
    final Condition<String> nameCondition =
        new Condition<String>() {
          @Override
          public boolean value(String s) {
            return matcher.prefixMatches(s);
          }
        };

    PsiMethodCallExpression call =
        PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
    boolean checkInitialized =
        parameters.getInvocationCount() <= 1
            && call != null
            && PsiKeyword.SUPER.equals(call.getMethodExpression().getText());

    final JavaCompletionProcessor processor =
        new JavaCompletionProcessor(
            element, elementFilter, options.withInitialized(checkInitialized), nameCondition);
    final PsiType plainQualifier = processor.getQualifierType();
    PsiType qualifierType = plainQualifier;

    PsiType runtimeQualifier = getQualifierCastType(javaReference, parameters);
    if (runtimeQualifier != null) {
      PsiType composite =
          qualifierType == null
              ? runtimeQualifier
              : PsiIntersectionType.createIntersection(qualifierType, runtimeQualifier);
      PsiElement ctx = createContextWithXxxVariable(element, composite);
      javaReference =
          (PsiReferenceExpression)
              JavaPsiFacade.getElementFactory(element.getProject())
                  .createExpressionFromText("xxx.xxx", ctx);
      qualifierType = runtimeQualifier;
      processor.setQualifierType(qualifierType);
    }

    javaReference.processVariants(processor);

    final PsiTypeLookupItem castItem =
        runtimeQualifier == null
            ? null
            : PsiTypeLookupItem.createLookupItem(
                runtimeQualifier, (PsiReferenceExpression) javaReference);

    final boolean pkgContext = inSomePackage(element);

    final Set<PsiMember> mentioned = new THashSet<PsiMember>();
    for (CompletionElement completionElement : processor.getResults()) {
      for (LookupElement item : createLookupElements(completionElement, javaReference)) {
        item.putUserData(QUALIFIER_TYPE_ATTR, qualifierType);
        final Object o = item.getObject();
        if (o instanceof PsiClass && !isSourceLevelAccessible(element, (PsiClass) o, pkgContext)) {
          continue;
        }
        if (o instanceof PsiMember) {
          if (isInExcludedPackage((PsiMember) o, true)) {
            continue;
          }
          mentioned.add(CompletionUtil.getOriginalOrSelf((PsiMember) o));
        }
        set.add(
            highlightIfNeeded(
                qualifierType,
                castQualifier(item, castItem, plainQualifier, processor),
                o,
                element));
      }
    }

    if (javaReference instanceof PsiJavaCodeReferenceElement
        && !((PsiJavaCodeReferenceElement) javaReference).isQualified()) {
      final StaticMemberProcessor memberProcessor = new JavaStaticMemberProcessor(parameters);
      memberProcessor.processMembersOfRegisteredClasses(
          matcher,
          new PairConsumer<PsiMember, PsiClass>() {
            @Override
            public void consume(PsiMember member, PsiClass psiClass) {
              if (!mentioned.contains(member)
                  && processor.satisfies(member, ResolveState.initial())) {
                set.add(memberProcessor.createLookupElement(member, psiClass, true));
              }
            }
          });
    }

    return set;
  }