find usages tests -> community
authorpeter <peter@jetbrains.com>
Fri, 27 Jan 2012 22:24:53 +0000 (23:24 +0100)
committerpeter <peter@jetbrains.com>
Fri, 27 Jan 2012 22:24:53 +0000 (23:24 +0100)
33 files changed:
java/java-tests/testData/psi/search/findUsages/fieldInJavadoc/A.java [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages/implicitConstructorUsage/A.java [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages/protectedMethodInPackageLocalClass/bar/Bar.java [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages/protectedMethodInPackageLocalClass/foo/Foo.java [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages/xml/Test.xml [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages/xml/com/Foo.java [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages15/enumConstructor/pack/OurEnum.java [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages15/findRawOverriddenUsages/pack/RawOverridden.java [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages15/genericMethodOverriderUsages/pack/GenericClass.java [new file with mode: 0644]
java/java-tests/testData/psi/search/findUsages15/genericOverride/pack/Gen.java [new file with mode: 0644]
java/java-tests/testData/psi/search/inheritors/noScanJdk/empty.txt [new file with mode: 0644]
java/java-tests/testData/psi/search/inheritors/sameNamedClasses/x/Test.java [new file with mode: 0644]
java/java-tests/testData/psi/search/inheritors/scope/Derived2.java [new file with mode: 0644]
java/java-tests/testData/psi/search/inheritors/scope/pack1/Base.java [new file with mode: 0644]
java/java-tests/testData/psi/search/inheritors/scope/pack1/Derived1.java [new file with mode: 0644]
java/java-tests/testData/psi/search/inheritors/scope/pack1/Derived3.java [new file with mode: 0644]
java/java-tests/testData/psi/search/plainTextUsages/simple/Test.txt [new file with mode: 0644]
java/java-tests/testData/psi/search/plainTextUsages/xmlOutOfScope/com/Foo.java [new file with mode: 0644]
java/java-tests/testData/psi/search/plainTextUsages/xmlOutOfScope/resources/Test.xml [new file with mode: 0644]
java/java-tests/testData/psi/search/searchInLibs/lib/classes/LibraryClass1.class [new file with mode: 0644]
java/java-tests/testData/psi/search/searchInLibs/lib/classes/LibraryClass2.class [new file with mode: 0644]
java/java-tests/testData/psi/search/searchInLibs/lib/src/LibraryClass1.java [new file with mode: 0644]
java/java-tests/testData/psi/search/searchInLibs/lib/src/LibraryClass2.java [new file with mode: 0644]
java/java-tests/testData/psi/search/searchInLibs/project/ProjectClass.java [new file with mode: 0644]
java/java-tests/testData/psi/search/searchInLibs/project/src2/ProjectClass2.java [new file with mode: 0644]
java/java-tests/testData/psi/search/updateCache/1.java [new file with mode: 0644]
java/java-tests/testData/psi/search/updateCache/aDir/2.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/psi/search/FindUsages15Test.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/psi/search/FindUsagesTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/psi/search/InheritorsTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/psi/search/PlainTextUsagesTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/psi/search/SearchInLibsTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/psi/search/UpdateCacheTest.java [new file with mode: 0644]

diff --git a/java/java-tests/testData/psi/search/findUsages/fieldInJavadoc/A.java b/java/java-tests/testData/psi/search/findUsages/fieldInJavadoc/A.java
new file mode 100644 (file)
index 0000000..2587d22
--- /dev/null
@@ -0,0 +1,8 @@
+class A{
+  static int FIELD;
+
+  /**
+   * @see #FIELD
+   */
+  void foo(){}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages/implicitConstructorUsage/A.java b/java/java-tests/testData/psi/search/findUsages/implicitConstructorUsage/A.java
new file mode 100644 (file)
index 0000000..7d9db80
--- /dev/null
@@ -0,0 +1,13 @@
+class Foo {
+       public <caret>Foo() {
+       }
+
+       public Foo(String text) {
+       }
+}
+class Bar extends Foo {
+
+       public Bar() {
+               super("hello");
+       }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages/protectedMethodInPackageLocalClass/bar/Bar.java b/java/java-tests/testData/psi/search/findUsages/protectedMethodInPackageLocalClass/bar/Bar.java
new file mode 100644 (file)
index 0000000..d37d296
--- /dev/null
@@ -0,0 +1,11 @@
+import foo.*;
+
+class Bar extends Foo {
+  protected void foo();
+}
+
+class Goo extends Foo {
+  {
+    foo();
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages/protectedMethodInPackageLocalClass/foo/Foo.java b/java/java-tests/testData/psi/search/findUsages/protectedMethodInPackageLocalClass/foo/Foo.java
new file mode 100644 (file)
index 0000000..72ee6e5
--- /dev/null
@@ -0,0 +1,7 @@
+package foo;
+
+class PackageLocal {
+  protected void foo() {}
+}
+
+public class Foo extends PackageLocal {}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages/xml/Test.xml b/java/java-tests/testData/psi/search/findUsages/xml/Test.xml
new file mode 100644 (file)
index 0000000..136aa9f
--- /dev/null
@@ -0,0 +1,3 @@
+<document>
+  <action class="com.Foo" />
+</document>
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages/xml/com/Foo.java b/java/java-tests/testData/psi/search/findUsages/xml/com/Foo.java
new file mode 100644 (file)
index 0000000..9689077
--- /dev/null
@@ -0,0 +1,2 @@
+package com;
+public class Foo {}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages15/enumConstructor/pack/OurEnum.java b/java/java-tests/testData/psi/search/findUsages15/enumConstructor/pack/OurEnum.java
new file mode 100644 (file)
index 0000000..bbd25e7
--- /dev/null
@@ -0,0 +1,7 @@
+package pack;
+enum OurEnum {
+  A(10), B, C(27);
+
+  OurEnum(int i) {}
+  OurEnum() {}
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages15/findRawOverriddenUsages/pack/RawOverridden.java b/java/java-tests/testData/psi/search/findUsages15/findRawOverriddenUsages/pack/RawOverridden.java
new file mode 100644 (file)
index 0000000..ca6fc7e
--- /dev/null
@@ -0,0 +1,10 @@
+package pack;
+
+class Base {
+    void foo(List<String> l) {}
+}
+
+class Derived extends Base {
+    void foo(List l) {
+    }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages15/genericMethodOverriderUsages/pack/GenericClass.java b/java/java-tests/testData/psi/search/findUsages15/genericMethodOverriderUsages/pack/GenericClass.java
new file mode 100644 (file)
index 0000000..0d5e198
--- /dev/null
@@ -0,0 +1,13 @@
+package pack;
+
+class GenericClass<T> {
+  void foo (T t) {}
+}
+
+class GenericClassDerived extends GenericClass<String> {
+  void foo (String s) {}
+
+  void bar () {
+    foo ("");
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/findUsages15/genericOverride/pack/Gen.java b/java/java-tests/testData/psi/search/findUsages15/genericOverride/pack/Gen.java
new file mode 100644 (file)
index 0000000..b93c64e
--- /dev/null
@@ -0,0 +1,18 @@
+package pack;
+import java.util.Map;
+
+class BeforeRunTask {}
+class RunConfiguration{}
+class Key<T> {}
+public abstract class Gen {
+    public abstract <T extends BeforeRunTask> Map<Key<T>, BeforeRunTask> getBeforeRunTasks(RunConfiguration settings);
+}
+
+class X2 extends Gen {
+    Object o = getBeforeRunTasks(null);
+
+    public Map<Key<? extends BeforeRunTask>, BeforeRunTask> getBeforeRunTasks(RunConfiguration settings) {
+
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/inheritors/noScanJdk/empty.txt b/java/java-tests/testData/psi/search/inheritors/noScanJdk/empty.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/java/java-tests/testData/psi/search/inheritors/sameNamedClasses/x/Test.java b/java/java-tests/testData/psi/search/inheritors/sameNamedClasses/x/Test.java
new file mode 100644 (file)
index 0000000..2c4691f
--- /dev/null
@@ -0,0 +1,18 @@
+package x;
+
+public class Test<T> {
+  public void foo(T t) {
+      //Tracked f;
+  }
+}
+
+class Goo<T> extends Test<T> {
+    public void foo(T t) {}
+}
+class Goo  {
+
+}
+
+class Zoo extends Goo {
+    public void foo(Object t) {}
+}
diff --git a/java/java-tests/testData/psi/search/inheritors/scope/Derived2.java b/java/java-tests/testData/psi/search/inheritors/scope/Derived2.java
new file mode 100644 (file)
index 0000000..443181b
--- /dev/null
@@ -0,0 +1,6 @@
+
+import pack1.Derived1;
+import pack1.Base;
+
+public class Derived2 extends Base{
+}
diff --git a/java/java-tests/testData/psi/search/inheritors/scope/pack1/Base.java b/java/java-tests/testData/psi/search/inheritors/scope/pack1/Base.java
new file mode 100644 (file)
index 0000000..10104fc
--- /dev/null
@@ -0,0 +1,4 @@
+package pack1;
+
+public class Base {
+}
diff --git a/java/java-tests/testData/psi/search/inheritors/scope/pack1/Derived1.java b/java/java-tests/testData/psi/search/inheritors/scope/pack1/Derived1.java
new file mode 100644 (file)
index 0000000..205a3d9
--- /dev/null
@@ -0,0 +1,4 @@
+package pack1;
+
+public class Derived1 extends Base{
+}
diff --git a/java/java-tests/testData/psi/search/inheritors/scope/pack1/Derived3.java b/java/java-tests/testData/psi/search/inheritors/scope/pack1/Derived3.java
new file mode 100644 (file)
index 0000000..51c2170
--- /dev/null
@@ -0,0 +1,6 @@
+package pack1;
+
+import Derived2;
+
+public class Derived3 extends Derived2{
+}
diff --git a/java/java-tests/testData/psi/search/plainTextUsages/simple/Test.txt b/java/java-tests/testData/psi/search/plainTextUsages/simple/Test.txt
new file mode 100644 (file)
index 0000000..0b33aa0
--- /dev/null
@@ -0,0 +1,3 @@
+aaa com.Foo bbb
+aaacom.Foo
+aaa com.Foobbb
diff --git a/java/java-tests/testData/psi/search/plainTextUsages/xmlOutOfScope/com/Foo.java b/java/java-tests/testData/psi/search/plainTextUsages/xmlOutOfScope/com/Foo.java
new file mode 100644 (file)
index 0000000..ad0c3f4
--- /dev/null
@@ -0,0 +1,3 @@
+package com;
+
+public class Foo {}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/plainTextUsages/xmlOutOfScope/resources/Test.xml b/java/java-tests/testData/psi/search/plainTextUsages/xmlOutOfScope/resources/Test.xml
new file mode 100644 (file)
index 0000000..136aa9f
--- /dev/null
@@ -0,0 +1,3 @@
+<document>
+  <action class="com.Foo" />
+</document>
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/searchInLibs/lib/classes/LibraryClass1.class b/java/java-tests/testData/psi/search/searchInLibs/lib/classes/LibraryClass1.class
new file mode 100644 (file)
index 0000000..c1148b0
Binary files /dev/null and b/java/java-tests/testData/psi/search/searchInLibs/lib/classes/LibraryClass1.class differ
diff --git a/java/java-tests/testData/psi/search/searchInLibs/lib/classes/LibraryClass2.class b/java/java-tests/testData/psi/search/searchInLibs/lib/classes/LibraryClass2.class
new file mode 100644 (file)
index 0000000..6bf93d0
Binary files /dev/null and b/java/java-tests/testData/psi/search/searchInLibs/lib/classes/LibraryClass2.class differ
diff --git a/java/java-tests/testData/psi/search/searchInLibs/lib/src/LibraryClass1.java b/java/java-tests/testData/psi/search/searchInLibs/lib/src/LibraryClass1.java
new file mode 100644 (file)
index 0000000..b2bb5f3
--- /dev/null
@@ -0,0 +1,4 @@
+class LibraryClass1{
+  LibraryClass2 libClass2;
+  ProjectClass projectClass; // should not find this!
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/searchInLibs/lib/src/LibraryClass2.java b/java/java-tests/testData/psi/search/searchInLibs/lib/src/LibraryClass2.java
new file mode 100644 (file)
index 0000000..2136ef2
--- /dev/null
@@ -0,0 +1,3 @@
+class LibraryClass2{
+  LibraryClass1 libClass1;
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/searchInLibs/project/ProjectClass.java b/java/java-tests/testData/psi/search/searchInLibs/project/ProjectClass.java
new file mode 100644 (file)
index 0000000..4e8e07e
--- /dev/null
@@ -0,0 +1,4 @@
+class ProjectClass{
+  ProjectClass aClass;
+  LibraryClass1 libClass1;
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/searchInLibs/project/src2/ProjectClass2.java b/java/java-tests/testData/psi/search/searchInLibs/project/src2/ProjectClass2.java
new file mode 100644 (file)
index 0000000..b7a9285
--- /dev/null
@@ -0,0 +1,3 @@
+class ProjectClass2{
+  ProjectClass2 aClass;
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/search/updateCache/1.java b/java/java-tests/testData/psi/search/updateCache/1.java
new file mode 100644 (file)
index 0000000..6ea2061
--- /dev/null
@@ -0,0 +1,4 @@
+class Class1{
+  Exception e;
+  String s; //newtodo
+}
diff --git a/java/java-tests/testData/psi/search/updateCache/aDir/2.java b/java/java-tests/testData/psi/search/updateCache/aDir/2.java
new file mode 100644 (file)
index 0000000..df23af2
--- /dev/null
@@ -0,0 +1,4 @@
+class B{
+  Exception e;
+  Thread thread; //todo
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/search/FindUsages15Test.java b/java/java-tests/testSrc/com/intellij/psi/search/FindUsages15Test.java
new file mode 100644 (file)
index 0000000..818b044
--- /dev/null
@@ -0,0 +1,76 @@
+package com.intellij.psi.search;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.MethodReferencesSearch;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+
+public class FindUsages15Test extends PsiTestCase{
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
+    String root = JavaTestUtil.getJavaTestDataPath() + "/psi/search/findUsages15/" + getTestName(true);
+    PsiTestUtil.removeAllRoots(myModule, JavaSdkImpl.getMockJdk17("java 1.5"));
+    PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete);
+  }
+
+  public void testEnumConstructor() throws Exception {
+    PsiClass enumClass = myJavaFacade.findClass("pack.OurEnum", GlobalSearchScope.moduleScope(myModule));
+    assertNotNull(enumClass);
+    assertTrue(enumClass.isEnum());
+    PsiMethod[] constructors = enumClass.getConstructors();
+    assertEquals(2, constructors.length);
+    PsiReference[] references0 =
+      ReferencesSearch.search(constructors[0], GlobalSearchScope.moduleScope(myModule), false).toArray(new PsiReference[0]);
+    assertEquals(2, references0.length);
+    assertTrue(references0[0].getElement() instanceof PsiEnumConstant);
+    assertTrue(references0[1].getElement() instanceof PsiEnumConstant);
+    PsiReference[] references1 =
+      ReferencesSearch.search(constructors[1], GlobalSearchScope.moduleScope(myModule), false).toArray(new PsiReference[0]);
+    assertEquals(1, references1.length);
+    assertTrue(references1[0].getElement() instanceof PsiEnumConstant);
+  }
+
+  public void testGenericMethodOverriderUsages () throws Exception {
+    final PsiClass baseClass = myJavaFacade.findClass("pack.GenericClass", GlobalSearchScope.moduleScope(myModule));
+    assertNotNull(baseClass);
+    final PsiMethod method = baseClass.getMethods()[0];
+    PsiReference[] references =
+      MethodReferencesSearch.search(method, GlobalSearchScope.moduleScope(myModule), false).toArray(PsiReference.EMPTY_ARRAY);
+    assertEquals(1, references.length);
+    final PsiElement element = references[0].getElement();
+    final PsiClass refClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
+    assertEquals(refClass.getName(), "GenericClassDerived");
+  }
+
+  public void testFindRawOverriddenUsages () throws Exception {
+    final PsiClass baseClass = myJavaFacade.findClass("pack.Base", GlobalSearchScope.moduleScope(myModule));
+    assertNotNull(baseClass);
+    final PsiMethod method = baseClass.getMethods()[0];
+    PsiMethod[] overriders =
+      OverridingMethodsSearch.search(method, GlobalSearchScope.moduleScope(myModule), true).toArray(PsiMethod.EMPTY_ARRAY);
+    assertEquals(1, overriders.length);
+  }
+  public void testGenericOverride() throws Exception {
+    final PsiClass baseClass = myJavaFacade.findClass("pack.Gen", GlobalSearchScope.moduleScope(myModule));
+    assertNotNull(baseClass);
+    final PsiMethod method = baseClass.getMethods()[0];
+    PsiReference[] references =
+      MethodReferencesSearch.search(method, GlobalSearchScope.projectScope(getProject()), true).toArray(PsiReference.EMPTY_ARRAY);
+
+    assertEquals(1, references.length);
+
+    PsiClass refClass = PsiTreeUtil.getParentOfType(references[0].getElement(), PsiClass.class);
+    assertEquals("X2", refClass.getName());
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/search/FindUsagesTest.java b/java/java-tests/testSrc/com/intellij/psi/search/FindUsagesTest.java
new file mode 100644 (file)
index 0000000..4be491c
--- /dev/null
@@ -0,0 +1,241 @@
+package com.intellij.psi.search;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.find.findUsages.JavaFindUsagesHandler;
+import com.intellij.find.findUsages.JavaFindUsagesHandlerFactory;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.MethodReferencesSearch;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
+import com.intellij.testFramework.fixtures.TempDirTestFixture;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.IntArrayList;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class FindUsagesTest extends PsiTestCase{
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    String root = JavaTestUtil.getJavaTestDataPath() + "/psi/search/findUsages/" + getTestName(true);
+    PsiTestUtil.removeAllRoots(myModule, JavaSdkImpl.getMockJdk17());
+    PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete);
+  }
+
+  public void testOverloadConstructors() throws Exception {
+    PsiClass aClass = myJavaFacade.findClass("B", GlobalSearchScope.allScope(myProject));
+    PsiMethod constructor;
+//    constructor = myJavaFacade.getElementFactory().createConstructor();
+//    constructor = aClass.findMethodBySignature(constructor, false);
+    constructor = aClass.findMethodsByName("B", false)[0];
+    PsiMethodCallExpression superCall = (PsiMethodCallExpression) constructor.getBody().getStatements()[0].getFirstChild();
+    PsiReferenceExpression superExpr = superCall.getMethodExpression();
+    String[] fileNames = new String[]{"B.java", "A.java", "A.java", "B.java"};
+    int[] starts = new int[]{};
+    int[] ends = new int[]{};
+    final ArrayList<PsiFile> filesList = new ArrayList<PsiFile>();
+    final IntArrayList startsList = new IntArrayList();
+    final IntArrayList endsList = new IntArrayList();
+    PsiReference[] refs =
+      MethodReferencesSearch.search((PsiMethod)superExpr.resolve(), GlobalSearchScope.projectScope(myProject), false).toArray(PsiReference.EMPTY_ARRAY);
+    for (PsiReference ref : refs) {
+      addReference(ref, filesList, startsList, endsList);
+    }
+    checkResult(fileNames, filesList, starts, startsList, ends, endsList);
+  }
+
+  public void testSiblingImplement() throws Exception {
+    PsiClass anInterface = myJavaFacade.findClass("A.I", GlobalSearchScope.allScope(myProject));
+    PsiMethod method = anInterface.getMethods()[0];
+    final Collection<PsiMethod> overriders = OverridingMethodsSearch.search(method).findAll();
+    assertEquals(1, overriders.size());
+  }
+
+  public void testProtectedMethodInPackageLocalClass() throws Throwable {
+    PsiMethod method = myJavaFacade.findClass("foo.PackageLocal", GlobalSearchScope.allScope(myProject)).getMethods()[0];
+    assertEquals(1, OverridingMethodsSearch.search(method).findAll().size());
+    assertEquals(1, ReferencesSearch.search(method).findAll().size());
+  }
+
+  public void testImplicitConstructorUsage() throws Throwable {
+    PsiMethod[] ctrs = myJavaFacade.findClass("Foo", GlobalSearchScope.allScope(myProject)).getConstructors();
+    PsiMethod method = ctrs[0];
+    assertEquals(0, method.getParameterList().getParametersCount());
+    assertEquals(0, ReferencesSearch.search(method).findAll().size());
+
+    PsiMethod usedMethod = ctrs[1];
+    assertEquals(1, usedMethod.getParameterList().getParametersCount());
+    assertEquals(1, ReferencesSearch.search(usedMethod).findAll().size());
+  }
+
+  private static void addReference(PsiReference ref, ArrayList<PsiFile> filesList, IntArrayList startsList, IntArrayList endsList) {
+    PsiElement element = ref.getElement();
+    filesList.add(element.getContainingFile());
+    TextRange range = element.getTextRange();
+    TextRange rangeInElement = ref.getRangeInElement();
+    startsList.add(range.getStartOffset() + rangeInElement.getStartOffset());
+    endsList.add(range.getStartOffset() + rangeInElement.getEndOffset());
+  }
+
+  public void testFieldInJavadoc() throws Exception{
+    PsiClass aClass = myJavaFacade.findClass("A", GlobalSearchScope.allScope(myProject));
+    PsiField field = aClass.findFieldByName("FIELD", false);
+    doTest(field, new String[]{"A.java"}, new int[]{}, new int[]{});
+  }
+
+  public void testXml() throws Exception{
+    PsiClass aClass = myJavaFacade.findClass("com.Foo", GlobalSearchScope.allScope(myProject));
+    doTest(aClass, new String[]{"Test.xml"}, new int[]{32}, new int[]{35});
+
+    final PsiFile nonCodeUsage = PsiFileFactory.getInstance(myProject).createFileFromText("a.xml", StdFileTypes.XML, "<root action='com.Foo'/>", 0, true);
+    assertTrue(new UsageInfo(nonCodeUsage, 14, 21, true).getNavigationOffset() > 0);
+  }
+
+  public void testNonCodeClassUsages() throws Exception {
+    final TempDirTestFixture tdf = IdeaTestFixtureFactory.getFixtureFactory().createTempDirTestFixture();
+    tdf.setUp();
+
+    try {
+      new WriteCommandAction(getProject()) {
+        @Override
+        protected void run(Result result) throws Throwable {
+          final ModifiableModuleModel moduleModel = ModuleManager.getInstance(getProject()).getModifiableModel();
+          moduleModel.newModule("independent/independent.iml", StdModuleTypes.JAVA);
+          moduleModel.commit();
+
+          tdf.createFile("plugin.xml", "<document>\n" +
+                                       "  <action class=\"com.Foo\" />\n" +
+                                       "  <action class=\"com.Foo.Bar\" />\n" +
+                                       "  <action class=\"com.Foo$Bar\" />\n" +
+                                       "</document>");
+
+          PsiTestUtil.addContentRoot(ModuleManager.getInstance(getProject()).findModuleByName("independent"), tdf.getFile(""));
+        }
+      }.execute();
+
+      GlobalSearchScope scope = GlobalSearchScope.allScope(getProject());
+      PsiClass foo = myJavaFacade.findClass("com.Foo", scope);
+      PsiClass bar = myJavaFacade.findClass("com.Foo.Bar", scope);
+
+      final int[] count = {0};
+      Processor<UsageInfo> processor = new Processor<UsageInfo>() {
+        @Override
+        public boolean process(UsageInfo usageInfo) {
+          int navigationOffset = usageInfo.getNavigationOffset();
+          assertTrue(navigationOffset > 0);
+          String textAfter = usageInfo.getFile().getText().substring(navigationOffset);
+          assertTrue(textAfter, textAfter.startsWith("Foo") || textAfter.startsWith("Bar") ||
+                                textAfter.startsWith("com.Foo.Bar") // sorry, can't get references with dollar-dot mismatch to work now
+          );
+          count[0]++;
+          return true;
+        }
+      };
+      JavaFindUsagesHandler handler = new JavaFindUsagesHandler(bar, JavaFindUsagesHandlerFactory.getInstance(getProject()));
+
+      count[0] = 0;
+      handler.processUsagesInText(foo, processor, scope);
+      assertEquals(3, count[0]);
+
+      count[0] = 0;
+      handler.processUsagesInText(bar, processor, scope);
+      assertEquals(2, count[0]);
+    }
+    finally {
+      tdf.tearDown();
+    }
+  }
+
+  public static void doTest(PsiElement element, String[] fileNames, int[] starts, int[] ends) throws Exception {
+    final ArrayList<PsiFile> filesList = new ArrayList<PsiFile>();
+    final IntArrayList startsList = new IntArrayList();
+    final IntArrayList endsList = new IntArrayList();
+    ReferencesSearch.search(element, GlobalSearchScope.projectScope(element.getProject()), false).forEach(new PsiReferenceProcessorAdapter(new PsiReferenceProcessor() {
+        @Override
+        public boolean execute(PsiReference ref) {
+          addReference(ref, filesList, startsList, endsList);
+          return true;
+        }
+      }));
+
+    checkResult(fileNames, filesList, starts, startsList, ends, endsList);
+
+  }
+
+  private static class SearchResult implements Comparable<SearchResult> {
+    String fileName;
+    int startOffset;
+    int endOffset;
+
+    private SearchResult(final String fileName, final int startOffset, final int endOffset) {
+      this.fileName = fileName;
+      this.startOffset = startOffset;
+      this.endOffset = endOffset;
+    }
+
+    @Override
+    public int compareTo(final SearchResult o) {
+      int rc = fileName.compareTo(o.fileName);
+      if (rc != 0) return rc;
+
+      rc = startOffset - o.startOffset;
+      if (rc != 0) return rc;
+
+      return endOffset - o.endOffset;
+    }
+
+    public String toString() {
+      return fileName + "[" + startOffset + ":" + endOffset + "]";
+    }
+
+    public boolean equals(final Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      final SearchResult that = (SearchResult)o;
+
+      if (endOffset != that.endOffset) return false;
+      if (startOffset != that.startOffset) return false;
+      if (fileName != null ? !fileName.equals(that.fileName) : that.fileName != null) return false;
+
+      return true;
+    }
+  }
+
+  private static void checkResult(String[] fileNames, final ArrayList<PsiFile> filesList, int[] starts, final IntArrayList startsList, int[] ends, final IntArrayList endsList) {
+    List<SearchResult> expected = new ArrayList<SearchResult>();
+    for (int i = 0; i < fileNames.length; i++) {
+      String fileName = fileNames[i];
+      expected.add(new SearchResult(fileName, i < starts.length ? starts[i] : -1, i < ends.length ? ends[i] : -1));
+    }
+
+    List<SearchResult> actual = new ArrayList<SearchResult>();
+    for (int i = 0; i < filesList.size(); i++) {
+      PsiFile psiFile = filesList.get(i);
+      actual.add(
+        new SearchResult(psiFile.getName(), i < starts.length ? startsList.get(i) : -1, i < ends.length ? endsList.get(i) : -1));
+    }
+
+    Collections.sort(expected);
+    Collections.sort(actual);
+
+    assertEquals("Usages don't match", expected, actual);
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/search/InheritorsTest.java b/java/java-tests/testSrc/com/intellij/psi/search/InheritorsTest.java
new file mode 100644 (file)
index 0000000..2c8548a
--- /dev/null
@@ -0,0 +1,73 @@
+package com.intellij.psi.search;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+public class InheritorsTest extends PsiTestCase{
+  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.search.InheritorsTest");
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    String root = JavaTestUtil.getJavaTestDataPath() + "/psi/search/inheritors/" + getTestName(true);
+    PsiTestUtil.removeAllRoots(myModule, JavaSdkImpl.getMockJdk17());
+    PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete);
+  }
+
+  public void testScope() throws Exception {
+    doTest("pack1.Base", "pack1", true, "pack1.Derived1", "pack1.Derived3");
+  }
+
+  public void testNoScanJdk() throws Exception {
+    doTest("javax.swing.JPanel", "", false);
+  }
+
+  public void testSameNamedClasses() throws Exception {
+    doTest("x.Test", "", true, "x.Goo", "x.Zoo");
+  }
+
+  private void doTest(String className, String packageScopeName, final boolean deep, String... inheritorNames) throws Exception {
+    final PsiClass aClass = myJavaFacade.findClass(className);
+    assertNotNull(aClass);
+
+    final SearchScope scope;
+    if (packageScopeName != null){
+      PsiPackage aPackage = JavaPsiFacade.getInstance(myPsiManager.getProject()).findPackage(packageScopeName);
+      scope = PackageScope.packageScope(aPackage, true).intersectWith(GlobalSearchScope.projectScope(myProject));
+    }
+    else{
+      scope = GlobalSearchScope.projectScope(myProject);
+    }
+
+    final ArrayList<String> inheritorsList = new ArrayList<String>();
+    ProgressManager.getInstance().runProcess(
+      new Runnable() {
+        @Override
+        public void run() {
+          ClassInheritorsSearch.search(aClass, scope, deep).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
+            @Override
+            public boolean execute(@NotNull PsiClass element) {
+              inheritorsList.add(element.getQualifiedName());
+              return true;
+            }
+          }));
+        }
+      },
+      null
+    );
+
+    assertSameElements(inheritorsList, inheritorNames);
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/search/PlainTextUsagesTest.java b/java/java-tests/testSrc/com/intellij/psi/search/PlainTextUsagesTest.java
new file mode 100644 (file)
index 0000000..6aa4ba7
--- /dev/null
@@ -0,0 +1,91 @@
+package com.intellij.psi.search;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.util.containers.IntArrayList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PlainTextUsagesTest extends PsiTestCase {
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    String root = JavaTestUtil.getJavaTestDataPath() + "/psi/search/plainTextUsages/" + getTestName(true);
+    PsiTestUtil.removeAllRoots(myModule, JavaSdkImpl.getMockJdk17());
+    PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete);
+  }
+
+  public void testSimple() throws Exception {
+    doTest("com.Foo", null, new String[]{"Test.txt"}, new int[]{4}, new int[]{11});
+  }
+
+  public void testXmlOutOfScope() throws Exception {
+    final VirtualFile resourcesDir = ModuleRootManager.getInstance(myModule).getSourceRoots()[0].findChild("resources");
+    assertNotNull(resourcesDir);
+    new WriteAction() {
+      @Override
+      protected void run(final Result result) {
+        final Module module = createModule("res");
+        PsiTestUtil.addContentRoot(module, resourcesDir);
+        final VirtualFile child = resourcesDir.findChild("Test.xml");
+        assert child != null;
+        assertSame(module, ModuleUtil.findModuleForFile(child, getProject()));
+      }
+    }.execute();
+
+    PsiClass aClass = myJavaFacade.findClass("com.Foo", GlobalSearchScope.allScope(myProject));
+    assertNotNull(aClass);
+    doTest("com.Foo", aClass, new String[]{"Test.xml"}, new int[]{28}, new int[]{35});
+  }
+
+  private void doTest(String qNameToSearch,
+                      final PsiElement originalElement,
+                      String[] fileNames,
+                      int[] starts,
+                      int[] ends) throws Exception {
+    PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(myProject);
+    final List<PsiFile> filesList = new ArrayList<PsiFile>();
+    final IntArrayList startsList = new IntArrayList();
+    final IntArrayList endsList = new IntArrayList();
+    helper.processUsagesInNonJavaFiles(originalElement,
+                                       qNameToSearch,
+                                       new PsiNonJavaFileReferenceProcessor() {
+                                         @Override
+                                         public boolean process(PsiFile file, int startOffset, int endOffset) {
+                                           filesList.add(file);
+                                           startsList.add(startOffset);
+                                           endsList.add(endOffset);
+                                           return true;
+                                         }
+                                       },
+                                       GlobalSearchScope.projectScope(myProject)
+    );
+
+    assertEquals("usages count", fileNames.length, filesList.size());
+
+    for (int i = 0; i < fileNames.length; i++) {
+      assertEquals("files[" + i + "]", fileNames[i], filesList.get(i).getName());
+    }
+
+    for (int i = 0; i < starts.length; i++) {
+      assertEquals("starts[" + i + "]", starts[i], startsList.get(i));
+    }
+
+    for (int i = 0; i < ends.length; i++) {
+      assertEquals("ends[" + i + "]", ends[i], endsList.get(i));
+    }
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/search/SearchInLibsTest.java b/java/java-tests/testSrc/com/intellij/psi/search/SearchInLibsTest.java
new file mode 100644 (file)
index 0000000..8755e4e
--- /dev/null
@@ -0,0 +1,106 @@
+package com.intellij.psi.search;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class SearchInLibsTest extends PsiTestCase {
+  public void testSearchInProject() throws Exception {
+    doTest("ProjectClass", new String[]{"ProjectClass.java"}, GlobalSearchScope.projectScope(myProject));
+    doTest("LibraryClass1", new String[]{"ProjectClass.java"}, GlobalSearchScope.projectScope(myProject));
+    doTest("LibraryClass2", new String[]{}, GlobalSearchScope.projectScope(myProject));
+  }
+
+  public void testSearchInLibs() throws Exception {
+    doTest("ProjectClass", new String[]{"ProjectClass.java"}, GlobalSearchScope.allScope(myProject));
+    doTest("LibraryClass1", new String[]{"LibraryClass2.java", "ProjectClass.java"}, GlobalSearchScope.allScope(myProject));
+    doTest("LibraryClass2", new String[]{"LibraryClass1.java"}, GlobalSearchScope.allScope(myProject));
+  }
+
+  public void testInnerSourceRoot() throws Exception {
+    doTest("ProjectClass2", new String[]{"ProjectClass2.java"}, GlobalSearchScope.projectScope(myProject));
+  }
+
+  private void doTest(String classNameToSearch, String[] expectedFileNames, SearchScope scope) throws Exception {
+
+    String root = JavaTestUtil.getJavaTestDataPath() + "/psi/search/searchInLibs";
+    VirtualFile rootFile = PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete, false);
+
+    final VirtualFile projectRoot = rootFile.findChild("project");
+    assertNotNull(projectRoot);
+
+    final VirtualFile innerSourceRoot = projectRoot.findChild("src2");
+    assertNotNull(innerSourceRoot);
+
+    VirtualFile libRoot = rootFile.findChild("lib");
+    final VirtualFile libClassesRoot = libRoot.findChild("classes");
+    final VirtualFile libSrcRoot = libRoot.findChild("src");
+    assertNotNull(libRoot);
+    final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule);
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        final ModifiableRootModel rootModel = rootManager.getModifiableModel();
+        rootModel.clear();
+        rootModel.setSdk(null);
+        final ContentEntry contentEntry = rootModel.addContentEntry(projectRoot);
+        contentEntry.addSourceFolder(projectRoot, false);
+        contentEntry.addSourceFolder(innerSourceRoot, false);
+        final Library.ModifiableModel libraryModel = rootModel.getModuleLibraryTable().createLibrary().getModifiableModel();
+        libraryModel.addRoot(libSrcRoot, OrderRootType.SOURCES);
+        libraryModel.addRoot(libClassesRoot, OrderRootType.CLASSES);
+        libraryModel.commit();
+        rootModel.commit();
+      }
+    });
+
+
+    final PsiClass aClass = myJavaFacade.findClass(classNameToSearch);
+    assertNotNull(aClass);
+
+    PsiReference[] refs = ReferencesSearch.search(aClass, scope, false).toArray(new PsiReference[0]);
+
+    ArrayList<PsiFile> files = new ArrayList<PsiFile>();
+    for (int i = 0; i < refs.length; i++) {
+      PsiReference ref = refs[i];
+      PsiFile file = ref.getElement().getContainingFile();
+      if (!files.contains(file)) {
+        files.add(file);
+      }
+    }
+
+    assertEquals("files count", expectedFileNames.length, files.size());
+
+    Collections.sort(files, new Comparator() {
+      @Override
+      public int compare(Object o1, Object o2) {
+        PsiFile file1 = (PsiFile) o1;
+        PsiFile file2 = (PsiFile) o2;
+        return file1.getName().compareTo(file2.getName());
+      }
+    });
+    Arrays.sort(expectedFileNames);
+
+    for (int i = 0; i < expectedFileNames.length; i++) {
+      String name = expectedFileNames[i];
+      PsiFile file = (PsiFile) files.get(i);
+      assertEquals(name, file.getName());
+    }
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/search/UpdateCacheTest.java b/java/java-tests/testSrc/com/intellij/psi/search/UpdateCacheTest.java
new file mode 100644 (file)
index 0000000..d1877bd
--- /dev/null
@@ -0,0 +1,537 @@
+package com.intellij.psi.search;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.ide.todo.TodoConfiguration;
+import com.intellij.lang.injection.InjectedLanguageManager;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ex.ProjectManagerEx;
+import com.intellij.openapi.projectRoots.impl.ProjectRootUtil;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.JavaPsiFacadeImpl;
+import com.intellij.psi.impl.PsiManagerImpl;
+import com.intellij.psi.impl.cache.impl.id.IdIndex;
+import com.intellij.psi.impl.cache.impl.todo.TodoIndex;
+import com.intellij.psi.impl.cache.impl.todo.TodoIndexEntry;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.indexing.FileBasedIndex;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.util.*;
+
+@PlatformTestCase.WrapInCommand
+public class UpdateCacheTest extends PsiTestCase{
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    FileBasedIndex.requestRebuild(IdIndex.NAME);
+    FileBasedIndex.requestRebuild(TodoIndex.NAME);
+  }
+
+  @Override
+  protected void setUpProject() throws Exception {
+    myProjectManager = ProjectManagerEx.getInstanceEx();
+    LOG.assertTrue(myProjectManager != null, "Cannot instantiate ProjectManager component");
+
+    File projectFile = getIprFile();
+    loadAndSetupProject(projectFile.getPath());
+  }
+
+  private void loadAndSetupProject(String path) throws Exception {
+    LocalFileSystem.getInstance().refreshIoFiles(myFilesToDelete);
+
+    myProject = ProjectManager.getInstance().loadAndOpenProject(path);
+
+    setUpModule();
+
+    final String root = JavaTestUtil.getJavaTestDataPath() + "/psi/search/updateCache";
+    PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete);
+
+    setUpJdk();
+
+    myProjectManager.setCurrentTestProject(myProject);
+    runStartupActivities();
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    ProjectManager.getInstance().closeProject(myProject);
+    super.tearDown();
+  }
+
+  public void testFileCreation() throws Exception {
+    PsiDirectory root = ProjectRootUtil.getAllContentRoots(myProject) [0];
+
+    PsiFile file = PsiFileFactory.getInstance(myProject).createFileFromText("New.java", "class A{ Object o;}");
+    file = (PsiFile)root.add(file);
+    assertNotNull(file);
+
+    PsiClass objectClass = myJavaFacade.findClass("java.lang.Object", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(objectClass);
+    checkUsages(objectClass, new String[]{"New.java"});
+  }
+
+  public void testExternalFileCreation() throws Exception {
+    VirtualFile root = ProjectRootManager.getInstance(myProject).getContentRoots()[0];
+
+    String newFilePath = root.getPresentableUrl() + File.separatorChar + "New.java";
+    FileUtil.writeToFile(new File(newFilePath), "class A{ Object o;}".getBytes());
+    VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(newFilePath.replace(File.separatorChar, '/'));
+    assertNotNull(file);
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    PsiClass objectClass = myJavaFacade.findClass("java.lang.Object", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(objectClass);
+    checkUsages(objectClass, new String[]{"New.java"});
+  }
+
+  public void testExternalFileDeletion() throws Exception {
+    VirtualFile root = ProjectRootManager.getInstance(myProject).getContentRoots()[0];
+
+    VirtualFile file = root.findChild("1.java");
+    assertNotNull(file);
+    file.delete(null);
+
+    PsiClass stringClass = myJavaFacade.findClass("java.lang.String", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(stringClass);
+    checkUsages(stringClass, ArrayUtil.EMPTY_STRING_ARRAY);
+  }
+
+  public void testExternalFileModification() throws Exception {
+    VirtualFile root = ProjectRootManager.getInstance(myProject).getContentRoots()[0];
+
+    VirtualFile file = root.findChild("1.java");
+    assertNotNull(file);
+    VfsUtil.saveText(file, "class A{ Object o;}");
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    PsiClass objectClass = myJavaFacade.findClass("java.lang.Object", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(objectClass);
+    checkUsages(objectClass, new String[]{"1.java"});
+  }
+
+  @Override
+  protected boolean isRunInWriteAction() {
+    return !getTestName(false).equals("ExternalFileModificationWhileProjectClosed");
+  }
+
+  public void testExternalFileModificationWhileProjectClosed() throws Exception {
+    VirtualFile root = ProjectRootManager.getInstance(myProject).getContentRoots()[0];
+
+    PsiClass objectClass = myJavaFacade.findClass("java.lang.Object", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(objectClass);
+    checkUsages(objectClass, new String[]{});
+    FileBasedIndex.getInstance().getContainingFiles(TodoIndex.NAME, new TodoIndexEntry("todo", true), GlobalSearchScope.allScope(getProject()));
+
+    final String projectLocation = myProject.getLocation();
+    myProject.save();
+    final VirtualFile content = ModuleRootManager.getInstance(getModule()).getContentRoots()[0];
+    ProjectUtil.closeAndDispose(myProject);
+    ((InjectedLanguageManagerImpl)InjectedLanguageManager.getInstance(getProject())).checkInjectorsAreDisposed();
+    assertTrue("Project was not disposed", myProject.isDisposed());
+    myModule = null;
+    
+    final File file = new File(root.getPath(), "1.java");
+    assertTrue(file.exists());
+
+    FileUtil.writeToFile(file, "class A{ Object o;}".getBytes());
+    root.refresh(false, true);
+
+    LocalFileSystem.getInstance().refresh(false);
+
+    myProject = ProjectManager.getInstance().loadAndOpenProject(projectLocation);
+    ((InjectedLanguageManagerImpl)InjectedLanguageManager.getInstance(getProject())).pushInjectors();
+    setUpModule();
+    setUpJdk();
+    ProjectManagerEx.getInstanceEx().setCurrentTestProject(myProject);
+    runStartupActivities();
+    PsiTestUtil.addSourceContentToRoots(getModule(), content);
+
+    assertNotNull(myProject);
+    myPsiManager = (PsiManagerImpl) PsiManager.getInstance(myProject);
+    myJavaFacade = (JavaPsiFacadeImpl) JavaPsiFacade.getInstance(myProject);
+
+    objectClass = myJavaFacade.findClass("java.lang.Object", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(objectClass);
+    checkUsages(objectClass, new String[]{"1.java"});
+  }
+
+  public void testExternalDirCreation() throws Exception {
+    VirtualFile root = ProjectRootManager.getInstance(myProject).getContentRoots()[0];
+
+    String newFilePath = root.getPresentableUrl() + File.separatorChar + "dir" + File.separatorChar + "New.java";
+    LOG.assertTrue(new File(newFilePath).getParentFile().mkdir());
+    FileUtil.writeToFile(new File(newFilePath), "class A{ Object o;}".getBytes());
+    VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(newFilePath.replace(File.separatorChar, '/'));
+    assertNotNull(file);
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    PsiClass objectClass = myJavaFacade.findClass("java.lang.Object", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(objectClass);
+    checkUsages(objectClass, new String[]{"New.java"});
+  }
+
+  public void testExternalDirDeletion() throws Exception {
+    VirtualFile root = ProjectRootManager.getInstance(myProject).getContentRoots()[0];
+
+    VirtualFile file = root.findChild("aDir");
+    assertNotNull(file);
+    file.delete(null);
+
+    PsiClass threadClass = myJavaFacade.findClass("java.lang.Thread", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(threadClass);
+    checkUsages(threadClass, ArrayUtil.EMPTY_STRING_ARRAY);
+  }
+
+  public void testTodoConfigurationChange() throws Exception{
+    TodoPattern pattern = new TodoPattern("newtodo", TodoAttributes.createDefault(), true);
+    TodoPattern[] oldPatterns = TodoConfiguration.getInstance().getTodoPatterns();
+    
+    checkTodos(new String[]{"2.java"});
+    
+    TodoConfiguration.getInstance().setTodoPatterns(new TodoPattern[]{pattern});
+
+    try{
+      checkTodos(new String[]{"1.java"});
+    }
+    finally{
+      TodoConfiguration.getInstance().setTodoPatterns(oldPatterns);
+      checkTodos(new String[]{"2.java"});
+    }
+  }
+
+  public void testAddExcludeRoot() throws Exception{
+    PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to initialize caches
+
+    ProjectRootManagerEx rootManager = (ProjectRootManagerEx)ProjectRootManager.getInstance(myProject);
+    final VirtualFile root = rootManager.getContentRoots()[0];
+
+    final VirtualFile dir = root.findChild("aDir");
+
+    new WriteCommandAction.Simple(getProject()) {
+      @Override
+      protected void run() throws Throwable {
+        VirtualFile newFile = dir.createChildData(null, "New.java");
+        VfsUtil.saveText(newFile, "class A{ Exception e;} //todo");
+      }
+    }.execute().throwException();
+
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
+        final ContentEntry[] content = rootModel.getContentEntries();
+        for (ContentEntry contentEntry : content) {
+          if (root.equals(contentEntry.getFile())) {
+            contentEntry.addExcludeFolder(dir);
+            break;
+          }
+        }
+        rootModel.commit();
+      }
+    });
+
+
+    PsiClass exceptionClass = myJavaFacade.findClass("java.lang.Exception",GlobalSearchScope.allScope(getProject()));
+    assertNotNull(exceptionClass);
+    checkUsages(exceptionClass, new String[]{"1.java"});
+    checkTodos(new String[]{});
+  }
+
+  public void testRemoveExcludeRoot() throws Exception{
+    ProjectRootManagerEx rootManager = (ProjectRootManagerEx)ProjectRootManager.getInstance(myProject);
+    final VirtualFile root = rootManager.getContentRoots()[0];
+
+    final VirtualFile dir = root.findChild("aDir");
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
+        final ContentEntry[] content = rootModel.getContentEntries();
+        for (ContentEntry contentEntry : content) {
+          if (root.equals(contentEntry.getFile())) {
+            contentEntry.addExcludeFolder(dir);
+            break;
+          }
+        }
+        rootModel.commit();
+      }
+    });
+
+
+    PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to initialize caches
+
+    new WriteCommandAction.Simple(getProject()) {
+      @Override
+      protected void run() throws Throwable {
+        VirtualFile newFile = dir.createChildData(null, "New.java");
+        VfsUtil.saveText(newFile, "class A{ Exception e;} //todo");
+      }
+    }.execute().throwException();
+
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to update caches
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        final ModifiableRootModel rootModel1 = ModuleRootManager.getInstance(myModule).getModifiableModel();
+        final ContentEntry[] content1 = rootModel1.getContentEntries();
+        contentLoop:
+        for (ContentEntry contentEntry : content1) {
+          if (root.equals(contentEntry.getFile())) {
+            final ExcludeFolder[] excludeFolders = contentEntry.getExcludeFolders();
+            for (ExcludeFolder excludeFolder : excludeFolders) {
+              if (dir.equals(excludeFolder.getFile())) {
+                contentEntry.removeExcludeFolder(excludeFolder);
+                break contentLoop;
+              }
+            }
+          }
+        }
+        rootModel1.commit();
+      }
+    });
+
+
+    PsiClass exceptionClass = myJavaFacade.findClass("java.lang.Exception", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(exceptionClass);
+    checkUsages(exceptionClass, new String[]{"1.java", "2.java", "New.java"});
+    checkTodos(new String[]{"2.java", "New.java"});
+  }
+
+  public void testAddSourceRoot() throws Exception{
+    File dir = createTempDirectory();
+
+    final VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/'));
+
+    new WriteCommandAction.Simple(getProject()) {
+      @Override
+      protected void run() throws Throwable {
+        final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
+        rootModel.addContentEntry(root);
+        rootModel.commit();
+
+        VirtualFile newFile = root.createChildData(null, "New.java");
+        VfsUtil.saveText(newFile, "class A{ Exception e;} //todo");
+      }
+    }.execute().throwException();
+
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to initialize caches
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        final ModifiableRootModel rootModel1 = ModuleRootManager.getInstance(myModule).getModifiableModel();
+        final ContentEntry[] content = rootModel1.getContentEntries();
+        for (ContentEntry contentEntry : content) {
+          if (root.equals(contentEntry.getFile())) {
+            contentEntry.addSourceFolder(root, false);
+            break;
+          }
+        }
+        rootModel1.commit();
+      }
+    });
+
+
+    PsiClass exceptionClass = myJavaFacade.findClass("java.lang.Exception", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(exceptionClass);
+    checkUsages(exceptionClass, new String[]{"1.java", "2.java", "New.java"});
+    checkTodos(new String[]{"2.java", "New.java"});
+  }
+
+  public void testRemoveSourceRoot() throws Exception{
+    final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule);
+    final VirtualFile root = rootManager.getContentRoots()[0];
+
+    PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to initialize caches
+
+    new WriteCommandAction.Simple(getProject()) {
+      @Override
+      protected void run() throws Throwable {
+        VirtualFile newFile = root.createChildData(null, "New.java");
+        VfsUtil.saveText(newFile, "class A{ Exception e;} //todo");
+      }
+    }.execute().throwException();
+
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to update caches
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        VirtualFile[] sourceRoots = rootManager.getSourceRoots();
+        LOG.assertTrue(sourceRoots.length == 1);
+        final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
+        final ContentEntry[] content1 = rootModel.getContentEntries();
+        contentLoop:
+        for (ContentEntry contentEntry : content1) {
+          if (root.equals(contentEntry.getFile())) {
+            final SourceFolder[] sourceFolders = contentEntry.getSourceFolders();
+            for (SourceFolder sourceFolder : sourceFolders) {
+              if (sourceRoots[0].equals(sourceFolder.getFile())) {
+                contentEntry.removeSourceFolder(sourceFolder);
+                break contentLoop;
+              }
+            }
+          }
+        }
+        rootModel.commit();
+      }
+    });
+
+
+    PsiClass exceptionClass = myJavaFacade.findClass("java.lang.Exception", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(exceptionClass);
+    // currently it actually finds usages by FQN due to Java PSI enabled for out-of-source java files
+    // so the following check is disabled 
+    //checkUsages(exceptionClass, new String[]{});
+    checkTodos(new String[]{"2.java", "New.java"});
+  }
+
+  public void testAddProjectRoot() throws Exception{
+    File dir = createTempDirectory();
+
+    final VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/'));
+
+    new WriteCommandAction.Simple(getProject()) {
+      @Override
+      protected void run() throws Throwable {
+        final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
+        rootModel.addContentEntry(root).addSourceFolder(root, false);
+        rootModel.commit();
+
+        VirtualFile newFile = root.createChildData(null, "New.java");
+        VfsUtil.saveText(newFile, "class A{ Exception e;} //todo");
+      }
+    }.execute().throwException();
+
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    PsiSearchHelper.SERVICE.getInstance(myProject).processAllFilesWithWord("aaa", GlobalSearchScope.allScope(myProject), new Processor<PsiFile>() {
+      @Override
+      public boolean process(final PsiFile psiFile) {
+        return true;
+      }
+    }, true); // to initialize caches
+
+/*
+    rootManager.startChange();
+    rootManager.addRoot(root, ProjectRootType.PROJECT);
+    rootManager.finishChange();
+*/
+
+    PsiClass exceptionClass = myJavaFacade.findClass("java.lang.Exception", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(exceptionClass);
+    checkUsages(exceptionClass, new String[]{"1.java", "2.java", "New.java"});
+    checkTodos(new String[]{"2.java", "New.java"});
+  }
+
+  public void testSCR6066() throws Exception{
+    ProjectRootManagerEx rootManager = (ProjectRootManagerEx)ProjectRootManager.getInstance(myProject);
+    final VirtualFile root = rootManager.getContentRoots()[0];
+
+    PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to initialize caches
+
+    new WriteCommandAction.Simple(getProject()) {
+      @Override
+      protected void run() throws Throwable {
+        VirtualFile newFile = root.createChildData(null, "New.java");
+        VfsUtil.saveText(newFile, "class A{ Exception e;} //todo");
+      }
+    }.execute().throwException();
+
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    PsiSearchHelper.SERVICE.getInstance(myProject).findFilesWithTodoItems(); // to update caches
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        final ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
+        final ContentEntry[] content = rootModel.getContentEntries();
+        for (ContentEntry contentEntry : content) {
+          if (root.equals(contentEntry.getFile())) {
+            contentEntry.addExcludeFolder(root);
+            break;
+          }
+        }
+        rootModel.commit();
+      }
+    });
+
+
+    PsiClass exceptionClass = myJavaFacade.findClass("java.lang.Exception", GlobalSearchScope.allScope(getProject()));
+    assertNotNull(exceptionClass);
+    checkUsages(exceptionClass, new String[]{});
+    checkTodos(new String[]{});
+  }
+
+  private void checkUsages(PsiElement element, @NonNls String[] expectedFiles){
+    PsiReference[] refs = ReferencesSearch.search(element, GlobalSearchScope.projectScope(myProject), false).toArray(new PsiReference[0]);
+
+    List<PsiFile> files = new ArrayList<PsiFile>();
+    for (PsiReference ref : refs) {
+      PsiFile file = ref.getElement().getContainingFile();
+      if (!files.contains(file)) {
+        files.add(file);
+      }
+    }
+
+    assertEquals(expectedFiles.length, files.size());
+
+    Collections.sort(files, new Comparator<PsiFile>() {
+      @Override
+      public int compare(PsiFile file1, PsiFile file2) {
+        return file1.getName().compareTo(file2.getName());
+      }
+    });
+    Arrays.sort(expectedFiles);
+
+    for(int i = 0; i < expectedFiles.length; i++){
+      String name = expectedFiles[i];
+      PsiFile file = files.get(i);
+      assertEquals(name, file.getName());
+    }
+  }
+
+  private void checkTodos(@NonNls String[] expectedFiles){
+    PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(myProject);
+
+    PsiFile[] files = helper.findFilesWithTodoItems();
+
+    assertEquals(expectedFiles.length, files.length);
+
+    Arrays.sort(files, new Comparator<PsiFile>() {
+      @Override
+      public int compare(PsiFile file1, PsiFile file2) {
+        return file1.getName().compareTo(file2.getName());
+      }
+    });
+    Arrays.sort(expectedFiles);
+
+    for(int i = 0; i < expectedFiles.length; i++){
+      String name = expectedFiles[i];
+      PsiFile file = files[i];
+      assertEquals(name, file.getName());
+    }
+  }
+}