Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425

from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/java/java-indexing-impl/java-indexing-impl.iml b/java/java-indexing-impl/java-indexing-impl.iml
new file mode 100644
index 0000000..0379d94
--- /dev/null
+++ b/java/java-indexing-impl/java-indexing-impl.iml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="java-psi-api" exported="" />
+    <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-impl" />
+    <orderEntry type="module" module-name="java-indexing-api" />
+  </component>
+</module>
+
diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/ReadableExternalAnnotationsManager.java b/java/java-indexing-impl/src/com/intellij/codeInsight/ReadableExternalAnnotationsManager.java
new file mode 100644
index 0000000..727f4a2
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/codeInsight/ReadableExternalAnnotationsManager.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2012 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.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.psi.PsiManager;
+import com.intellij.util.ThreeState;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ReadableExternalAnnotationsManager extends BaseExternalAnnotationsManager {
+  @NotNull private volatile ThreeState myHasAnyAnnotationsRoots = ThreeState.UNSURE;
+
+  public ReadableExternalAnnotationsManager(PsiManager psiManager) {
+    super(psiManager);
+  }
+
+  @Override
+  protected boolean hasAnyAnnotationsRoots() {
+    if (myHasAnyAnnotationsRoots == ThreeState.UNSURE) {
+      final Module[] modules = ModuleManager.getInstance(myPsiManager.getProject()).getModules();
+      for (Module module : modules) {
+        for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
+          final String[] urls = AnnotationOrderRootType.getUrls(entry);
+          if (urls.length > 0) {
+            myHasAnyAnnotationsRoots = ThreeState.YES;
+            return true;
+          }
+        }
+      }
+      myHasAnyAnnotationsRoots = ThreeState.NO;
+    }
+    return myHasAnyAnnotationsRoots == ThreeState.YES;
+  }
+
+  @NotNull
+  @Override
+  protected List<VirtualFile> getExternalAnnotationsRoots(@NotNull VirtualFile libraryFile) {
+    final List<OrderEntry> entries = ProjectRootManager.getInstance(myPsiManager.getProject()).getFileIndex().getOrderEntriesForFile(
+      libraryFile);
+    List<VirtualFile> result = new ArrayList<VirtualFile>();
+    for (OrderEntry entry : entries) {
+      if (entry instanceof ModuleOrderEntry) {
+        continue;
+      }
+      final String[] externalUrls = AnnotationOrderRootType.getUrls(entry);
+      for (String url : externalUrls) {
+        VirtualFile root = VirtualFileManager.getInstance().findFileByUrl(url);
+        if (root != null) {
+          result.add(root);
+        }
+      }
+    }
+    return result;
+  }
+
+  @Override
+  protected void dropCache() {
+    myHasAnyAnnotationsRoots = ThreeState.UNSURE;
+    super.dropCache();
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/ClassImplementationsSearch.java b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/ClassImplementationsSearch.java
new file mode 100644
index 0000000..a19630d
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/ClassImplementationsSearch.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2009 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.navigation;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.search.PsiElementProcessor;
+import com.intellij.psi.search.PsiElementProcessorAdapter;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import org.jetbrains.annotations.NotNull;
+
+public class ClassImplementationsSearch implements QueryExecutor<PsiElement, PsiElement> {
+  public boolean execute(@NotNull final PsiElement sourceElement, @NotNull final Processor<PsiElement> consumer) {
+    return !(sourceElement instanceof PsiClass) || processImplementations((PsiClass)sourceElement, consumer);
+  }
+
+  public static boolean processImplementations(final PsiClass psiClass, final Processor<? super PsiClass> processor) {
+    final boolean showInterfaces = Registry.is("ide.goto.implementation.show.interfaces");
+    return ClassInheritorsSearch.search(psiClass, ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
+      @Override
+      public SearchScope compute() {
+        return psiClass.getUseScope();
+      }
+    }), true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
+      public boolean execute(@NotNull PsiClass element) {
+        if (!showInterfaces && element.isInterface()) {
+          return true;
+        }
+        return processor.process(element);
+      }
+    }));
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java
new file mode 100644
index 0000000..dfe436a
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2009 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.navigation;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.util.QueryExecutor;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+public class MethodImplementationsSearch implements QueryExecutor<PsiElement, PsiElement> {
+  public boolean execute(@NotNull final PsiElement sourceElement, @NotNull final Processor<PsiElement> consumer) {
+    if (sourceElement instanceof PsiMethod) {
+      PsiMethod[] implementations = getMethodImplementations((PsiMethod)sourceElement);
+      return ContainerUtil.process(implementations, consumer);
+    }
+    return true;
+  }
+
+  public static void getOverridingMethods(PsiMethod method, ArrayList<PsiMethod> list) {
+    for (PsiMethod psiMethod : OverridingMethodsSearch.search(method)) {
+      list.add(psiMethod);
+    }
+  }
+
+  public static PsiMethod[] getMethodImplementations(final PsiMethod method) {
+    ArrayList<PsiMethod> result = new ArrayList<PsiMethod>();
+
+    getOverridingMethods(method, result);
+    return result.toArray(new PsiMethod[result.size()]);
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/openapi/roots/impl/ProjectPackageIndexImpl.java b/java/java-indexing-impl/src/com/intellij/openapi/roots/impl/ProjectPackageIndexImpl.java
new file mode 100644
index 0000000..601ff49
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/openapi/roots/impl/ProjectPackageIndexImpl.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 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.openapi.roots.impl;
+
+import com.intellij.openapi.roots.PackageIndex;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Query;
+import org.jetbrains.annotations.NotNull;
+
+public class ProjectPackageIndexImpl extends PackageIndex {
+  private final DirectoryIndex myDirectoryIndex;
+
+  public ProjectPackageIndexImpl(DirectoryIndex directoryIndex) {
+    myDirectoryIndex = directoryIndex;
+  }
+
+  @Override
+  public VirtualFile[] getDirectoriesByPackageName(@NotNull String packageName, boolean includeLibrarySources) {
+    return getDirsByPackageName(packageName, includeLibrarySources).toArray(VirtualFile.EMPTY_ARRAY);
+  }
+
+  @Override
+  public Query<VirtualFile> getDirsByPackageName(@NotNull String packageName, boolean includeLibrarySources) {
+    return myDirectoryIndex.getDirectoriesByPackageName(packageName, includeLibrarySources);
+  }
+
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java b/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
new file mode 100644
index 0000000..269006b
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/CompositeShortNamesCache.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2000-2012 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.psi.impl;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashSet;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Set;
+
+public class CompositeShortNamesCache extends PsiShortNamesCache {
+  private final PsiShortNamesCache[] myCaches;
+
+  public CompositeShortNamesCache(Project project) {
+    myCaches = project.isDefault() ? new PsiShortNamesCache[0] : project.getExtensions(PsiShortNamesCache.EP_NAME);
+  }
+
+  @Override
+  @NotNull
+  public PsiFile[] getFilesByName(@NotNull String name) {
+    Merger<PsiFile> merger = null;
+    for (PsiShortNamesCache cache : myCaches) {
+      PsiFile[] classes = cache.getFilesByName(name);
+      if (classes.length != 0) {
+        if (merger == null) merger = new Merger<PsiFile>();
+        merger.add(classes);
+      }
+    }
+    PsiFile[] result = merger == null ? null : merger.getResult();
+    return result != null ? result : PsiFile.EMPTY_ARRAY;
+  }
+
+  @Override
+  @NotNull
+  public String[] getAllFileNames() {
+    Merger<String> merger = new Merger<String>();
+    for (PsiShortNamesCache cache : myCaches) {
+      merger.add(cache.getAllFileNames());
+    }
+    String[] result = merger.getResult();
+    return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY;
+  }
+
+  @Override
+  @NotNull
+  public PsiClass[] getClassesByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
+    Merger<PsiClass> merger = null;
+    for (PsiShortNamesCache cache : myCaches) {
+      PsiClass[] classes = cache.getClassesByName(name, scope);
+      if (classes.length != 0) {
+        if (merger == null) merger = new Merger<PsiClass>();
+        merger.add(classes);
+      }
+    }
+    PsiClass[] result = merger == null ? null : merger.getResult();
+    return result != null ? result : PsiClass.EMPTY_ARRAY;
+  }
+
+  @Override
+  @NotNull
+  public String[] getAllClassNames() {
+    Merger<String> merger = new Merger<String>();
+    for (PsiShortNamesCache cache : myCaches) {
+      String[] names = cache.getAllClassNames();
+      merger.add(names);
+    }
+    String[] result = merger.getResult();
+    return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY;
+  }
+
+  @Override
+  public void getAllClassNames(@NotNull HashSet<String> dest) {
+    for (PsiShortNamesCache cache : myCaches) {
+      cache.getAllClassNames(dest);
+    }
+  }
+
+  @Override
+  @NotNull
+  public PsiMethod[] getMethodsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
+    Merger<PsiMethod> merger = null;
+    for (PsiShortNamesCache cache : myCaches) {
+      PsiMethod[] methods = cache.getMethodsByName(name, scope);
+      if (methods.length != 0) {
+        if (merger == null) merger = new Merger<PsiMethod>();
+        merger.add(methods);
+      }
+    }
+    PsiMethod[] result = merger == null ? null : merger.getResult();
+    return result == null ? PsiMethod.EMPTY_ARRAY : result;
+  }
+
+  @Override
+  @NotNull
+  public PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @NotNull final String name, @NotNull final GlobalSearchScope scope, final int maxCount) {
+    Merger<PsiMethod> merger = null;
+    for (PsiShortNamesCache cache : myCaches) {
+      PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(name, scope, maxCount);
+      if (methods.length == maxCount) return methods;
+      if (methods.length != 0) {
+        if (merger == null) merger = new Merger<PsiMethod>();
+        merger.add(methods);
+      }
+    }
+    PsiMethod[] result = merger == null ? null : merger.getResult();
+    return result == null ? PsiMethod.EMPTY_ARRAY : result;
+  }
+
+  @NotNull
+  @Override
+  public PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @NotNull String name, @NotNull GlobalSearchScope scope, int maxCount) {
+    Merger<PsiField> merger = null;
+    for (PsiShortNamesCache cache : myCaches) {
+      PsiField[] fields = cache.getFieldsByNameIfNotMoreThan(name, scope, maxCount);
+      if (fields.length == maxCount) return fields;
+      if (fields.length != 0) {
+        if (merger == null) merger = new Merger<PsiField>();
+        merger.add(fields);
+      }
+    }
+    PsiField[] result = merger == null ? null : merger.getResult();
+    return result == null ? PsiField.EMPTY_ARRAY : result;
+  }
+
+  @Override
+  public boolean processMethodsWithName(@NonNls @NotNull String name,
+                                        @NotNull GlobalSearchScope scope,
+                                        @NotNull Processor<PsiMethod> processor) {
+    for (PsiShortNamesCache cache : myCaches) {
+      if (!cache.processMethodsWithName(name, scope, processor)) return false;
+    }
+    return true;
+  }
+
+  @Override
+  @NotNull
+  public String[] getAllMethodNames() {
+    Merger<String> merger = new Merger<String>();
+    for (PsiShortNamesCache cache : myCaches) {
+      merger.add(cache.getAllMethodNames());
+    }
+    String[] result = merger.getResult();
+    return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY;
+  }
+
+  @Override
+  public void getAllMethodNames(@NotNull HashSet<String> set) {
+    for (PsiShortNamesCache cache : myCaches) {
+      cache.getAllMethodNames(set);
+    }
+  }
+
+  @Override
+  @NotNull
+  public PsiField[] getFieldsByName(@NotNull String name, @NotNull GlobalSearchScope scope) {
+    Merger<PsiField> merger = null;
+    for (PsiShortNamesCache cache : myCaches) {
+      PsiField[] classes = cache.getFieldsByName(name, scope);
+      if (classes.length != 0) {
+        if (merger == null) merger = new Merger<PsiField>();
+        merger.add(classes);
+      }
+    }
+    PsiField[] result = merger == null ? null : merger.getResult();
+    return result == null ? PsiField.EMPTY_ARRAY : result;
+  }
+
+  @Override
+  @NotNull
+  public String[] getAllFieldNames() {
+    Merger<String> merger = null;
+    for (PsiShortNamesCache cache : myCaches) {
+      String[] classes = cache.getAllFieldNames();
+      if (classes.length != 0) {
+        if (merger == null) merger = new Merger<String>();
+        merger.add(classes);
+      }
+    }
+    String[] result = merger == null ? null : merger.getResult();
+    return result == null ? ArrayUtil.EMPTY_STRING_ARRAY : result;
+  }
+
+  @Override
+  public void getAllFieldNames(@NotNull HashSet<String> set) {
+    for (PsiShortNamesCache cache : myCaches) {
+      cache.getAllFieldNames(set);
+    }
+  }
+
+  private static class Merger<T> {
+    private T[] mySingleItem;
+    private Set<T> myAllItems;
+
+    public void add(@NotNull T[] items) {
+      if (items.length == 0) return;
+      if (mySingleItem == null) {
+        mySingleItem = items;
+        return;
+      }
+      if (myAllItems == null) {
+        T[] elements = mySingleItem;
+        myAllItems = ContainerUtil.addAll(new THashSet<T>(elements.length), elements);
+      }
+      ContainerUtil.addAll(myAllItems, items);
+    }
+
+    public T[] getResult() {
+      if (myAllItems == null) return mySingleItem;
+      return myAllItems.toArray(mySingleItem);
+    }
+  }
+
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  @Override
+  public String toString() {
+    return "Composite cache: " + Arrays.asList(myCaches);
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java b/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
new file mode 100644
index 0000000..215c9eb
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/PsiShortNamesCacheImpl.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2000-2009 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.psi.impl;
+
+import com.intellij.openapi.progress.ProgressIndicatorProvider;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.java.stubs.index.JavaFieldNameIndex;
+import com.intellij.psi.impl.java.stubs.index.JavaMethodNameIndex;
+import com.intellij.psi.impl.java.stubs.index.JavaShortClassNameIndex;
+import com.intellij.psi.impl.java.stubs.index.JavaStubIndexKeys;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.FilenameIndex;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.psi.stubs.StubIndex;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.Processor;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.HashSet;
+import gnu.trove.THashSet;
+import gnu.trove.TObjectHashingStrategy;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+public class PsiShortNamesCacheImpl extends PsiShortNamesCache {
+  private final PsiManagerEx myManager;
+
+  public PsiShortNamesCacheImpl(PsiManagerEx manager) {
+    myManager = manager;
+  }
+
+  @Override
+  @NotNull
+  public PsiFile[] getFilesByName(@NotNull String name) {
+    return FilenameIndex.getFilesByName(myManager.getProject(), name, GlobalSearchScope.projectScope(myManager.getProject()));
+  }
+
+  @Override
+  @NotNull
+  public String[] getAllFileNames() {
+    return FilenameIndex.getAllFilenames(myManager.getProject());
+  }
+
+  @Override
+  @NotNull
+  public PsiClass[] getClassesByName(@NotNull String name, @NotNull final GlobalSearchScope scope) {
+    final Collection<PsiClass> classes = JavaShortClassNameIndex.getInstance().get(name, myManager.getProject(), scope);
+
+    if (classes.isEmpty()) return PsiClass.EMPTY_ARRAY;
+    ArrayList<PsiClass> list = new ArrayList<PsiClass>(classes.size());
+
+    OuterLoop:
+    for (PsiClass aClass : classes) {
+      VirtualFile vFile = aClass.getContainingFile().getVirtualFile();
+      if (!scope.contains(vFile)) continue;
+
+      for (int j = 0; j < list.size(); j++) {
+        PsiClass aClass1 = list.get(j);
+
+        String qName = aClass.getQualifiedName();
+        String qName1 = aClass1.getQualifiedName();
+        if (qName != null && qName1 != null && qName.equals(qName1)) {
+          VirtualFile vFile1 = aClass1.getContainingFile().getVirtualFile();
+          int res = scope.compare(vFile1, vFile);
+          if (res > 0) {
+            continue OuterLoop; // aClass1 hides aClass
+          }
+          else if (res < 0) {
+            list.remove(j);
+            //noinspection AssignmentToForLoopParameter
+            j--;      // aClass hides aClass1
+          }
+        }
+      }
+
+      list.add(aClass);
+    }
+    return list.toArray(new PsiClass[list.size()]);
+  }
+
+  @Override
+  @NotNull
+  public String[] getAllClassNames() {
+    final Collection<String> names = JavaShortClassNameIndex.getInstance().getAllKeys(myManager.getProject());
+    return ArrayUtil.toStringArray(names);
+  }
+
+  @Override
+  public void getAllClassNames(@NotNull HashSet<String> set) {
+    set.addAll(JavaShortClassNameIndex.getInstance().getAllKeys(myManager.getProject()));
+  }
+
+  @Override
+  @NotNull
+  public PsiMethod[] getMethodsByName(@NotNull String name, @NotNull final GlobalSearchScope scope) {
+    Collection<PsiMethod> methods = StubIndex.getInstance().get(JavaStubIndexKeys.METHODS, name, myManager.getProject(), new JavaSourceFilterScope(scope));
+    if (methods.isEmpty()) return PsiMethod.EMPTY_ARRAY;
+
+    List<PsiMethod> list = filterMembers(methods, scope);
+    return list.toArray(new PsiMethod[list.size()]);
+  }
+
+
+  @Override
+  @NotNull
+  public PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @NotNull final String name, @NotNull final GlobalSearchScope scope, final int maxCount) {
+    final List<PsiMethod> methods = new SmartList<PsiMethod>();
+    StubIndex.getInstance().process(JavaStubIndexKeys.METHODS, name, myManager.getProject(), scope, new CommonProcessors.CollectProcessor<PsiMethod>(methods){
+      @Override
+      public boolean process(PsiMethod method) {
+        return methods.size() != maxCount && super.process(method);
+      }
+    });
+    if (methods.isEmpty()) return PsiMethod.EMPTY_ARRAY;
+
+    List<PsiMethod> list = filterMembers(methods, scope);
+    return list.toArray(new PsiMethod[list.size()]);
+  }
+
+  @Override
+  public boolean processMethodsWithName(@NonNls @NotNull String name,
+                                        @NotNull GlobalSearchScope scope,
+                                        @NotNull Processor<PsiMethod> processor) {
+    return StubIndex.getInstance().process(JavaStubIndexKeys.METHODS, name, myManager.getProject(), scope, processor);
+  }
+
+  @Override
+  @NotNull
+  public String[] getAllMethodNames() {
+    final Collection<String> names = JavaMethodNameIndex.getInstance().getAllKeys(myManager.getProject());
+    return ArrayUtil.toStringArray(names);
+  }
+
+  @Override
+  public void getAllMethodNames(@NotNull HashSet<String> set) {
+    set.addAll(JavaMethodNameIndex.getInstance().getAllKeys(myManager.getProject()));
+  }
+
+  @Override
+  @NotNull
+  public PsiField[] getFieldsByNameIfNotMoreThan(@NotNull String name, @NotNull final GlobalSearchScope scope, final int maxCount) {
+    final List<PsiField> methods = new SmartList<PsiField>();
+    StubIndex.getInstance().process(JavaStubIndexKeys.FIELDS, name, myManager.getProject(), scope, new CommonProcessors.CollectProcessor<PsiField>(methods){
+      @Override
+      public boolean process(PsiField method) {
+        return methods.size() != maxCount && super.process(method);
+      }
+    });
+    if (methods.isEmpty()) return PsiField.EMPTY_ARRAY;
+
+    List<PsiField> list = filterMembers(methods, scope);
+    return list.toArray(new PsiField[list.size()]);
+  }
+
+  @NotNull
+  @Override
+  public PsiField[] getFieldsByName(@NotNull String name, @NotNull final GlobalSearchScope scope) {
+    final Collection<PsiField> fields = JavaFieldNameIndex.getInstance().get(name, myManager.getProject(), scope);
+
+    if (fields.isEmpty()) return PsiField.EMPTY_ARRAY;
+
+    List<PsiField> list = filterMembers(fields, scope);
+    return list.toArray(new PsiField[list.size()]);
+  }
+
+  @Override
+  @NotNull
+  public String[] getAllFieldNames() {
+    final Collection<String> names = JavaFieldNameIndex.getInstance().getAllKeys(myManager.getProject());
+    return ArrayUtil.toStringArray(names);
+  }
+
+  @Override
+  public void getAllFieldNames(@NotNull HashSet<String> set) {
+    set.addAll(JavaFieldNameIndex.getInstance().getAllKeys(myManager.getProject()));
+  }
+
+  private <T extends PsiMember> List<T> filterMembers(Collection<T> members, final GlobalSearchScope scope) {
+    List<T> result = new ArrayList<T>(members.size());
+    Set<PsiMember> set = new THashSet<PsiMember>(members.size(), new TObjectHashingStrategy<PsiMember>() {
+      @Override
+      public int computeHashCode(PsiMember member) {
+        int code = 0;
+        final PsiClass clazz = member.getContainingClass();
+        if (clazz != null) {
+          String name = clazz.getName();
+          if (name != null) {
+            code += name.hashCode();
+          }
+          else {
+            //anonymous classes are not equivalent
+            code += clazz.hashCode();
+          }
+        }
+        if (member instanceof PsiMethod) {
+          code += 37 * ((PsiMethod)member).getParameterList().getParametersCount();
+        }
+        return code;
+      }
+
+      @Override
+      public boolean equals(PsiMember object, PsiMember object1) {
+        return myManager.areElementsEquivalent(object, object1);
+      }
+    });
+
+    for (T member : members) {
+      ProgressIndicatorProvider.checkCanceled();
+
+      if (!scope.contains(member.getContainingFile().getVirtualFile())) continue;
+      if (!set.add(member)) continue;
+      result.add(member);
+    }
+
+    return result;
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java
new file mode 100644
index 0000000..d559187
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaFileManagerBase.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2000-2012 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.psi.impl.file.impl;
+
+import com.intellij.ProjectTopics;
+import com.intellij.ide.highlighter.JavaClassFileType;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.openapi.vfs.VirtualFileWithId;
+import com.intellij.openapi.vfs.newvfs.BulkFileListener;
+import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiManagerEx;
+import com.intellij.psi.impl.file.PsiPackageImpl;
+import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.util.Query;
+import com.intellij.util.containers.ConcurrentHashMap;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.indexing.FileBasedIndex;
+import com.intellij.util.messages.MessageBus;
+import com.intellij.util.messages.MessageBusConnection;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * Author: dmitrylomov
+ */
+public abstract class JavaFileManagerBase implements JavaFileManager, Disposable {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.impl.JavaFileManagerImpl");
+  @NonNls private static final String JAVA_EXTENSION = ".java";
+  @NonNls private static final String CLASS_EXTENSION = ".class";
+  private final ConcurrentHashMap<GlobalSearchScope, PsiClass> myCachedObjectClassMap = new ConcurrentHashMap<GlobalSearchScope, PsiClass>();
+  private final Map<String,PsiClass> myNameToClassMap = new ConcurrentHashMap<String, PsiClass>(); // used only in mode without repository
+  private final PsiManagerEx myManager;
+  private final ProjectRootManager myProjectRootManager;
+  private final FileManager myFileManager;
+  private final boolean myUseRepository;
+  private Set<String> myNontrivialPackagePrefixes = null;
+  private boolean myInitialized = false;
+  private boolean myDisposed = false;
+  private final PackageIndex myPackageIndex;
+  protected final MessageBusConnection myConnection;
+
+  public JavaFileManagerBase(
+    final PsiManagerEx manager, final ProjectRootManager projectRootManager,
+    final MessageBus bus) {
+    myManager = manager;
+    myFileManager = manager.getFileManager();
+    myProjectRootManager = projectRootManager;
+    myUseRepository = true;
+    myPackageIndex = PackageIndex.getInstance(myManager.getProject());
+    myConnection = bus.connect();
+    myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
+      @Override
+      public void rootsChanged(final ModuleRootEvent event) {
+        myNontrivialPackagePrefixes = null;
+        clearNonRepositoryMaps();
+      }
+    });
+
+    myConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
+      @Override
+      public void before(@NotNull final List<? extends VFileEvent> events) {
+        clearNonRepositoryMaps();
+      }
+
+      @Override
+      public void after(@NotNull final List<? extends VFileEvent> events) {
+        clearNonRepositoryMaps();
+      }
+    });
+
+    myManager.registerRunnableToRunOnChange(new Runnable() {
+      @Override
+      public void run() {
+        myCachedObjectClassMap.clear();
+      }
+    });
+
+    Disposer.register(myManager.getProject(), this);
+  }
+
+  @Override
+  public void initialize() {
+    myInitialized = true;
+  }
+
+  @Override
+  public void dispose() {
+    myDisposed = true;
+    myCachedObjectClassMap.clear();
+  }
+
+  protected void clearNonRepositoryMaps() {
+    if (!myUseRepository) {
+      myNameToClassMap.clear();
+    }
+  }
+
+  @Override
+  @Nullable
+  public PsiPackage findPackage(@NotNull String packageName) {
+    Query<VirtualFile> dirs = myPackageIndex.getDirsByPackageName(packageName, false);
+    if (dirs.findFirst() == null) return null;
+    return new PsiPackageImpl(myManager, packageName);
+  }
+
+  @Override
+  public PsiClass[] findClasses(@NotNull String qName, @NotNull final GlobalSearchScope scope) {
+    final Collection<? extends PsiElement> classes = JavaFullClassNameIndex.getInstance().get(qName.hashCode(), myManager.getProject(), scope);
+    if (classes.isEmpty()) return PsiClass.EMPTY_ARRAY;
+    List<PsiClass> result = new ArrayList<PsiClass>(classes.size());
+    int count = 0;
+    PsiClass aClass = null;
+    for (PsiElement found : classes) {
+      if (notClass(found)) continue;
+
+      aClass = (PsiClass)found;
+      final String qualifiedName = aClass.getQualifiedName();
+      if (qualifiedName == null || !qualifiedName.equals(qName)) continue;
+
+      VirtualFile vFile = aClass.getContainingFile().getVirtualFile();
+      if (!hasAcceptablePackage(vFile)) continue;
+
+      result.add(aClass);
+      count++;
+    }
+
+    if (count == 0) return PsiClass.EMPTY_ARRAY;
+    if (count == 1) return new PsiClass[] {aClass};
+
+    ContainerUtil.quickSort(result, new Comparator<PsiClass>() {
+      @Override
+      public int compare(PsiClass o1, PsiClass o2) {
+        return scope.compare(o2.getContainingFile().getVirtualFile(), o1.getContainingFile().getVirtualFile());
+      }
+    });
+
+    return result.toArray(new PsiClass[count]);
+  }
+
+  @Override
+  @Nullable
+  public PsiClass findClass(@NotNull String qName, @NotNull GlobalSearchScope scope) {
+    if (!myUseRepository) {
+      return findClassWithoutRepository(qName);
+    }
+
+    if (!myInitialized) {
+      LOG.error("Access to psi files should be performed only after startup activity");
+      return null;
+    }
+    LOG.assertTrue(!myDisposed);
+
+    if (CommonClassNames.JAVA_LANG_OBJECT.equals(qName)) { // optimization
+      PsiClass cached = myCachedObjectClassMap.get(scope);
+      if (cached == null) {
+        cached = findClassInIndex(qName, scope);
+        if (cached != null) {
+          cached = myCachedObjectClassMap.cacheOrGet(scope, cached);
+        }
+      }
+
+      return cached;
+    }
+
+    return findClassInIndex(qName, scope);
+  }
+
+  @Nullable
+  private PsiClass findClassWithoutRepository(String qName) {
+    PsiClass aClass = myNameToClassMap.get(qName);
+    if (aClass != null) {
+      return aClass;
+    }
+
+    aClass = _findClassWithoutRepository(qName);
+    myNameToClassMap.put(qName, aClass);
+    return aClass;
+  }
+
+  @Nullable
+  private PsiClass _findClassWithoutRepository(String qName) {
+    VirtualFile[] sourcePath = myProjectRootManager.orderEntries().sources().usingCache().getRoots();
+    VirtualFile[] classPath = myProjectRootManager.orderEntries().withoutModuleSourceEntries().classes().usingCache().getRoots();
+
+    int index = 0;
+    while (index < qName.length()) {
+      int index1 = qName.indexOf('.', index);
+      if (index1 < 0) {
+        index1 = qName.length();
+      }
+      String name = qName.substring(index, index1);
+
+      final int sourceType = 0;
+      //final int compiledType = 1;
+
+      for (int type = 0; type < 2; type++) {
+        VirtualFile[] vDirs = type == sourceType ? sourcePath : classPath;
+        for (VirtualFile vDir : vDirs) {
+          if (vDir != null) {
+            VirtualFile vChild = type == sourceType
+                                 ? vDir.findChild(name + JAVA_EXTENSION)
+                                 : vDir.findChild(name + CLASS_EXTENSION);
+            if (vChild != null) {
+              PsiFile file = myFileManager.findFile(vChild);
+              if (file instanceof PsiJavaFile) {
+                PsiClass aClass = findClassByName((PsiJavaFile)file, name);
+                if (aClass != null) {
+                  index = index1 + 1;
+                  while (index < qName.length()) {
+                    index1 = qName.indexOf('.', index);
+                    if (index1 < 0) {
+                      index1 = qName.length();
+                    }
+                    name = qName.substring(index, index1);
+                    aClass = findClassByName(aClass, name);
+                    if (aClass == null) return null;
+                    index = index1 + 1;
+                  }
+                  return aClass;
+                }
+              }
+            }
+          }
+        }
+      }
+
+      boolean existsDir = false;
+      for (int type = 0; type < 2; type++) {
+        VirtualFile[] vDirs = type == sourceType ? sourcePath : classPath;
+        for (int i = 0; i < vDirs.length; i++) {
+          if (vDirs[i] != null) {
+            VirtualFile vDirChild = vDirs[i].findChild(name);
+            if (vDirChild != null) {
+              PsiDirectory dir = myFileManager.findDirectory(vDirChild);
+              if (dir != null) {
+                vDirs[i] = vDirChild;
+                existsDir = true;
+                continue;
+              }
+            }
+            vDirs[i] = null;
+          }
+        }
+      }
+      if (!existsDir) return null;
+      index = index1 + 1;
+    }
+    return null;
+  }
+
+  @Nullable
+  private PsiClass findClassInIndex(String qName, GlobalSearchScope scope) {
+    VirtualFile bestFile = null;
+    PsiClass bestClass = null;
+    final Collection<? extends PsiElement> classes = JavaFullClassNameIndex.getInstance().get(qName.hashCode(), myManager.getProject(), scope);
+
+    for (PsiElement found : classes) {
+      if (notClass(found)) continue;
+
+      PsiClass aClass = (PsiClass)found;
+      PsiFile file = aClass.getContainingFile();
+      if (file == null) {
+        LOG.error("aClass=" + aClass);
+        continue;
+      }
+      final boolean valid = aClass.isValid();
+      VirtualFile vFile = file.getVirtualFile();
+      if (!valid) {
+        LOG.error("Invalid class " + aClass + "; " +
+                  file + (file.isValid() ? "" : " (invalid)") +
+                  "; virtualFile:" + vFile +
+                  (vFile != null && !vFile.isValid() ? " (invalid)" : "") +
+                  "; id=" + (vFile == null ? 0 : ((VirtualFileWithId)vFile).getId()),
+                  new PsiInvalidElementAccessException(aClass));
+        continue;
+      }
+
+      final String qualifiedName = aClass.getQualifiedName();
+      if (qualifiedName == null || !qualifiedName.equals(qName)) continue;
+
+
+      if (!hasAcceptablePackage(vFile)) continue;
+      if (bestFile == null || scope.compare(vFile, bestFile) > 0) {
+        bestFile = vFile;
+        bestClass = aClass;
+      }
+    }
+    return bestClass;
+  }
+
+  private boolean hasAcceptablePackage(final VirtualFile vFile) {
+    if (vFile.getFileType() == JavaClassFileType.INSTANCE) {
+      // See IDEADEV-5626
+      final VirtualFile root = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex().getClassRootForFile(vFile);
+      VirtualFile parent = vFile.getParent();
+      final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myManager.getProject()).getNameHelper();
+      while (parent != null && !Comparing.equal(parent, root)) {
+        if (!nameHelper.isIdentifier(parent.getName())) return false;
+        parent = parent.getParent();
+      }
+    }
+
+    return true;
+  }
+
+  @Override
+  public Collection<String> getNonTrivialPackagePrefixes() {
+    if (myNontrivialPackagePrefixes == null) {
+      Set<String> names = new HashSet<String>();
+      final ProjectRootManager rootManager = myProjectRootManager;
+      final VirtualFile[] sourceRoots = rootManager.getContentSourceRoots();
+      final ProjectFileIndex fileIndex = rootManager.getFileIndex();
+      for (final VirtualFile sourceRoot : sourceRoots) {
+        final String packageName = fileIndex.getPackageNameByDirectory(sourceRoot);
+        if (packageName != null && !packageName.isEmpty()) {
+          names.add(packageName);
+        }
+      }
+      myNontrivialPackagePrefixes = names;
+    }
+    return myNontrivialPackagePrefixes;
+  }
+
+  private static boolean notClass(final PsiElement found) {
+    if (found instanceof PsiClass) return false;
+
+    VirtualFile faultyContainer = PsiUtilCore.getVirtualFile(found);
+    LOG.error("Non class in class list: " + faultyContainer + ". found: " + found);
+    if (faultyContainer != null && faultyContainer.isValid()) {
+      FileBasedIndex.getInstance().requestReindex(faultyContainer);
+    }
+
+    return true;
+  }
+
+  @Nullable
+  private static PsiClass findClassByName(PsiJavaFile scope, String name) {
+    PsiClass[] classes = scope.getClasses();
+    for (PsiClass aClass : classes) {
+      if (name.equals(aClass.getName())) {
+        return aClass;
+      }
+    }
+    return null;
+  }
+
+  @Nullable
+  private static PsiClass findClassByName(PsiClass scope, String name) {
+    PsiClass[] classes = scope.getInnerClasses();
+    for (PsiClass aClass : classes) {
+      if (name.equals(aClass.getName())) {
+        return aClass;
+      }
+    }
+    return null;
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaAnnotationIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaAnnotationIndex.java
new file mode 100644
index 0000000..fbf4508
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaAnnotationIndex.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiAnnotation;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaAnnotationIndex extends StringStubIndexExtension<PsiAnnotation> {
+
+  private static final JavaAnnotationIndex ourInstance = new JavaAnnotationIndex();
+  public static JavaAnnotationIndex getInstance() {
+    return ourInstance;
+  }
+
+  @NotNull
+  @Override
+  public StubIndexKey<String, PsiAnnotation> getKey() {
+    return JavaStubIndexKeys.ANNOTATIONS;
+  }
+
+  @Override
+  public Collection<PsiAnnotation> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(s, project, new JavaSourceFilterScope(scope));
+  }
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaAnonymousClassBaseRefOccurenceIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaAnonymousClassBaseRefOccurenceIndex.java
new file mode 100644
index 0000000..2521522
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaAnonymousClassBaseRefOccurenceIndex.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiAnonymousClass;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaAnonymousClassBaseRefOccurenceIndex extends StringStubIndexExtension<PsiAnonymousClass> {
+
+  private static final JavaAnonymousClassBaseRefOccurenceIndex ourInstance = new JavaAnonymousClassBaseRefOccurenceIndex();
+  public static JavaAnonymousClassBaseRefOccurenceIndex getInstance() {
+    return ourInstance;
+  }
+
+
+  @NotNull
+  @Override
+  public StubIndexKey<String, PsiAnonymousClass> getKey() {
+    return JavaStubIndexKeys.ANONYMOUS_BASEREF;
+  }
+
+  @Override
+  public Collection<PsiAnonymousClass> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(s, project, new JavaSourceFilterScope(scope));
+  }
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaFieldNameIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaFieldNameIndex.java
new file mode 100644
index 0000000..54eb0ed
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaFieldNameIndex.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaFieldNameIndex extends StringStubIndexExtension<PsiField> {
+
+  private static final JavaFieldNameIndex ourInstance = new JavaFieldNameIndex();
+  public static JavaFieldNameIndex getInstance() {
+    return ourInstance;
+  }
+
+  @NotNull
+  @Override
+  public StubIndexKey<String, PsiField> getKey() {
+    return JavaStubIndexKeys.FIELDS;
+  }
+
+  @Override
+  public Collection<PsiField> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(s, project, new JavaSourceFilterScope(scope));
+  }
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaFullClassNameIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaFullClassNameIndex.java
new file mode 100644
index 0000000..40c75f3
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaFullClassNameIndex.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.IntStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaFullClassNameIndex extends IntStubIndexExtension<PsiClass> {
+
+  private static final JavaFullClassNameIndex ourInstance = new JavaFullClassNameIndex();
+  public static JavaFullClassNameIndex getInstance() {
+    return ourInstance;
+  }
+
+  @NotNull
+  @Override
+  public StubIndexKey<Integer, PsiClass> getKey() {
+    return JavaStubIndexKeys.CLASS_FQN;
+  }
+
+  @Override
+  public Collection<PsiClass> get(final Integer integer, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(integer, project, new JavaSourceFilterScope(scope));
+  }
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodNameIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodNameIndex.java
new file mode 100644
index 0000000..a92856f
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodNameIndex.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaMethodNameIndex extends StringStubIndexExtension<PsiMethod> {
+
+  private static final JavaMethodNameIndex ourInstance = new JavaMethodNameIndex();
+  public static JavaMethodNameIndex getInstance() {
+    return ourInstance;
+  }
+
+  @NotNull
+  @Override
+  public StubIndexKey<String, PsiMethod> getKey() {
+    return JavaStubIndexKeys.METHODS;
+  }
+
+  @Override
+  public Collection<PsiMethod> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(s, project, new JavaSourceFilterScope(scope));
+  }
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaShortClassNameIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaShortClassNameIndex.java
new file mode 100644
index 0000000..5cd6454
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaShortClassNameIndex.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaShortClassNameIndex extends StringStubIndexExtension<PsiClass> {
+
+  private static final JavaShortClassNameIndex ourInstance = new JavaShortClassNameIndex();
+  public static JavaShortClassNameIndex getInstance() {
+    return ourInstance;
+  }
+
+  @NotNull
+  @Override
+  public StubIndexKey<String, PsiClass> getKey() {
+    return JavaStubIndexKeys.CLASS_SHORT_NAMES;
+  }
+
+  @Override
+  public Collection<PsiClass> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(s, project, new JavaSourceFilterScope(scope));
+  }
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStaticMemberNameIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStaticMemberNameIndex.java
new file mode 100644
index 0000000..3cb51d9
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStaticMemberNameIndex.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2012 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaStaticMemberNameIndex extends StringStubIndexExtension<PsiMember> {
+
+  private static final JavaStaticMemberNameIndex ourInstance = new JavaStaticMemberNameIndex();
+  public static JavaStaticMemberNameIndex getInstance() {
+    return ourInstance;
+  }
+
+  @NotNull
+  @Override
+  public StubIndexKey<String, PsiMember> getKey() {
+    return JavaStubIndexKeys.JVM_STATIC_MEMBERS_NAMES;
+  }
+
+  public Collection<PsiMember> getStaticMembers(final String name, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(name, project, new JavaSourceFilterScope(scope));
+  }
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStaticMemberTypeIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStaticMemberTypeIndex.java
new file mode 100644
index 0000000..3898c73
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStaticMemberTypeIndex.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2012 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaStaticMemberTypeIndex extends StringStubIndexExtension<PsiMember> {
+
+  private static final JavaStaticMemberTypeIndex ourInstance = new JavaStaticMemberTypeIndex();
+  public static JavaStaticMemberTypeIndex getInstance() {
+    return ourInstance;
+  }
+
+  @NotNull
+  @Override
+  public StubIndexKey<String, PsiMember> getKey() {
+    return JavaStubIndexKeys.JVM_STATIC_MEMBERS_TYPES;
+  }
+
+  public Collection<PsiMember> getStaticMembers(@NotNull final String shortTypeText, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(shortTypeText, project, new JavaSourceFilterScope(scope));
+  }
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaSuperClassNameOccurenceIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaSuperClassNameOccurenceIndex.java
new file mode 100644
index 0000000..a70b7ea
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaSuperClassNameOccurenceIndex.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.java.stubs.index;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiReferenceList;
+import com.intellij.psi.impl.search.JavaSourceFilterScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.stubs.StringStubIndexExtension;
+import com.intellij.psi.stubs.StubIndexKey;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class JavaSuperClassNameOccurenceIndex extends StringStubIndexExtension<PsiReferenceList> {
+  private static final int VERSION = 1;
+
+  private static final JavaSuperClassNameOccurenceIndex ourInstance = new JavaSuperClassNameOccurenceIndex();
+  public static JavaSuperClassNameOccurenceIndex getInstance() {
+    return ourInstance;
+  }
+
+  @NotNull
+  @Override
+  public StubIndexKey<String, PsiReferenceList> getKey() {
+    return JavaStubIndexKeys.SUPER_CLASSES;
+  }
+
+  @Override
+  public Collection<PsiReferenceList> get(final String s, final Project project, @NotNull final GlobalSearchScope scope) {
+    return super.get(s, project, new JavaSourceFilterScope(scope));
+  }
+
+  @Override
+  public int getVersion() {
+    return super.getVersion() + VERSION;
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/AllClassesSearchExecutor.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/AllClassesSearchExecutor.java
new file mode 100644
index 0000000..bae6155
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/AllClassesSearchExecutor.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.search;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressIndicatorProvider;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.JavaRecursiveElementWalkingVisitor;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.searches.AllClassesSearch;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class AllClassesSearchExecutor implements QueryExecutor<PsiClass, AllClassesSearch.SearchParameters> {
+  @Override
+  public boolean execute(@NotNull final AllClassesSearch.SearchParameters queryParameters, @NotNull final Processor<PsiClass> consumer) {
+    SearchScope scope = queryParameters.getScope();
+
+    if (scope instanceof GlobalSearchScope) {
+      return processAllClassesInGlobalScope((GlobalSearchScope)scope, consumer, queryParameters);
+    }
+
+    PsiElement[] scopeRoots = ((LocalSearchScope)scope).getScope();
+    for (final PsiElement scopeRoot : scopeRoots) {
+      if (!processScopeRootForAllClasses(scopeRoot, consumer)) return false;
+    }
+    return true;
+  }
+
+  private static boolean processAllClassesInGlobalScope(final GlobalSearchScope scope, final Processor<PsiClass> processor, AllClassesSearch.SearchParameters parameters) {
+    final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(parameters.getProject());
+
+    final String[] names = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
+      @Override
+      public String[] compute() {
+        return cache.getAllClassNames();
+      }
+    });
+
+    final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
+    if (indicator != null) {
+      indicator.checkCanceled();
+    }
+
+    List<String> sorted = new ArrayList<String>(names.length);
+    for (int i = 0; i < names.length; i++) {
+      String name = names[i];
+      if (parameters.nameMatches(name)) {
+        sorted.add(name);
+      }
+      if (indicator != null && i % 512 == 0) {
+        indicator.checkCanceled();
+      }
+    }
+
+    if (indicator != null) {
+      indicator.checkCanceled();
+    }
+
+    Collections.sort(sorted, new Comparator<String>() {
+      @Override
+      public int compare(final String o1, final String o2) {
+        return o1.compareToIgnoreCase(o2);
+      }
+    });
+
+    for (final String name : sorted) {
+      ProgressIndicatorProvider.checkCanceled();
+      final PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
+        @Override
+        public PsiClass[] compute() {
+          return cache.getClassesByName(name, scope);
+        }
+      });
+      for (PsiClass psiClass : classes) {
+        ProgressIndicatorProvider.checkCanceled();
+        if (!processor.process(psiClass)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  private static boolean processScopeRootForAllClasses(PsiElement scopeRoot, final Processor<PsiClass> processor) {
+    if (scopeRoot == null) return true;
+    final boolean[] stopped = new boolean[]{false};
+
+    scopeRoot.accept(new JavaRecursiveElementWalkingVisitor() {
+      @Override
+      public void visitElement(PsiElement element) {
+        if (!stopped[0]) {
+          super.visitElement(element);
+        }
+      }
+
+      @Override public void visitClass(PsiClass aClass) {
+        stopped[0] = !processor.process(aClass);
+        super.visitClass(aClass);
+      }
+    });
+
+    return !stopped[0];
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedElementsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedElementsSearcher.java
new file mode 100644
index 0000000..a4aa952
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/AnnotatedElementsSearcher.java
@@ -0,0 +1,134 @@
+package com.intellij.psi.impl.search;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiManagerImpl;
+import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.searches.AnnotatedElementsSearch;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import com.intellij.util.indexing.FileBasedIndex;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author max
+ */
+public class AnnotatedElementsSearcher implements QueryExecutor<PsiModifierListOwner, AnnotatedElementsSearch.Parameters> {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.AnnotatedMembersSearcher");
+
+  @Override
+  public boolean execute(@NotNull final AnnotatedElementsSearch.Parameters p, @NotNull final Processor<PsiModifierListOwner> consumer) {
+    final PsiClass annClass = p.getAnnotationClass();
+    assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search";
+
+    final String annotationFQN = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+      @Override
+      public String compute() {
+        return annClass.getQualifiedName();
+      }
+    });
+    assert annotationFQN != null;
+
+    final PsiManagerImpl psiManager = (PsiManagerImpl)annClass.getManager();
+
+    final SearchScope useScope = p.getScope();
+    Class<? extends PsiModifierListOwner>[] types = p.getTypes();
+
+    for (PsiElement elt : getAnnotationCandidates(annClass, useScope)) {
+      if (notAnnotation(elt)) continue;
+
+      final PsiAnnotation ann = (PsiAnnotation)elt;
+      final PsiJavaCodeReferenceElement ref = ApplicationManager.getApplication().runReadAction(new Computable<PsiJavaCodeReferenceElement>() {
+        @Override
+        public PsiJavaCodeReferenceElement compute() {
+          return ann.getNameReferenceElement();
+        }
+      });
+      if (ref == null) continue;
+
+      PsiElement parent = ann.getParent();
+      if (!(parent instanceof PsiModifierList)) continue; // Can be a PsiNameValuePair, if annotation is used to annotate annotation parameters
+
+      final PsiElement owner = parent.getParent();
+
+      if (!isInstanceof(owner, types)) continue;
+
+      final PsiModifierListOwner candidate = (PsiModifierListOwner)owner;
+
+      if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+        @Override
+        public Boolean compute() {
+          if (!candidate.isValid()) {
+            return false;
+          }
+          if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) {
+            return false;
+          }
+          return !(useScope instanceof GlobalSearchScope) ||
+                 ((GlobalSearchScope)useScope).contains(candidate.getContainingFile().getVirtualFile());
+        }
+      })) {
+        continue;
+      }
+
+      if (!consumer.process(candidate)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  private static Collection<? extends PsiElement> getAnnotationCandidates(final PsiClass annClass, final SearchScope useScope) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<Collection<? extends PsiElement>>() {
+      @Override
+      public Collection<? extends PsiElement> compute() {
+        if (useScope instanceof GlobalSearchScope) {
+          return JavaAnnotationIndex.getInstance().get(annClass.getName(), annClass.getProject(), (GlobalSearchScope)useScope);
+        }
+        final List<PsiElement> result = new ArrayList<PsiElement>();
+        for (PsiElement element : ((LocalSearchScope)useScope).getScope()) {
+          element.accept(new PsiRecursiveElementWalkingVisitor() {
+            @Override
+            public void visitElement(PsiElement element) {
+              if (element instanceof PsiAnnotation) {
+                result.add(element);
+              }
+            }
+          });
+        }
+        return result;
+      }
+    });
+  }
+
+  public static boolean isInstanceof(PsiElement owner, Class<? extends PsiModifierListOwner>[] types) {
+    for (Class<? extends PsiModifierListOwner> type : types) {
+        if(type.isInstance(owner)) return true;
+    }
+    return false;
+  }
+
+  private static boolean notAnnotation(final PsiElement found) {
+    if (found instanceof PsiAnnotation) return false;
+
+    VirtualFile faultyContainer = PsiUtilCore.getVirtualFile(found);
+    LOG.error("Non annotation in annotations list: " + faultyContainer+"; element:"+found);
+    if (faultyContainer != null && faultyContainer.isValid()) {
+      FileBasedIndex.getInstance().requestReindex(faultyContainer);
+    }
+
+    return true;
+  }
+}
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
new file mode 100644
index 0000000..2aad613
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
@@ -0,0 +1,193 @@
+package com.intellij.psi.impl.search;
+
+import com.intellij.openapi.util.TextRange;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.light.LightMemberReference;
+import com.intellij.psi.search.PsiSearchScopeUtil;
+import com.intellij.psi.search.SearchRequestCollector;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.Processor;
+
+/**
+ * @author max
+ */
+public class ConstructorReferencesSearchHelper {
+  private final PsiManager myManager;
+
+  public ConstructorReferencesSearchHelper(final PsiManager manager) {
+    myManager = manager;
+  }
+
+  public boolean processConstructorReferences(final Processor<PsiReference> processor,
+                                              final PsiMethod constructor,
+                                              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;
+            }
+          }
+        }
+      }
+    }
+
+    // search usages like "new XXX(..)"
+    PairProcessor<PsiReference, SearchRequestCollector> processor1 = new PairProcessor<PsiReference, SearchRequestCollector>() {
+      @Override
+      public boolean process(PsiReference reference, SearchRequestCollector collector) {
+        PsiElement parent = reference.getElement().getParent();
+        if (parent instanceof PsiAnonymousClass) {
+          parent = parent.getParent();
+        }
+        if (parent instanceof PsiNewExpression) {
+          PsiMethod constructor1 = ((PsiNewExpression)parent).resolveConstructor();
+          if (constructor1 != null) {
+            if (isStrictSignatureSearch) {
+              if (myManager.areElementsEquivalent(constructor, constructor1)) {
+                return processor.process(reference);
+              }
+            }
+            else {
+              if (myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass())) {
+                return processor.process(reference);
+              }
+            }
+          }
+        }
+        return true;
+      }
+    };
+
+    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;
+        }
+      });
+    }
+
+    final boolean constructorCanBeCalledImplicitly = constructor.getParameterList().getParametersCount() == 0;
+    // search usages like "this(..)"
+    if (!processSuperOrThis(processor, aClass, constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
+                            PsiKeyword.THIS)) {
+      return false;
+    }
+
+    // search usages like "super(..)"
+    Processor<PsiClass> processor2 = new Processor<PsiClass>() {
+      @Override
+      public boolean process(PsiClass inheritor) {
+        return processSuperOrThis(processor, (PsiClass)inheritor.getNavigationElement(), constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
+                                  PsiKeyword.SUPER);
+      }
+    };
+
+    return ClassInheritorsSearch.search(aClass, 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) {
+    PsiMethod[] constructors = inheritor.getConstructors();
+    if (constructors.length == 0 && constructorCanBeCalledImplicitly) {
+      processImplicitConstructorCall(inheritor, processor, constructor, inheritor);
+    }
+    for (PsiMethod method : constructors) {
+      PsiCodeBlock body = method.getBody();
+      if (body == null) {
+        continue;
+      }
+      PsiStatement[] statements = body.getStatements();
+      if (statements.length != 0) {
+        PsiStatement statement = statements[0];
+        if (statement instanceof PsiExpressionStatement) {
+          PsiExpression expr = ((PsiExpressionStatement)statement).getExpression();
+          if (expr instanceof PsiMethodCallExpression) {
+            PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression();
+            if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) {
+              if (refExpr.getText().equals(superOrThisKeyword)) {
+                PsiElement referencedElement = refExpr.resolve();
+                if (referencedElement instanceof PsiMethod) {
+                  PsiMethod constructor1 = (PsiMethod)referencedElement;
+                  boolean match = isStrictSignatureSearch
+                                  ? myManager.areElementsEquivalent(constructor1, constructor)
+                                  : myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass());
+                  if (match && !processor.process(refExpr)) return false;
+                }
+                //as long as we've encountered super/this keyword, no implicit ctr calls are possible here
+                continue;
+              }
+            }
+          }
+        }
+      }
+      if (constructorCanBeCalledImplicitly) {
+        processImplicitConstructorCall(method, processor, constructor, inheritor);
+      }
+    }
+
+    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();
+        }
+      });
+    }
+  }
+}
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
new file mode 100644
index 0000000..933a748
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
@@ -0,0 +1,27 @@
+package com.intellij.psi.impl.search;
+
+import com.intellij.openapi.application.QueryExecutorBase;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @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());
+    }
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java
new file mode 100644
index 0000000..d855ab6
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaAllOverridingMethodsSearcher.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2009 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.psi.impl.search;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.*;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.searches.AllOverridingMethodsSearch;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.psi.util.MethodSignature;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author ven
+ */
+public class JavaAllOverridingMethodsSearcher implements QueryExecutor<Pair<PsiMethod, PsiMethod>, AllOverridingMethodsSearch.SearchParameters> {
+  @Override
+  public boolean execute(@NotNull final AllOverridingMethodsSearch.SearchParameters p, @NotNull final Processor<Pair<PsiMethod, PsiMethod>> consumer) {
+    final PsiClass psiClass = p.getPsiClass();
+
+    PsiMethod[] methodsArray = psiClass.getMethods();
+    final List<PsiMethod> methods = new ArrayList<PsiMethod>(methodsArray.length);
+    for (PsiMethod method : methodsArray) {
+      if (PsiUtil.canBeOverriden(method)) methods.add(method);
+    }
+
+    final SearchScope scope = p.getScope();
+
+    Processor<PsiClass> inheritorsProcessor = new Processor<PsiClass>() {
+      @Override
+      public boolean process(PsiClass inheritor) {
+        //could be null if not java inheritor, TODO only JavaClassInheritors are needed
+        PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(psiClass, inheritor, PsiSubstitutor.EMPTY);
+        if (substitutor == null) return true;
+
+        for (PsiMethod method : methods) {
+          if (method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) &&
+              !JavaPsiFacade.getInstance(inheritor.getProject()).arePackagesTheSame(psiClass, inheritor)) continue;
+          
+          MethodSignature signature = method.getSignature(substitutor);
+          PsiMethod inInheritor = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false);
+          if (inInheritor == null || inInheritor.hasModifierProperty(PsiModifier.STATIC)) {
+            if (psiClass.isInterface() && !inheritor.isInterface()) {  //check for sibling implementation
+              final PsiClass superClass = inheritor.getSuperClass();
+              if (superClass != null && !superClass.isInheritor(psiClass, true)) {
+                inInheritor = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true);
+                if (inInheritor != null && !inInheritor.hasModifierProperty(PsiModifier.STATIC)) {
+                  if (!consumer.process(new Pair<PsiMethod, PsiMethod>(method, inInheritor))) return false;
+                }
+              }
+            }
+            continue;
+          }
+          if (!consumer.process(new Pair<PsiMethod, PsiMethod>(method, inInheritor))) return false;
+        }
+
+        return true;
+      }
+    };
+
+    return ClassInheritorsSearch.search(psiClass, scope, true).forEach(inheritorsProcessor);
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java
new file mode 100644
index 0000000..fb01267
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2000-2012 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.psi.impl.search;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.progress.ProgressIndicatorProvider;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiManagerImpl;
+import com.intellij.psi.impl.java.stubs.index.JavaAnonymousClassBaseRefOccurenceIndex;
+import com.intellij.psi.impl.java.stubs.index.JavaSuperClassNameOccurenceIndex;
+import com.intellij.psi.search.EverythingGlobalScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.searches.AllClassesSearch;
+import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author max
+ */
+public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, DirectClassInheritorsSearch.SearchParameters> {
+  @Override
+  public boolean execute(@NotNull final DirectClassInheritorsSearch.SearchParameters p, @NotNull final Processor<PsiClass> consumer) {
+    final PsiClass aClass = p.getClassToProcess();
+    final PsiManagerImpl psiManager = (PsiManagerImpl)aClass.getManager();
+
+    final SearchScope useScope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
+      @Override
+      public SearchScope compute() {
+        return aClass.getUseScope();
+      }
+    });
+
+    final String qualifiedName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+      @Override
+      public String compute() {
+        return aClass.getQualifiedName();
+      }
+    });
+
+    if (CommonClassNames.JAVA_LANG_OBJECT.equals(qualifiedName)) {
+      //[pasynkov]: WTF?
+      //final SearchScope scope = useScope.intersectWith(GlobalSearchScope.notScope(GlobalSearchScope.getScopeRestrictedByFileTypes(
+      //    GlobalSearchScope.allScope(psiManager.getProject()), StdFileTypes.JSP, StdFileTypes.JSPX)));
+      final SearchScope scope = useScope;
+
+      return AllClassesSearch.search(scope, aClass.getProject()).forEach(new Processor<PsiClass>() {
+        @Override
+        public boolean process(final PsiClass psiClass) {
+          if (psiClass.isInterface()) {
+            return consumer.process(psiClass);
+          }
+          final PsiClass superClass = psiClass.getSuperClass();
+          if (superClass != null && CommonClassNames.JAVA_LANG_OBJECT.equals(ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+            public String compute() {
+              return superClass.getQualifiedName();
+            }
+          }))) {
+            return consumer.process(psiClass);
+          }
+          return true;
+        }
+      });
+    }
+
+    final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : new EverythingGlobalScope(psiManager.getProject());
+    final String searchKey = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+      @Override
+      public String compute() {
+        return aClass.getName();
+      }
+    });
+    if (StringUtil.isEmpty(searchKey)) {
+      return true;
+    }
+
+    Collection<PsiReferenceList> candidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiReferenceList>>() {
+      @Override
+      public Collection<PsiReferenceList> compute() {
+        return JavaSuperClassNameOccurenceIndex.getInstance().get(searchKey, psiManager.getProject(), scope);
+      }
+    });
+
+    Map<String, List<PsiClass>> classes = new HashMap<String, List<PsiClass>>();
+
+    for (PsiReferenceList referenceList : candidates) {
+      ProgressIndicatorProvider.checkCanceled();
+      final PsiClass candidate = (PsiClass)referenceList.getParent();
+      if (!checkInheritance(p, aClass, candidate)) continue;
+
+      String fqn = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+        @Override
+        public String compute() {
+          return candidate.getQualifiedName();
+        }
+      });
+      List<PsiClass> list = classes.get(fqn);
+      if (list == null) {
+        list = new ArrayList<PsiClass>();
+        classes.put(fqn, list);
+      }
+      list.add(candidate);
+    }
+
+    for (List<PsiClass> sameNamedClasses : classes.values()) {
+      if (!processSameNamedClasses(consumer, aClass, sameNamedClasses)) return false;
+    }
+
+    if (p.includeAnonymous()) {
+      Collection<PsiAnonymousClass> anonymousCandidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiAnonymousClass>>() {
+        @Override
+        public Collection<PsiAnonymousClass> compute() {
+          return JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(searchKey, psiManager.getProject(), scope);
+        }
+      });
+
+      for (PsiAnonymousClass candidate : anonymousCandidates) {
+        ProgressIndicatorProvider.checkCanceled();
+        if (!checkInheritance(p, aClass, candidate)) continue;
+
+        if (!consumer.process(candidate)) return false;
+      }
+
+      if (aClass.isEnum()) {
+        // abstract enum can be subclassed in the body
+        PsiField[] fields = ApplicationManager.getApplication().runReadAction(new Computable<PsiField[]>() {
+          @Override
+          public PsiField[] compute() {
+            return aClass.getFields();
+          }
+        });
+        for (final PsiField field : fields) {
+          if (field instanceof PsiEnumConstant) {
+            PsiEnumConstantInitializer initializingClass =
+              ApplicationManager.getApplication().runReadAction(new Computable<PsiEnumConstantInitializer>() {
+                @Override
+                public PsiEnumConstantInitializer compute() {
+                  return ((PsiEnumConstant)field).getInitializingClass();
+                }
+              });
+            if (initializingClass != null) {
+              if (!consumer.process(initializingClass)) return false;
+            }
+          }
+        }
+      }
+    }
+
+    return true;
+  }
+
+  private static boolean checkInheritance(final DirectClassInheritorsSearch.SearchParameters p, final PsiClass aClass, final PsiClass candidate) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      @Override
+      public Boolean compute() {
+        return !p.isCheckInheritance() || candidate.isInheritor(aClass, false);
+      }
+    });
+  }
+
+  private static boolean processSameNamedClasses(Processor<PsiClass> consumer, PsiClass aClass, List<PsiClass> sameNamedClasses) {
+    // if there is a class from the same jar, prefer it
+    boolean sameJarClassFound = false;
+
+    VirtualFile jarFile = PsiUtil.getJarFile(aClass);
+    if (jarFile != null) {
+      for (PsiClass sameNamedClass : sameNamedClasses) {
+        boolean fromSameJar = Comparing.equal(PsiUtil.getJarFile(sameNamedClass), jarFile);
+        if (fromSameJar) {
+          sameJarClassFound = true;
+          if (!consumer.process(sameNamedClass)) return false;
+        }
+      }
+    }
+
+    return sameJarClassFound || ContainerUtil.process(sameNamedClasses, consumer);
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java
new file mode 100644
index 0000000..9ccebc2
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java
@@ -0,0 +1,80 @@
+package com.intellij.psi.impl.search;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.*;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.psi.util.MethodSignature;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author max
+ */
+public class JavaOverridingMethodsSearcher implements QueryExecutor<PsiMethod, OverridingMethodsSearch.SearchParameters> {
+  @Override
+  public boolean execute(@NotNull final OverridingMethodsSearch.SearchParameters p, @NotNull final Processor<PsiMethod> consumer) {
+    final PsiMethod method = p.getMethod();
+    final SearchScope scope = p.getScope();
+
+    final PsiClass parentClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+      @Nullable
+      @Override
+      public PsiClass compute() {
+        return method.getContainingClass();
+      }
+    });
+    assert parentClass != null;
+    Processor<PsiClass> inheritorsProcessor = new Processor<PsiClass>() {
+      @Override
+      public boolean process(final PsiClass inheritor) {
+        PsiMethod found = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod>() {
+          @Override
+          @Nullable
+          public PsiMethod compute() {
+            return findOverridingMethod(inheritor, parentClass, method);
+          }
+        });
+        return found == null || consumer.process(found) && p.isCheckDeep();
+      }
+    };
+
+    return ClassInheritorsSearch.search(parentClass, scope, true).forEach(inheritorsProcessor);
+  }
+
+  @Nullable
+  private static PsiMethod findOverridingMethod(PsiClass inheritor, @NotNull PsiClass parentClass, PsiMethod method) {
+    PsiSubstitutor substitutor = inheritor.isInheritor(parentClass, true) ?
+                                 TypeConversionUtil.getSuperClassSubstitutor(parentClass, inheritor, PsiSubstitutor.EMPTY) :
+                                 PsiSubstitutor.EMPTY;
+    MethodSignature signature = method.getSignature(substitutor);
+    PsiMethod found = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false);
+    if (found != null && isAcceptable(found, method)) {
+      return found;
+    }
+
+    if (parentClass.isInterface() && !inheritor.isInterface()) {  //check for sibling implementation
+      final PsiClass superClass = inheritor.getSuperClass();
+      if (superClass != null && !superClass.isInheritor(parentClass, true)) {
+        PsiMethod derived = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true);
+        if (derived != null && isAcceptable(derived, method)) {
+          return derived;
+        }
+      }
+    }
+    return null;
+  }
+
+  private static boolean isAcceptable(final PsiMethod found, final PsiMethod method) {
+    return !found.hasModifierProperty(PsiModifier.STATIC) &&
+           (!method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) ||
+            JavaPsiFacade.getInstance(found.getProject())
+              .arePackagesTheSame(method.getContainingClass(), found.getContainingClass()));
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java
new file mode 100644
index 0000000..086a20e
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaSourceFilterScope.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.impl.search;
+
+import com.intellij.ide.highlighter.JavaClassFileType;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.search.DelegatingGlobalSearchScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
+
+public class JavaSourceFilterScope extends DelegatingGlobalSearchScope {
+  private final ProjectFileIndex myIndex;
+
+  public JavaSourceFilterScope(@NotNull final GlobalSearchScope delegate) {
+    super(delegate);
+    myIndex = ProjectRootManager.getInstance(getProject()).getFileIndex();
+  }
+
+  @Override
+  public boolean contains(final VirtualFile file) {
+    if (!super.contains(file)) {
+      return false;
+    }
+
+    if (JavaClassFileType.INSTANCE == file.getFileType()) {
+      return myIndex.isInLibraryClasses(file);
+    }
+
+    return myIndex.isInSourceContent(file);
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java
new file mode 100644
index 0000000..2c9117b
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodDeepestSuperSearcher.java
@@ -0,0 +1,41 @@
+package com.intellij.psi.impl.search;
+
+import com.intellij.psi.PsiMethod;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author peter
+ */
+public class MethodDeepestSuperSearcher implements QueryExecutor<PsiMethod, PsiMethod> {
+  @Override
+  public boolean execute(@NotNull PsiMethod method, @NotNull Processor<PsiMethod> consumer) {
+    final Set<PsiMethod> methods = new THashSet<PsiMethod>();
+    methods.add(method);
+    return findDeepestSuperOrSelfSignature(method, methods, null, consumer);
+  }
+
+  private static boolean findDeepestSuperOrSelfSignature(PsiMethod method,
+                                                         Set<PsiMethod> set,
+                                                         Set<PsiMethod> guard,
+                                                         Processor<PsiMethod> processor) {
+    if (guard != null && !guard.add(method)) return true;
+    PsiMethod[] supers = method.findSuperMethods();
+
+    if (supers.length == 0 && set.add(method) && !processor.process(method)) {
+      return false;
+    }
+    for (PsiMethod superMethod : supers) {
+      if (guard == null) {
+        guard = new THashSet<PsiMethod>();
+        guard.add(method);
+      }
+      if (!findDeepestSuperOrSelfSignature(superMethod, set, guard, processor)) return false;
+    }
+    return true;
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java
new file mode 100644
index 0000000..d65e80e
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodSuperSearcher.java
@@ -0,0 +1,71 @@
+package com.intellij.psi.impl.search;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.SuperMethodsSearch;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author ven
+ */
+public class MethodSuperSearcher implements QueryExecutor<MethodSignatureBackedByPsiMethod, SuperMethodsSearch.SearchParameters> {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.MethodSuperSearcher");
+
+  @Override
+  public boolean execute(@NotNull final SuperMethodsSearch.SearchParameters queryParameters, @NotNull final Processor<MethodSignatureBackedByPsiMethod> consumer) {
+    final PsiClass parentClass = queryParameters.getPsiClass();
+    final PsiMethod method = queryParameters.getMethod();
+    HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
+
+    final boolean checkBases = queryParameters.isCheckBases();
+    final boolean allowStaticMethod = queryParameters.isAllowStaticMethod();
+    final List<HierarchicalMethodSignature> supers = signature.getSuperSignatures();
+    for (HierarchicalMethodSignature superSignature : supers) {
+      if (MethodSignatureUtil.isSubsignature(superSignature, signature)) {
+        if (!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) return false;
+      }
+    }
+
+    return true;
+  }
+
+  private static boolean addSuperMethods(final HierarchicalMethodSignature signature,
+                                         final PsiMethod method,
+                                         final PsiClass parentClass,
+                                         final boolean allowStaticMethod,
+                                         final boolean checkBases,
+                                         final Processor<MethodSignatureBackedByPsiMethod> consumer) {
+    PsiMethod signatureMethod = signature.getMethod();
+    PsiClass hisClass = signatureMethod.getContainingClass();
+    if (parentClass == null || InheritanceUtil.isInheritorOrSelf(parentClass, hisClass, true)) {
+      if (isAcceptable(signatureMethod, method, allowStaticMethod)) {
+        if (parentClass != null && !parentClass.equals(hisClass) && !checkBases) {
+          return true;
+        }
+        LOG.assertTrue(signatureMethod != method, method); // method != method.getsuper()
+        return consumer.process(signature); //no need to check super classes
+      }
+    }
+    for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) {
+      if (MethodSignatureUtil.isSubsignature(superSignature, signature)) {
+        addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer);
+      }
+    }
+
+    return true;
+  }
+
+  private static boolean isAcceptable(final PsiMethod superMethod, final PsiMethod method, final boolean allowStaticMethod) {
+    boolean hisStatic = superMethod.hasModifierProperty(PsiModifier.STATIC);
+    return hisStatic == method.hasModifierProperty(PsiModifier.STATIC) &&
+           (allowStaticMethod || !hisStatic) &&
+           JavaPsiFacade.getInstance(method.getProject()).getResolveHelper().isAccessible(superMethod, method, null);
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodTextOccurrenceProcessor.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodTextOccurrenceProcessor.java
new file mode 100644
index 0000000..5e6a35a
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodTextOccurrenceProcessor.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2000-2009 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.psi.impl.search;
+
+import com.intellij.psi.*;
+import com.intellij.psi.search.RequestResultProcessor;
+import com.intellij.psi.util.MethodSignature;
+import com.intellij.psi.util.MethodSignatureUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+
+/**
+ * @author peter
+ */
+public final class MethodTextOccurrenceProcessor extends RequestResultProcessor {
+  private static final PsiReferenceService ourReferenceService = PsiReferenceService.getService();
+  private final PsiMethod[] myMethods;
+  private final PsiClass myContainingClass;
+  private final boolean myStrictSignatureSearch;
+
+  public MethodTextOccurrenceProcessor(@NotNull final PsiClass aClass, final boolean strictSignatureSearch, final PsiMethod... methods) {
+    super(strictSignatureSearch, Arrays.asList(methods));
+    myMethods = methods;
+    myContainingClass = aClass;
+    myStrictSignatureSearch = strictSignatureSearch;
+  }
+
+  @Override
+  public boolean processTextOccurrence(@NotNull PsiElement element, int offsetInElement, @NotNull final Processor<PsiReference> consumer) {
+    for (PsiReference ref : ourReferenceService.getReferences(element, new PsiReferenceService.Hints(myMethods[0], offsetInElement))) {
+      if (ReferenceRange.containsOffsetInElement(ref, offsetInElement) && !processReference(consumer, ref)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+  private boolean processReference(Processor<PsiReference> consumer, PsiReference ref) {
+    for (PsiMethod method : myMethods) {
+      if (!method.isValid()) {
+        continue;
+      }
+
+      if (ref instanceof ResolvingHint && !((ResolvingHint)ref).canResolveTo(PsiMethod.class)) {
+        return true;
+      }
+      if (ref.isReferenceTo(method)) {
+        return consumer.process(ref);
+      }
+      PsiElement refElement = ref.resolve();
+
+      if (refElement instanceof PsiMethod) {
+        PsiMethod refMethod = (PsiMethod)refElement;
+        PsiClass refMethodClass = refMethod.getContainingClass();
+        if (refMethodClass == null) continue;
+
+        if (!refMethod.hasModifierProperty(PsiModifier.STATIC)) {
+          PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(myContainingClass, refMethodClass, PsiSubstitutor.EMPTY);
+          if (substitutor != null) {
+            MethodSignature superSignature = method.getSignature(substitutor);
+            MethodSignature refSignature = refMethod.getSignature(PsiSubstitutor.EMPTY);
+
+            if (MethodSignatureUtil.isSubsignature(superSignature, refSignature)) {
+              if (!consumer.process(ref)) return false;
+            }
+          }
+        }
+
+        if (!myStrictSignatureSearch) {
+          PsiManager manager = method.getManager();
+          if (manager.areElementsEquivalent(refMethodClass, myContainingClass)) {
+            if (!consumer.process(ref)) return false;
+          }
+        }
+      }
+    }
+
+    return true;
+  }
+
+}
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
new file mode 100644
index 0000000..49bd3f3
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
@@ -0,0 +1,82 @@
+package com.intellij.psi.impl.search;
+
+import com.intellij.openapi.application.QueryExecutorBase;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.search.SearchRequestCollector;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.UsageSearchContext;
+import com.intellij.psi.search.searches.MethodReferencesSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @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 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 (PsiUtil.isAnnotationMethod(method) &&
+        PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) &&
+        method.getParameterList().getParametersCount() == 0) {
+      ReferencesSearch.search(aClass, p.getScope()).forEach(PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer( consumer));
+    }
+
+    boolean needStrictSignatureSearch = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
+                                                             || aClass.hasModifierProperty(PsiModifier.FINAL)
+                                                             || method.hasModifierProperty(PsiModifier.STATIC)
+                                                             || method.hasModifierProperty(PsiModifier.FINAL)
+                                                             || method.hasModifierProperty(PsiModifier.PRIVATE));
+    if (needStrictSignatureSearch) {
+      ReferencesSearch.searchOptimized(method, searchScope, false, collector, consumer);
+      return;
+    }
+
+    final String textToSearch = method.getName();
+    if (StringUtil.isEmpty(textToSearch)) {
+      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());
+    }
+
+    final SearchScope restrictedByAccess = 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));
+
+    SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccess, collector);
+
+  }
+
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/PsiAnnotationMethodReferencesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/PsiAnnotationMethodReferencesSearcher.java
new file mode 100644
index 0000000..50f10ca
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/PsiAnnotationMethodReferencesSearcher.java
@@ -0,0 +1,48 @@
+package com.intellij.psi.impl.search;
+
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.Query;
+import com.intellij.util.QueryExecutor;
+import com.intellij.openapi.application.ReadActionProcessor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author max
+ */
+public class PsiAnnotationMethodReferencesSearcher implements QueryExecutor<PsiReference, ReferencesSearch.SearchParameters> {
+  @Override
+  public boolean execute(@NotNull final ReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
+    final PsiElement refElement = p.getElementToSearch();
+    if (PsiUtil.isAnnotationMethod(refElement)) {
+      PsiMethod method = (PsiMethod)refElement;
+      if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) && method.getParameterList().getParametersCount() == 0) {
+        final Query<PsiReference> query = ReferencesSearch.search(method.getContainingClass(), p.getScope(), p.isIgnoreAccessScope());
+        return query.forEach(createImplicitDefaultAnnotationMethodConsumer(consumer));
+      }
+    }
+
+    return true;
+  }
+
+  public static ReadActionProcessor<PsiReference> createImplicitDefaultAnnotationMethodConsumer(final Processor<PsiReference> consumer) {
+    return new ReadActionProcessor<PsiReference>() {
+      @Override
+      public boolean processInReadAction(final PsiReference reference) {
+        if (reference instanceof PsiJavaCodeReferenceElement) {
+          PsiJavaCodeReferenceElement javaReference = (PsiJavaCodeReferenceElement)reference;
+          if (javaReference.getParent() instanceof PsiAnnotation) {
+            PsiNameValuePair[] members = ((PsiAnnotation)javaReference.getParent()).getParameterList().getAttributes();
+            if (members.length == 1 && members[0].getNameIdentifier() == null) {
+              PsiReference t = members[0].getReference();
+              if (t != null && !consumer.process(t)) return false;
+            }
+          }
+        }
+        return true;
+      }
+    };
+  }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
new file mode 100644
index 0000000..1687068
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2009 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.psi.impl.search;
+
+import com.intellij.openapi.application.QueryExecutorBase;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchRequestCollector;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.UsageSearchContext;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PropertyUtil;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ven
+ */
+public class SimpleAccessorReferenceSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
+
+  public SimpleAccessorReferenceSearcher() {
+    super(true);
+  }
+
+  @Override
+  public void processQuery(@NotNull ReferencesSearch.SearchParameters queryParameters, @NotNull Processor<PsiReference> consumer) {
+    PsiElement refElement = queryParameters.getElementToSearch();
+    if (!(refElement instanceof PsiMethod)) return;
+
+    addPropertyAccessUsages((PsiMethod)refElement, queryParameters.getEffectiveSearchScope(), queryParameters.getOptimizer());
+  }
+
+  static void addPropertyAccessUsages(PsiMethod method, SearchScope scope, SearchRequestCollector collector) {
+    final String propertyName = PropertyUtil.getPropertyName(method);
+    if (StringUtil.isNotEmpty(propertyName)) {
+      SearchScope additional = GlobalSearchScope.EMPTY_SCOPE;
+      for (CustomPropertyScopeProvider provider : Extensions.getExtensions(CustomPropertyScopeProvider.EP_NAME)) {
+        additional = additional.union(provider.getScope(method.getProject()));
+      }
+      assert propertyName != null;
+      final SearchScope propScope = scope.intersectWith(method.getUseScope()).intersectWith(additional);
+      collector.searchWord(propertyName, propScope, UsageSearchContext.IN_FOREIGN_LANGUAGES, true, method);
+    }
+  }
+}