/*
 * 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.navigation;


import com.intellij.codeInsight.navigation.GotoImplementationHandler;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;

public class GotoImplementationHandlerTest extends JavaCodeInsightFixtureTestCase {

  public void testMultipleImplsFromAbstractCall() throws Throwable {
    PsiFile file = myFixture.addFileToProject("Foo.java", "public abstract class Hello {\n" +
                                                          "    abstract void foo();\n" +
                                                          "\n" +
                                                          "    class A {\n" +
                                                          "        {\n" +
                                                          "            fo<caret>o();\n" +
                                                          "        }\n" +
                                                          "    }\n" +
                                                          "    class Hello1 extends Hello {\n" +
                                                          "        void foo() {}\n" +
                                                          "    }\n" +
                                                          "    class Hello2 extends Hello {\n" +
                                                          "        void foo() {}\n" +
                                                          "    }\n" +
                                                          "}\n" +
                                                          "\n");
    myFixture.configureFromExistingVirtualFile(file.getVirtualFile());

    final PsiElement[] impls = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.getEditor(), file).targets;
    assertEquals(2, impls.length);
  }

  public void testMultipleImplsFromStaticCall() throws Throwable {
    PsiFile file = myFixture.addFileToProject("Foo.java", "public abstract class Hello {\n" +
                                                          "    static void bar (){}\n" +
                                                          "    class Hello1 extends Hello {\n" +
                                                          "    }\n" +
                                                          "    class Hello2 extends Hello {\n" +
                                                          "    }\n" +
                                                          "class D {\n" +
                                                          "    {\n" +
                                                          "        He<caret>llo.bar();\n" +
                                                          "    }\n" +
                                                          "}");
    myFixture.configureFromExistingVirtualFile(file.getVirtualFile());

    final PsiElement[] impls = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.getEditor(), file).targets;
    assertEquals(2, impls.length);
  }

  public void testFilterOutImpossibleVariants() throws Throwable {
    PsiFile file = myFixture.addFileToProject("Foo.java", "interface A {\n" +
                                                          "    void save();\n" +
                                                          "}\n" +
                                                          "interface B extends A {\n" +
                                                          "    void foo();\n" +
                                                          "}\n" +
                                                          "class X implements B {\n" +
                                                          "    public void foo() { }\n" +
                                                          "    public void save(){}\n" +
                                                          "}\n" +
                                                          "class Y implements A {\n" +
                                                          "    public void save(){}\n" +
                                                          "}\n" +
                                                          "class App {\n" +
                                                          "    private B b;\n" +
                                                          "    private void some() {\n" +
                                                          "        b.sa<caret>ve();\n" +
                                                          "    }\n" +
                                                          "}");
    myFixture.configureFromExistingVirtualFile(file.getVirtualFile());

    final PsiElement[] impls = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.getEditor(), file).targets;
    assertEquals(1, impls.length);
    final PsiElement meth = impls[0];
    assertTrue(meth instanceof PsiMethod);
    final PsiClass aClass = ((PsiMethod)meth).getContainingClass();
    assertNotNull(aClass);
    assertEquals(aClass.getName(), "X");
  }
}
@@ -700,16 +700,49 @@
 andler;%0A
+import com.intellij.idea.Bombed;%0A
 import c
@@ -767,16 +767,16 @@
 iClass;%0A
-
 import c
@@ -947,16 +947,44 @@
 tCase;%0A%0A
+import java.util.Calendar;%0A%0A
 public c
@@ -2592,32 +2592,32 @@
  file).targets;%0A
-
     assertEquals
@@ -2632,32 +2632,1778 @@
 s.length);%0A  %7D%0A%0A
+  @Bombed(user = %22maxim.medvedev%22, year = 2013, month = Calendar.MARCH, day = 5)%0A  public void testShowSelfNonAbstract() throws Throwable %7B%0A    //fails if groovy plugin is enabled: org.jetbrains.plugins.groovy.codeInsight.JavaClsMethodElementEvaluator%0A    PsiFile file = myFixture.addFileToProject(%22Foo.java%22, %22public class Hello %7B%5Cn%22 +%0A                                                          %22    void foo()%7B%7D%5Cn%22 +%0A                                                          %22%5Cn%22 +%0A                                                          %22    class A %7B%5Cn%22 +%0A                                                          %22        %7B%5Cn%22 +%0A                                                          %22            fo%3Ccaret%3Eo();%5Cn%22 +%0A                                                          %22        %7D%5Cn%22 +%0A                                                          %22    %7D%5Cn%22 +%0A                                                          %22    class Hello1 extends Hello %7B%5Cn%22 +%0A                                                          %22        void foo() %7B%7D%5Cn%22 +%0A                                                          %22    %7D%5Cn%22 +%0A                                                          %22    class Hello2 extends Hello %7B%5Cn%22 +%0A                                                          %22        void foo() %7B%7D%5Cn%22 +%0A                                                          %22    %7D%5Cn%22 +%0A                                                          %22%7D%5Cn%22 +%0A                                                          %22%5Cn%22);%0A    myFixture.configureFromExistingVirtualFile(file.getVirtualFile());%0A%0A    final PsiElement%5B%5D impls = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.getEditor(), file).targets;%0A    assertEquals(3, impls.length);%0A  %7D%0A%0A
   public void te

test for IDEA-102094