/*******************************************************************************
 * Copyright (c) 2017 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.compiler.regression;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.ArrayList;

import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CompilationProgress;
import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.compiler.batch.ClasspathLocation;
import org.eclipse.jdt.internal.compiler.batch.Main;

public abstract class AbstractBatchCompilerTest extends AbstractRegressionTest {

	protected static abstract class Matcher {
		abstract boolean match(String effective);
		abstract String expected(); // for use in JUnit comparison framework
	}

	/**
	 * Abstract normalizer for output comparison. This class merely embodies a
	 * chain of responsibility, plus the signature of the method of interest
	 * here, that is {@link #normalized(String) normalized}.
	 */
	protected static abstract class Normalizer {
		private Normalizer nextInChain;
		Normalizer(Normalizer nextInChain) {
			this.nextInChain = nextInChain;
		}
		String normalized(String originalValue) {
			String result;
			if (this.nextInChain == null)
				result = Util.convertToIndependantLineDelimiter(originalValue);
			else
				result = this.nextInChain.normalized(originalValue);
			return result;
		}
	}

	/**
	 * This normalizer replaces occurrences of a given string with a given
	 * placeholder.
	 */
	protected static class StringNormalizer extends Normalizer {
		private String match;
		private int matchLength;
		private String placeholder;
		StringNormalizer(Normalizer nextInChain, String match, String placeholder) {
			super(nextInChain);
			this.match = match;
			this.matchLength = match.length();
			this.placeholder = placeholder;
		}
		String normalized(String originalValue) {
			String result;
			StringBuffer normalizedValueBuffer = new StringBuffer(originalValue);
			int nextOccurrenceIndex;
			while ((nextOccurrenceIndex = normalizedValueBuffer.indexOf(this.match)) != -1)
				normalizedValueBuffer.replace(nextOccurrenceIndex,
						nextOccurrenceIndex + this.matchLength, this.placeholder);
			result = super.normalized(normalizedValueBuffer.toString());
			return result;
		}
	}

	protected static class TestCompilationProgress extends CompilationProgress {
		boolean isCanceled = false;
		int workedSoFar = 0;
		StringBuffer buffer = new StringBuffer();
		public void begin(int remainingWork) {
			this.buffer.append("----------\n[worked: 0 - remaining: ").append(remainingWork).append("]\n");
		}
		public void done() {
			this.buffer.append("----------\n");
		}
		public boolean isCanceled() {
			return this.isCanceled;
		}
		public void setTaskName(String name) {
			this.buffer.append(name).append('\n');
		}
		public String toString() {
			return this.buffer.toString();
		}
		public void worked(int workIncrement, int remainingWork) {
			this.workedSoFar += workIncrement;
			this.buffer.append("[worked: ").append(this.workedSoFar).append(" - remaining: ").append(remainingWork).append("]\n");
		}
	}

	public static final String OUTPUT_DIR_PLACEHOLDER = "---OUTPUT_DIR_PLACEHOLDER---";
	public static final String LIB_DIR_PLACEHOLDER = "---LIB_DIR_PLACEHOLDER---";

	/**
	 * Normalizer instance that replaces occurrences of OUTPUT_DIR with
	 * OUTPUT_DIR_PLACEHOLDER and changes file separator to / if the
	 * platform file separator is different from /.
	 */
	protected static Normalizer outputDirNormalizer;
	static {
		if (File.separatorChar == '/') {
			outputDirNormalizer =
				new StringNormalizer(
					new StringNormalizer(
						null, OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER),
					LIB_DIR, LIB_DIR_PLACEHOLDER);
		}
		else {
			outputDirNormalizer =
				new StringNormalizer(
					new StringNormalizer(
						new StringNormalizer(
							null, File.separator, "/"),
						OUTPUT_DIR, OUTPUT_DIR_PLACEHOLDER),
					LIB_DIR, LIB_DIR_PLACEHOLDER);
		}
	}

	public AbstractBatchCompilerTest(String name) {
		super(name);
	}

	protected static final String JRE_HOME_DIR = Util.getJREDirectory();
	protected static final Main MAIN = new Main(null/*outWriter*/, null/*errWriter*/, false/*systemExit*/, null/*options*/, null/*progress*/);

	private static boolean CASCADED_JARS_CREATED;
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		CASCADED_JARS_CREATED = false; // initialization needed for each subclass individually
	}
	
	protected void createCascadedJars() {
		if (!CASCADED_JARS_CREATED) {
			File libDir = new File(LIB_DIR);
			Util.delete(libDir); // make sure we recycle the libs
	 		libDir.mkdirs();
			try {
				Util.createJar(
					new String[] {
						"p/A.java",
						"package p;\n" +
						"public class A {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: lib2.jar\n",
						"p/S1.java",
						"package p;\n" +
						"public class S1 {\n" +
						"}",
					},
					LIB_DIR + "/lib1.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/B.java",
						"package p;\n" +
						"public class B {\n" +
						"}",
						"p/R.java",
						"package p;\n" +
						"public class R {\n" +
						"  public static final int R2 = 2;\n" +
						"}",
					},
					new String[] {
						"p/S2.java",
						"package p;\n" +
						"public class S2 {\n" +
						"}",
					},
					LIB_DIR + "/lib2.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/C.java",
						"package p;\n" +
						"public class C {\n" +
						"}",
						"p/R.java",
						"package p;\n" +
						"public class R {\n" +
						"  public static final int R3 = 3;\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: lib4.jar\n",
					},
					LIB_DIR + "/lib3.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/D.java",
						"package p;\n" +
						"public class D {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: lib1.jar lib3.jar\n",
					},
					LIB_DIR + "/lib4.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/C.java",
						"package p;\n" +
						"public class C {\n" +
						"}",
						"p/R.java",
						"package p;\n" +
						"public class R {\n" +
						"  public static final int R3 = 3;\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: s/lib6.jar\n",
					},
					LIB_DIR + "/lib5.jar",
					JavaCore.VERSION_1_4);
				new File(LIB_DIR + "/s").mkdir();
				Util.createJar(
					new String[] {
						"p/D.java",
						"package p;\n" +
						"public class D {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: ../lib7.jar\n",
					},
					LIB_DIR + "/s/lib6.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/A.java",
						"package p;\n" +
						"public class A {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: lib2.jar\n",
					},
					LIB_DIR + "/lib7.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/F.java",
						"package p;\n" +
						"public class F {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: " + LIB_DIR + "/lib3.jar lib1.jar\n",
					},
					LIB_DIR + "/lib8.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/G.java",
						"package p;\n" +
						"public class G {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: lib1.jar\n" +
						"Class-Path: lib3.jar\n",
					},
					LIB_DIR + "/lib9.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/A.java",
						"package p;\n" +
						"public class A {\n" +
						"}",
					},
					// spoiled jar: MANIFEST.MF is a directory
					new String[] {
						"META-INF/MANIFEST.MF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: lib2.jar\n",
					},
					LIB_DIR + "/lib10.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/A.java",
						"package p;\n" +
						"public class A {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path:\n",
					},
					LIB_DIR + "/lib11.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					null,
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path:lib1.jar\n", // missing space
					},
					LIB_DIR + "/lib12.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					null,
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path:lib1.jar lib1.jar\n", // missing space
					},
					LIB_DIR + "/lib13.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					null,
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						" Class-Path: lib1.jar\n", // extra space at line start
					},
					LIB_DIR + "/lib14.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					null,
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: lib1.jar", // missing newline at end
					},
					LIB_DIR + "/lib15.jar",
					JavaCore.VERSION_1_4);
				Util.createJar(
					new String[] {
						"p/A.java",
						"package p;\n" +
						"public class A {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: \n" +
						" lib2.jar\n",
						"p/S1.java",
						"package p;\n" +
						"public class S1 {\n" +
						"}",
					},
					LIB_DIR + "/lib16.jar",
					JavaCore.VERSION_1_4);
				new File(LIB_DIR + "/dir").mkdir();
				Util.createJar(
					new String[] {
						"p/A.java",
						"package p;\n" +
						"public class A {\n" +
						"}",
					},
					new String[] {
						"META-INF/MANIFEST.MF",
						"Manifest-Version: 1.0\n" +
						"Created-By: Eclipse JDT Test Harness\n" +
						"Class-Path: ../lib2.jar\n",
					},
					LIB_DIR + "/dir/lib17.jar",
					JavaCore.VERSION_1_4);
				CASCADED_JARS_CREATED = true;
			} catch (IOException e) {
				// ignore
			}
		}
	}

	protected String getLibraryClassesAsQuotedString() {
		String[] paths = Util.getJavaClassLibs();
		StringBuffer buffer = new StringBuffer();
		buffer.append('"');
		for (int i = 0, max = paths.length; i < max; i++) {
			if (i != 0) {
				buffer.append(File.pathSeparatorChar);
			}
			buffer.append(paths[i]);
		}
		buffer.append('"');
		return String.valueOf(buffer);
	}

	protected String getJCEJarAsQuotedString() {
		if (Util.isMacOS()) {
			return "\"" + JRE_HOME_DIR + "/../Classes/jce.jar\"";
		}
		return "\"" + JRE_HOME_DIR + "/lib/jce.jar\"";
	}

	protected String getExtDirectory() {
		return JRE_HOME_DIR + "/lib/ext";
	}

	/**
	 * Run a compilation test that is expected to complete successfully and
	 * compare the outputs to expected ones.
	 *
	 * @param testFiles
	 *            the source files, given as a suite of file name, file content;
	 *            file names are relative to the output directory
	 * @param commandLine
	 *            the command line to pass to
	 *            {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, org.eclipse.jdt.core.compiler.CompilationProgress) BatchCompiler#compile}
	 * @param expectedSuccessOutOutputString
	 *            the expected contents of the standard output stream; pass null
	 *            to bypass the comparison
	 * @param expectedSuccessErrOutputString
	 *            the expected contents of the standard error output stream;
	 *            pass null to bypass the comparison
	 * @param shouldFlushOutputDirectory
	 *            pass true to get the output directory flushed before the test
	 *            runs
	 */
	protected void runConformTest(String[] testFiles, String commandLine, String expectedSuccessOutOutputString, String expectedSuccessErrOutputString, boolean shouldFlushOutputDirectory) {
		runTest(true, testFiles, commandLine, expectedSuccessOutOutputString,
				expectedSuccessErrOutputString, shouldFlushOutputDirectory, null/*progress*/);
	}

	/**
	 * Run a compilation test that is expected to fail and compare the outputs
	 * to expected ones.
	 *
	 * @param testFiles
	 *            the source files, given as a suite of file name, file content;
	 *            file names are relative to the output directory
	 * @param commandLine
	 *            the command line to pass to
	 *            {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, org.eclipse.jdt.core.compiler.CompilationProgress) BatchCompiler#compile}
	 * @param expectedFailureOutOutputString
	 *            the expected contents of the standard output stream; pass null
	 *            to bypass the comparison
	 * @param expectedFailureErrOutputString
	 *            the expected contents of the standard error output stream;
	 *            pass null to bypass the comparison
	 * @param shouldFlushOutputDirectory
	 *            pass true to get the output directory flushed before the test
	 *            runs
	 */
	protected void runNegativeTest(String[] testFiles, String commandLine, String expectedFailureOutOutputString, String expectedFailureErrOutputString, boolean shouldFlushOutputDirectory) {
		runTest(false, testFiles, commandLine, expectedFailureOutOutputString,
				expectedFailureErrOutputString, shouldFlushOutputDirectory, null/*progress*/);
	}

	protected void runProgressTest(String[] testFiles, String commandLine, String expectedOutOutputString, String expectedErrOutputString, String expectedProgress) {
		runTest(true/*shouldCompileOK*/, testFiles, commandLine, expectedOutOutputString, expectedErrOutputString, true/*shouldFlushOutputDirectory*/, new TestCompilationProgress());
	}

	protected void runProgressTest(boolean shouldCompileOK, String[] testFiles, String commandLine, String expectedOutOutputString, String expectedErrOutputString, TestCompilationProgress progress, String expectedProgress) {
		runTest(shouldCompileOK, testFiles, commandLine, expectedOutOutputString, expectedErrOutputString, true/*shouldFlushOutputDirectory*/, progress);
		String actualProgress = progress.toString();
		if (!semiNormalizedComparison(expectedProgress, actualProgress, outputDirNormalizer)) {
			System.out.println(Util.displayString(outputDirNormalizer.normalized(actualProgress), 2));
			assertEquals(
				"Unexpected progress",
				expectedProgress,
				actualProgress);
		}
	}

	/**
	 * Worker method for runConformTest and runNegativeTest.
	 *
	 * @param shouldCompileOK
	 *            set to true if the compiler should compile the given sources
	 *            without errors
	 * @param testFiles
	 *            the source files, given as a suite of file name, file content;
	 *            file names are relative to the output directory
	 * @param extraArguments
	 *            the command line to pass to {@link Main#compile(String[])
	 *            Main#compile} or other arguments to pass to {@link
	 *            #invokeCompiler(PrintWriter, PrintWriter, Object,
	 *            BatchCompilerTest.TestCompilationProgress)} (for use
	 *            by extending test classes)
	 * @param expectedOutOutputString
	 *            the expected contents of the standard output stream; pass null
	 *            to bypass the comparison
	 * @param expectedErrOutputString
	 *            the expected contents of the standard error output stream;
	 *            pass null to bypass the comparison
	 * @param shouldFlushOutputDirectory
	 *            pass true to get the output directory flushed before the test
	 *            runs
	 */
	protected void runTest(boolean shouldCompileOK, String[] testFiles, Object extraArguments, String expectedOutOutputString, String expectedErrOutputString, boolean shouldFlushOutputDirectory, TestCompilationProgress progress) {
		File outputDirectory = new File(OUTPUT_DIR);
		if (shouldFlushOutputDirectory)
			Util.flushDirectoryContent(outputDirectory);
		try {
			if (!outputDirectory.isDirectory()) {
				outputDirectory.mkdirs();
			}
			if (testFiles != null) {
				PrintWriter sourceFileWriter;
				for (int i = 0; i < testFiles.length; i += 2) {
					String fileName = OUTPUT_DIR + File.separator + testFiles[i];
					File file = new File(fileName), innerOutputDirectory = file
							.getParentFile();
					if (!innerOutputDirectory.isDirectory()) {
						innerOutputDirectory.mkdirs();
					}
					sourceFileWriter = new PrintWriter(new FileOutputStream(file));
					try {
						sourceFileWriter.write(testFiles[i + 1]);
					} finally {
						sourceFileWriter.close();
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		String printerWritersNameRoot = OUTPUT_DIR + File.separator + testName();
		String outFileName = printerWritersNameRoot + "out.txt",
			   errFileName = printerWritersNameRoot + "err.txt";
		PrintWriter out = null;
		PrintWriter err = null;
		boolean compileOK;
		try {
			try {
				out = new PrintWriter(new FileOutputStream(outFileName));
				err = new PrintWriter(new FileOutputStream(errFileName));
			} catch (FileNotFoundException e) {
				System.out.println(getClass().getName() + '#' + getName());
				e.printStackTrace();
				throw new RuntimeException(e);
			}
			compileOK = invokeCompiler(out, err, extraArguments, progress);
		} finally {
			if (out != null)
				out.close();
			if (err != null)
				err.close();
		}
		String outOutputString = Util.fileContent(outFileName),
		       errOutputString = Util.fileContent(errFileName);
		boolean compareOK = false, outCompareOK = false, errCompareOK = false;
		if (compileOK == shouldCompileOK) {
			compareOK =
				(outCompareOK = semiNormalizedComparison(expectedOutOutputString,
					outOutputString, outputDirNormalizer))
				&& (errCompareOK = semiNormalizedComparison(expectedErrOutputString,
						errOutputString, outputDirNormalizer));
		}
		if (compileOK != shouldCompileOK || !compareOK) {
			System.out.println(getClass().getName() + '#' + getName());
			if (testFiles != null) {
				for (int i = 0; i < testFiles.length; i += 2) {
					System.out.print(testFiles[i]);
					System.out.println(" [");
					System.out.println(testFiles[i + 1]);
					System.out.println("]");
				}
			}
		}
		if (compileOK != shouldCompileOK)
			System.out.println(errOutputString);
		if (compileOK == shouldCompileOK && !compareOK) {
			System.out.println(
					    "------------ [START OUT] ------------\n"
					+   "------------- Expected: -------------\n"
					+ expectedOutOutputString
					+ "\n------------- but was:  -------------\n"
					+ outOutputString
					+ "\n--------- (cut and paste:) ----------\n"
					+ Util.displayString(outputDirNormalizer
							.normalized(outOutputString))
					+ "\n------------- [END OUT] -------------\n"
					+   "------------ [START ERR] ------------\n"
					+   "------------- Expected: -------------\n"
					+ expectedErrOutputString
					+ "\n------------- but was:  -------------\n"
					+ errOutputString
					+ "\n--------- (cut and paste:) ----------\n"
					+ Util.displayString(outputDirNormalizer
							.normalized(errOutputString))
					+ "\n------------- [END ERR] -------------\n");
		}
		if (shouldCompileOK)
			assertTrue("Unexpected problems [out: " + outOutputString + "][err: " + errOutputString + "]", compileOK);
		else
			assertFalse("Unexpected success: [out: " + outOutputString + "][err: " + errOutputString + "]", compileOK);
		if (!outCompareOK) {
			// calling assertEquals to benefit from the comparison UI
			// (need appropriate exception)
			assertEquals(
					"Unexpected standard output for invocation with arguments ["
						+ extraArguments + "]",
					expectedOutOutputString,
					outOutputString);
		}
		if (!errCompareOK) {
			assertEquals(
					"Unexpected error output for invocation with arguments ["
						+ extraArguments + "]",
					expectedErrOutputString,
					errOutputString);
		}
	}

	protected boolean invokeCompiler(PrintWriter out, PrintWriter err, Object extraArguments, TestCompilationProgress compilationProgress) {
		try {
			final String[] tokenizedCommandLine = Main.tokenize((String) extraArguments);
			return new Main(out, err, false, null /* customDefaultOptions */, compilationProgress /* compilationProgress*/).compile(tokenizedCommandLine);
		} catch (RuntimeException e) {
			System.out.println(getClass().getName() + '#' + getName());
			e.printStackTrace();
			throw e;
		}
	}

	protected void runTest(boolean shouldCompileOK, String[] testFiles, String commandLine, Matcher outOutputStringMatcher, Matcher errOutputStringMatcher, boolean shouldFlushOutputDirectory) {
		File outputDirectory = new File(OUTPUT_DIR);
		if (shouldFlushOutputDirectory)
			Util.flushDirectoryContent(outputDirectory);
		try {
			if (!outputDirectory.isDirectory()) {
				outputDirectory.mkdirs();
			}
			PrintWriter sourceFileWriter;
			for (int i = 0; i < testFiles.length; i += 2) {
				String fileName = OUTPUT_DIR + File.separator + testFiles[i];
				File file = new File(fileName), innerOutputDirectory = file
						.getParentFile();
				if (!innerOutputDirectory.isDirectory()) {
					innerOutputDirectory.mkdirs();
				}
				sourceFileWriter = new PrintWriter(new FileOutputStream(file));
				try {
					sourceFileWriter.write(testFiles[i + 1]);
				} finally {
					sourceFileWriter.close();
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		String printerWritersNameRoot = OUTPUT_DIR + File.separator + testName();
		String outFileName = printerWritersNameRoot + "out.txt",
			   errFileName = printerWritersNameRoot + "err.txt";
		Main batchCompiler;
		PrintWriter out = null;
		PrintWriter err = null;
		boolean compileOK;
		try {
			try {
				out = new PrintWriter(new FileOutputStream(outFileName));
				err = new PrintWriter(new FileOutputStream(errFileName));
				batchCompiler = new Main(out, err, false/*systemExit*/, null/*options*/, null/*progress*/);
			} catch (FileNotFoundException e) {
				System.out.println(getClass().getName() + '#' + getName());
				e.printStackTrace();
				throw new RuntimeException(e);
			}
			try {
				final String[] tokenizeCommandLine = Main.tokenize(commandLine);
				compileOK = batchCompiler.compile(tokenizeCommandLine);
			} catch (RuntimeException e) {
				compileOK = false;
				System.out.println(getClass().getName() + '#' + getName());
				e.printStackTrace();
				throw e;
			}
		} finally {
			if (out != null)
				out.close();
			if (err != null)
				err.close();
		}
		String outOutputString = Util.fileContent(outFileName),
		       errOutputString = Util.fileContent(errFileName);
		boolean compareOK = false, outCompareOK = false, errCompareOK = false;
		String expectedErrOutputString = null, expectedOutOutputString = null;
		if (compileOK == shouldCompileOK) {
			if (outOutputStringMatcher == null) {
				outCompareOK = true;
			} else {
				outCompareOK = outOutputStringMatcher.match(outOutputString);
				expectedOutOutputString = outOutputStringMatcher.expected();
			}
			if (errOutputStringMatcher == null) {
				errCompareOK = true;
			} else {
				errCompareOK = errOutputStringMatcher.match(errOutputString);
				expectedErrOutputString = errOutputStringMatcher.expected();
			}
			compareOK = outCompareOK && errCompareOK;
		}
		if (compileOK != shouldCompileOK || !compareOK) {
			System.out.println(getClass().getName() + '#' + getName());
			for (int i = 0; i < testFiles.length; i += 2) {
				System.out.print(testFiles[i]);
				System.out.println(" [");
				System.out.println(testFiles[i + 1]);
				System.out.println("]");
			}
		}
		if (compileOK != shouldCompileOK)
			System.out.println(errOutputString);
		if (compileOK == shouldCompileOK && !compareOK) {
			System.out.println(
					    "------------ [START OUT] ------------\n"
					+   "------------- Expected: -------------\n"
					+ expectedOutOutputString
					+ "\n------------- but was:  -------------\n"
					+ outOutputString
					+ "\n--------- (cut and paste:) ----------\n"
					+ Util.displayString(outputDirNormalizer
							.normalized(outOutputString))
					+ "\n------------- [END OUT] -------------\n"
					+   "------------ [START ERR] ------------\n"
					+   "------------- Expected: -------------\n"
					+ expectedErrOutputString
					+ "\n------------- but was:  -------------\n"
					+ errOutputString
					+ "\n--------- (cut and paste:) ----------\n"
					+ Util.displayString(outputDirNormalizer
							.normalized(errOutputString))
					+ "\n------------- [END ERR] -------------\n");
		}
		if (shouldCompileOK)
			assertTrue("Unexpected problems: " + errOutputString, compileOK);
		else
			assertTrue("Unexpected success: " + errOutputString, !compileOK);
		if (!outCompareOK) {
			// calling assertEquals to benefit from the comparison UI
			// (need appropriate exception)
			assertEquals(
					"Unexpected standard output for invocation with arguments ["
						+ commandLine + "]",
					expectedOutOutputString,
					outOutputString);
		}
		if (!errCompareOK) {
			assertEquals(
					"Unexpected error output for invocation with arguments ["
						+ commandLine + "]",
					expectedErrOutputString,
					errOutputString);
		}
	}

	protected void runClasspathTest(String classpathInput, String[] expectedClasspathEntries, String expectedError) {
		File outputDirectory = new File(OUTPUT_DIR);
		if (!outputDirectory.isDirectory()) {
			outputDirectory.mkdirs();
		}
		ArrayList<ClasspathLocation> paths = new ArrayList<>(Main.DEFAULT_SIZE_CLASSPATH);
		try {
			(new Main(new PrintWriter(System.out), new PrintWriter(System.err), true/*systemExit*/, null/*options*/, null/*progress*/)).
				processPathEntries(Main.DEFAULT_SIZE_CLASSPATH, paths, classpathInput, null /* customEncoding */, true /* isSourceOnly */, false /* rejectDestinationPathOnJars*/);
		} catch (IllegalArgumentException e) {
			// e.printStackTrace();
			if (expectedError == null) {
				fail("unexpected invalid input exception: " + e.getMessage());
			} else if (! expectedError.equals(e.getMessage())) {
				System.out.println("\"" + e.getMessage() + "\"");
				assertEquals(expectedError, e.getMessage());
			}
			return;
		}
		if (expectedError == null) {
			int l = paths.size();
			assertEquals("unexpected classpaths entries number: ",
					expectedClasspathEntries == null ? 0 : expectedClasspathEntries.length / 3, l);
			for (int i = 0, j = 0; i < l ; i++) {
				ClasspathLocation result = paths.get(i);
				String expected = expectedClasspathEntries[j++];
				String actual = result.toString();
				if (! actual.equals("ClasspathDirectory " + expected + File.separator) &&
						! actual.equals("Classpath for jar file " + expected)) {
					assertEquals("dir/jar " + expected, actual);
				}
				expected = expectedClasspathEntries[j++];
				if (result.accessRuleSet == null) {
					assertNull("actual access rule is null instead of <" + expected +">", expected);
				} else if (! result.accessRuleSet.toString(false).
						startsWith("AccessRuleSet " + expected)) {
					System.out.println("\"" + result.accessRuleSet.toString(false) + "\"");
					fail("inappropriate rules (expected " + expected +
						", got " + result.accessRuleSet.toString(false));
				}
				expected = expectedClasspathEntries[j++];
				if (expected == null) {
					assertNull(result.destinationPath);
				} else if (expected == Main.NONE &&
						result.destinationPath != Main.NONE) {
					fail("expected 'none' output directory");
				} else if (! expected.equals(result.destinationPath)) {
					System.out.println("\"" + result.destinationPath + "\"");
					assertEquals(expected, result.destinationPath);
				}
			}
		} else {
			fail("missing error: " + expectedError);
		}
	}

	/**
	 * Check that no line of message extends beyond width columns. Tabs count for
	 * 4 characters.
	 * @param message the message to check
	 * @param width the maximum number of columns for the message
	 */
	protected void checkWidth(String message, int width) {
		BufferedReader reader = new BufferedReader(
				new StringReader(message.replaceAll("\t", "    ")));
		String line;
		try {
			while ((line = reader.readLine()) != null) {
				assertTrue("line exceeds " + width + "characters: " + line,
					line.length() <= width);
			}
		} catch (IOException e) {
			// should never happen on a StringReader
		}
	}

	private static boolean equals(String a, String b) {
		StringBuffer aBuffer = new StringBuffer(a), bBuffer = new StringBuffer(b);
		int length = aBuffer.length(), bLength;
		boolean result = true;
		if (length != (bLength = bBuffer.length())) {
			System.err.println("a and b lengths differ");
			if (length > bLength) {
				length = bLength;
			}
			result = false;
		}
		for (int i = 0; i < length; i++)
			if (aBuffer.charAt(i) != bBuffer.charAt(i)) {
				int beforeStart = i - 5, beforeEnd = i - 1, afterStart = i + 1, afterEnd = i + 5;
				if (beforeStart < 0) {
					beforeStart = 0;
					if (beforeEnd < 0)
						beforeEnd = 0;
				}
				if (afterEnd >= length) {
					afterEnd = length - 1;
					if (afterStart >= length)
						afterStart = length - 1;
				}
				System.err.println("a and b differ at rank: " + i
						+ "\na: ..." + aBuffer.substring(beforeStart, beforeEnd)
							+ "<" + aBuffer.charAt(i) + ">"
							+ aBuffer.substring(afterStart, afterEnd) + "..."
						+ "\nb: ..." + bBuffer.substring(beforeStart, beforeEnd)
							+ "<" + bBuffer.charAt(i) + ">"
							+ bBuffer.substring(afterStart, afterEnd) + "...");
				return false;
			}
		return result; // may be false if one of the strings equals the beginning
		               // of the other one, which is longer anyway
	}

	/**
	 * Return true if and only if the two strings passed as parameters compare
	 * equal, modulo the transformation of the second string by a normalizer
	 * passed in parameter. This is meant to erase the variations of subparts of
	 * the compared strings in function of the test machine, the user account,
	 * etc.
	 *
	 * @param keep
	 *            the first string to compare, gets compared as it is
	 * @param normalize
	 *            the second string to compare, passed through the normalizer
	 *            before comparison
	 * @param normalizer
	 *            the transformation applied to normalize
	 * @return true if keep and normalize compare equal after normalize has been
	 *         normalized
	 */
	protected boolean semiNormalizedComparison(String keep, String normalize, Normalizer normalizer) {
		if (keep == null)
			return normalize == null;
		if (normalize == null)
			return false;
		// return keep.equals(normalizer.normalized(normalize));
		return equals(keep, normalizer.normalized(normalize));
	}

}
