/*******************************************************************************
 * Copyright (c) 2014, 2016 GK Software AG, and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Stephan Herrmann - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import junit.framework.Test;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.core.util.ExternalAnnotationUtil;
import org.eclipse.jdt.core.util.ExternalAnnotationUtil.MergeStrategy;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.core.ClasspathAttribute;
import org.osgi.framework.Bundle;

@SuppressWarnings({"rawtypes", "unchecked"})
public class ExternalAnnotations18Test extends ModifyingResourceTests {

	/** Bridge to hook the host JRE into the registered ContainerInitializer. */
	static class TestContainerInitializer implements ContainerInitializer.ITestInitializer {

		/** Use this container name in test projects. */
		private static final String TEST_CONTAINER_NAME = "org.eclipse.jdt.core.tests.model.TEST_CONTAINER";
		
		static class TestContainer implements IClasspathContainer {
			IPath path;
			IClasspathEntry[] entries;
			TestContainer(IPath path, IClasspathEntry[] entries){
				this.path = path;
				this.entries = entries;
			}
			public IPath getPath() { return this.path; }
			public IClasspathEntry[] getClasspathEntries() { return this.entries;	}
			public String getDescription() { return this.path.toString(); 	}
			public int getKind() { return 0; }
		}

		public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
			String[] jars = Util.getJavaClassLibs();
			IClasspathEntry[] entries = new IClasspathEntry[jars.length];
			for (int i = 0; i < jars.length; i++)
				entries[i] = JavaCore.newLibraryEntry(new Path(jars[i]), null, null);
			JavaCore.setClasspathContainer(
					new Path(TEST_CONTAINER_NAME),
					new IJavaProject[]{ project },
					new IClasspathContainer[] { new TestContainer(new Path(TEST_CONTAINER_NAME), entries) },
					null);
		}
		public boolean allowFailureContainer() {
			return false;
		}
	}
	
	static class LogListener implements ILogListener {
    	List<IStatus> loggedStatus = new ArrayList<>();
        public void logging(IStatus status, String plugin) {
            this.loggedStatus.add(status);
        }
	}


	protected IJavaProject project;
	protected IPackageFragmentRoot root;
	protected String ANNOTATION_LIB;
	protected final String compliance;
	protected final String jclLib;

	protected static final String MY_MAP_CONTENT = 
			"package libs;\n" + 
			"\n" + 
			"public interface MyMap<K,V> {\n" + 
			"	V get(Object key);\n" + 
			"	V put(K key, V val);\n" + 
			"	V remove(Object key);\n" + 
			"}\n";

	public ExternalAnnotations18Test(String name) {
		this(name, "1.8", "JCL18_LIB");
	}
	
	protected ExternalAnnotations18Test(String name, String compliance, String jclLib) {
		super(name);
		this.compliance = compliance;
		this.jclLib = jclLib;
	}

	// Use this static initializer to specify subset for tests
// All specified tests which do not belong to the class are skipped...
	static {
		// Names of tests to run: can be "testBugXXXX" or "BugXXXX")
//		TESTS_PREFIX = "testLibsWithTypeParameters";
//		TESTS_NAMES = new String[] {"test3"};
//		TESTS_NUMBERS = new int[] { 23, 28, 38 };
//		TESTS_RANGE = new int[] { 21, 38 };
	}
	public static Test suite() {
		return buildModelTestSuite(ExternalAnnotations18Test.class, BYTECODE_DECLARATION_ORDER);
	}

	public void setUpSuite() throws Exception {
		super.setUpSuite();
		
		Bundle[] bundles = getAnnotationBundles();
		File bundleFile = FileLocator.getBundleFile(bundles[0]);
		this.ANNOTATION_LIB = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath();

		// set up class path container bridging to the host JRE:
		ContainerInitializer.setInitializer(new TestContainerInitializer());
	}

	/**
	 * @deprecated indirectly uses deprecated class PackageAdmin
	 */
	protected Bundle[] getAnnotationBundles() {
		return org.eclipse.jdt.core.tests.Activator.getPackageAdmin().getBundles("org.eclipse.jdt.annotation", "[2.0.0,3.0.0)");
	}

	public void tearDownSuite() throws Exception {
		super.tearDownSuite();
		ContainerInitializer.setInitializer(null);
	}
	
	public String getSourceWorkspacePath() {
		// we read individual projects from within this folder:
		return super.getSourceWorkspacePath()+"/ExternalAnnotations18";
	}

	protected String getSourceWorkspacePathBase() {
		return super.getSourceWorkspacePath();
	}

	void setupJavaProject(String name) throws CoreException, IOException {
		this.project = setUpJavaProject(name, this.compliance); //$NON-NLS-1$
		addLibraryEntry(this.project, this.ANNOTATION_LIB, false);
		Map options = this.project.getOptions(true);
		options.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
		this.project.setOptions(options);

		IPackageFragmentRoot[] roots = this.project.getAllPackageFragmentRoots();
		int count = 0;
		for (int i = 0, max = roots.length; i < max; i++) {
			final IPackageFragmentRoot packageFragmentRoot = roots[i];
			switch(packageFragmentRoot.getKind()) {
				case IPackageFragmentRoot.K_SOURCE :
					count++;
					if (this.root == null) {
						this.root = packageFragmentRoot;
					}
			}
		}
		assertEquals("Wrong value", 1, count); //$NON-NLS-1$
		assertNotNull("Should not be null", this.root); //$NON-NLS-1$
	}
	
	void myCreateJavaProject(String name) throws CoreException {
		this.project = createJavaProject(name, new String[]{"src"}, new String[]{this.jclLib}, null, null, "bin", null, null, null, this.compliance);
		addLibraryEntry(this.project, this.ANNOTATION_LIB, false);
		Map options = this.project.getOptions(true);
		options.put(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
		this.project.setOptions(options);

		IPackageFragmentRoot[] roots = this.project.getAllPackageFragmentRoots();
		int count = 0;
		for (int i = 0, max = roots.length; i < max; i++) {
			final IPackageFragmentRoot packageFragmentRoot = roots[i];
			switch(packageFragmentRoot.getKind()) {
				case IPackageFragmentRoot.K_SOURCE :
					count++;
					if (this.root == null) {
						this.root = packageFragmentRoot;
					}
			}
		}
		assertEquals("Wrong value", 1, count); //$NON-NLS-1$
		assertNotNull("Should not be null", this.root); //$NON-NLS-1$
	}
	
	protected void tearDown() throws Exception {
		if (this.project != null)
			this.project.getProject().delete(true, true, null);
		this.project = null;
		this.root = null;
		super.tearDown();
	}

	protected void addLibraryWithExternalAnnotations(
			IJavaProject javaProject,
			String jarName,
			String externalAnnotationPath,
			String[] pathAndContents,
			Map options) throws CoreException, IOException
	{
		createLibrary(javaProject, jarName, "src.zip", pathAndContents, null, this.compliance, options);
		String jarPath = '/' + javaProject.getProject().getName() + '/' + jarName;
		IClasspathAttribute[] extraAttributes = new IClasspathAttribute[] { new ClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, externalAnnotationPath) };
		IClasspathEntry entry = JavaCore.newLibraryEntry(
				new Path(jarPath),
				new Path('/'+javaProject.getProject().getName()+"/src.zip"),
				null/*src attach root*/,
				null/*access rules*/,
				extraAttributes,
				false/*exported*/);
		addClasspathEntry(this.project, entry);
	}

	protected void addProjectDependencyWithExternalAnnotations(
			IJavaProject javaProject,
			String referencedProjectName,
			String externalAnnotationPath,
			Map options) throws CoreException, IOException
	{
		IClasspathAttribute[] extraAttributes = new IClasspathAttribute[] { new ClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, externalAnnotationPath) };
		IClasspathEntry entry = JavaCore.newProjectEntry(
				new Path(referencedProjectName),
				null/*access rules*/,
				false/*combine access rules*/,
				extraAttributes,
				false/*exported*/);
		addClasspathEntry(this.project, entry);
	}

	protected void createFileInProject(String projectRelativeFolder, String fileName, String content) throws CoreException {
		String folderPath = this.project.getProject().getName()+'/'+projectRelativeFolder;
		createFolder(folderPath);
		createFile(folderPath+'/'+fileName, content);
	}

	protected void assertNoMarkers(IMarker[] markers) throws CoreException {
		for (int i = 0; i < markers.length; i++)
			System.err.println("Unexpected marker: "+markers[i].getAttributes().entrySet());
		assertEquals("Number of markers", 0, markers.length);
	}
	
	protected void assertNoProblems(IProblem[] problems) throws CoreException {
		for (int i = 0; i < problems.length; i++)
			System.err.println("Unexpected marker: "+problems[i]);
		assertEquals("Number of markers", 0, problems.length);
	}

	protected void assertProblems(IProblem[] problems, String[] messages, int[] lines) throws CoreException {
		int nMatch = 0;
		for (int i = 0; i < problems.length; i++) {
			for (int j = 0; j < messages.length; j++) {
				if (messages[j] == null) continue;
				if (problems[i].toString().equals(messages[j])
						&& problems[i].getSourceLineNumber() == lines[j]) {
					messages[j] = null;
					problems[i] = null;
					nMatch++;
					break;
				}
			}
		}
		for (int i = 0; i < problems.length; i++) {
			if (problems[i] != null)
				fail("Unexpected problem "+problems[i]+" at "+problems[i].getSourceLineNumber());
		}
		for (int i = 0; i < messages.length; i++) {
			if (messages[i] != null)
				System.err.println("Unmatched problem "+messages[i]);
		}
		assertEquals("Number of problems", messages.length, nMatch);
	}

	protected void assertProblems(IProblem[] problems, String[] messages, int[] lines, int[] severities) throws CoreException {
		int nMatch = 0;
		for (int i = 0; i < problems.length; i++) {
			for (int j = 0; j < messages.length; j++) {
				if (messages[j] == null) continue;
				if (problems[i].toString().equals(messages[j])
						&& problems[i].getSourceLineNumber() == lines[j]) {
					switch(severities[j] & ProblemSeverities.CoreSeverityMASK ) {
					case ProblemSeverities.Error:
						if (!problems[i].isError()) continue;
						break;
					case ProblemSeverities.Warning:
						if (!problems[i].isWarning()) continue;
						break;
					case ProblemSeverities.Info:
						if (!problems[i].isInfo()) continue;
						break;
					default:
						throw new IllegalArgumentException("Bad severity expected: "+severities[j]);
					}
					messages[j] = null;
					problems[i] = null;
					nMatch++;
					break;
				}
			}
		}
		for (int i = 0; i < problems.length; i++) {
			if (problems[i] != null)
				fail("Unexpected problem "+problems[i]+" at "+problems[i].getSourceLineNumber());
		}
		for (int i = 0; i < messages.length; i++) {
			if (messages[i] != null)
				System.err.println("Unmatched problem "+messages[i]);
		}
		assertEquals("Number of problems", messages.length, nMatch);
	}
	protected boolean hasJRE18() {
		return ((AbstractCompilerTest.getPossibleComplianceLevels() & AbstractCompilerTest.F_1_8) != 0);
	}

	String readFully(IFile file) throws IOException, CoreException {
		try (BufferedInputStream bs = new BufferedInputStream(file.getContents())) {
			int available = 0;
			StringBuilder buf = new StringBuilder();
			while ((available = bs.available()) > 0) {
				byte[] contents = new byte[available];
				bs.read(contents);
				buf.append(new String(contents));
			}
			return buf.toString();
		}
	}

	/** Perform full build. */
	public void test1FullBuild() throws Exception {
		setupJavaProject("Test1");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/MyMap.java",
				MY_MAP_CONTENT
			}, null);
		this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
		IMarker[] markers = this.project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
		assertNoMarkers(markers);
	}

	/** Perform full build, annotations are found relative to a variable. */
	public void test1FullBuildWithVariable() throws Exception {
		setupJavaProject("Test1");
		JavaCore.setClasspathVariable("MY_PRJ_ROOT", this.project.getProject().getLocation(), null);
		try {
			addLibraryWithExternalAnnotations(this.project, "lib1.jar", "MY_PRJ_ROOT/annots", new String[] {
					"/UnannotatedLib/libs/MyMap.java",
					MY_MAP_CONTENT
				}, null);
			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			assertNoMarkers(markers);
		} finally {
			JavaCore.removeClasspathVariable("MY_PRJ_ROOT", null);
		}
	}

	/** Reconcile an individual CU. */
	public void test1Reconcile() throws Exception {
		setupJavaProject("Test1");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/MyMap.java",
				MY_MAP_CONTENT
			}, null);
		IPackageFragment fragment = this.root.getPackageFragment("test1");
		ICompilationUnit unit = fragment.getCompilationUnit("Test1.java").getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertNoProblems(problems);
	}
	
	public void testLibs1() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" + 
				"import java.util.Collection;\n" + 
				"import java.util.Iterator;\n" + 
				"\n" + 
				"public interface Lib1 {\n" + 
				"	<T> Iterator<T> unconstrainedTypeArguments1(Collection<T> in);\n" + 
				"	Iterator<String> unconstrainedTypeArguments2(Collection<String> in);\n" + 
				"	<T> Iterator<? extends T> constrainedWildcards(Collection<? extends T> in);\n" + 
				"	<T extends Collection<?>> T constrainedTypeParameter(T in);\n" + 
				"}\n"
			}, null);
		// annotations on type variables & class type in various positions:
		createFileInProject("annots/libs", "Lib1.eea",
				"class libs/Lib1\n" + 
				"\n" + 
				"unconstrainedTypeArguments1\n" + 
				" <T:Ljava/lang/Object;>(Ljava/util/Collection<TT;>;)Ljava/util/Iterator<TT;>;\n" + 
				" <T:Ljava/lang/Object;>(Ljava/util/Collection<T0T;>;)Ljava/util/Iterator<TT;>;\n" +  // position: type argument
				"\n" + 
				"unconstrainedTypeArguments2\n" + 
				" (Ljava/util/Collection<Ljava/lang/String;>;)Ljava/util/Iterator<Ljava/lang/String;>;\n" + 
				" (Ljava/util/Collection<Ljava/lang/String;>;)Ljava/util/Iterator<L1java/lang/String;>;\n" + // position: type argument bound (class type)
				"constrainedWildcards\n" +
				" <T:Ljava/lang/Object;>(Ljava/util/Collection<+TT;>;)Ljava/util/Iterator<+TT;>;\n" +
				" <T:Ljava/lang/Object;>(Ljava/util/Collection<+T0T;>;)Ljava/util/Iterator<+T1T;>;\n" + // positions: wildcard bound
				"constrainedTypeParameter\n" +
				" <T::Ljava/util/Collection<*>;>(TT;)TT;\n" +
				" <T::Ljava/util/Collection<*>;>(T0T;)T1T;\n"); // position: top-level type
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import java.util.Collection;\n" + 
				"import java.util.Iterator;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	Iterator<@NonNull String> test1(Lib1 lib, Collection<@Nullable String> coll) {\n" + 
				"		return lib.unconstrainedTypeArguments1(coll);\n" + 
				"	}\n" + 
				"	Iterator<@NonNull String> test2(Lib1 lib, Collection<@Nullable String> coll) {\n" + 
				"		return lib.unconstrainedTypeArguments2(coll);\n" + 
				"	}\n" +
				"	Iterator<? extends @NonNull String> test3(Lib1 lib, Collection<String> coll) {\n" +
				"		return lib.constrainedWildcards(coll);\n" +
				"	}\n" +
				"	@NonNull Collection<String> test4(Lib1 lib, @Nullable Collection<String> in) {\n" +
				"		return lib.constrainedTypeParameter(in);\n" +
				"	}\n" + 
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertNoProblems(problems);
	}

	public void testLibsWithWildcards() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" + 
				"import java.util.Collection;\n" + 
				"import java.util.Iterator;\n" + 
				"\n" + 
				"public interface Lib1 {\n" + 
				"	Iterator<?> unconstrainedWildcard1(Collection<?> in);\n" + 
				"	Iterator<?> unconstrainedWildcard2(Collection<?> in);\n" + 
				"	Iterator<? extends CharSequence> constrainedWildcard1(Collection<? extends CharSequence> in);\n" + 
				"	Iterator<? super CharSequence> constrainedWildcard2(Collection<? super CharSequence> in);\n" + 
				"}\n"
			}, null);
		// annotations directly on a wildcard (*, +, -)
		createFileInProject("annots/libs", "Lib1.eea",
				"class libs/Lib1\n" + 
				"\n" + 
				"unconstrainedWildcard1\n" + 
				" (Ljava/util/Collection<*>;)Ljava/util/Iterator<*>;\n" + 
				" (Ljava/util/Collection<*>;)Ljava/util/Iterator<*1>;\n" +
				"\n" + 
				"unconstrainedWildcard2\n" + 
				" (Ljava/util/Collection<*>;)Ljava/util/Iterator<*>;\n" + 
				" (Ljava/util/Collection<*>;)Ljava/util/Iterator<*0>;\n" + 
				"\n" + 
				"constrainedWildcard1\n" + 
				" (Ljava/util/Collection<+Ljava/lang/CharSequence;>;)Ljava/util/Iterator<+Ljava/lang/CharSequence;>;\n" + 
				" (Ljava/util/Collection<+Ljava/lang/CharSequence;>;)Ljava/util/Iterator<+0Ljava/lang/CharSequence;>;\n" + 
				"\n" + 
				"constrainedWildcard2\n" + 
				" (Ljava/util/Collection<-Ljava/lang/CharSequence;>;)Ljava/util/Iterator<-Ljava/lang/CharSequence;>;\n" + 
				" (Ljava/util/Collection<-Ljava/lang/CharSequence;>;)Ljava/util/Iterator<-0Ljava/lang/CharSequence;>;\n" + 
				"\n" + 
				"\n");
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import java.util.Collection;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull Object test1(Lib1 lib, Collection<@Nullable String> coll) {\n" + 
				"		 return lib.unconstrainedWildcard1(coll).next();\n" + // OK
				"	}\n" + 
				"	@NonNull Object test2(Lib1 lib, Collection<@Nullable String> coll) {\n" + 
				"		 return lib.unconstrainedWildcard2(coll).next();\n" + // return is nullable -> error
				"	}\n" + 
				"	@NonNull CharSequence test3(Lib1 lib, Collection<@Nullable String> coll) {\n" + 
				"		 return lib.constrainedWildcard1(coll).next();\n" + // '@Nullable ? extends CharSequence' -> error
				"	}\n" + 
				"	@NonNull Object test4(Lib1 lib, Collection<@Nullable CharSequence> coll) {\n" + 
				"		 return lib.constrainedWildcard2(coll).next();\n" + // return is '@Nullable ? super CharSequence' -> error
				"	}\n" + 
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
				"Pb(980) Unsafe interpretation of method return type as '@NonNull' based on the receiver type 'Iterator<@NonNull capture#of ?>'. Type 'Iterator<E>' doesn't seem to be designed with null type annotations in mind",
				"Pb(953) Null type mismatch (type annotations): required '@NonNull Object' but this expression has type '@Nullable capture#of ?'",
				"Pb(953) Null type mismatch (type annotations): required '@NonNull CharSequence' but this expression has type '@Nullable capture#of ? extends CharSequence'",
				"Pb(953) Null type mismatch (type annotations): required '@NonNull Object' but this expression has type '@Nullable capture#of ? super CharSequence'"
			}, new int[] { 10, 13, 16, 19 });
	}
	
	public void testLibsWithArrays() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" + 
				"import java.util.Collection;\n" + 
				"import java.util.Iterator;\n" + 
				"\n" + 
				"public interface Lib1 {\n" + 
				"	String[] constraintArrayTop(String[] in);\n" + 
				"	String[] constraintArrayFull(String[] in);\n" + 
				"	String[][] constraintDeep(String[][] in);\n" + 
				"}\n"
			}, null);
		createFileInProject("annots/libs", "Lib1.eea", 
				"class libs/Lib1\n" + 
				"\n" + 
				"constraintArrayTop\n" + 
				" ([Ljava/lang/String;)[Ljava/lang/String;\n" + 
				" ([0Ljava/lang/String;)[1Ljava/lang/String;\n" + 
				"\n" + 
				"constraintArrayFull\n" + 
				" ([Ljava/lang/String;)[Ljava/lang/String;\n" +
				" ([0L0java/lang/String;)[1L1java/lang/String;\n" +
				"\n" +
				"constraintDeep\n" +
				" ([[Ljava/lang/String;)[[Ljava/lang/String;\n" +
				" ([0[1L0java/lang/String;)[1[0L1java/lang/String;\n");
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	String @NonNull[] test1(Lib1 lib, String @Nullable[] ok, String[] nok) {\n" + 
				"		lib.constraintArrayTop(nok);\n" + 
				"		return lib.constraintArrayTop(ok);\n" + 
				"	}\n" +
				"	@NonNull String @NonNull[] test2(Lib1 lib, @Nullable String @Nullable[] ok, String[] nok) {\n" + 
				"		lib.constraintArrayFull(nok);\n" + 
				"		return lib.constraintArrayFull(ok);\n" + 
				"	}\n" + 
				"	@NonNull String @NonNull[] @Nullable[] test3(Lib1 lib, @Nullable String @Nullable[] @NonNull[] ok, String[][] nok) {\n" + 
				"		lib.constraintDeep(nok);\n" + 
				"		return lib.constraintDeep(ok);\n" + 
				"	}\n" + 
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
			"Pb(955) Null type safety (type annotations): The expression of type 'String[]' needs unchecked conversion to conform to '@Nullable String @Nullable[]'",
			"Pb(955) Null type safety (type annotations): The expression of type 'String[][]' needs unchecked conversion to conform to '@Nullable String @Nullable[] @NonNull[]'",
		}, new int[] { 12, 16 });
	}

	public void testLibsWithFields() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" +
				"public interface Lib1 {\n" + 
				"	String one = \"1\";\n" + 
				"	String none = null;\n" + 
				"}\n"
			}, null);
		createFileInProject("annots/libs", "Lib1.eea", 
				"class libs/Lib1\n" +
				"\n" + 
				"one\n" + 
				" Ljava/lang/String;\n" + 
				" L1java/lang/String;\n" + 
				"\n" + 
				"none\n" + 
				" Ljava/lang/String;\n" +
				" L0java/lang/String;\n" +
				"\n");
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull String test0() {\n" + 
				"		return Lib1.none;\n" + 
				"	}\n" +
				"	@NonNull String test1() {\n" + 
				"		return Lib1.one;\n" + 
				"	}\n" +
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
			"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
		}, new int[] { 8 });
	}

	public void testLibsWithFieldsZipped() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots.zip", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" +
				"public interface Lib1 {\n" + 
				"	String one = \"1\";\n" + 
				"	String none = null;\n" + 
				"}\n"
			}, null);
		Util.createSourceZip(
			new String[] {
				"libs/Lib1.eea", 
				"class libs/Lib1\n" +
				"\n" + 
				"one\n" + 
				" Ljava/lang/String;\n" + 
				" L1java/lang/String;\n" + 
				"\n" + 
				"none\n" + 
				" Ljava/lang/String;\n" +
				" L0java/lang/String;\n" +
				"\n"
			},
			this.project.getProject().getLocation().toString()+"/annots.zip");
	    this.project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);

		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull String test0() {\n" + 
				"		return Lib1.none;\n" + 
				"	}\n" +
				"	@NonNull String test1() {\n" + 
				"		return Lib1.one;\n" + 
				"	}\n" +
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
			"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
		}, new int[] { 8 });
	}

	public void testLibsWithFieldsExternalZipped() throws Exception {
		myCreateJavaProject("TestLibs");
		String zipPath = Util.getOutputDirectory() + '/' + "annots.zip";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", zipPath, new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" +
				"public interface Lib1 {\n" + 
				"	String one = \"1\";\n" + 
				"	String none = null;\n" + 
				"}\n"
			}, null);
		Util.createSourceZip(
			new String[] {
				"libs/Lib1.eea", 
				"class libs/Lib1\n" +
				"\n" + 
				"one\n" + 
				" Ljava/lang/String;\n" + 
				" L1java/lang/String;\n" + 
				"\n" + 
				"none\n" + 
				" Ljava/lang/String;\n" +
				" L0java/lang/String;\n" +
				"\n"
			},
			zipPath);

		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull String test0() {\n" + 
				"		return Lib1.none;\n" + 
				"	}\n" +
				"	@NonNull String test1() {\n" + 
				"		return Lib1.one;\n" + 
				"	}\n" +
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
			"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
		}, new int[] { 8 });
	}

	public void testLibsWithTypeParameters() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" +
				"public interface Lib1<U,V,W extends U> {\n" + 
				"	U getU();\n" + 
				"	V getV();\n" +
				"	W getW();\n" +
				"	<X,Y extends CharSequence> Y fun(X x);\n" + 
				"}\n"
			}, null);
		createFileInProject("annots/libs", "Lib1.eea", 
				"class libs/Lib1\n" +
				" <U:Ljava/lang/Object;V:Ljava/lang/Object;W:TU;>\n" +
				" <0U:Ljava/lang/Object;1V:Ljava/lang/Object;W:T1U;>\n" +
				"\n" +
				"fun\n" +
				" <X:Ljava/lang/Object;Y::Ljava/lang/CharSequence;>(TX;)TY;\n" +
				" <1X:Ljava/lang/Object;Y::L1java/lang/CharSequence;>(TX;)TY;\n" +
				"\n");
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull String test0(Lib1<@Nullable String,@NonNull String,@NonNull String> l) {\n" + 
				"		return l.getU();\n" + // mismatch: U is nullable 
				"	}\n" +
				"	@NonNull String test1(Lib1<@Nullable String,@NonNull String,@NonNull String> l) {\n" + 
				"		return l.getV();\n" + // OK: V is nonnull
				"	}\n" +
				"	@NonNull String test2(Lib1<@Nullable String,@NonNull String,@NonNull String> l) {\n" + 
				"		return l.getW();\n" + // OK: V is nonnull
				"	}\n" +
				"	Lib1<@NonNull String, @NonNull String, @NonNull String> f1;\n" + // mismatch at U
				"	Lib1<@Nullable String, String, @NonNull String> f2;\n" + // mismatch at V
				"	Lib1<@Nullable String, @NonNull String, @Nullable String> f3;\n" + // mismatch at W
				"	@Nullable String test3(Lib1<@Nullable String,@NonNull String,@NonNull String> l) {\n" +
				"		return l.<@Nullable String,@Nullable String>fun(\"\");\n" + // mismatches at X and Y
				"	}\n" +
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
			"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
			"Pb(964) Null constraint mismatch: The type '@NonNull String' is not a valid substitute for the type parameter '@Nullable U extends Object'",
			"Pb(964) Null constraint mismatch: The type 'String' is not a valid substitute for the type parameter '@NonNull V extends Object'",
			"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter 'W extends @NonNull U extends Object'",
			"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter '@NonNull X extends Object'",
			"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter 'Y extends @NonNull CharSequence'",
		}, new int[] { 8, 16, 17, 18, 20, 20 });
	}

	public void testLibsWithTypeArgOfSuper() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/LibSuper.java",
				"package libs;\n" + 
				"\n" +
				"public interface LibSuper<T,U> {\n" + 
				"	U apply(T t);\n" + 
				"}\n",
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" +
				"public interface Lib1 extends LibSuper<String,Exception> {\n" + 
				"}\n"
			}, null);
		createFileInProject("annots/libs", "Lib1.eea", 
				"class libs/Lib1\n" +
				"super libs/LibSuper\n" +
				" <Ljava/lang/String;Ljava/lang/Exception;>\n" +
				" <L1java/lang/String;L0java/lang/Exception;>\n" +
				"\n");
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull Exception test0(Lib1 lib, @Nullable String str) {\n" + 
				"		return lib\n" +
				"				.apply(str);\n" + 
				"	}\n" +
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
			"Pb(953) Null type mismatch (type annotations): required '@NonNull Exception' but this expression has type '@Nullable Exception'",
			"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
		}, new int[] { 8, 9 });
	}

	/** Project with real JRE. */
	public void test2() throws Exception {
		// library type used: j.u.Map (no need for JRE8)
		Hashtable options = JavaCore.getOptions();
		try {
			setupJavaProject("Test2");
			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			assertNoMarkers(markers);
		} finally {
			// project using a full JRE container initializes global options to 1.8 -- must reset now:
			JavaCore.setOptions(options);
		}
	}

	/** Project with real JRE8.
	 * More interesting work with generics
	 * .classpath uses var TESTWORK for path to external annotations.
	 */
	public void test3() throws Exception {
		if (!hasJRE18()) {
			System.out.println("Skipping ExternalAnnotations18Test.test3(), needs JRE8");
			return;
		}
		final String TESTWORK_VAR_NAME = "TESTWORK";
		JavaCore.setClasspathVariable(TESTWORK_VAR_NAME, new Path(getSourceWorkspacePath()), null);
		Hashtable options = JavaCore.getOptions();
		try {
			setupJavaProject("Test3");
			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			assertNoMarkers(markers);
		} finally {
			// project using a full JRE container initializes global options to 1.8 -- must reset now:
			JavaCore.setOptions(options);
			JavaCore.removeClasspathVariable(TESTWORK_VAR_NAME, null);
		}
	}

	// ===== Full round trip: detect problem - annotated - detect problem change =====

	public void testAnnotateFieldWithParameterizedType() throws Exception {
		myCreateJavaProject("TestLibs");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"public abstract class Lib1<T> {\n" +
				"	public Lib1<T> one;\n" +
				"	public abstract T get();\n" +
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				lib1Content
			}, null);

		// type check sources:
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit cu = fragment.createCompilationUnit("Test1.java",
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull String test0(Lib1<String> stringLib) {\n" + 
				"		return stringLib.one.get();\n" + 
				"	}\n" +
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = cu.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertProblems(reconciled.getProblems(), new String[] {
				"Pb(955) Null type safety (type annotations): The expression of type 'String' needs unchecked conversion to conform to '@NonNull String'",
		}, new int[] { 8 });

		// acquire library AST:
		IType type = this.project.findType("libs.Lib1");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("one");
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be simple name", name.getNodeType() == ASTNode.SIMPLE_NAME);
		IVariableBinding fieldBinding = (IVariableBinding) ((SimpleName)name).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, fieldBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestLibs/annots/libs/Lib1.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericTypeSignature(fieldBinding.getVariableDeclaration().getType());
		ExternalAnnotationUtil.annotateMember("libs/Lib1", annotationFile,
				"one", 
				originalSignature, 
				"Llibs/Lib1<T0T;>;", 
				MergeStrategy.OVERWRITE_ANNOTATIONS, null);
		assertTrue("file should exist", annotationFile.exists());

		// check that the error is even worse now:
		reconciled = cu.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertProblems(reconciled.getProblems(), new String[] {
				"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
		}, new int[] { 8 });
	}
	

	public void testAnnotateMethodParameter() throws Exception {
		myCreateJavaProject("TestLibs");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"public abstract class Lib1<T,U> {\n" +
				"	public abstract void take(Lib1<X,U> lx);\n" +
				"	public static class X {}\n" +
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				lib1Content
			}, null);

		// type check sources:
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit cu = fragment.createCompilationUnit("Test1.java",
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	void test0(Lib1<Lib1.X,@Nullable String> xLib1, Lib1<Lib1.@Nullable X,@NonNull String> xLib2) {\n" + 
				"		xLib1.take(xLib2);\n" + 
				"	}\n" +
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = cu.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertProblems(reconciled.getProblems(), new String[] {
				"Pb(953) Null type mismatch (type annotations): required 'Lib1<Lib1.X,@Nullable String>' but this expression has type 'Lib1<Lib1.@Nullable X,@NonNull String>'",
		}, new int[] { 7 });

		// acquire library AST:
		IType type = this.project.findType("libs.Lib1");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("take");
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be simple name", name.getNodeType() == ASTNode.SIMPLE_NAME);
		ASTNode method = name.getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestLibs/annots/libs/Lib1.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		ExternalAnnotationUtil.annotateMember("libs/Lib1", annotationFile,
				"take", 
				originalSignature, 
				"(Llibs/Lib1<L0libs/Lib1$X;T1U;>;)V", // <- two annotations: @Nullable X and @NonNull U
				MergeStrategy.OVERWRITE_ANNOTATIONS, null);
		assertTrue("file should exist", annotationFile.exists());

		// check that the error is resolved now:
		reconciled = cu.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertNoProblems(reconciled.getProblems());
	}
	

	public void testAnnotateConstructorParameter() throws Exception {
		myCreateJavaProject("TestLibs");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"public class Lib1<U> {\n" +
				"	public Lib1(int ignore, U string) {}\n" +
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				lib1Content
			}, null);

		// type check sources:
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit cu = fragment.createCompilationUnit("Test1.java",
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	Object test0() {\n" + 
				"		Lib1<@NonNull String> lib = new Lib1<>(1, null);\n" +
				"		return lib;\n" + 
				"	}\n" +
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = cu.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertProblems(reconciled.getProblems(), new String[] {
				"Pb(910) Null type mismatch: required '@NonNull String' but the provided value is null",
		}, new int[] { 7 });

		// acquire library AST:
		IType type = this.project.findType("libs.Lib1");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("U string");
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be simple name", name.getNodeType() == ASTNode.SIMPLE_NAME);
		ASTNode method = name.getParent().getParent().getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestLibs/annots/libs/Lib1.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		ExternalAnnotationUtil.annotateMember("libs/Lib1", annotationFile,
				"<init>", 
				originalSignature, 
				"(IT0U;)V", // <- @Nullable U
				MergeStrategy.OVERWRITE_ANNOTATIONS, null);
		assertTrue("file should exist", annotationFile.exists());

		// check that the error is resolved now:
		reconciled = cu.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertNoProblems(reconciled.getProblems());
		
		// invert annotation:
		ExternalAnnotationUtil.annotateMethodParameterType("libs/Lib1", annotationFile,
				"<init>", 
				originalSignature, 
				"T1U;", // <- @NonNull U
				1, // position 
				MergeStrategy.OVERWRITE_ANNOTATIONS, null);
		assertTrue("file should exist", annotationFile.exists());

		// check that the error is back now:
		reconciled = cu.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertProblems(reconciled.getProblems(), new String[] {
				"Pb(910) Null type mismatch: required '@NonNull String' but the provided value is null",
		}, new int[] { 7 });

		// check that the previous entry has been overwritten:
		assertEquals(
				"class libs/Lib1\n" + 
				"<init>\n" + 
				" (ITU;)V\n" + 
				" (IT1U;)V\n",
				readFully(annotationFile));
	}

	// ===== white box tests for ExternalAnnotationUtil =====

	public void testBug470666a() throws CoreException, IOException {
		myCreateJavaProject("TestAnnot");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"interface Function<T,U> {}\n" +
				"interface Collector<T,A,R> {}\n" +
				"public class Collectors {\n" +
				"	 public static <T, U, A, R>\n" + 
				"    Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,\n" + 
				"                               Collector<? super U, A, R> downstream) { return null; }\n" +
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Collectors.java",
				lib1Content
			}, null);

		// acquire library AST:
		IType type = this.project.findType("libs.Collectors");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("T, ? extends U>"); // bound of type param of method param
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be simple name", name.getNodeType() == ASTNode.SIMPLE_NAME);
		ASTNode method = name.getParent();
		while (!(method instanceof MethodDeclaration))
			method = method.getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestAnnot/annots/libs/Collectors.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		String[] annotatedSign = ExternalAnnotationUtil.annotateParameterType(
				originalSignature, 
				"Llibs/Function<-T1T;+TU;>;",  // <- @NonNull T
				0, MergeStrategy.OVERWRITE_ANNOTATIONS);
		assertEquals("dry-run result", "[<T:Ljava/lang/Object;U:Ljava/lang/Object;A:Ljava/lang/Object;R:Ljava/lang/Object;>(, " + 
				"Llibs/Function<-TT;+TU;>;, " + 
				"Llibs/Function<-T1T;+TU;>;, " +  // <- @NonNull T
				"Llibs/Collector<-TU;TA;TR;>;)Llibs/Collector<TT;*TR;>;]",
				Arrays.toString(annotatedSign));
	}

	public void testBug470666b() throws CoreException, IOException {
		myCreateJavaProject("TestAnnot");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"interface Function<T,U> {}\n" +
				"interface Collector<T,A,R> {}\n" +
				"public class Collectors {\n" +
				"	 public static <T, U, A, R>\n" + 
				"    Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,\n" + 
				"                               Collector<? super U, A, R> downstream) { return null; }\n" +
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Collectors.java",
				lib1Content
			}, null);

		// acquire library AST:
		IType type = this.project.findType("libs.Collectors");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("T, ?, R>"); // bound of return type
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be simple name", name.getNodeType() == ASTNode.SIMPLE_NAME);
		ASTNode method = name.getParent();
		while (!(method instanceof MethodDeclaration))
			method = method.getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestAnnot/annots/libs/Collectors.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		String[] annotatedSign = ExternalAnnotationUtil.annotateReturnType(
				originalSignature, 
				"Llibs/Collector<T1T;*TR;>;",  // <- @NonNull T
				MergeStrategy.OVERWRITE_ANNOTATIONS);
		assertEquals("dry-run result", "[<T:Ljava/lang/Object;U:Ljava/lang/Object;A:Ljava/lang/Object;R:Ljava/lang/Object;>(Llibs/Function<-TT;+TU;>;Llibs/Collector<-TU;TA;TR;>;), " + 
				"Llibs/Collector<TT;*TR;>;, " +
				"Llibs/Collector<T1T;*TR;>;, " +  // <- @NonNull T
				"]",
				Arrays.toString(annotatedSign));
	}

	public void testBug464081() throws CoreException, IOException {
		myCreateJavaProject("TestAnnot");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"interface List<T> {}\n" +
				"public class Collections {\n" +
				"	 public static <T> List<T> unmodifiableList(List<? extends T> list) { return null; }\n" +
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Collections.java",
				lib1Content
			}, null);

		// acquire library AST:
		IType type = this.project.findType("libs.Collections");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("List<? extends T>");
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be simple name", name.getNodeType() == ASTNode.SIMPLE_NAME);
		ASTNode method = name.getParent();
		while (!(method instanceof MethodDeclaration))
			method = method.getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestAnnot/annots/libs/Collections.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		String[] annotatedSign = ExternalAnnotationUtil.annotateParameterType(
				originalSignature, 
				"Llibs/List<+T1T;>;",  // <- @NonNull T
				0, MergeStrategy.OVERWRITE_ANNOTATIONS);
		assertEquals("dry-run result",
				"[<T:Ljava/lang/Object;>(, " +
				"Llibs/List<+TT;>;, " + 
				"Llibs/List<+T1T;>;, " +  // <- @NonNull T
				")Llibs/List<TT;>;]",
				Arrays.toString(annotatedSign));
	}

	public void testBug471352() throws CoreException, IOException {
		myCreateJavaProject("TestAnnot");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"interface List<T> {}\n" +
				"class Random {}\n" +
				"public class Collections {\n" +
				"	 public static void shuffle(List<?> list, Random rnd) { }\n" +
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Collections.java",
				lib1Content
			}, null);

		// acquire library AST:
		IType type = this.project.findType("libs.Collections");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("Random rnd");
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be simple name", name.getNodeType() == ASTNode.SIMPLE_NAME);
		ASTNode method = name.getParent();
		while (!(method instanceof MethodDeclaration))
			method = method.getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestAnnot/annots/libs/Collections.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		String[] annotatedSign = ExternalAnnotationUtil.annotateParameterType(
				originalSignature, 
				"L1libs/Random;",  // <- @NonNull Random
				1, MergeStrategy.OVERWRITE_ANNOTATIONS);
		assertEquals("dry-run result",
				"[(Llibs/List<*>;, " +
				"Llibs/Random;, " + 
				"L1libs/Random;, " +  // <- @NonNull Random
				")V]",
				Arrays.toString(annotatedSign));
	}

	// array content
	public void testBug471034a() throws CoreException, IOException {
		myCreateJavaProject("TestAnnot");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"interface List<T> {}\n" +
				"class Random {}\n" +
				"public class Thread {\n" +
				"	 public static int enumerate(Thread tarray[]) { return 1; }\n" + 
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Thread.java",
				lib1Content
			}, null);

		// acquire library AST:
		IType type = this.project.findType("libs.Thread");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("Thread tarray[]");
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be simple name", name.getNodeType() == ASTNode.SIMPLE_NAME);
		ASTNode method = name.getParent();
		while (!(method instanceof MethodDeclaration))
			method = method.getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestAnnot/annots/libs/Thread.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		String[] annotatedSign = ExternalAnnotationUtil.annotateParameterType(
				originalSignature, 
				"[L1libs/Thread;",  // <- @NonNull Thread
				0, MergeStrategy.OVERWRITE_ANNOTATIONS);
		assertEquals("dry-run result",
				"[(, " +
				"[Llibs/Thread;, " + 
				"[L1libs/Thread;, " +  // <- @NonNull Thread
				")I]",
				Arrays.toString(annotatedSign));
	}

	// array dimension
	public void testBug471034b() throws CoreException, IOException {
		myCreateJavaProject("TestAnnot");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"interface List<T> {}\n" +
				"class Random {}\n" +
				"public class Thread {\n" +
				"	 public static int enumerate(Thread tarray[][]) { return 1; }\n" + 
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Thread.java",
				lib1Content
			}, null);

		// acquire library AST:
		IType type = this.project.findType("libs.Thread");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("[][]");
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be dimension", name.getNodeType() == ASTNode.DIMENSION);
		ASTNode method = name.getParent();
		while (!(method instanceof MethodDeclaration))
			method = method.getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestAnnot/annots/libs/Thread.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		String[] annotatedSign = ExternalAnnotationUtil.annotateParameterType(
				originalSignature, 
				"[1[Llibs/Thread;",  // <- @NonNull array
				0, MergeStrategy.OVERWRITE_ANNOTATIONS);
		assertEquals("dry-run result",
				"[(, " +
				"[[Llibs/Thread;, " + 
				"[1[Llibs/Thread;, " +  // <- @NonNull array
				")I]",
				Arrays.toString(annotatedSign));
	}

	// varargs
	public void testBug471034c() throws CoreException, IOException {
		myCreateJavaProject("TestAnnot");
		String lib1Content =
				"package libs;\n" + 
				"\n" +
				"interface List<T> {}\n" +
				"class Random {}\n" +
				"public class Thread {\n" +
				"	 public static int enumerate(Thread ... tarray) { return 1; }\n" + 
				"}\n";
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Thread.java",
				lib1Content
			}, null);

		// acquire library AST:
		IType type = this.project.findType("libs.Thread");
		ICompilationUnit libWorkingCopy = type.getClassFile().getWorkingCopy(this.wcOwner, null);
		ASTParser parser = ASTParser.newParser(AST.JLS8);
		parser.setSource(libWorkingCopy);
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(false);
		parser.setBindingsRecovery(false);
		CompilationUnit unit = (CompilationUnit) parser.createAST(null);
		libWorkingCopy.discardWorkingCopy();
		
		// find type binding:
		int start = lib1Content.indexOf("...");
		ASTNode name = NodeFinder.perform(unit, start, 0);
		assertTrue("should be variable", name.getNodeType() == ASTNode.SINGLE_VARIABLE_DECLARATION);
		ASTNode method = name.getParent();
		while (!(method instanceof MethodDeclaration))
			method = method.getParent();
		IMethodBinding methodBinding = ((MethodDeclaration)method).resolveBinding();
		
		// find annotation file (not yet existing):
		IFile annotationFile = ExternalAnnotationUtil.getAnnotationFile(this.project, methodBinding.getDeclaringClass(), null);
		assertFalse("file should not exist", annotationFile.exists());
		assertEquals("file path", "/TestAnnot/annots/libs/Thread.eea", annotationFile.getFullPath().toString());

		// annotate:
		String originalSignature = ExternalAnnotationUtil.extractGenericSignature(methodBinding);
		String[] annotatedSign = ExternalAnnotationUtil.annotateParameterType(
				originalSignature, 
				"[1Llibs/Thread;",  // <- @NonNull array
				0, MergeStrategy.OVERWRITE_ANNOTATIONS);
		assertEquals("dry-run result",
				"[(, " +
				"[Llibs/Thread;, " + 
				"[1Llibs/Thread;, " +  // <- @NonNull array
				")I]",
				Arrays.toString(annotatedSign));
	}

	public void testBrokenConfig1() throws Exception {
		LogListener listener = new LogListener();
		try {
			Platform.addLogListener(listener);
	
			myCreateJavaProject("TestBrokenConfig1");
			addLibraryWithExternalAnnotations(this.project, "lib1.jar", "/NoProject", new String[] {
					"/UnannotatedLib/libs/Lib1.java",
					"package libs;\n" + 
					"\n" + 
					"import java.util.Collection;\n" + 
					"import java.util.Iterator;\n" + 
					"\n" + 
					"public interface Lib1 {\n" + 
					"	<T> Iterator<T> unconstrainedTypeArguments1(Collection<T> in);\n" + 
					"	Iterator<String> unconstrainedTypeArguments2(Collection<String> in);\n" + 
					"	<T> Iterator<? extends T> constrainedWildcards(Collection<? extends T> in);\n" + 
					"	<T extends Collection<?>> T constrainedTypeParameter(T in);\n" + 
					"}\n",
					"/UnannotatedLib/libs/Lib2.java",
					"package libs;\n" +
					"public interface Lib2 {\n" +
					"	String test(String s);\n" +
					"}\n"
				}, null);
			IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
			ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
					"package tests;\n" + 
					"import org.eclipse.jdt.annotation.*;\n" + 
					"\n" + 
					"import java.util.Collection;\n" + 
					"import java.util.Iterator;\n" + 
					"\n" + 
					"import libs.Lib1;\n" + 
					"\n" + 
					"public class Test1 {\n" + 
					"	Iterator<@NonNull String> test1(Lib1 lib, Collection<@Nullable String> coll) {\n" + 
					"		return lib.unconstrainedTypeArguments1(coll);\n" + 
					"	}\n" + 
					"	Iterator<@NonNull String> test2(Lib1 lib, Collection<@Nullable String> coll) {\n" + 
					"		return lib.unconstrainedTypeArguments2(coll);\n" + 
					"	}\n" +
					"	Iterator<? extends @NonNull String> test3(Lib1 lib, Collection<String> coll) {\n" +
					"		return lib.constrainedWildcards(coll);\n" +
					"	}\n" +
					"	@NonNull Collection<String> test4(Lib1 lib, @Nullable Collection<String> in) {\n" +
					"		return lib.constrainedTypeParameter(in);\n" +
					"	}\n" + 
					"}\n",
					true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
			CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
			IProblem[] problems = reconciled.getProblems();
			assertEquals("number of problems", 4, problems.length);

			// second class to test if problem is logged more than once
			ICompilationUnit unit2 = fragment.createCompilationUnit("Test2.java", 
					"package tests;\n" + 
					"import libs.Lib2;\n" + 
					"\n" + 
					"public class Test2 {\n" + 
					"	void test1(Lib2 lib) {\n" +
					"		lib.test(null);\n" + 
					"	}\n" + 
					"}\n",
					true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
			CompilationUnit reconciled2 = unit2.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
			assertNoProblems(reconciled2.getProblems());
			
			assertEquals("number of log entries", 0, listener.loggedStatus.size());
		} finally {
			Platform.removeLogListener(listener);
		}
	}

	/** Lib exists as workspace project. Perform full build. */
	public void testProjectDependencyFullBuild() throws Exception {
		try {
			setupJavaProject("Lib");
			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
	
			setupJavaProject("Test1");
			addProjectDependencyWithExternalAnnotations(this.project, "/Lib", "annots", null);
			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			IMarker[] markers = this.project.getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			assertNoMarkers(markers);
		} finally {
			deleteProject("Lib");
		}
	}

	/** Lib exists as workspace project. Reconcile an individual CU. */
	public void testProjectDependencyReconcile1() throws Exception {
		try {
			setupJavaProject("Lib");
			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			this.root = null; // prepare to get the root from project Test1
	
			setupJavaProject("Test1");
			addProjectDependencyWithExternalAnnotations(this.project, "/Lib", "annots", null);
			IPackageFragment fragment = this.root.getPackageFragment("test1");
			ICompilationUnit unit = fragment.getCompilationUnit("Test1.java").getWorkingCopy(new NullProgressMonitor());
			CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
			IProblem[] problems = reconciled.getProblems();
			assertNoProblems(problems);
		} finally {
			deleteProject("Lib");
		}
	}

	/** Lib exists as workspace project. Type-Annotations in zip file. Reconcile an individual CU. */
	public void testProjectDependencyReconcile2() throws Exception {
		try {
			setupJavaProject("Lib");
			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			this.root = null; // prepare to get the root from project Test1
	
			setupJavaProject("Test3b");
			Util.createSourceZip(
				new String[] {
					"libs/MyFunction.eea", 
					"class libs/MyFunction\n" + 
					" <T:R:>\n" + 
					"\n" + 
					"compose\n" + 
					" <V:Ljava/lang/Object;>(Llibs/MyFunction<-TV;+TT;>;)Llibs/MyFunction<TV;TR;>;\n" + 
					" <V:Ljava/lang/Object;>(Llibs/MyFunction<-TV;+T0T;>;)Llibs/MyFunction<TV;TR;>;\n" + 
					"\n",
					"libs/Arrays.eea", 
					"class libs/Arrays\n" + 
					"\n" +
					"array\n" +
					" [Ljava/lang/String;\n" +
					" [1L0java/lang/String;\n" +
					"\n" + 
					"getArray\n" +
					" ()[[Ljava/lang/String;\n" +
					" ()[0[1L0java/lang/String;\n"
				},
				this.project.getProject().getLocation().toString()+"/annots.zip");
			this.project.getProject().refreshLocal(1, new NullProgressMonitor());

			addProjectDependencyWithExternalAnnotations(this.project, "/Lib", "annots.zip", null);
			IPackageFragment fragment = this.root.getPackageFragment("test1");
			ICompilationUnit unit = fragment.getCompilationUnit("Reconcile2.java").getWorkingCopy(new NullProgressMonitor());
			CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
			IProblem[] problems = reconciled.getProblems();
			assertNoProblems(problems);
		} finally {
			deleteProject("Lib");
		}
	}

	/** Lib exists as workspace project. Invocations conflict with type parameter constraints. Reconcile an individual CU. */
	public void testProjectDependencyReconcile3() throws Exception {
		try {
			setupJavaProject("Lib");
			this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
			this.root = null; // prepare to get the root from project Test1
	
			setupJavaProject("Test3b");
			Util.createSourceZip(
				new String[] {
					"libs/MyFunction.eea", 
					"class libs/MyFunction\n" + 
					" <T:R:>\n" + 
					" <T:1R:>\n" + 
					"\n" + 
					"compose\n" + 
					" <V:Ljava/lang/Object;>(Llibs/MyFunction<-TV;+TT;>;)Llibs/MyFunction<TV;TR;>;\n" + 
					" <1V:Ljava/lang/Object;>(Llibs/MyFunction<-TV;+TT;>;)Llibs/MyFunction<TV;TR;>;\n" + 
					"\n",
				},
				this.project.getProject().getLocation().toString()+"/annots.zip");
			this.project.getProject().refreshLocal(1, new NullProgressMonitor());

			addProjectDependencyWithExternalAnnotations(this.project, "/Lib", "annots.zip", null);
			IPackageFragment fragment = this.root.getPackageFragment("test1");
			ICompilationUnit unit = fragment.getCompilationUnit("Reconcile3.java").getWorkingCopy(new NullProgressMonitor());
			CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
			assertProblems(reconciled.getProblems(), new String[] {
					"Pb(964) Null constraint mismatch: The type '@Nullable B' is not a valid substitute for the type parameter '@NonNull R'",
					"Pb(964) Null constraint mismatch: The type '@Nullable String' is not a valid substitute for the type parameter '@NonNull V'",
			}, new int[] { 12, 17 });
		} finally {
			deleteProject("Lib");
		}
	}
	
	public void testFreeTypeVariableReturn() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" + 
				"public interface Lib1<T> {\n" + 
				"	T get();\n" + 
				"}\n"
			}, null);
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull String test0(Lib1<@Nullable String> lib) {\n" + 
				"		return lib.get();\n" + 
				"	}\n" + 
				"	@NonNull String test1(Lib1<@NonNull String> lib) {\n" + 
				"		return lib.get();\n" + 
				"	}\n" + 
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertProblems(reconciled.getProblems(), new String[] {
				"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
				"Pb(980) Unsafe interpretation of method return type as '@NonNull' based on the receiver type 'Lib1<@NonNull String>'. Type 'Lib1<T>' doesn't seem to be designed with null type annotations in mind",
		}, new int[] { 8, 11 });
		// just mark that Lib1 now has null annotations:
		createFileInProject("annots/libs", "Lib1.eea",
				"class libs/Lib1\n" +
				" <T:Ljava/lang/Object;>\n" + 
				" <T:Ljava/lang/Object;>\n" + 
				"\n");
		reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertProblems(reconciled.getProblems(), new String[] {
				"Pb(953) Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'",
		}, new int[] { 8 });
	}
	
	public void testFreeTypeVariableReturnSeverities() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" + 
				"public interface Lib1<T> {\n" + 
				"	T get();\n" + 
				"}\n"
			}, null);
		this.currentProject = this.project;
		addLibrary("lib2.jar", null, new String[] {
				"/UnanntatedLib2/libs/Lib2.java",
				"package libs;\n" + 
				"\n" + 
				"public interface Lib2<T> {\n" + 
				"	T get();\n" + 
				"}\n"				
		}, "1.8");
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		fragment.createCompilationUnit("Lib3.java", 
				"package tests;\n" +
				"public interface Lib3<T> {\n" +
				"	T get();\n" +
				"}\n",
				true, new NullProgressMonitor());
		this.project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import org.eclipse.jdt.annotation.*;\n" + 
				"\n" + 
				"import libs.Lib1;\n" + 
				"import libs.Lib2;\n" + 
				"import tests.Lib3;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	@NonNull String test1(Lib1<@NonNull String> lib) {\n" + 
				"		return lib.get();\n" + // legacy, prepared for .eea but still not annotated (=> Warning)
				"	}\n" + 
				"	@NonNull String test2(Lib2<@NonNull String> lib) {\n" + 
				"		return lib.get();\n" + // legacy, not prepared for .eea (=> Info)
				"	}\n" + 
				"	@NonNull String test3(Lib3<@NonNull String> lib) {\n" + 
				"		return lib.get();\n" + // not legacy, is from the same project
				"	}\n" + 
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		assertProblems(reconciled.getProblems(), new String[] {
				"Pb(980) Unsafe interpretation of method return type as '@NonNull' based on the receiver type 'Lib1<@NonNull String>'. Type 'Lib1<T>' doesn't seem to be designed with null type annotations in mind",
				"Pb(980) Unsafe interpretation of method return type as '@NonNull' based on the receiver type 'Lib2<@NonNull String>'. Type 'Lib2<T>' doesn't seem to be designed with null type annotations in mind",
		}, new int[] { 10, 13 }, new int[] { ProblemSeverities.Warning, ProblemSeverities.Info } );
	}

	public void testBug490343() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLibs/libs/Map.java",
				"package libs;\n" +
				"\n" +
				"interface Comparator<T> {}\n" +
				"interface Comparable<T> {}\n" +
				"\n" +
				"public interface Map<K, V> {\n" +
				"    interface Entry<K, V> {\n" +
				"        K getKey();\n" +
				"\n" +
				"        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {\n" +
				"            throw new RuntimeException();\n" +
				"        }\n" +
				"    }\n" +
				"}\n"
		}, null);
		createFileInProject("annots/libs", "Map$Entry.eea",
				"class libs/Map$Entry\n" + 
				"comparingByKey\n" +
				 " <K::Llibs/Comparable<-TK;>;V:Ljava/lang/Object;>()Llibs/Comparator<Llibs/Map$Entry<TK;TV;>;>;\n" +
				 " <K::Llibs/Comparable<-TK;>;V:Ljava/lang/Object;>()L1libs/Comparator<Llibs/Map$Entry<TK;TV;>;>;\n"
		);
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test.java", 
				"package tests;\n" +
				"\n" +
				"import libs.Map;\n" +
				"\n" +
				"public class Test {\n" +
				"    static boolean f() {\n" +
				"        if(Map.Entry.comparingByKey() == null) {\n" +
				"            return false;\n" +
				"        }\n" +
				"        return true;\n" +
				"    }\n" +
				"}\n" +
				"",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
				"Pb(149) Dead code"
			}, new int[] { 7 });
	}
	public void testBug507256() throws Exception {
		myCreateJavaProject("TestLibs");
		addLibraryWithExternalAnnotations(this.project, "lib1.jar", "annots", new String[] {
				"/UnannotatedLib/libs/Lib1.java",
				"package libs;\n" + 
				"\n" + 
				"public interface Lib1 {\n" + 
				"	void methodWithParamAfterWildcard(Class<?> c, Object s);\n" + 
				"}\n"
			}, null);
		// annotations directly on a wildcard (*, +, -)
		createFileInProject("annots/libs", "Lib1.eea",
				"class libs/Lib1\n" + 
				"\n" + 
				"methodWithParamAfterWildcard\n" + 
				" (Ljava/lang/Class<*>;Ljava/lang/Object;)V\n" + 
				" (L1java/lang/Class<*>;L1java/lang/Object;)V\n" +
				"\n" + 
				"\n");
		IPackageFragment fragment = this.project.getPackageFragmentRoots()[0].createPackageFragment("tests", true, null);
		ICompilationUnit unit = fragment.createCompilationUnit("Test1.java", 
				"package tests;\n" + 
				"import libs.Lib1;\n" + 
				"\n" + 
				"public class Test1 {\n" + 
				"	void test1(Lib1 lib) {\n" + 
				"		 lib.methodWithParamAfterWildcard(Object.class, null);\n" + // error, second param must not be null
				"	}\n" + 
				"}\n",
				true, new NullProgressMonitor()).getWorkingCopy(new NullProgressMonitor());
		CompilationUnit reconciled = unit.reconcile(AST.JLS8, true, null, new NullProgressMonitor());
		IProblem[] problems = reconciled.getProblems();
		assertProblems(problems, new String[] {
				"Pb(910) Null type mismatch: required '@NonNull Object' but the provided value is null"
			}, new int[] { 6 });
	}
}
