/*******************************************************************************
 * Copyright (c) 2008, 2010 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.compiler.tool.tests;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.LogRecord;

import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileObject;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject.Kind;

import junit.framework.Test;

import org.eclipse.jdt.internal.compiler.batch.Main;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;

public class CompilerInvocationTests extends AbstractCompilerToolTest {
	static {
//		TESTS_NAMES = new String[] { "test000" };
//		TESTS_NUMBERS = new int[] { 5 };
//		TESTS_RANGE = new int[] { 1, -1 };
	}
public CompilerInvocationTests(String name) {
	super(name);
}
public static Test suite() {
	return buildUniqueComplianceTestSuite(CompilerInvocationTests.class, ClassFileConstants.JDK1_6);
}
public static Class<CompilerInvocationTests> testClass() {
	return CompilerInvocationTests.class;
}

protected void checkClassFiles(String[] fileNames) {
	for (int i = 0, l = fileNames.length; i < l; i++) {
		ClassFileReader reader = null;
		try {
			reader = ClassFileReader.read(new File(OUTPUT_DIR, fileNames[i]), true);
		} catch (ClassFormatException e) {
			fail("Class format exception for file " + fileNames[i]);
		} catch (IOException e) {
			fail("IO exception for file " + fileNames[i]);
		}
		assertNotNull("Could not read " + fileNames[i], reader);
		assertEquals("Wrong Java version for " + fileNames[i], ClassFileConstants.JDK1_6, reader.getVersion());
	}
}
void runTest(
		boolean shouldCompileOK, 
		String[] sourceFiles,
		StandardJavaFileManager standardJavaFileManager,
		List<String> options,
		String[] compileFileNames,
		String expectedOutOutputString,
		String expectedErrOutputString, 
		boolean shouldFlushOutputDirectory,
		String[] classFileNames) {
	super.runTest(
		shouldCompileOK,
		sourceFiles, 
		new CompilerInvocationTestsArguments(standardJavaFileManager, options, compileFileNames),
		expectedOutOutputString,
		expectedErrOutputString,
		shouldFlushOutputDirectory,
		null /* progress */);
	// TODO maxime introduce stderr comparison based upon specific diagnostic listener
	if (classFileNames != null) {
		checkClassFiles(classFileNames);
	}
}
class GetLocationDetector extends ForwardingStandardJavaFileManager<StandardJavaFileManager>  {
	private Location match;
	private boolean matchFound;
	GetLocationDetector(StandardJavaFileManager javaFileManager, Location location) {
		super(javaFileManager);
		this.match = location;
	}
	@Override
	public Iterable<? extends File> getLocation(Location location) {
		if (location == this.match) {
			this.matchFound = true;
		}
		return super.getLocation(location);
	}
	boolean matchFound() {
		return this.matchFound;
	}
}
abstract class GetJavaFileDetector extends ForwardingStandardJavaFileManager<StandardJavaFileManager>  {
	boolean matchFound;
	String discriminatingSuffix;
	GetJavaFileDetector(StandardJavaFileManager javaFileManager) {
		super(javaFileManager);
	}
	GetJavaFileDetector(StandardJavaFileManager javaFileManager,
			String discriminatingSuffix) {
		super(javaFileManager);
		this.discriminatingSuffix = discriminatingSuffix;
	}
	abstract JavaFileObject detector(JavaFileObject original);
	@Override
	public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
		return getJavaFileObjectsFromFiles(Arrays.asList(files));
	}
	@Override
	public Iterable<? extends JavaFileObject> getJavaFileObjects(
			String... names) {
		return getJavaFileObjectsFromStrings(Arrays.asList(names));
	}
	@Override
	public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(
			Iterable<? extends File> files) {
		ArrayList<JavaFileObject> result = new ArrayList<JavaFileObject>();
		for (JavaFileObject file: super.getJavaFileObjectsFromFiles(files)) {
			result.add(detector(file));
		}
		return result;
	}
	@Override
	public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(
			Iterable<String> names) {
		ArrayList<JavaFileObject> result = new ArrayList<JavaFileObject>();
		for (JavaFileObject file: getJavaFileObjectsFromStrings(names)) {
			result.add(detector(file));
		}
		return result;
	}
	@Override
	public Iterable<JavaFileObject> list(Location location, String packageName,
			Set<Kind> kinds, boolean recurse) throws IOException {
		ArrayList<JavaFileObject> result = new ArrayList<JavaFileObject>();
		for (JavaFileObject file: super.list(location, packageName, kinds, recurse)) {
			result.add(detector(file));
		}
		return result;
	}
}
class GetJavaFileForInputDetector extends GetJavaFileDetector  {
	private Kind discriminatingKind;
	GetJavaFileForInputDetector(StandardJavaFileManager javaFileManager) {
		super(javaFileManager);
		this.discriminatingKind = Kind.SOURCE;
	}
	GetJavaFileForInputDetector(StandardJavaFileManager javaFileManager,
			String discriminatingSuffix,
			Kind discriminatingKind) {
		super(javaFileManager, discriminatingSuffix);
		this.discriminatingKind = discriminatingKind;
	}
	class JavaFileInputDetector extends ForwardingJavaFileObject<JavaFileObject> {
		JavaFileInputDetector(JavaFileObject fileObject) {
			super(fileObject);
		}
		@Override
		public CharSequence getCharContent(boolean ignoreEncodingErrors)
				throws IOException {
			matchFound = true;
			return super.getCharContent(ignoreEncodingErrors);
		}
		@Override
		public InputStream openInputStream() throws IOException {
			matchFound = true;
			return super.openInputStream();
		}
		@Override
		public Reader openReader(boolean ignoreEncodingErrors)
				throws IOException {
			matchFound = true;
			return super.openReader(ignoreEncodingErrors);
		}
	}
	JavaFileObject detector(JavaFileObject original) {
		if (original != null && original.getKind() == this.discriminatingKind
				&& (this.discriminatingSuffix == null || original.getName().endsWith(this.discriminatingSuffix))) {
			return new JavaFileInputDetector(original);
		}
		return original;
	}
	@Override
	public FileObject getFileForInput(Location location, String packageName,
			String relativeName) throws IOException {
		FileObject result = 
			super.getFileForInput(location, packageName, relativeName);
		if (result instanceof JavaFileObject) {
			return detector((JavaFileObject) result);
		}
		return result;
	}
	@Override
	public JavaFileObject getJavaFileForInput(Location location,
			String className, Kind kind) throws IOException {
		return detector(super.getJavaFileForInput(location, className, kind));
	}
}
class GetJavaFileForOutputDetector extends GetJavaFileDetector  {
	GetJavaFileForOutputDetector(StandardJavaFileManager javaFileManager) {
		super(javaFileManager);
	}
	GetJavaFileForOutputDetector(StandardJavaFileManager javaFileManager,
			String discriminatingSuffix) {
		super(javaFileManager, discriminatingSuffix);
	}
	class JavaFileOutputDetector extends ForwardingJavaFileObject<JavaFileObject> {
		JavaFileOutputDetector(JavaFileObject fileObject) {
			super(fileObject);
		}
		@Override
		public OutputStream openOutputStream() throws IOException {
			matchFound = true;
			return super.openOutputStream();
		}
		@Override
		public Writer openWriter() throws IOException {
			matchFound = true;
			return super.openWriter();
		}
	}
	JavaFileObject detector(JavaFileObject original) {
		if (original != null && original.getKind() == Kind.CLASS
				&& (this.discriminatingSuffix == null || original.getName().endsWith(this.discriminatingSuffix))) {
			return new JavaFileOutputDetector(original);
		}
		return original;
	}
	@Override
	public FileObject getFileForOutput(Location location, String packageName,
			String relativeName, FileObject sibling) throws IOException {
		FileObject result = 
			super.getFileForOutput(location, packageName, relativeName, sibling);
		if (result instanceof JavaFileObject) {
			return detector((JavaFileObject) result);
		}
		return result;
	}
	@Override
	public JavaFileObject getJavaFileForOutput(Location location,
			String className, Kind kind, FileObject sibling) throws IOException {
		return detector(super.getJavaFileForOutput(location, className, kind, sibling));
	}
}
class SetLocationDetector extends ForwardingStandardJavaFileManager<StandardJavaFileManager>  {
	private Location match;
	private boolean matchFound;
	SetLocationDetector(StandardJavaFileManager javaFileManager, Location location) {
		super(javaFileManager);
		this.match = location;
	}
	@Override
	public void setLocation(Location location, Iterable<? extends File> path)
			throws IOException {
		if (location == this.match) {
			this.matchFound = true;
		}
		super.setLocation(location, path);
	}
	boolean matchFound() {
		return this.matchFound;
	}
}
class SubstringDetector extends java.util.logging.Logger {
	private String match;
	private boolean matchFound;
	SubstringDetector(String match) {
		super("SubstringDetector", null);
		this.match = match;
	}
	@Override
	public void log(LogRecord record) {
		if (!this.matchFound && record.getMessage().indexOf(this.match) != -1) {
			this.matchFound = true;
		}
	}
	boolean matchFound() {
		return this.matchFound;
	}
}
// most possibly basic test
public void test001_basic() {
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"X.java",
			"public class X {}",
		}, 
		null /* standardJavaFileManager */,
		Arrays.asList("-d", OUTPUT_DIR) /* options */, 
		new String[] { /* compileFileNames */
			"X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"X.class"
		});
}
// exploring -d / FileManager interaction
// -d changes CLASS_OUTPUT location
public void test002_dash_d_option() {
	StandardJavaFileManager javacStandardJavaFileManager =  JAVAC_COMPILER.getStandardFileManager(null, null, null); // will pick defaults up
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"X.java",
			"public class X {}",
		}, 
		javacStandardJavaFileManager /* standardJavaFileManager */,
		Arrays.asList("-d", OUTPUT_DIR) /* options */, 
		new String[] { /* compileFileNames */
			"X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"X.class"
		});
	assertEquals(OUTPUT_DIR, javacStandardJavaFileManager.getLocation(StandardLocation.CLASS_OUTPUT).toString());
}
// exploring -d / FileManager interaction
// -d changes CLASS_OUTPUT location (OUTPUT_DIR subdirectory)
public void test003_dash_d_option() {
	StandardJavaFileManager javacStandardJavaFileManager =  JAVAC_COMPILER.getStandardFileManager(null, null, null); // will pick defaults up
	String outputDir = OUTPUT_DIR + File.separator + "bin";
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src/X.java",
			"public class X {}",
		}, 
		javacStandardJavaFileManager /* standardJavaFileManager */,
		Arrays.asList("-d", outputDir) /* options */, 
		new String[] { /* compileFileNames */
			"src/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"bin/X.class"
		});
	assertEquals(outputDir, javacStandardJavaFileManager.getLocation(StandardLocation.CLASS_OUTPUT).toString());
}
// exploring -d / FileManager interaction
// ecj uses the output location from the javac standard Java file manager if it
// is set
public void test004_no_dash_d_option() throws IOException {
	File binDirectory = new File(OUTPUT_DIR + File.separator + "bin");
	binDirectory.mkdir();
	StandardJavaFileManager javacStandardJavaFileManager =  JAVAC_COMPILER.getStandardFileManager(null, null, null); // will pick defaults up
	javacStandardJavaFileManager.setLocation(
			StandardLocation.CLASS_OUTPUT, 
			Arrays.asList(binDirectory));
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src/X.java",
			"public class X {}",
		}, 
		javacStandardJavaFileManager /* standardJavaFileManager */,
		null /* options */, 
		new String[] { /* compileFileNames */
			"src/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"bin/X.class"
		});
}
// exploring -d / FileManager interaction
// ecj does not call setLocation on standard Java file managers; it uses 
// handleOption instead; javac does the same
public void test005_dash_d_option_custom_file_manager() {
	StandardJavaFileManager javacJavaFileManager = JAVAC_COMPILER.getStandardFileManager(null, null, null);
	SetLocationDetector customJavaFileManager =
		new SetLocationDetector(
				javacJavaFileManager, 
				StandardLocation.CLASS_OUTPUT);
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"X.java",
			"public class X {}",
		}, 
		customJavaFileManager /* standardJavaFileManager */,
		Arrays.asList("-d", OUTPUT_DIR) /* options */, 
		new String[] { /* compileFileNames */
			"X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"X.class"
		});
	assertEquals(OUTPUT_DIR, customJavaFileManager.getLocation(StandardLocation.CLASS_OUTPUT).toString());
	assertFalse(customJavaFileManager.matchFound());
	if (RUN_JAVAC) {
		customJavaFileManager =	new SetLocationDetector(javacJavaFileManager, 
					StandardLocation.CLASS_OUTPUT);
		assertTrue(JAVAC_COMPILER.getTask(null, customJavaFileManager, null, 
				Arrays.asList("-d", OUTPUT_DIR), null, 
				customJavaFileManager.getJavaFileObjectsFromFiles(
						Arrays.asList(new File(OUTPUT_DIR + File.separator + "X.java")))).call());
		assertFalse(customJavaFileManager.matchFound());
	}
}
// exploring -d / FileManager interaction
// ecj calls getLocation on a non-javac standard Java file manager
public void test006_no_dash_d_option_custom_file_manager() throws IOException {
	File binDirectory = new File(OUTPUT_DIR + File.separator + "bin");
	binDirectory.mkdirs();
	GetLocationDetector customJavaFileManager =
		new GetLocationDetector(
				JAVAC_COMPILER.getStandardFileManager(null, null, null),
				StandardLocation.CLASS_OUTPUT);
	customJavaFileManager.setLocation(
			StandardLocation.CLASS_OUTPUT, 
			Arrays.asList(binDirectory));
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src/X.java",
			"public class X {}",
		}, 
		customJavaFileManager /* standardJavaFileManager */,
		null /* options */, 
		new String[] { /* compileFileNames */
			"src/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"bin/X.class"
		});
	assertTrue(customJavaFileManager.matchFound()); // failure here means that getLocation was not called for the class output location
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=226918
// options consumption - compare with javac and ensure the consumption mechanism
// behaves the same on an option that is supported by both compilers
public void test007_options_consumption() throws IOException {
	List<String> remainingAsList = Arrays.asList("output", "remainder");
	StandardJavaFileManager ecjStandardJavaFileManager = 
		COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */);
	Iterator<String> remaining = remainingAsList.iterator();
	assertTrue("does not support -d option", ecjStandardJavaFileManager.handleOption("-d", remaining));
	assertEquals("unexpected consumption rate", "remainder", remaining.next());
	if (RUN_JAVAC) {
		StandardJavaFileManager javacStandardJavaFileManager =  
			ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null); // will pick defaults up
		remaining = remainingAsList.iterator();
		assertTrue("does not support -d option", javacStandardJavaFileManager.handleOption("-d", remaining));
		assertEquals("unexpected consumption rate", "remainder", remaining.next());
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=226918
// options consumption - check consumption rate on supported zero-args options
public void test008_options_consumption() throws IOException {
	final String REMAINDER = "remainder";
	List<String> remainingAsList = Arrays.asList("output", REMAINDER);
	StandardJavaFileManager ecjStandardJavaFileManager = 
		COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */);
	for (String option: CompilerToolTests.ZERO_ARG_OPTIONS) {
		if (ecjStandardJavaFileManager.isSupportedOption(option) != -1) { // some options that the compiler support could well not be supported by the file manager
			Iterator<String> remaining = remainingAsList.iterator();
			assertTrue("does not support " + option + " option", ecjStandardJavaFileManager.handleOption(option, remaining));
			assertEquals("unexpected consumption rate", REMAINDER, remaining.next());
		}
	}
	for (String option: CompilerToolTests.FAKE_ZERO_ARG_OPTIONS) {
		if (ecjStandardJavaFileManager.isSupportedOption(option) != -1) {
			Iterator<String> remaining = remainingAsList.iterator();
			assertTrue("does not support " + option + " option", ecjStandardJavaFileManager.handleOption(option, remaining));
			assertEquals("unexpected consumption rate", REMAINDER, remaining.next());
		}
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=226918
// options consumption - check consumption rate on supported one-arg options
public void test009_options_consumption() throws IOException {
	final String REMAINDER = "remainder";
	List<String> remainingAsList = Arrays.asList("utf-8", REMAINDER);
	StandardJavaFileManager ecjStandardJavaFileManager = 
		COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */);
	for (String option: CompilerToolTests.ONE_ARG_OPTIONS) {
		if (ecjStandardJavaFileManager.isSupportedOption(option) != -1) { // some options that the compiler support could well not be supported by the file manager
			Iterator<String> remaining = remainingAsList.iterator();
			assertTrue("does not support " + option + " option", ecjStandardJavaFileManager.handleOption(option, remaining));
			assertEquals("unexpected consumption rate", REMAINDER, remaining.next());
		}
	}
}
// tests #10-11 show that ecj throws a RuntimeException when encountering a wrong
// encoding in its parameters, while the default compiler swallows it silently
// based upon the behavior of the command-line javac for the same level, we
// would expect an error to be raised in some fashion here, hence we make the
// tests fail when RUN_JAVAC is on
public void test010_inappropriate_encoding_diagnosis() throws IOException {
	List<String> buggyEncoding = Arrays.asList("dummy");
	boolean passed = true;
	try {
		passed = COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */).
		handleOption("-encoding", buggyEncoding.iterator());
	} catch (RuntimeException e) {
		passed = false;
	}
	assertFalse("does not catch inappropriate -encoding option", passed);
	if (RUN_JAVAC) {
		// this fails, which may be deemed appropriate or not; but at least
		// test #11 shows that the behavior that can be observed from the 
		// outside is inappropriate
		passed = true;
		try {
			passed = JAVAC_COMPILER.getStandardFileManager(null, null, null).
				handleOption("-encoding", buggyEncoding.iterator());
		} catch (Throwable t) {
			passed = false;
		}
		assertFalse("does not catch inappropriate -encoding option", passed);
	}
}
public void test011_inappropriate_encoding_diagnosis() {
	List<String> options = Arrays.asList("-d", OUTPUT_DIR, "-encoding", "dummy");
	boolean passed = true;
	try {
	runTest(
		false /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"X.java",
			"public class X {}",
		}, 
		null /* standardJavaFileManager */,
		options /* options */, 
		new String[] { /* compileFileNames */
			"X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		null /* classFileNames */);
	} catch (RuntimeException e) {
		passed = false;
	}
	assertFalse("does not catch inappropriate -encoding option", passed);
	if (RUN_JAVAC) {
		// compared to what the command-line javac does, this is due to be a
		// bug
		passed = true;
		try {
			passed = JAVAC_COMPILER.getTask(null, null, null, options, null, 
					JAVAC_COMPILER.getStandardFileManager(null, null, null).getJavaFileObjectsFromFiles(
						Arrays.asList(new File(OUTPUT_DIR + File.separator + "X.java")))).call();
		} catch (Throwable t) {
			passed = false;
		}
		assertFalse("does not catch inappropriate -encoding option", passed);		
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=188796
// files access must happen through the user-specified file manager
// simplest source read case
public void test012_files_access_read() throws IOException {
	GetJavaFileForInputDetector customJavaFileManager =
		new GetJavaFileForInputDetector(
				JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */));
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"X.java",
			"public class X {}",
		}, 
		customJavaFileManager /* standardJavaFileManager */,
		Arrays.asList("-d", OUTPUT_DIR) /* options */, 
		new String[] { /* compileFileNames */
			"X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"X.class"
		});
	assertTrue(customJavaFileManager.matchFound);
	if (RUN_JAVAC) {
		customJavaFileManager.matchFound = false;
		assertTrue(JAVAC_COMPILER.getTask(null, customJavaFileManager, null, 
				Arrays.asList("-d", OUTPUT_DIR), null, 
				customJavaFileManager.getJavaFileObjectsFromFiles(
						Arrays.asList(new File(OUTPUT_DIR + File.separator + "X.java")))).call());
		assertTrue(customJavaFileManager.matchFound);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=188796
// files access must happen through the user-specified file manager
// source file accessed through the sourcepath
public void _test013_files_access_read() throws IOException {
	GetJavaFileForInputDetector customJavaFileManager =
		new GetJavaFileForInputDetector(
				JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */),
				"Y.java", Kind.SOURCE);
	List<String> options = Arrays.asList(
			"-d", OUTPUT_DIR, 
			"-sourcepath", OUTPUT_DIR + File.separator + "src2");
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src1/X.java",
			"public class X {\n" +
			"  Y y;\n" +
			"}",
			"src2/Y.java",
			"public class Y {}",
		}, 
		customJavaFileManager /* standardJavaFileManager */,
		options /* options */, 
		new String[] { /* compileFileNames */
			"src1/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"X.class"
		});
	assertTrue(customJavaFileManager.matchFound);
	if (RUN_JAVAC) {
		customJavaFileManager.matchFound = false;
		assertTrue(JAVAC_COMPILER.getTask(null, customJavaFileManager, null, 
				options, null, 
				customJavaFileManager.getJavaFileObjectsFromFiles(
						Arrays.asList(new File(OUTPUT_DIR + File.separator + "src1/X.java")))).call());
		assertTrue(customJavaFileManager.matchFound);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=188796
// files access must happen through the user-specified file manager
// class file accessed for read through the classpath
public void _test014_files_access_read() throws IOException {
	GetJavaFileForInputDetector customJavaFileManager =
		new GetJavaFileForInputDetector(
				JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */),
				"Y.class", Kind.CLASS);
	List<String> options = Arrays.asList(
			"-d", OUTPUT_DIR,
			"-classpath", OUTPUT_DIR);
	runTest(
			true /* shouldCompileOK */,
			new String [] { /* sourceFiles */
				"src2/Y.java",
				"public class Y {}",
			}, 
			customJavaFileManager /* standardJavaFileManager */,
			options /* options */, 
			new String[] { /* compileFileNames */
				"src2/Y.java"
			}, 
			"" /* expectedOutOutputString */, 
			"" /* expectedErrOutputString */,
			true /* shouldFlushOutputDirectory */,
			new String[] { /* classFileNames */
				"Y.class"
			});
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src1/X.java",
			"public class X {\n" +
			"  Y y;\n" +
			"}",
		}, 
		customJavaFileManager /* standardJavaFileManager */,
		options /* options */, 
		new String[] { /* compileFileNames */
			"src1/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		false /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"X.class"
		});
	assertTrue(customJavaFileManager.matchFound);
	if (RUN_JAVAC) {
		// javac merely throws an exception, which is due to be a bug on their
		// side
		customJavaFileManager.matchFound = false;
		assertTrue(JAVAC_COMPILER.getTask(null, customJavaFileManager, null, 
				options, null, 
				customJavaFileManager.getJavaFileObjectsFromFiles(
						Arrays.asList(new File(OUTPUT_DIR + File.separator + "src1/X.java")))).call());
		assertTrue(customJavaFileManager.matchFound);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=188796
// files access must happen through the user-specified file manager
// class file accessed for write
public void test015_files_access_write() throws IOException {
	GetJavaFileForOutputDetector customJavaFileManager =
		new GetJavaFileForOutputDetector(
				JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */),
				"X.class");
	List<String> options = Arrays.asList("-d", OUTPUT_DIR);
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src/X.java",
			"public class X {\n" +
			"}",
		}, 
		customJavaFileManager /* standardJavaFileManager */,
		options /* options */, 
		new String[] { /* compileFileNames */
			"src/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"X.class"
		});
	assertTrue(customJavaFileManager.matchFound);
	if (RUN_JAVAC) {
		customJavaFileManager.matchFound = false;
		assertTrue(JAVAC_COMPILER.getTask(null, customJavaFileManager, null, 
				options, null, 
				customJavaFileManager.getJavaFileObjectsFromFiles(
						Arrays.asList(new File(OUTPUT_DIR + File.separator + "src/X.java")))).call());
		assertTrue(customJavaFileManager.matchFound);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=188796
// files access must happen through the user-specified file manager
// class file accessed for write
public void test016_files_access_write() throws IOException {
	GetJavaFileForOutputDetector customJavaFileManager =
		new GetJavaFileForOutputDetector(
				JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */),
				"Y.class");
	List<String> options = Arrays.asList(
			"-sourcepath", OUTPUT_DIR + File.separator + "src2");
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src/X.java",
			"public class X {\n" +
			"  Y y;\n" +
			"}",
			"src2/Y.java",
			"public class Y {\n" +
			"}",
		}, 
		customJavaFileManager /* standardJavaFileManager */,
		options /* options */, 
		new String[] { /* compileFileNames */
			"src/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"src/X.class"
		});
	assertTrue(customJavaFileManager.matchFound);
	if (RUN_JAVAC) {
		customJavaFileManager.matchFound = false;
		assertTrue(JAVAC_COMPILER.getTask(null, customJavaFileManager, null, 
				options, null, 
				customJavaFileManager.getJavaFileObjectsFromFiles(
						Arrays.asList(new File(OUTPUT_DIR + File.separator + "src/X.java")))).call());
		assertTrue(customJavaFileManager.matchFound);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227583
public void test017_sourcepath_without_destination() throws IOException {
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src1/X.java",
			"public class X {\n" +
			"  Y y;\n" +
			"}",
			"src2/Y.java",
			"public class Y {}",
		}, 
		null /* standardJavaFileManager */,
		Arrays.asList(
				"-d", OUTPUT_DIR + "/bin1", /* options */
				"-sourcepath", OUTPUT_DIR + "/src2"), 
		new String[] { /* compileFileNames */
			"src1/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"bin1/X.class",
			"bin1/Y.class"
		});
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227583
// see BatchCompilerTest#68 and following, that show how the option works
// with jsr199-less ecj
public void _test018_sourcepath_with_destination() throws IOException {
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src1/X.java",
			"public class X {\n" +
			"  Y y;\n" +
			"}",
			"src2/Y.java",
			"public class Y {}",
		}, 
		null /* standardJavaFileManager */,
		Arrays.asList(
				"-d", OUTPUT_DIR + "/bin1", /* options */
				"-sourcepath", "\"" + OUTPUT_DIR + "/src2\"[-d \"" + OUTPUT_DIR + "/bin2\"]"), 
		new String[] { /* compileFileNames */
			"src1/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"bin1/X.class",
			"bin2/Y.class"
		});
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227583
public void test019_sourcepath_without_destination() throws IOException {
	StandardJavaFileManager ecjStandardJavaFileManager =
		JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */);
	assertTrue(ecjStandardJavaFileManager.handleOption(
			"-sourcepath", 
			Arrays.asList(OUTPUT_DIR + "/src2").iterator()));
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src1/X.java",
			"public class X {\n" +
			"  Y y;\n" +
			"}",
			"src2/Y.java",
			"public class Y {}",
		}, 
		ecjStandardJavaFileManager /* standardJavaFileManager */,
		Arrays.asList("-d", OUTPUT_DIR + "/bin1") /* options */, 
		new String[] { /* compileFileNames */
			"src1/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"bin1/X.class",
			"bin1/Y.class"
		});
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227583
public void _test020_sourcepath_with_destination() throws IOException {
	StandardJavaFileManager ecjStandardJavaFileManager =
		JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */);
	assertTrue(ecjStandardJavaFileManager.handleOption(
			"-sourcepath", 
			Arrays.asList("\"" + OUTPUT_DIR + "/src2\"[-d \"" + OUTPUT_DIR + "/bin2\"]").iterator()));
	runTest(
		true /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"src1/X.java",
			"public class X {\n" +
			"  Y y;\n" +
			"}",
			"src2/Y.java",
			"public class Y {}",
		}, 
		ecjStandardJavaFileManager /* standardJavaFileManager */,
		Arrays.asList("-d", OUTPUT_DIR + "/bin1") /* options */, 
		new String[] { /* compileFileNames */
			"src1/X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"" /* expectedErrOutputString */,
		true /* shouldFlushOutputDirectory */,
		new String[] { /* classFileNames */
			"bin1/X.class",
			"bin2/Y.class"
		});
}
// most basic output test
public void test021_output_streams() throws IOException {
	ByteArrayOutputStream 
			outBuffer = new ByteArrayOutputStream(),
			errBuffer = new ByteArrayOutputStream();
	CompilationTask task = COMPILER.getTask(
		new PrintWriter(outBuffer), 
		JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */), 
		new CompilerInvocationDiagnosticListener(new PrintWriter(errBuffer)), 
		Arrays.asList("-v"), null, null);
	assertTrue(task.call());
	Properties properties = new Properties();
	InputStream resourceAsStream = null;
	try {
		resourceAsStream = Main.class.getResourceAsStream("messages.properties");
		properties.load(resourceAsStream);
	} finally {
		if (resourceAsStream != null) {
			resourceAsStream.close();
		}
	}
	assertTrue(outBuffer.toString().startsWith(properties.getProperty("compiler.name")));
	assertTrue(errBuffer.toString().isEmpty());
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=236814
public void test022_output_streams() throws IOException {
	ByteArrayOutputStream 
	outBuffer = new ByteArrayOutputStream(),
	errBuffer = new ByteArrayOutputStream();
	PrintStream 
	systemOut = System.out,
	systemErr = System.err;
	System.setOut(new PrintStream(outBuffer));
	System.setErr(new PrintStream(errBuffer));
	CompilationTask task = COMPILER.getTask(
			null, 
			JAVAC_COMPILER.getStandardFileManager(null /* diagnosticListener */, null /* locale */, null /* charset */), 
			new CompilerInvocationDiagnosticListener(new PrintWriter(errBuffer)), 
			Arrays.asList("-v"), null, null);
	try {
		assertTrue(task.call());
		assertTrue(outBuffer.toString().isEmpty());
		assertTrue(errBuffer.toString().startsWith("Eclipse Compiler for Java"));
	} finally {
		System.setOut(systemOut);
		System.setErr(systemErr);
	}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=236817
// according to JavaCompiler#getTask, out should receive supplementary compiler
// output only; errors should be funneled through the diagnostic listener 
public void _test023_output_streams() throws IOException {
	runTest(
		false /* shouldCompileOK */,
		new String [] { /* sourceFiles */
			"X.java",
			"public class Y {}",
		}, 
		null /* standardJavaFileManager */,
		Arrays.asList("-d", OUTPUT_DIR) /* options */, 
		new String[] { /* compileFileNames */
			"X.java"
		}, 
		"" /* expectedOutOutputString */, 
		"----------\n" + /* expectedErrOutputString */
		"1. ERROR in X.java (at line 1)\n" + 
		"	public class Y {}\n" + 
		"	             ^\n" + 
		"The public type Y must be defined in its own file\n" + 
		"----------\n" + 
		"1 problem (1 error)",
		true /* shouldFlushOutputDirectory */,
		null /* classFileNames */);
}
}
