<?xml version="1.0" encoding="UTF-8"?>
<test-data
    xmlns="http://pmd.sourceforge.net/rule-tests"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">

    <test-code>
        <description>1, nothing wrong</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo {
    private List list;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>2, valid implements</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo implements List {
}
        ]]></code>
    </test-code>

    <test-code>
        <description>3, invalid implements</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo implements java.util.List {
}
        ]]></code>
    </test-code>

    <test-code>
        <description>4, valid extends</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.ArrayList;
public class Foo implements ArrayList {
}
        ]]></code>
    </test-code>

    <test-code>
        <description>5, invalid extends</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.ArrayList;
public class Foo implements java.util.ArrayList {
}
        ]]></code>
    </test-code>

    <test-code>
        <description>6, valid field</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo {
    private List list;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>7, invalid field</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo {
    private java.util.List list;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>8, valid return type</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo {
    private List list();
}
        ]]></code>
    </test-code>

    <test-code>
        <description>9, invalid return type</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo {
    private java.util.List list();
}
        ]]></code>
    </test-code>

    <test-code>
        <description>10, valid formal parameter</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo {
    private void list(List list);
}
        ]]></code>
    </test-code>

    <test-code>
        <description>11, invalid formal parameter</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.List;
public class Foo {
    private void list(java.util.List list);
}
        ]]></code>
    </test-code>

    <test-code>
        <description>12, valid static method call</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.Arrays;
import java.util.List;
public class Foo {
    List list = Arrays.asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>13, invalid static method call</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>4</expected-linenumbers>
        <expected-messages>
            <message>Unnecessary qualifier 'java.util': 'Arrays' is already in scope because it is imported in this file</message>
        </expected-messages>
        <code><![CDATA[
import java.util.Arrays;
import java.util.List;
public class Foo {
    List list = java.util.Arrays.asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>14, valid static import method call</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import static java.util.Arrays.asList;
import java.util.List;
public class Foo {
    List list = asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>15, invalid static import method call</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import static java.util.Arrays.asList;
import java.util.List;
public class Foo {
    List list = java.util.Arrays.asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>16, valid static import method call with class import</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.Arrays;
import static java.util.Arrays.asList;
import java.util.List;
public class Foo {
    List list = asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>17, invalid static import method call with class import</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.Arrays;
import java.util.List;
import static java.util.Arrays.asList;
public class Foo {
    List list = Arrays.asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>18, on-demand, valid field</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.*;
public class Foo {
    private List list;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>19, on-demand, invalid field</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.*;
public class Foo {
    private java.util.List list;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>20, on-demand, valid static import method call </description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import static java.util.Arrays.asList;
import java.util.List;
public class Foo {
    List list = asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>21, on-demand, invalid static import method call</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import static java.util.Arrays.*;
import java.util.List;
public class Foo {
    List list = java.util.Arrays.asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>22, valid on-demand static import method call with class import</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.Arrays;
import static java.util.Arrays.*;
import java.util.List;
public class Foo {
    List list = asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>23, invalid on-demand static import method call with class import</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
import java.util.Arrays;
import static java.util.Arrays.*;
import java.util.List;
public class Foo {
    List list = Arrays.asList("one");
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1078 Package statement introduces false positive UnnecessaryFullyQualifiedName violation</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package a.b;

import a.*;

public class Test {}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1404 Java8 'Unnecessary use of fully qualified name' in Streams Collector</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>15</expected-linenumbers>
        <expected-messages>
            <message>Unnecessary qualifier 'Collectors': 'toList' is already in scope</message>
        </expected-messages>
        <code><![CDATA[
// https://github.com/FenixEdu/fenixedu-learning/blob/master/src/main/java/org/fenixedu/learning/domain/executionCourse/components/InitialPageComponent.java#L50
import java.util.Comparator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

public class InitialPageComponent {
    public void handle(Map<String, List<String>> globalContext) {
        List<String> lst = new ArrayList<>();
        globalContext.put("professorships",
                lst.stream().sorted(Comparator.comparingInt(String::length).reversed()
                            .collect(Collectors.toList())));
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1436 UnnecessaryFullyQualifiedName false positive on clashing static imports with enums</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.ENUM2;
import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.ENUM1.*;
import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.ENUM2.*;

public class UnnecessaryFullyQualifiedName {
    public static void main(String[] args) {
        System.out.println(A);
        System.out.println(D);
        System.out.println(ENUM2.values());
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1546 part 1 UnnecessaryFullyQualifiedName doesn't take into consideration conflict resolution</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.PhonyMockito;
import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.PhonyMockito.*;
import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.Container.PhonyMockito.*;

public class Foo {
    private Foo bar = PhonyMockito.mock(Foo.class); // doing simply mock(Foo.class) is ambiguous (compile error)
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1546 part 2 UnnecessaryFullyQualifiedName doesn't take into consideration conflict resolution</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.PhonyMockito;
import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.PhonyMockito.*;
import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.Container.PhonyMockito.mock;

public class Foo {
    private Foo bar = PhonyMockito.mock(Foo.class); // doing simply mock(Foo.class) would use a differen method than intended
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1555 - UnnecessaryFullyQualifiedName for conflict resolution with inner class</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.util.*;

final class Test {
    private Test() { }

    private static class Locale {
        public final java.util.Locale locale; // Here we need to fully qualify
        public Locale(final String tag) {
            this.locale = java.util.Locale.forLanguageTag(tag);
        }
    }

    public static void main(String[] args) {
        final Locale l = new Locale("fr-CA");
        System.out.println(l.toString());
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1114 - Star import overwritten by explicit import is not correctly handled</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.subpackage.*;
import net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.MyClass;

public class CauseProblem {
    public MyClass convert(net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.subpackage.MyClass original) { // necessary
        return new MyClass();
    }
}
            ]]></code>
    </test-code>

    <test-code>
        <description>#1186 [java] UnnecessaryFullyQualifiedName doesn't detect java.lang FQ names as violations: without import</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Unnecessary qualifier 'java.lang': 'String' is already in scope because it is declared in java.lang</message>
        </expected-messages>
        <code><![CDATA[
public class JavaLang {
    public void convert(java.lang.String s) { // violation here
    }
    public void access(java.lang.reflect.Field f) { // no violation
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1186 [java] UnnecessaryFullyQualifiedName doesn't detect java.lang FQ names as violations: with import</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Unnecessary qualifier 'java.lang': 'String' is already in scope because it is imported in this file</message>
        </expected-messages>
        <code><![CDATA[
import java.lang.String;
public class JavaLang {
    public void convert(java.lang.String s) { // violation here
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1186 [java] UnnecessaryFullyQualifiedName doesn't detect java.lang FQ names as violations: with avoiding conflict import</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import org.foo.String;
public class JavaLang {
    public void convert(java.lang.String s) { // no violation
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1186 [java] UnnecessaryFullyQualifiedName doesn't detect java.lang FQ names as violations: static members of classes in java.lang</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
public class JavaLang {
    public void foo() {
        ProcessBuilder pb = new ProcessBuilder("echo");
        pb.redirectError(java.lang.ProcessBuilder.Redirect.DISCARD); // violation
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1216 [java] UnnecessaryFullyQualifiedName false positive for the same name method</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import java.awt.Component;
import java.awt.Container;
import java.util.Arrays;
import java.util.asList.*; // we don't use stream since we're on java 7
import java.util.List;

public final class Test {
    public static List<String> stream(Container parent) {
        return Arrays.asList("", "");
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1255 [java] UnnecessaryFullyQualifiedName false positive: static method on shadowed implicitly imported class</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import x.y.Thread;

public class ThreadStuff {
    public Thread stuff() {
        return new Thread(java.lang.Thread.currentThread());
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Nullpointer in isJavaLangImplicit for java.lang.String[] arrays</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>6</expected-linenumbers>
        <code><![CDATA[
public class TestArrayType {
    String[] someArray = new String[0];

    public void foo() {
        boolean b1 = someArray instanceof String[];
        boolean b2 = someArray instanceof java.lang.String[]; // unnecessary FQN
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1199 false negative for same package FQCN</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>4</expected-linenumbers>
        <expected-messages>
            <message>Unnecessary qualifier 'java.util': 'ArrayList' is already in scope because it is declared in the same package</message>
        </expected-messages>
        <code><![CDATA[
package java.util;

public class SamePackage {
    public void convert(java.util.ArrayList s) { // violation
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#1951 false positive when package name is obscured by variable</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package threads;

public class FQNTest {
  public static void main(String[] args) {
    Thread[] threads = new Thread[5];
    int i = threads.length;
  }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False positive when package name is obscured by variable (2)</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package threads;

public class FQNTest {
    public static void main(String[] args) {
        Thread[] threads = new Thread[5];
        int i = threads.length.foo;
    }
}

class length {
    static int foo;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False negative when name refers to static field</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>6</expected-linenumbers>
        <expected-messages>
            <message>Unnecessary qualifier 'threads': 'length' is already in scope because it is declared in the same package</message>
        </expected-messages>
        <code><![CDATA[
package threads;

public class FQNTest {
    public static void main(String[] args) {
        // threads.length is the class
        int i = threads.length.foo;
    }
}

class length {
    static int foo;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False positive when type name is obscured by variable</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[

public class FQNTest {
    public static void main(String[] args) {
        length length = new length();
        // the type name 'length' is obscured.
        int i = length.foo;
    }
}

class length {
    static int foo;
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False positive when subpackage is referenced</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>6</expected-linenumbers>
        <code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;

public class FQNTest {
    public void foo() {
        new net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.subpackage.MyClass(); // no violation
        new net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.TestClass(); // violation
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False positive when same package static method is referenced</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package java.util;

public class Problem {
    {
        Collections.emptySet(); // false positive for UnnecessaryFullyQualifiedName
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False positive when same package inner class is referenced</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.codestyle;

public class UnnecessaryFullyQualifiedName {
    public static void main(String[] args) {
        System.out.println(UnnecessaryFullyQualifiedNameTest.ENUM1.A);
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>False positive when same package inner class is referenced (not enum) #4085</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;

public class OuterTestClass {
	public static class TestClass{
        private final net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.TestClass test;

        public TestClass(net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.TestClass test){

            this.test = test;
        }
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>Should report fully-qualified name usage of a class in itself #4085</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>4</expected-linenumbers>
        <code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;

public class TestClass {
    public static net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.TestClass INSTANCE(){
        return new TestClass();
    }
}
        ]]></code>
    </test-code>

    <test-code>
        <description>#2098 false positive with annotated package</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
@com.example.subpackage.ExampleAnnotation
package com.example;
        ]]></code>
    </test-code>

    <test-code>
        <description>#2098 false positive with annotated package - with type-resolution</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
@net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.subpackage.MyAnnotation
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;
        ]]></code>
    </test-code>

    <test-code>
        <description>False-Negative when referencing inner class</description>
        <expected-problems>7</expected-problems>
        <expected-linenumbers>3,4,6,7,8,9,12</expected-linenumbers>
        <expected-messages>
            <message>Unnecessary qualifier 'com.example': 'ClassTwo' is already in scope because it is declared in the same package</message>
            <message>Unnecessary qualifier 'com.example': 'ClassTwo' is already in scope because it is declared in the same package</message>
            <message>Unnecessary qualifier 'com.example.ClassOne': 'MyException' is already in scope because it is declared in an enclosing type</message>
            <message>Unnecessary qualifier 'com.example.ClassOne': 'Builder' is already in scope because it is declared in an enclosing type</message>
            <message>Unnecessary qualifier 'com.example': 'ClassTwo' is already in scope because it is declared in the same package</message>
            <message>Unnecessary qualifier 'com.example.ClassOne': 'MyException' is already in scope because it is declared in an enclosing type</message>
            <message>Unnecessary qualifier 'com.example': 'ClassTwo' is already in scope because it is declared in the same package</message>
        </expected-messages>
        <code><![CDATA[
package com.example;

public class ClassOne extends com.example.ClassTwo { // 3
    com.example.ClassTwo.Builder builder = null;     // 4

    public void run() throws com.example.ClassOne.MyException { // 6
        com.example.ClassOne.Builder builder = null;            // 7
        com.example.ClassTwo.Builder builder2 = null;           // 8
        throw new com.example.ClassOne.MyException();           // 9
    }

    public class Builder extends com.example.ClassTwo.Builder { // 12
    }

    public static class MyException extends Exception { }
}

class ClassTwo {
    class Builder { }
}

        ]]></code>
    </test-code>

    <test-code>
        <description>#2029 [java] UnnecessaryFullyQualifiedName false-positive for non-static nested classes</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;

import static net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.TestClass.*;

public class SomeClass {

    public void theMethod() {
        someMethod();
        Object someObject = new Object();
        if(someObject instanceof TestClass.SomeInnerClass) {
            System.out.println("");
        }
    }
}
        ]]></code>
    </test-code>
    <test-code>
        <description>Type parameter shadows java lang</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package ohio;

public class InnerClass<RuntimeException extends ClassCastException> {
    public void method1() throws RuntimeException,
                                 java.lang.RuntimeException {
    }
}

        ]]></code>
    </test-code>
    <test-code>
        <description>Static import on demand does not import same method</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package ohio;

import static org.junit.Assert.*;

public class Something{
    {
        // this is ohio.Assert.isNull, not org.junit.Assert.isNull
        Assert.isNull(null);
    }
}

class Assert {

    public static void isNull(Object o) {}

}

        ]]></code>
    </test-code>
    <test-code>
        <description>Static import on demand from same file</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
package ohio;

import static ohio.Assert.*;

public class Something{
    {
        Assert.isNull(null);
    }
}

class Assert {

    public static void isNull(Object o) {}

}

        ]]></code>
    </test-code>
    <test-code>
        <description>#1790 Enum constant obscures type name!</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            public enum DataType {
                Float(Float.class) {
                    @Override
                    public String toString(final Object value) {
                        if (value == null) {
                            return null;
                        }
                        final int bits = java.lang.Float.floatToIntBits((java.lang.Float) value); // false positive
                        return "";
                    }
                };
                private Class<?> dataClass;

                private DataType(Class<?> dataClass) {
                    this.dataClass = dataClass;
                }

                @Override
                public Class<?> getDataClass() {
                    return dataClass;
                }
            }
        ]]></code>
    </test-code>
    <test-code>
        <description>#2299 Package should not use startsWith</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            package a.b.c;

            class A {
                a.b.car.Car c;
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>Just the Map prefix is a violation</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>7</expected-linenumbers>
        <expected-messages>
            <message>Unnecessary qualifier 'java.util': 'Map' is already in scope because it is imported in this file</message>
        </expected-messages>
        <code><![CDATA[
            package a;

            import java.util.Map;
            import java.util.Set;

            class A<K, V> {
                public Set<java.util.Map.Entry<K, V>> entrySet() {return null;}
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>Inherited method is in scope</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>6</expected-linenumbers>
        <expected-messages>
            <message>Unnecessary qualifier 'ClassLoader': 'registerAsParallelCapable' is already in scope</message>
        </expected-messages>
        <code><![CDATA[
            package a;
            import java.net.URLClassLoader;

            class MyClassLoader extends URLClassLoader {
                {
                    ClassLoader.registerAsParallelCapable();
                }
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>FQCN before field access</description>
        <expected-problems>1</expected-problems>
        <expected-linenumbers>4</expected-linenumbers>
        <expected-messages>
            <message>Unnecessary qualifier 'java.lang': 'Math' is already in scope because it is declared in java.lang</message>
        </expected-messages>
        <code><![CDATA[
            class ComplexButNotFlagged {

                public final double SpecialSum = 2 + 1e10,
                                    SpecialDifference = 4 - java.lang.Math.PI;
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>If there are type argument before method, it should not be flagged</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            package ohio;

            import static ohio.Assert.*;

            public class Something{
                {
                    Assert.<Class<?>>isNull(null);
                }
            }

            class Assert {

                public static <T> void isNull(Object o) {}

            }
            ]]></code>
    </test-code>
    <test-code disabled="true">
        <!-- TODO this causes an error, bc of early disambiguation       -->
        <!--  solution: import on demands must be made entirely lazy     -->
        <description>FN with static method imported through subtype (same file)</description>
        <expected-problems>1</expected-problems>
        <code><![CDATA[
            package ohio;

            import org.junit.Assert;
            import static ohio.Assert2.*;

            public class Something {
                {
                    // this is actually a reference to org.junit.Assert.isNull
                    Assert2.isNull(null);
                }
            }

            class Assert2 extends Assert {}
            ]]></code>
    </test-code>
    <test-code>
        <description>FN with static method imported through subtype</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Unnecessary qualifier 'MockitoInherited': 'PhonyMockito::mock' is already in scope</message>
        </expected-messages>
        <code><![CDATA[
            package ohio;

            import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.PhonyMockito.mock;
            import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.MockitoInherited.*;

            import net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.MockitoInherited;

            public class Something {

                {
                    // this is actually a reference to PhonyMockito::mock
                    MockitoInherited.mock(null);
                }
            }

            ]]></code>
    </test-code>
    <test-code>
        <description>Test field access</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Unnecessary qualifier 'Math': 'PI' is already in scope because it is imported in this file</message>
        </expected-messages>
        <code><![CDATA[
            package ohio;

            import static java.lang.Math.PI;

            public class Something {
                static int i = Math.PI * 2;
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>Test field access FQCN</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Unnecessary qualifier 'java.lang.Math': 'PI' is already in scope because it is imported in this file</message>
        </expected-messages>
        <code><![CDATA[
            package ohio;

            import static java.lang.Math.PI;

            public class Something {
                static int i = java.lang.Math.PI * 2;
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>Test field access disabled</description>
        <rule-property name="reportStaticFields">false</rule-property>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
            package ohio;

            import static java.lang.Math.PI;

            public class Something {
                static int i = Math.PI * 2;
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>Test field access disabled, FQCN is still reported</description>
        <rule-property name="reportStaticFields">false</rule-property>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Unnecessary qualifier 'java.lang': 'Math' is already in scope because it is declared in java.lang</message>
        </expected-messages>
        <code><![CDATA[
            package ohio;

            import static java.lang.Math.PI;

            public class Something {
                static int i = java.lang.Math.PI * 2;
            }
            ]]></code>
    </test-code>
    <test-code>
        <description>Test field access imported through subtype</description>
        <expected-problems>1</expected-problems>
        <expected-messages>
            <message>Unnecessary qualifier 'MockitoInherited': 'PhonyMockito::TWO' is already in scope because it is imported in this file</message>
        </expected-messages>
        <code><![CDATA[
            package ohio;

            import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.PhonyMockito.mock;
            import static net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.MockitoInherited.*;

            import net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameTest.MockitoInherited;

            public class Something {
                static int i = MockitoInherited.TWO * 2;
            }
            ]]></code>
    </test-code>

    <test-code>
        <description>[java] UnnecessaryFullyQualifiedName - FP for inner class pkg.ClassA.Foo implementing pkg.Foo #4133</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;

public class ClassA {
    public static class Foo implements net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.Foo {}
}
]]></code>
    </test-code>

    <test-code>
        <description>[java] UnnecessaryFullyQualifiedName FP when the same simple class name exists in the current package #4139</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname;
class Scratch {
    // note: there is also net.sourceforge.pmd.lang.java.rule.codestyle.unnecessaryfullyqualifiedname.Deprecated...
    @java.lang.Deprecated
    int aField;
}
]]></code>
    </test-code>

    <test-code>
        <description>[java] UnnecessaryFullyQualifiedName fails to recognize illegal self reference in enums #4631</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
package impl;

import api.ObjectID;
import static api.ObjectID.*;

public enum Tree {
    // src/impl/Tree.java:8:   UnnecessaryFullyQualifiedName:  Unnecessary use of fully qualified name 'ObjectID.TEAK_TREE' due to existing static import 'api.ObjectID.*'
    TEAK_TREE(ObjectID.TEAK_TREE, TEAK_TREE_30437, TEAK_TREE_40758);

    private final int[] treeIds;

    Tree(int... treeIds) {
        this.treeIds = treeIds;
    }
}
/*
package api;

public final class ObjectID {
    public static final int TEAK_TREE = 9036;
    public static final int TEAK_TREE_30437 = 30437;
    public static final int TEAK_TREE_40758 = 40758;
}
*/
]]></code>
    </test-code>

    <test-code>
        <description>#1316 FP for local method shadowing static import</description>
        <expected-problems>0</expected-problems>
        <code><![CDATA[
import static java.lang.Thread.setUncaughtExceptionHandler;

public class Foo {
    static {
        setUncaughtExceptionHandler(null); // using static import, ok
    }

    public interface ExceptionHandler {
        void setUncaughtExceptionHandler(Object o);
    }

    private final ExceptionHandler noopHandler = new ExceptionHandler() {
        @Override
        public void setUncaughtExceptionHandler(Object o) {
            Thread.setUncaughtExceptionHandler(null); // need to fully qualify, should be ok
        }
    };
}
]]></code>
    </test-code>
</test-data>
