Snapshot 568f05589922685b8c8f9a2f2f465043b8128542 from master branch of git://git.jetbrains.org/idea/community.git

Change-Id: I47fe8cb5d8a3c9876cd4c313dca1a8cc531288ec
diff --git a/java/java-indexing-impl/java-indexing-impl.iml b/java/java-indexing-impl/java-indexing-impl.iml
index 0379d94..bd58ec0 100644
--- a/java/java-indexing-impl/java-indexing-impl.iml
+++ b/java/java-indexing-impl/java-indexing-impl.iml
@@ -11,9 +11,9 @@
     <orderEntry type="module" module-name="java-psi-impl" exported="" />
     <orderEntry type="module" module-name="indexing-api" exported="" />
     <orderEntry type="module" module-name="indexing-impl" exported="" />
-    <orderEntry type="module" module-name="projectModel-api" />
+    <orderEntry type="module" module-name="projectModel-api" exported="" />
     <orderEntry type="module" module-name="projectModel-impl" />
-    <orderEntry type="module" module-name="java-indexing-api" />
+    <orderEntry type="module" module-name="java-indexing-api" exported="" />
   </component>
 </module>
 
diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java b/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
new file mode 100644
index 0000000..1fec41c
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiMethod;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:johnnyclark@gmail.com">Johnny Clark</a>
+ *         Creation Date: 8/3/12
+ */
+@State(
+  name = "ConditionCheckManager",
+  storages = {
+    @Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/checker.xml", scheme = StorageScheme.DIRECTORY_BASED),
+    @Storage(file = StoragePathMacros.PROJECT_FILE)
+  }
+)
+public class ConditionCheckManager implements PersistentStateComponent<ConditionCheckManager.State> {
+  @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) private State state;
+  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheckManager");
+
+  private final List<ConditionChecker> myIsNullCheckMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myIsNotNullCheckMethods = new ArrayList<ConditionChecker>();
+
+  private final List<ConditionChecker> myAssertIsNullMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myAssertIsNotNullMethods = new ArrayList<ConditionChecker>();
+
+  private final List<ConditionChecker> myAssertTrueMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myAssertFalseMethods = new ArrayList<ConditionChecker>();
+
+  public static ConditionCheckManager getInstance(Project project) {
+    return ServiceManager.getService(project, ConditionCheckManager.class);
+  }
+
+  public void setIsNullCheckMethods(List<ConditionChecker> methodConditionChecks) {
+    myIsNullCheckMethods.clear();
+    myIsNullCheckMethods.addAll(methodConditionChecks);
+  }
+
+  public void setIsNotNullCheckMethods(List<ConditionChecker> methodConditionChecks) {
+    myIsNotNullCheckMethods.clear();
+    myIsNotNullCheckMethods.addAll(methodConditionChecks);
+  }
+
+  public void setAssertIsNullMethods(List<ConditionChecker> methodConditionChecks) {
+    myAssertIsNullMethods.clear();
+    myAssertIsNullMethods.addAll(methodConditionChecks);
+  }
+
+  public void setAssertIsNotNullMethods(List<ConditionChecker> methodConditionChecks) {
+    myAssertIsNotNullMethods.clear();
+    myAssertIsNotNullMethods.addAll(methodConditionChecks);
+  }
+
+  public void setAssertTrueMethods(List<ConditionChecker> psiMethodWrappers) {
+    myAssertTrueMethods.clear();
+    myAssertTrueMethods.addAll(psiMethodWrappers);
+  }
+
+  public void setAssertFalseMethods(List<ConditionChecker> psiMethodWrappers) {
+    myAssertFalseMethods.clear();
+    myAssertFalseMethods.addAll(psiMethodWrappers);
+  }
+
+  public List<ConditionChecker> getIsNullCheckMethods() {
+    return myIsNullCheckMethods;
+  }
+
+  public List<ConditionChecker> getIsNotNullCheckMethods() {
+    return myIsNotNullCheckMethods;
+  }
+
+  public List<ConditionChecker> getAssertIsNullMethods() {
+    return myAssertIsNullMethods;
+  }
+
+  public List<ConditionChecker> getAssertIsNotNullMethods() {
+    return myAssertIsNotNullMethods;
+  }
+
+  public List<ConditionChecker> getAssertFalseMethods() {
+    return myAssertFalseMethods;
+  }
+
+  public List<ConditionChecker> getAssertTrueMethods() {
+    return myAssertTrueMethods;
+  }
+
+  public static class State {
+    public List<String> myIsNullCheckMethods = new ArrayList<String>();
+    public List<String> myIsNotNullCheckMethods = new ArrayList<String>();
+    public List<String> myAssertIsNullMethods = new ArrayList<String>();
+    public List<String> myAssertIsNotNullMethods = new ArrayList<String>();
+    public List<String> myAssertTrueMethods = new ArrayList<String>();
+    public List<String> myAssertFalseMethods = new ArrayList<String>();
+  }
+
+  @Override
+  public State getState() {
+    State state = new State();
+
+    loadMethodChecksToState(state.myIsNullCheckMethods, myIsNullCheckMethods);
+    loadMethodChecksToState(state.myIsNotNullCheckMethods, myIsNotNullCheckMethods);
+    loadMethodChecksToState(state.myAssertIsNullMethods, myAssertIsNullMethods);
+    loadMethodChecksToState(state.myAssertIsNotNullMethods, myAssertIsNotNullMethods);
+    loadMethodChecksToState(state.myAssertTrueMethods, myAssertTrueMethods);
+    loadMethodChecksToState(state.myAssertFalseMethods, myAssertFalseMethods);
+
+    return state;
+  }
+
+  private static void loadMethodChecksToState(List<String> listToLoadTo, List<ConditionChecker> listToLoadFrom) {
+    for (ConditionChecker checker : listToLoadFrom) {
+      listToLoadTo.add(checker.toString());
+    }
+  }
+
+  @Override
+  public void loadState(State state) {
+    this.state = state;
+    loadMethods(myIsNullCheckMethods, state.myIsNullCheckMethods, ConditionChecker.Type.IS_NULL_METHOD);
+    loadMethods(myIsNotNullCheckMethods, state.myIsNotNullCheckMethods, ConditionChecker.Type.IS_NOT_NULL_METHOD);
+    loadMethods(myAssertIsNullMethods, state.myAssertIsNullMethods, ConditionChecker.Type.ASSERT_IS_NULL_METHOD);
+    loadMethods(myAssertIsNotNullMethods, state.myAssertIsNotNullMethods, ConditionChecker.Type.ASSERT_IS_NOT_NULL_METHOD);
+    loadMethods(myAssertTrueMethods, state.myAssertTrueMethods, ConditionChecker.Type.ASSERT_TRUE_METHOD);
+    loadMethods(myAssertFalseMethods, state.myAssertFalseMethods, ConditionChecker.Type.ASSERT_FALSE_METHOD);
+  }
+
+  private static void loadMethods(List<ConditionChecker> listToLoadTo, List<String> listToLoadFrom, ConditionChecker.Type type){
+    listToLoadTo.clear();
+    for (String setting : listToLoadFrom) {
+      try {
+        listToLoadTo.add(new ConditionChecker.FromConfigBuilder(setting, type).build());
+      } catch (Exception e) {
+        LOG.error("Problem occurred while attempting to load Condition Check from configuration file. " + e.getMessage());
+      }
+    }
+  }
+
+  @Nullable
+  public static ConditionChecker findConditionChecker(@NotNull PsiMethod method) {
+    ConditionCheckManager instance = getInstance(method.getProject());
+    ConditionChecker checker = methodMatches(method, instance.getIsNullCheckMethods());
+    if (checker == null) checker = methodMatches(method, instance.getIsNotNullCheckMethods());
+    if (checker == null) checker = methodMatches(method, instance.getAssertIsNullMethods());
+    if (checker == null) checker = methodMatches(method, instance.getAssertIsNotNullMethods());
+    if (checker == null) checker = methodMatches(method, instance.getAssertTrueMethods());
+    if (checker == null) checker = methodMatches(method, instance.getAssertFalseMethods());
+    return checker;
+  }
+
+  private static ConditionChecker methodMatches(PsiMethod psiMethod, List<ConditionChecker> checkers) {
+    for (ConditionChecker checker : checkers) {
+      if (checker.matchesPsiMethod(psiMethod)) {
+        return checker;
+      }
+    }
+    return null;
+  }
+
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
index 2aad613..600bfc0 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
@@ -1,5 +1,8 @@
 package com.intellij.psi.impl.search;
 
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadActionProcessor;
+import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.*;
@@ -12,6 +15,7 @@
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.PairProcessor;
 import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author max
@@ -19,31 +23,30 @@
 public class ConstructorReferencesSearchHelper {
   private final PsiManager myManager;
 
-  public ConstructorReferencesSearchHelper(final PsiManager manager) {
+  public ConstructorReferencesSearchHelper(@NotNull PsiManager manager) {
     myManager = manager;
   }
 
-  public boolean processConstructorReferences(final Processor<PsiReference> processor,
-                                              final PsiMethod constructor,
-                                              final SearchScope searchScope,
+  public boolean processConstructorReferences(@NotNull final Processor<PsiReference> processor,
+                                              @NotNull final PsiMethod constructor,
+                                              @NotNull final PsiClass containingClass,
+                                              @NotNull final SearchScope searchScope,
                                               boolean ignoreAccessScope,
-                                              final boolean isStrictSignatureSearch, SearchRequestCollector collector) {
-    PsiClass aClass = constructor.getContainingClass();
-    if (aClass == null) {
-      return true;
-    }
-
-    if (aClass.isEnum()) {
-      for (PsiField field : aClass.getFields()) {
-        if (field instanceof PsiEnumConstant) {
-          PsiReference reference = field.getReference();
-          if (reference != null && reference.isReferenceTo(constructor)) {
-            if (!processor.process(reference)) {
-              return false;
-            }
-          }
-        }
+                                              final boolean isStrictSignatureSearch,
+                                              @NotNull SearchRequestCollector collector) {
+    final boolean[] constructorCanBeCalledImplicitly = new boolean[1];
+    final boolean[] isEnum = new boolean[1];
+    final boolean[] isUnder18 = new boolean[1];
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        constructorCanBeCalledImplicitly[0] = constructor.getParameterList().getParametersCount() == 0;
+        isEnum[0] = containingClass.isEnum();
+        isUnder18[0] = PsiUtil.getLanguageLevel(containingClass).isAtLeast(LanguageLevel.JDK_1_8);
       }
+    });
+
+    if (isEnum[0]) {
+      if (!processEnumReferences(processor, constructor, containingClass)) return false;
     }
 
     // search usages like "new XXX(..)"
@@ -63,7 +66,7 @@
               }
             }
             else {
-              if (myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass())) {
+              if (myManager.areElementsEquivalent(containingClass, constructor1.getContainingClass())) {
                 return processor.process(reference);
               }
             }
@@ -73,30 +76,18 @@
       }
     };
 
-    ReferencesSearch.searchOptimized(aClass, searchScope, ignoreAccessScope, collector, true, processor1);
-    if (PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8)) {
-      ReferencesSearch.search(aClass).forEach(new Processor<PsiReference>() {
-        @Override
-        public boolean process(PsiReference reference) {
-          final PsiElement element = reference.getElement();
-          if (element != null) {
-            final PsiElement parent = element.getParent();
-            if (parent instanceof PsiMethodReferenceExpression &&
-                ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) {
-              if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) {
-                processor.process((PsiReference)parent);
-              }
-            }
-          }
-          return true;
-        }
-      });
+    ReferencesSearch.searchOptimized(containingClass, searchScope, ignoreAccessScope, collector, true, processor1);
+    if (isUnder18[0]) {
+      if (!process18MethodPointers(processor, constructor, containingClass)) return false;
     }
 
-    final boolean constructorCanBeCalledImplicitly = constructor.getParameterList().getParametersCount() == 0;
     // search usages like "this(..)"
-    if (!processSuperOrThis(processor, aClass, constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
-                            PsiKeyword.THIS)) {
+    if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      public Boolean compute() {
+        return processSuperOrThis(containingClass, constructor, constructorCanBeCalledImplicitly[0], searchScope, isStrictSignatureSearch,
+                                  PsiKeyword.THIS, processor);
+      }
+    })) {
       return false;
     }
 
@@ -104,22 +95,69 @@
     Processor<PsiClass> processor2 = new Processor<PsiClass>() {
       @Override
       public boolean process(PsiClass inheritor) {
-        return processSuperOrThis(processor, (PsiClass)inheritor.getNavigationElement(), constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
-                                  PsiKeyword.SUPER);
+        final PsiElement navigationElement = inheritor.getNavigationElement();
+        if (navigationElement instanceof PsiClass) {
+          return processSuperOrThis((PsiClass)navigationElement, constructor, constructorCanBeCalledImplicitly[0], searchScope,
+                                    isStrictSignatureSearch, PsiKeyword.SUPER, processor);
+        }
+        return true;
       }
     };
 
-    return ClassInheritorsSearch.search(aClass, searchScope, false).forEach(processor2);
+    return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2);
   }
 
-  private boolean processSuperOrThis(final Processor<PsiReference> processor,
-                                                             final PsiClass inheritor,
-                                                             final PsiMethod constructor, final boolean constructorCanBeCalledImplicitly, final SearchScope searchScope,
-                                                             final boolean isStrictSignatureSearch,
-                                                             final String superOrThisKeyword) {
+  private static boolean processEnumReferences(@NotNull final Processor<PsiReference> processor,
+                                               @NotNull final PsiMethod constructor,
+                                               @NotNull final PsiClass aClass) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      public Boolean compute() {
+        for (PsiField field : aClass.getFields()) {
+          if (field instanceof PsiEnumConstant) {
+            PsiReference reference = field.getReference();
+            if (reference != null && reference.isReferenceTo(constructor)) {
+              if (!processor.process(reference)) {
+                return false;
+              }
+            }
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  private static boolean process18MethodPointers(@NotNull final Processor<PsiReference> processor,
+                                                 @NotNull final PsiMethod constructor,
+                                                 @NotNull PsiClass aClass) {
+    return ReferencesSearch.search(aClass).forEach(new ReadActionProcessor<PsiReference>() {
+      @Override
+      public boolean processInReadAction(PsiReference reference) {
+        final PsiElement element = reference.getElement();
+        if (element != null) {
+          final PsiElement parent = element.getParent();
+          if (parent instanceof PsiMethodReferenceExpression &&
+              ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) {
+            if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) {
+              if (!processor.process((PsiReference)parent)) return false;
+            }
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  private boolean processSuperOrThis(@NotNull PsiClass inheritor,
+                                     @NotNull PsiMethod constructor,
+                                     final boolean constructorCanBeCalledImplicitly,
+                                     @NotNull SearchScope searchScope,
+                                     final boolean isStrictSignatureSearch,
+                                     @NotNull String superOrThisKeyword,
+                                     @NotNull Processor<PsiReference> processor) {
     PsiMethod[] constructors = inheritor.getConstructors();
     if (constructors.length == 0 && constructorCanBeCalledImplicitly) {
-      processImplicitConstructorCall(inheritor, processor, constructor, inheritor);
+      if (!processImplicitConstructorCall(inheritor, processor, constructor, inheritor)) return false;
     }
     for (PsiMethod method : constructors) {
       PsiCodeBlock body = method.getBody();
@@ -134,7 +172,7 @@
           if (expr instanceof PsiMethodCallExpression) {
             PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression();
             if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) {
-              if (refExpr.getText().equals(superOrThisKeyword)) {
+              if (refExpr.textMatches(superOrThisKeyword)) {
                 PsiElement referencedElement = refExpr.resolve();
                 if (referencedElement instanceof PsiMethod) {
                   PsiMethod constructor1 = (PsiMethod)referencedElement;
@@ -151,43 +189,48 @@
         }
       }
       if (constructorCanBeCalledImplicitly) {
-        processImplicitConstructorCall(method, processor, constructor, inheritor);
+        if (!processImplicitConstructorCall(method, processor, constructor, inheritor)) return false;
       }
     }
 
     return true;
   }
 
-  private void processImplicitConstructorCall(final PsiMember usage,
-                                              final Processor<PsiReference> processor,
-                                              final PsiMethod constructor,
-                                              final PsiClass containingClass) {
-    if (containingClass instanceof PsiAnonymousClass) return;
-    PsiClass superClass = containingClass.getSuperClass();
-    if (myManager.areElementsEquivalent(constructor.getContainingClass(), superClass)) {
-      processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) {
-        @Override
-        public PsiElement getElement() {
-          return usage;
-        }
-
-        @Override
-        public TextRange getRangeInElement() {
-          if (usage instanceof PsiClass) {
-            PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier();
-            if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
-          }
-          else if (usage instanceof PsiField) {
-            PsiIdentifier identifier = ((PsiField)usage).getNameIdentifier();
-            return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
-          }
-          else if (usage instanceof PsiMethod) {
-            PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier();
-            if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
-          }
-          return super.getRangeInElement();
-        }
-      });
+  private boolean processImplicitConstructorCall(@NotNull final PsiMember usage,
+                                                 @NotNull final Processor<PsiReference> processor,
+                                                 @NotNull final PsiMethod constructor,
+                                                 @NotNull final PsiClass containingClass) {
+    if (containingClass instanceof PsiAnonymousClass) return true;
+    boolean same = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      public Boolean compute() {
+        return myManager.areElementsEquivalent(constructor.getContainingClass(), containingClass.getSuperClass());
+      }
+    });
+    if (!same) {
+      return true;
     }
+    return processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) {
+      @Override
+      public PsiElement getElement() {
+        return usage;
+      }
+
+      @Override
+      public TextRange getRangeInElement() {
+        if (usage instanceof PsiClass) {
+          PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier();
+          if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+        }
+        else if (usage instanceof PsiField) {
+          PsiIdentifier identifier = ((PsiField)usage).getNameIdentifier();
+          return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+        }
+        else if (usage instanceof PsiMethod) {
+          PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier();
+          if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+        }
+        return super.getRangeInElement();
+      }
+    });
   }
 }
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
index 933a748..5bc07cb 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
@@ -1,9 +1,9 @@
 package com.intellij.psi.impl.search;
 
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiReference;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.*;
 import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.util.Processor;
 import org.jetbrains.annotations.NotNull;
@@ -12,16 +12,26 @@
  * @author max
  */
 public class ConstructorReferencesSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
-  public ConstructorReferencesSearcher() {
-    super(true);
-  }
-
   @Override
   public void processQuery(@NotNull ReferencesSearch.SearchParameters p, @NotNull Processor<PsiReference> consumer) {
     final PsiElement element = p.getElementToSearch();
-    if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
-      new ConstructorReferencesSearchHelper(element.getManager())
-        .processConstructorReferences(consumer, (PsiMethod)p.getElementToSearch(), p.getScope(), p.isIgnoreAccessScope(), true, p.getOptimizer());
+    if (!(element instanceof PsiMethod)) {
+      return;
     }
+    final PsiMethod method = (PsiMethod)element;
+    final PsiManager[] manager = new PsiManager[1];
+    PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+      public PsiClass compute() {
+        if (!method.isConstructor()) return null;
+        PsiClass aClass = method.getContainingClass();
+        manager[0] = aClass == null ? null : aClass.getManager();
+        return aClass;
+      }
+    });
+    if (aClass == null) {
+      return;
+    }
+    new ConstructorReferencesSearchHelper(manager[0])
+      .processConstructorReferences(consumer, method, aClass, p.getScope(), p.isIgnoreAccessScope(), true, p.getOptimizer());
   }
 }
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
index 49bd3f3..ec298ce 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
@@ -1,7 +1,8 @@
 package com.intellij.psi.impl.search;
 
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.search.SearchRequestCollector;
@@ -17,66 +18,77 @@
  * @author max
  */
 public class MethodUsagesSearcher extends QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters> {
-  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.MethodUsagesSearcher");
-  public MethodUsagesSearcher() {
-    super(true);
-  }
-
   @Override
   public void processQuery(@NotNull MethodReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
     final PsiMethod method = p.getMethod();
+    final boolean[] isConstructor = new boolean[1];
+    final PsiManager[] psiManager = new PsiManager[1];
+    final String[] methodName = new String[1];
+    final boolean[] isValueAnnotation = new boolean[1];
+    final boolean[] needStrictSignatureSearch = new boolean[1];
+    final boolean strictSignatureSearch = p.isStrictSignatureSearch();
+
+    final PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+      public PsiClass compute() {
+        PsiClass aClass = method.getContainingClass();
+        if (aClass == null) return null;
+        isConstructor[0] = method.isConstructor();
+        psiManager[0] = aClass.getManager();
+        methodName[0] = method.getName();
+        isValueAnnotation[0] = PsiUtil.isAnnotationMethod(method) &&
+                    PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(methodName[0]) &&
+                    method.getParameterList().getParametersCount() == 0;
+        needStrictSignatureSearch[0] = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
+                                                                 || aClass.hasModifierProperty(PsiModifier.FINAL)
+                                                                 || method.hasModifierProperty(PsiModifier.STATIC)
+                                                                 || method.hasModifierProperty(PsiModifier.FINAL)
+                                                                 || method.hasModifierProperty(PsiModifier.PRIVATE));
+        return aClass;
+      }
+    });
+    if (aClass == null) return;
+
     final SearchRequestCollector collector = p.getOptimizer();
 
     final SearchScope searchScope = p.getScope();
 
-    final PsiManager psiManager = method.getManager();
-
-    final PsiClass aClass = method.getContainingClass();
-    if (aClass == null) return;
-
-    final boolean strictSignatureSearch = p.isStrictSignatureSearch();
-
-    if (method.isConstructor()) {
-      new ConstructorReferencesSearchHelper(psiManager).
-        processConstructorReferences(consumer, method, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
+    if (isConstructor[0]) {
+      new ConstructorReferencesSearchHelper(psiManager[0]).
+        processConstructorReferences(consumer, method, aClass, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
     }
 
-    if (PsiUtil.isAnnotationMethod(method) &&
-        PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) &&
-        method.getParameterList().getParametersCount() == 0) {
-      ReferencesSearch.search(aClass, p.getScope()).forEach(PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer( consumer));
+    if (isValueAnnotation[0]) {
+      Processor<PsiReference> refProcessor = PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer(consumer);
+      ReferencesSearch.search(aClass, searchScope).forEach(refProcessor);
     }
 
-    boolean needStrictSignatureSearch = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
-                                                             || aClass.hasModifierProperty(PsiModifier.FINAL)
-                                                             || method.hasModifierProperty(PsiModifier.STATIC)
-                                                             || method.hasModifierProperty(PsiModifier.FINAL)
-                                                             || method.hasModifierProperty(PsiModifier.PRIVATE));
-    if (needStrictSignatureSearch) {
+    if (needStrictSignatureSearch[0]) {
       ReferencesSearch.searchOptimized(method, searchScope, false, collector, consumer);
       return;
     }
 
-    final String textToSearch = method.getName();
-    if (StringUtil.isEmpty(textToSearch)) {
+    if (StringUtil.isEmpty(methodName[0])) {
       return;
     }
-    final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(textToSearch, false);
 
-    SearchScope accessScope = methods[0].getUseScope();
-    for (int i = 1; i < methods.length; i++) {
-      PsiMethod method1 = methods[i];
-      accessScope = accessScope.union(method1.getUseScope());
-    }
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(methodName[0], false);
+        SearchScope accessScope = methods[0].getUseScope();
+        for (int i = 1; i < methods.length; i++) {
+          PsiMethod method1 = methods[i];
+          accessScope = accessScope.union(method1.getUseScope());
+        }
 
-    final SearchScope restrictedByAccess = searchScope.intersectWith(accessScope);
+        SearchScope restrictedByAccessScope = searchScope.intersectWith(accessScope);
 
-    short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
-    collector.searchWord(textToSearch, restrictedByAccess, searchContext, true,
-                         new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods));
+        short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
+        collector.searchWord(methodName[0], restrictedByAccessScope, searchContext, true,
+                             new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods));
 
-    SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccess, collector);
-
+        SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccessScope, collector);
+      }
+    });
   }
 
 }