/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Tom Tromey - Contribution for bug 125961
 *     Tom Tromey - Contribution for bug 159641
 *     Benjamin Muskalla - Contribution for bug 239066
 *     Stephan Herrmann  - Contributions for 
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
 *     							bug 295551 - Add option to automatically promote all warnings to errors
 *     							bug 359721 - [options] add command line option for new warning token "resource"
 *								bug 365208 - [compiler][batch] command line options for annotation based null analysis
 *								bug 374605 - Unreasonable warning for enum-based switch statements
 *								bug 375366 - ECJ ignores unusedParameterIncludeDocCommentReference unless enableJavadoc option is set
 *								bug 388281 - [compiler][null] inheritance of null annotations as an option
 *								bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
 *								Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
 *								Bug 440687 - [compiler][batch][null] improve command line option for external annotations
 *								Bug 408815 - [batch][null] Add CLI option for COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS
 *     Jesper S Moller   - Contributions for
 *								bug 407297 - [1.8][compiler] Control generation of parameter names by option
 *    Mat Booth - Contribution for bug 405176 
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.batch;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.CompilationProgress;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
import org.eclipse.jdt.internal.compiler.AbstractAnnotationProcessorManager;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
import org.eclipse.jdt.internal.compiler.batch.ModuleFinder.AddExport;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.AccessRule;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.IModule;
import org.eclipse.jdt.internal.compiler.env.IModule.IPackageExport;
import org.eclipse.jdt.internal.compiler.env.IUpdatableModule.UpdateKind;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.CompilerStats;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.util.GenericXMLWriter;
import org.eclipse.jdt.internal.compiler.util.HashtableOfInt;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
import org.eclipse.jdt.internal.compiler.util.Messages;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.compiler.util.Util;

public class Main implements ProblemSeverities, SuffixConstants {

	public static class Logger {
		private PrintWriter err;
		private PrintWriter log;
		private Main main;
		private PrintWriter out;
		private HashMap<String, Object> parameters;
		int tagBits;
		private static final String CLASS = "class"; //$NON-NLS-1$
		private static final String CLASS_FILE = "classfile"; //$NON-NLS-1$
		private static final String CLASSPATH = "classpath"; //$NON-NLS-1$
		private static final String CLASSPATH_FILE = "FILE"; //$NON-NLS-1$
		private static final String CLASSPATH_FOLDER = "FOLDER"; //$NON-NLS-1$
		private static final String CLASSPATH_ID = "id"; //$NON-NLS-1$
		private static final String CLASSPATH_JAR = "JAR"; //$NON-NLS-1$
		private static final String CLASSPATHS = "classpaths"; //$NON-NLS-1$
		private static final String COMMAND_LINE_ARGUMENT = "argument"; //$NON-NLS-1$
		private static final String COMMAND_LINE_ARGUMENTS = "command_line"; //$NON-NLS-1$
		private static final String COMPILER = "compiler"; //$NON-NLS-1$
		private static final String COMPILER_COPYRIGHT = "copyright"; //$NON-NLS-1$
		private static final String COMPILER_NAME = "name"; //$NON-NLS-1$
		private static final String COMPILER_VERSION = "version"; //$NON-NLS-1$
		public static final int EMACS = 2;
		private static final String ERROR = "ERROR"; //$NON-NLS-1$
		private static final String ERROR_TAG = "error"; //$NON-NLS-1$
		private static final String WARNING_TAG = "warning"; //$NON-NLS-1$
		private static final String EXCEPTION = "exception"; //$NON-NLS-1$
		private static final String EXTRA_PROBLEM_TAG = "extra_problem"; //$NON-NLS-1$
		private static final String EXTRA_PROBLEMS = "extra_problems"; //$NON-NLS-1$
		private static final HashtableOfInt FIELD_TABLE = new HashtableOfInt();
		private static final String KEY = "key"; //$NON-NLS-1$
		private static final String MESSAGE = "message"; //$NON-NLS-1$
		private static final String NUMBER_OF_CLASSFILES = "number_of_classfiles"; //$NON-NLS-1$
		private static final String NUMBER_OF_ERRORS = "errors"; //$NON-NLS-1$
		private static final String NUMBER_OF_LINES = "number_of_lines"; //$NON-NLS-1$
		private static final String NUMBER_OF_PROBLEMS = "problems"; //$NON-NLS-1$
		private static final String NUMBER_OF_TASKS = "tasks"; //$NON-NLS-1$
		private static final String NUMBER_OF_WARNINGS = "warnings"; //$NON-NLS-1$
		private static final String NUMBER_OF_INFOS = "infos"; //$NON-NLS-1$
		private static final String OPTION = "option"; //$NON-NLS-1$
		private static final String OPTIONS = "options"; //$NON-NLS-1$
		private static final String OUTPUT = "output"; //$NON-NLS-1$
		private static final String PACKAGE = "package"; //$NON-NLS-1$
		private static final String PATH = "path"; //$NON-NLS-1$
		private static final String PROBLEM_ARGUMENT = "argument"; //$NON-NLS-1$
		private static final String PROBLEM_ARGUMENT_VALUE = "value"; //$NON-NLS-1$
		private static final String PROBLEM_ARGUMENTS = "arguments"; //$NON-NLS-1$
		private static final String PROBLEM_CATEGORY_ID = "categoryID"; //$NON-NLS-1$
		private static final String ID = "id"; //$NON-NLS-1$
		private static final String PROBLEM_ID = "problemID"; //$NON-NLS-1$
		private static final String PROBLEM_LINE = "line"; //$NON-NLS-1$
		private static final String PROBLEM_OPTION_KEY = "optionKey"; //$NON-NLS-1$
		private static final String PROBLEM_MESSAGE = "message"; //$NON-NLS-1$
		private static final String PROBLEM_SEVERITY = "severity"; //$NON-NLS-1$
		private static final String PROBLEM_SOURCE_END = "charEnd"; //$NON-NLS-1$
		private static final String PROBLEM_SOURCE_START = "charStart"; //$NON-NLS-1$
		private static final String PROBLEM_SUMMARY = "problem_summary"; //$NON-NLS-1$
		private static final String PROBLEM_TAG = "problem"; //$NON-NLS-1$
		private static final String PROBLEMS = "problems"; //$NON-NLS-1$
		private static final String SOURCE = "source"; //$NON-NLS-1$
		private static final String SOURCE_CONTEXT = "source_context"; //$NON-NLS-1$
		private static final String SOURCE_END = "sourceEnd"; //$NON-NLS-1$
		private static final String SOURCE_START = "sourceStart"; //$NON-NLS-1$
		private static final String SOURCES = "sources"; //$NON-NLS-1$

		private static final String STATS = "stats"; //$NON-NLS-1$

		private static final String TASK = "task"; //$NON-NLS-1$
		private static final String TASKS = "tasks"; //$NON-NLS-1$
		private static final String TIME = "time"; //$NON-NLS-1$
		private static final String VALUE = "value"; //$NON-NLS-1$
		private static final String WARNING = "WARNING"; //$NON-NLS-1$
		private static final String INFO = "INFO"; //$NON-NLS-1$

		public static final int XML = 1;
		private static final String XML_DTD_DECLARATION = "<!DOCTYPE compiler PUBLIC \"-//Eclipse.org//DTD Eclipse JDT 3.2.005 Compiler//EN\" \"http://www.eclipse.org/jdt/core/compiler_32_005.dtd\">"; //$NON-NLS-1$
		static {
			try {
				Class<?> c = IProblem.class;
				Field[] fields = c.getFields();
				for (int i = 0, max = fields.length; i < max; i++) {
					Field field = fields[i];
					if (field.getType().equals(Integer.TYPE)) {
						Integer value = (Integer) field.get(null);
						int key2 = value.intValue() & IProblem.IgnoreCategoriesMask;
						if (key2 == 0) {
							key2 = Integer.MAX_VALUE;
						}
						Logger.FIELD_TABLE.put(key2, field.getName());
					}
				}
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		public Logger(Main main, PrintWriter out, PrintWriter err) {
			this.out = out;
			this.err = err;
			this.parameters = new HashMap<>();
			this.main = main;
		}

		public String buildFileName(
			String outputPath,
			String relativeFileName) {
			char fileSeparatorChar = File.separatorChar;
			String fileSeparator = File.separator;

			outputPath = outputPath.replace('/', fileSeparatorChar);
			// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
			StringBuffer outDir = new StringBuffer(outputPath);
			if (!outputPath.endsWith(fileSeparator)) {
				outDir.append(fileSeparator);
			}
			StringTokenizer tokenizer =
				new StringTokenizer(relativeFileName, fileSeparator);
			String token = tokenizer.nextToken();
			while (tokenizer.hasMoreTokens()) {
				outDir.append(token).append(fileSeparator);
				token = tokenizer.nextToken();
			}
			// token contains the last one
			return outDir.append(token).toString();
		}

		public void close() {
			if (this.log != null) {
				if ((this.tagBits & Logger.XML) != 0) {
					endTag(Logger.COMPILER);
					flush();
				}
				this.log.close();
			}
		}

		/**
		 *
		 */
		public void compiling() {
			printlnOut(this.main.bind("progress.compiling")); //$NON-NLS-1$
		}
		private void endLoggingExtraProblems() {
			endTag(Logger.EXTRA_PROBLEMS);
		}
		/**
		 * Used to stop logging problems.
		 * Only use in xml mode.
		 */
		private void endLoggingProblems() {
			endTag(Logger.PROBLEMS);
		}
		public void endLoggingSource() {
			if ((this.tagBits & Logger.XML) != 0) {
				endTag(Logger.SOURCE);
			}
		}

		public void endLoggingSources() {
			if ((this.tagBits & Logger.XML) != 0) {
				endTag(Logger.SOURCES);
			}
		}

		public void endLoggingTasks() {
			if ((this.tagBits & Logger.XML) != 0) {
				endTag(Logger.TASKS);
			}
		}
		private void endTag(String name) {
			if (this.log != null) {
				((GenericXMLWriter) this.log).endTag(name, true, true);
			}
		}
		private String errorReportSource(CategorizedProblem problem, char[] unitSource, int bits) {
			//extra from the source the innacurate     token
			//and "highlight" it using some underneath ^^^^^
			//put some context around too.

			//this code assumes that the font used in the console is fixed size

			//sanity .....
			int startPosition = problem.getSourceStart();
			int endPosition = problem.getSourceEnd();
			if (unitSource == null) {
				if (problem.getOriginatingFileName() != null) {
					try {
						unitSource = Util.getFileCharContent(new File(new String(problem.getOriginatingFileName())), null);
					} catch (IOException e) {
						// ignore;
					}
				}
			}
			int length;
			if ((startPosition > endPosition)
				|| ((startPosition < 0) && (endPosition < 0))
				|| (unitSource == null)
				|| (length = unitSource.length) == 0)
				return Messages.problem_noSourceInformation;

			StringBuffer errorBuffer = new StringBuffer();
			if ((bits & Main.Logger.EMACS) == 0) {
				errorBuffer.append(' ').append(Messages.bind(Messages.problem_atLine, String.valueOf(problem.getSourceLineNumber())));
				errorBuffer.append(Util.LINE_SEPARATOR);
			}
			errorBuffer.append('\t');

			char c;
			final char SPACE = '\u0020';
			final char MARK = '^';
			final char TAB = '\t';
			//the next code tries to underline the token.....
			//it assumes (for a good display) that token source does not
			//contain any \r \n. This is false on statements !
			//(the code still works but the display is not optimal !)

			// expand to line limits
			int begin;
			int end;
			for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
				if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
			}
			for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
				if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
			}

			// trim left and right spaces/tabs
			while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
			//while ((c = unitSource[end]) == ' ' || c == '\t') end--; TODO (philippe) should also trim right, but all tests are to be updated

			// copy source
			errorBuffer.append(unitSource, begin, end-begin+1);
			errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$

			// compute underline
			for (int i = begin; i <startPosition; i++) {
				errorBuffer.append((unitSource[i] == TAB) ? TAB : SPACE);
			}
			for (int i = startPosition; i <= (endPosition >= length ? length - 1 : endPosition); i++) {
				errorBuffer.append(MARK);
			}
			return errorBuffer.toString();
		}

		private void extractContext(CategorizedProblem problem, char[] unitSource) {
			//sanity .....
			int startPosition = problem.getSourceStart();
			int endPosition = problem.getSourceEnd();
			if (unitSource == null) {
				if (problem.getOriginatingFileName() != null) {
					try {
						unitSource = Util.getFileCharContent(new File(new String(problem.getOriginatingFileName())), null);
					} catch(IOException e) {
						// ignore
					}
				}
			}
			int length;
			if ((startPosition > endPosition)
					|| ((startPosition < 0) && (endPosition < 0))
					|| (unitSource == null)
					|| ((length = unitSource.length) <= 0)
					|| (endPosition > length)) {
				this.parameters.put(Logger.VALUE, Messages.problem_noSourceInformation);
				this.parameters.put(Logger.SOURCE_START, "-1"); //$NON-NLS-1$
				this.parameters.put(Logger.SOURCE_END, "-1"); //$NON-NLS-1$
				printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
				return;
			}

			char c;
			//the next code tries to underline the token.....
			//it assumes (for a good display) that token source does not
			//contain any \r \n. This is false on statements !
			//(the code still works but the display is not optimal !)

			// expand to line limits
			int begin, end;
			for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
				if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
			}
			for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
				if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
			}

			// trim left and right spaces/tabs
			while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
			while ((c = unitSource[end]) == ' ' || c == '\t') end--;

			// copy source
			StringBuffer buffer = new StringBuffer();
			buffer.append(unitSource, begin, end - begin + 1);

			this.parameters.put(Logger.VALUE, String.valueOf(buffer));
			this.parameters.put(Logger.SOURCE_START, Integer.toString(startPosition - begin));
			this.parameters.put(Logger.SOURCE_END, Integer.toString(endPosition - begin));
			printTag(Logger.SOURCE_CONTEXT, this.parameters, true, true);
		}
		public void flush() {
			this.out.flush();
			this.err.flush();
			if (this.log != null) {
				this.log.flush();
			}
		}

		private String getFieldName(int id) {
			int key2 = id & IProblem.IgnoreCategoriesMask;
			if (key2 == 0) {
				key2 = Integer.MAX_VALUE;
			}
			return (String) Logger.FIELD_TABLE.get(key2);
		}

		// find out an option name controlling a given problemID
		private String getProblemOptionKey(int problemID) {
			int irritant = ProblemReporter.getIrritant(problemID);
			return CompilerOptions.optionKeyFromIrritant(irritant);
		}

		public void logAverage() {
			Arrays.sort(this.main.compilerStats);
			long lineCount = this.main.compilerStats[0].lineCount;
			final int length = this.main.maxRepetition;
			long sum = 0;
			long parseSum = 0, resolveSum = 0, analyzeSum = 0, generateSum = 0;
			for (int i = 1, max = length - 1; i < max; i++) {
				CompilerStats stats = this.main.compilerStats[i];
				sum += stats.elapsedTime();
				parseSum += stats.parseTime;
				resolveSum += stats.resolveTime;
				analyzeSum += stats.analyzeTime;
				generateSum += stats.generateTime;
			}
			long time = sum / (length - 2);
			long parseTime = parseSum/(length - 2);
			long resolveTime = resolveSum/(length - 2);
			long analyzeTime = analyzeSum/(length - 2);
			long generateTime = generateSum/(length - 2);
			printlnOut(this.main.bind(
				"compile.averageTime", //$NON-NLS-1$
				new String[] {
					String.valueOf(lineCount),
					String.valueOf(time),
					String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0),
				}));
			if ((this.main.timing & Main.TIMING_DETAILED) != 0) {
				printlnOut(
						this.main.bind("compile.detailedTime", //$NON-NLS-1$
							new String[] {
								String.valueOf(parseTime),
								String.valueOf(((int) (parseTime * 1000.0 / time)) / 10.0),
								String.valueOf(resolveTime),
								String.valueOf(((int) (resolveTime * 1000.0 / time)) / 10.0),
								String.valueOf(analyzeTime),
								String.valueOf(((int) (analyzeTime * 1000.0 / time)) / 10.0),
								String.valueOf(generateTime),
								String.valueOf(((int) (generateTime * 1000.0 / time)) / 10.0),
							}));
			}
		}
		public void logClassFile(boolean generatePackagesStructure, String outputPath, String relativeFileName) {
			if ((this.tagBits & Logger.XML) != 0) {
				String fileName = null;
				if (generatePackagesStructure) {
					fileName = buildFileName(outputPath, relativeFileName);
				} else {
					char fileSeparatorChar = File.separatorChar;
					String fileSeparator = File.separator;
					// First we ensure that the outputPath exists
					outputPath = outputPath.replace('/', fileSeparatorChar);
					// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
					int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar);
					if (indexOfPackageSeparator == -1) {
						if (outputPath.endsWith(fileSeparator)) {
							fileName = outputPath + relativeFileName;
						} else {
							fileName = outputPath + fileSeparator + relativeFileName;
						}
					} else {
						int length = relativeFileName.length();
						if (outputPath.endsWith(fileSeparator)) {
							fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length);
						} else {
							fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length);
						}
					}
				}
				File f = new File(fileName);
				try {
					this.parameters.put(Logger.PATH, f.getCanonicalPath());
					printTag(Logger.CLASS_FILE, this.parameters, true, true);
				} catch (IOException e) {
					logNoClassFileCreated(outputPath, relativeFileName, e);
				}
			}
		}
		public void logClasspath(FileSystem.Classpath[] classpaths) {
			if (classpaths == null) return;
			if ((this.tagBits & Logger.XML) != 0) {
				final int length = classpaths.length;
				if (length != 0) {
					// generate xml output
					printTag(Logger.CLASSPATHS, null, true, false);
					for (int i = 0; i < length; i++) {
						String classpath = classpaths[i].getPath();
						this.parameters.put(Logger.PATH, classpath);
						File f = new File(classpath);
						String id = null;
						if (f.isFile()) {
							int kind = Util.archiveFormat(classpath);
							switch (kind) {
								case Util.ZIP_FILE:
									id = Logger.CLASSPATH_JAR;
									break;
								default:
									id = Logger.CLASSPATH_FILE;
									break;
							}
						} else if (f.isDirectory()) {
							id = Logger.CLASSPATH_FOLDER;
						}
						if (id != null) {
							this.parameters.put(Logger.CLASSPATH_ID, id);
							printTag(Logger.CLASSPATH, this.parameters, true, true);
						}
					}
					endTag(Logger.CLASSPATHS);
				}
			}

		}

		public void logCommandLineArguments(String[] commandLineArguments) {
			if (commandLineArguments == null) return;
			if ((this.tagBits & Logger.XML) != 0) {
				final int length = commandLineArguments.length;
				if (length != 0) {
					// generate xml output
					printTag(Logger.COMMAND_LINE_ARGUMENTS, null, true, false);
					for (int i = 0; i < length; i++) {
						this.parameters.put(Logger.VALUE, commandLineArguments[i]);
						printTag(Logger.COMMAND_LINE_ARGUMENT, this.parameters, true, true);
					}
					endTag(Logger.COMMAND_LINE_ARGUMENTS);
				}
			}
		}

		/**
		 * @param e the given exception to log
		 */
		public void logException(Exception e) {
			StringWriter writer = new StringWriter();
			PrintWriter printWriter = new PrintWriter(writer);
			e.printStackTrace(printWriter);
			printWriter.flush();
			printWriter.close();
			final String stackTrace = writer.toString();
			if ((this.tagBits & Logger.XML) != 0) {
				LineNumberReader reader = new LineNumberReader(new StringReader(stackTrace));
				String line;
				int i = 0;
				StringBuffer buffer = new StringBuffer();
				String message = e.getMessage();
				if (message != null) {
					buffer.append(message).append(Util.LINE_SEPARATOR);
				}
				try {
					while ((line = reader.readLine()) != null && i < 4) {
						buffer.append(line).append(Util.LINE_SEPARATOR);
						i++;
					}
					reader.close();
				} catch (IOException e1) {
					// ignore
				}
				message = buffer.toString();
				this.parameters.put(Logger.MESSAGE, message);
				this.parameters.put(Logger.CLASS, e.getClass());
				printTag(Logger.EXCEPTION, this.parameters, true, true);
			}
			String message = e.getMessage();
			if (message == null) {
				this.printlnErr(stackTrace);
			} else {
				this.printlnErr(message);
			}
		}

		private void logExtraProblem(CategorizedProblem problem, int localErrorCount, int globalErrorCount) {
			char[] originatingFileName = problem.getOriginatingFileName();
			if (originatingFileName == null) {
				// simplified message output
				String severity = problem.isError() ? "requestor.extraerror" //$NON-NLS-1$
						: problem.isInfo() ? "requestor.extrainfo" : "requestor.extrawarning"; //$NON-NLS-1$ //$NON-NLS-2$
				printErr(this.main.bind(
								severity,
								Integer.toString(globalErrorCount)));
				printErr(" "); //$NON-NLS-1$
				this.printlnErr(problem.getMessage());
			} else {
				String fileName = new String(originatingFileName);
				if ((this.tagBits & Logger.EMACS) != 0) {
					String severity = problem.isError() ? "output.emacs.error" : //$NON-NLS-1$
										problem.isInfo() ? "output.emacs.info" //$NON-NLS-1$
													: "output.emacs.warning"; //$NON-NLS-1$
					String result = fileName
							+ ":" //$NON-NLS-1$
							+ problem.getSourceLineNumber()
							+ ": " //$NON-NLS-1$
							+ this.main.bind(severity)
							+ ": " //$NON-NLS-1$
							+ problem.getMessage();
					this.printlnErr(result);
					final String errorReportSource = errorReportSource(problem, null, this.tagBits);
					this.printlnErr(errorReportSource);
				} else {
					if (localErrorCount == 0) {
						this.printlnErr("----------"); //$NON-NLS-1$
					}
					String severity = problem.isError() ? "requestor.error" //$NON-NLS-1$
							: problem.isInfo() ? "requestor.info" : "requestor.warning"; //$NON-NLS-1$ //$NON-NLS-2$
					printErr(this.main.bind(
								severity,
								Integer.toString(globalErrorCount),
								new String(fileName)));
					final String errorReportSource = errorReportSource(problem, null, 0);
					this.printlnErr(errorReportSource);
					this.printlnErr(problem.getMessage());
					this.printlnErr("----------"); //$NON-NLS-1$
				}
			}
		}

		public void loggingExtraProblems(Main currentMain) {
			ArrayList<CategorizedProblem> problems = currentMain.extraProblems;
			final int count = problems.size();
			int localProblemCount = 0;
			if (count != 0) {
				int errors = 0;
				int warnings = 0;
				int infos = 0;
				for (int i = 0; i < count; i++) {
					CategorizedProblem problem = problems.get(i);
					if (problem != null) {
						currentMain.globalProblemsCount++;
						logExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
						localProblemCount++;
						if (problem.isError()) {
							errors++;
							currentMain.globalErrorsCount++;
						} else if (problem.isInfo()) {
							currentMain.globalInfoCount++;
							infos++;
						} else {
							currentMain.globalWarningsCount++;
							warnings++;
						}
					}
				}
				if ((this.tagBits & Logger.XML) != 0) {
					if ((errors + warnings + infos) != 0) {
						startLoggingExtraProblems(count);
						for (int i = 0; i < count; i++) {
							CategorizedProblem problem = problems.get(i);
							if (problem!= null) {
								if (problem.getID() != IProblem.Task) {
									logXmlExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
								}
							}
						}
						endLoggingExtraProblems();
					}
				}
			}
		}

		public void logUnavaibleAPT(String className) {
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.MESSAGE, this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$
				printTag(Logger.ERROR_TAG, this.parameters, true, true);
			}
			this.printlnErr(this.main.bind("configure.unavailableAPT", className)); //$NON-NLS-1$
		}

		public void logIncorrectVMVersionForAnnotationProcessing() {
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.MESSAGE, this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
				printTag(Logger.ERROR_TAG, this.parameters, true, true);
			}
			this.printlnErr(this.main.bind("configure.incorrectVMVersionforAPT")); //$NON-NLS-1$
		}

		/**
		 *
		 */
		public void logNoClassFileCreated(String outputDir, String relativeFileName, IOException e) {
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.MESSAGE, this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
					new String[] {
						outputDir,
						relativeFileName,
						e.getMessage()
					}));
				printTag(Logger.ERROR_TAG, this.parameters, true, true);
			}
			this.printlnErr(this.main.bind("output.noClassFileCreated", //$NON-NLS-1$
				new String[] {
					outputDir,
					relativeFileName,
					e.getMessage()
				}));
		}

		/**
		 * @param exportedClassFilesCounter
		 */
		public void logNumberOfClassFilesGenerated(int exportedClassFilesCounter) {
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.VALUE, Integer.valueOf(exportedClassFilesCounter));
				printTag(Logger.NUMBER_OF_CLASSFILES, this.parameters, true, true);
			}
			if (exportedClassFilesCounter == 1) {
				printlnOut(this.main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$
			} else {
				printlnOut(this.main.bind("compile.severalClassFilesGenerated", //$NON-NLS-1$
					String.valueOf(exportedClassFilesCounter)));
			}
		}

		/**
		 * @param options the given compiler options
		 */
		public void logOptions(Map<String, String> options) {
			if ((this.tagBits & Logger.XML) != 0) {
				printTag(Logger.OPTIONS, null, true, false);
				final Set<Map.Entry<String, String>> entriesSet = options.entrySet();
				Map.Entry<String, String>[] entries = entriesSet.toArray(new Map.Entry[entriesSet.size()]);
				Arrays.sort(entries, new Comparator<Map.Entry<String, String>>() {
					@Override
					public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
						Map.Entry<String, String> entry1 = o1;
						Map.Entry<String, String> entry2 = o2;
						return entry1.getKey().compareTo(entry2.getKey());
					}
				});
				for (int i = 0, max = entries.length; i < max; i++) {
					Map.Entry<String, String> entry = entries[i];
					String key = entry.getKey();
					this.parameters.put(Logger.KEY, key);
					this.parameters.put(Logger.VALUE, entry.getValue());
					printTag(Logger.OPTION, this.parameters, true, true);
				}
				endTag(Logger.OPTIONS);
			}
		}

		/**
		 * @param error the given error
		 */
		public void logPendingError(String error) {
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.MESSAGE, error);
				printTag(Logger.ERROR_TAG, this.parameters, true, true);
			}
			this.printlnErr(error);
		}

		/**
		 * @param message the given message
		 */
		public void logWarning(String message) {
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.MESSAGE, message);
				printTag(Logger.WARNING_TAG, this.parameters, true, true);
			}
			this.printlnOut(message);
		}

		private void logProblem(CategorizedProblem problem, int localErrorCount,
			int globalErrorCount, char[] unitSource) {
			if ((this.tagBits & Logger.EMACS) != 0) {
				String severity = problem.isError() ? "output.emacs.error" : //$NON-NLS-1$
									problem.isInfo() ? "output.emacs.info" //$NON-NLS-1$
											: "output.emacs.warning"; //$NON-NLS-1$
				String result = (new String(problem.getOriginatingFileName())
						+ ":" //$NON-NLS-1$
						+ problem.getSourceLineNumber()
						+ ": " //$NON-NLS-1$
						+ (this.main.bind(severity))
						+ ": " //$NON-NLS-1$
						+ problem.getMessage());
				this.printlnErr(result);
				final String errorReportSource = errorReportSource(problem, unitSource, this.tagBits);
				if (errorReportSource.length() != 0) this.printlnErr(errorReportSource);
			} else {
				if (localErrorCount == 0) {
					this.printlnErr("----------"); //$NON-NLS-1$
				}
				String severity = problem.isError() ? "requestor.error" : problem.isInfo() ? "requestor.info" : "requestor.warning";  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
				printErr(this.main.bind(severity,
										Integer.toString(globalErrorCount),
										new String(problem.getOriginatingFileName())));
				try {
					final String errorReportSource = errorReportSource(problem, unitSource, 0);
					this.printlnErr(errorReportSource);
					this.printlnErr(problem.getMessage());
				} catch (Exception e) {
					this.printlnErr(this.main.bind(
						"requestor.notRetrieveErrorMessage", problem.toString())); //$NON-NLS-1$
				}
				this.printlnErr("----------"); //$NON-NLS-1$
			}
		}

		public int logProblems(CategorizedProblem[] problems, char[] unitSource, Main currentMain) {
			final int count = problems.length;
			int localErrorCount = 0;
			int localProblemCount = 0;
			if (count != 0) {
				int errors = 0;
				int warnings = 0;
				int infos = 0;
				int tasks = 0;
				for (int i = 0; i < count; i++) {
					CategorizedProblem problem = problems[i];
					if (problem != null) {
						currentMain.globalProblemsCount++;
						logProblem(problem, localProblemCount, currentMain.globalProblemsCount, unitSource);
						localProblemCount++;
						if (problem.isError()) {
							localErrorCount++;
							errors++;
							currentMain.globalErrorsCount++;
						} else if (problem.getID() == IProblem.Task) {
							currentMain.globalTasksCount++;
							tasks++;
						} else if (problem.isInfo()) {
							currentMain.globalInfoCount++;
							infos++;
						} else {
							currentMain.globalWarningsCount++;
							warnings++;
						}
					}
				}
				if ((this.tagBits & Logger.XML) != 0) {
					if ((errors + warnings + infos) != 0) {
						startLoggingProblems(errors, warnings, infos);
						for (int i = 0; i < count; i++) {
							CategorizedProblem problem = problems[i];
							if (problem!= null) {
								if (problem.getID() != IProblem.Task) {
									logXmlProblem(problem, unitSource);
								}
							}
						}
						endLoggingProblems();
					}
					if (tasks != 0) {
						startLoggingTasks(tasks);
						for (int i = 0; i < count; i++) {
							CategorizedProblem problem = problems[i];
							if (problem!= null) {
								if (problem.getID() == IProblem.Task) {
									logXmlTask(problem, unitSource);
								}
							}
						}
						endLoggingTasks();
					}
				}
			}
			return localErrorCount;
		}

		/**
		 * @param globalProblemsCount
		 * @param globalErrorsCount
		 * @param globalWarningsCount
		 */
		public void logProblemsSummary(int globalProblemsCount,
			int globalErrorsCount, int globalWarningsCount, int globalInfoCount, int globalTasksCount) {
			if ((this.tagBits & Logger.XML) != 0) {
				// generate xml
				this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(globalProblemsCount));
				this.parameters.put(Logger.NUMBER_OF_ERRORS, Integer.valueOf(globalErrorsCount));
				this.parameters.put(Logger.NUMBER_OF_WARNINGS, Integer.valueOf(globalWarningsCount));
				this.parameters.put(Logger.NUMBER_OF_INFOS, Integer.valueOf(globalInfoCount));
				this.parameters.put(Logger.NUMBER_OF_TASKS, Integer.valueOf(globalTasksCount));
				printTag(Logger.PROBLEM_SUMMARY, this.parameters, true, true);
			}
			if (globalProblemsCount == 1) {
				String message = null;
				if (globalErrorsCount == 1) {
					message = this.main.bind("compile.oneError"); //$NON-NLS-1$
				} else if (globalInfoCount == 1) {
					message = this.main.bind("compile.oneInfo"); //$NON-NLS-1$
				} else {
					message = this.main.bind("compile.oneWarning"); //$NON-NLS-1$
				}
				printErr(this.main.bind("compile.oneProblem", message)); //$NON-NLS-1$
			} else {
				String errorMessage = null;
				String warningMessage = null;
				String infoMessage = null;
				if (globalErrorsCount > 0) {
					if (globalErrorsCount == 1) {
						errorMessage = this.main.bind("compile.oneError"); //$NON-NLS-1$
					} else {
						errorMessage = this.main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$
					}
				}
				int warningsNumber = globalWarningsCount + globalTasksCount;
				if (warningsNumber > 0) {
					if (warningsNumber == 1) {
						warningMessage = this.main.bind("compile.oneWarning"); //$NON-NLS-1$
					} else {
						warningMessage = this.main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$
					}
				}
				if (globalInfoCount == 1) {
					infoMessage = this.main.bind("compile.oneInfo"); //$NON-NLS-1$
				} else if (globalInfoCount > 1) {
					infoMessage = this.main.bind("compile.severalInfos", String.valueOf(warningsNumber)); //$NON-NLS-1$					
				}
				if (globalProblemsCount == globalInfoCount || globalProblemsCount == globalErrorsCount || globalProblemsCount == globalWarningsCount) {
					String msg = errorMessage != null ? errorMessage : warningMessage != null ? warningMessage : infoMessage;
					printErr(this.main.bind(
						"compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
						String.valueOf(globalProblemsCount),
						msg));
				} else {
					if (globalInfoCount == 0) {
						printErr(this.main.bind(
								"compile.severalProblemsErrorsAndWarnings", //$NON-NLS-1$
								new String[] {
									String.valueOf(globalProblemsCount),
									errorMessage,
									warningMessage
								}));
					} else {
						if (errorMessage == null) {
							errorMessage  = this.main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$
						}
						if (warningMessage == null) {
							warningMessage  = this.main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$
						}
						printErr(this.main.bind(
								"compile.severalProblems", //$NON-NLS-1$
								new String[] {
									String.valueOf(globalProblemsCount),
									errorMessage,
									warningMessage,
									infoMessage
								}));
					}
				}
			}
			if ((this.tagBits & Logger.XML) == 0) {
				this.printlnErr();
			}
		}

		/**
		 *
		 */
		public void logProgress() {
			printOut('.');
		}

		/**
		 * @param i
		 *            the current repetition number
		 * @param repetitions
		 *            the given number of repetitions
		 */
		public void logRepetition(int i, int repetitions) {
			printlnOut(this.main.bind("compile.repetition", //$NON-NLS-1$
				String.valueOf(i + 1), String.valueOf(repetitions)));
		}
		/**
		 * @param compilerStats
		 */
		public void logTiming(CompilerStats compilerStats) {
			long time = compilerStats.elapsedTime();
			long lineCount = compilerStats.lineCount;
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.VALUE, Long.valueOf(time));
				printTag(Logger.TIME, this.parameters, true, true);
				this.parameters.put(Logger.VALUE, Long.valueOf(lineCount));
				printTag(Logger.NUMBER_OF_LINES, this.parameters, true, true);
			}
			if (lineCount != 0) {
				printlnOut(
					this.main.bind("compile.instantTime", //$NON-NLS-1$
						new String[] {
							String.valueOf(lineCount),
							String.valueOf(time),
							String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0),
						}));
			} else {
				printlnOut(
					this.main.bind("compile.totalTime", //$NON-NLS-1$
						new String[] {
							String.valueOf(time),
						}));
			}
			if ((this.main.timing & Main.TIMING_DETAILED) != 0) {
				printlnOut(
						this.main.bind("compile.detailedTime", //$NON-NLS-1$
							new String[] {
								String.valueOf(compilerStats.parseTime),
								String.valueOf(((int) (compilerStats.parseTime * 1000.0 / time)) / 10.0),
								String.valueOf(compilerStats.resolveTime),
								String.valueOf(((int) (compilerStats.resolveTime * 1000.0 / time)) / 10.0),
								String.valueOf(compilerStats.analyzeTime),
								String.valueOf(((int) (compilerStats.analyzeTime * 1000.0 / time)) / 10.0),
								String.valueOf(compilerStats.generateTime),
								String.valueOf(((int) (compilerStats.generateTime * 1000.0 / time)) / 10.0),
							}));
			}
		}

		/**
		 * Print the usage of the compiler
		 * @param usage
		 */
		public void logUsage(String usage) {
			printlnOut(usage);
		}

		/**
		 * Print the version of the compiler in the log and/or the out field
		 */
		public void logVersion(final boolean printToOut) {
			if (this.log != null && (this.tagBits & Logger.XML) == 0) {
				final String version = this.main.bind("misc.version", //$NON-NLS-1$
					new String[] {
						this.main.bind("compiler.name"), //$NON-NLS-1$
						this.main.bind("compiler.version"), //$NON-NLS-1$
						this.main.bind("compiler.copyright") //$NON-NLS-1$
					}
				);
				this.log.println("# " + version); //$NON-NLS-1$
				if (printToOut) {
					this.out.println(version);
					this.out.flush();
				}
			} else if (printToOut) {
				final String version = this.main.bind("misc.version", //$NON-NLS-1$
					new String[] {
						this.main.bind("compiler.name"), //$NON-NLS-1$
						this.main.bind("compiler.version"), //$NON-NLS-1$
						this.main.bind("compiler.copyright") //$NON-NLS-1$
					}
				);
				this.out.println(version);
				this.out.flush();
			}
		}

		/**
		 * Print the usage of wrong JDK
		 */
		public void logWrongJDK() {
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.MESSAGE, this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
				printTag(Logger.ERROR, this.parameters, true, true);
			}
			this.printlnErr(this.main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
		}

		private void logXmlExtraProblem(CategorizedProblem problem, int globalErrorCount, int localErrorCount) {
			final int sourceStart = problem.getSourceStart();
			final int sourceEnd = problem.getSourceEnd();
			boolean isError = problem.isError();
			this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : (problem.isInfo() ? Logger.INFO : Logger.WARNING));
			this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
			this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(sourceStart));
			this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(sourceEnd));
			printTag(Logger.EXTRA_PROBLEM_TAG, this.parameters, true, false);
			this.parameters.put(Logger.VALUE, problem.getMessage());
			printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
			extractContext(problem, null);
			endTag(Logger.EXTRA_PROBLEM_TAG);
		}
		/**
		 * @param problem
		 *            the given problem to log
		 * @param unitSource
		 *            the given unit source
		 */
		private void logXmlProblem(CategorizedProblem problem, char[] unitSource) {
			final int sourceStart = problem.getSourceStart();
			final int sourceEnd = problem.getSourceEnd();
			final int id = problem.getID();
			this.parameters.put(Logger.ID, getFieldName(id)); // ID as field name
			this.parameters.put(Logger.PROBLEM_ID, Integer.valueOf(id)); // ID as numeric value
			boolean isError = problem.isError();
			int severity = isError ? ProblemSeverities.Error : ProblemSeverities.Warning;
			this.parameters.put(Logger.PROBLEM_SEVERITY, isError ? Logger.ERROR : (problem.isInfo() ? Logger.INFO : Logger.WARNING));
			this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
			this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(sourceStart));
			this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(sourceEnd));
			String problemOptionKey = getProblemOptionKey(id);
			if (problemOptionKey != null) {
				this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
			}
			int categoryID = ProblemReporter.getProblemCategory(severity, id);
			this.parameters.put(Logger.PROBLEM_CATEGORY_ID, Integer.valueOf(categoryID));
			printTag(Logger.PROBLEM_TAG, this.parameters, true, false);
			this.parameters.put(Logger.VALUE, problem.getMessage());
			printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
			extractContext(problem, unitSource);
			String[] arguments = problem.getArguments();
			final int length = arguments.length;
			if (length != 0) {
				printTag(Logger.PROBLEM_ARGUMENTS, null, true, false);
				for (int i = 0; i < length; i++) {
					this.parameters.put(Logger.PROBLEM_ARGUMENT_VALUE, arguments[i]);
					printTag(Logger.PROBLEM_ARGUMENT, this.parameters, true, true);
				}
				endTag(Logger.PROBLEM_ARGUMENTS);
			}
			endTag(Logger.PROBLEM_TAG);
		}
		/**
		 * @param problem
		 *            the given problem to log
		 * @param unitSource
		 *            the given unit source
		 */
		private void logXmlTask(CategorizedProblem problem, char[] unitSource) {
			this.parameters.put(Logger.PROBLEM_LINE, Integer.valueOf(problem.getSourceLineNumber()));
			this.parameters.put(Logger.PROBLEM_SOURCE_START, Integer.valueOf(problem.getSourceStart()));
			this.parameters.put(Logger.PROBLEM_SOURCE_END, Integer.valueOf(problem.getSourceEnd()));
			String problemOptionKey = getProblemOptionKey(problem.getID());
			if (problemOptionKey != null) {
				this.parameters.put(Logger.PROBLEM_OPTION_KEY, problemOptionKey);
			}
			printTag(Logger.TASK, this.parameters, true, false);
			this.parameters.put(Logger.VALUE, problem.getMessage());
			printTag(Logger.PROBLEM_MESSAGE, this.parameters, true, true);
			extractContext(problem, unitSource);
			endTag(Logger.TASK);
		}

		private void printErr(String s) {
			this.err.print(s);
			if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
				this.log.print(s);
			}
		}

		private void printlnErr() {
			this.err.println();
			if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
				this.log.println();
			}
		}

		private void printlnErr(String s) {
			this.err.println(s);
			if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
				this.log.println(s);
			}
		}

		private void printlnOut(String s) {
			this.out.println(s);
			if ((this.tagBits & Logger.XML) == 0 && this.log != null) {
				this.log.println(s);
			}
		}

		/**
		 *
		 */
		public void printNewLine() {
			this.out.println();
		}

		private void printOut(char c) {
			this.out.print(c);
		}

		public void printStats() {
			final boolean isTimed = (this.main.timing & TIMING_ENABLED) != 0;
			if ((this.tagBits & Logger.XML) != 0) {
				printTag(Logger.STATS, null, true, false);
			}
			if (isTimed) {
				CompilerStats compilerStats = this.main.batchCompiler.stats;
				compilerStats.startTime = this.main.startTime; // also include batch initialization times
				compilerStats.endTime = System.currentTimeMillis(); // also include batch output times
				logTiming(compilerStats);
			}
			if (this.main.globalProblemsCount > 0) {
				logProblemsSummary(this.main.globalProblemsCount, this.main.globalErrorsCount, this.main.globalWarningsCount, 
						this.main.globalInfoCount, this.main.globalTasksCount);
			}
			if (this.main.exportedClassFilesCounter != 0
					&& (this.main.showProgress || isTimed || this.main.verbose)) {
				logNumberOfClassFilesGenerated(this.main.exportedClassFilesCounter);
			}
			if ((this.tagBits & Logger.XML) != 0) {
				endTag(Logger.STATS);
			}
		}

		private void printTag(String name, HashMap<String, Object> params, boolean insertNewLine, boolean closeTag) {
			if (this.log != null) {
				((GenericXMLWriter) this.log).printTag(name, this.parameters, true, insertNewLine, closeTag);
			}
			this.parameters.clear();
		}

		public void setEmacs() {
			this.tagBits |= Logger.EMACS;
		}
		public void setLog(String logFileName) {
			final Date date = new Date();
			final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.getDefault());
			try {
				int index = logFileName.lastIndexOf('.');
				if (index != -1) {
					if (logFileName.substring(index).toLowerCase().equals(".xml")) { //$NON-NLS-1$
						this.log = new GenericXMLWriter(new OutputStreamWriter(new FileOutputStream(logFileName, false), Util.UTF_8), Util.LINE_SEPARATOR, true);
						this.tagBits |= Logger.XML;
						// insert time stamp as comment
						this.log.println("<!-- " + dateFormat.format(date) + " -->");//$NON-NLS-1$//$NON-NLS-2$
						this.log.println(Logger.XML_DTD_DECLARATION);
						this.parameters.put(Logger.COMPILER_NAME, this.main.bind("compiler.name")); //$NON-NLS-1$
						this.parameters.put(Logger.COMPILER_VERSION, this.main.bind("compiler.version")); //$NON-NLS-1$
						this.parameters.put(Logger.COMPILER_COPYRIGHT, this.main.bind("compiler.copyright")); //$NON-NLS-1$
						printTag(Logger.COMPILER, this.parameters, true, false);
					} else {
						this.log = new PrintWriter(new FileOutputStream(logFileName, false));
						this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
					}
				} else {
					this.log = new PrintWriter(new FileOutputStream(logFileName, false));
					this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$
				}
			} catch (FileNotFoundException e) {
				throw new IllegalArgumentException(this.main.bind("configure.cannotOpenLog", logFileName), e); //$NON-NLS-1$
			} catch (UnsupportedEncodingException e) {
				throw new IllegalArgumentException(this.main.bind("configure.cannotOpenLogInvalidEncoding", logFileName), e); //$NON-NLS-1$
			}
		}
		private void startLoggingExtraProblems(int count) {
			this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(count));
			printTag(Logger.EXTRA_PROBLEMS, this.parameters, true, false);
		}

		/**
		 * Used to start logging problems.
		 * Only use in xml mode.
		 */
		private void startLoggingProblems(int errors, int warnings, int infos) {
			this.parameters.put(Logger.NUMBER_OF_PROBLEMS, Integer.valueOf(errors + warnings));
			this.parameters.put(Logger.NUMBER_OF_ERRORS, Integer.valueOf(errors));
			this.parameters.put(Logger.NUMBER_OF_WARNINGS, Integer.valueOf(warnings));
			this.parameters.put(Logger.NUMBER_OF_INFOS, Integer.valueOf(infos));
			printTag(Logger.PROBLEMS, this.parameters, true, false);
		}

		public void startLoggingSource(CompilationResult compilationResult) {
			if ((this.tagBits & Logger.XML) != 0) {
				ICompilationUnit compilationUnit = compilationResult.compilationUnit;
				if (compilationUnit != null) {
    				char[] fileName = compilationUnit.getFileName();
    				File f = new File(new String(fileName));
    				if (fileName != null) {
    					this.parameters.put(Logger.PATH, f.getAbsolutePath());
    				}
    				char[][] packageName = compilationResult.packageName;
    				if (packageName != null) {
    					this.parameters.put(
    							Logger.PACKAGE,
    							new String(CharOperation.concatWith(packageName, File.separatorChar)));
    				}
    				CompilationUnit unit = (CompilationUnit) compilationUnit;
    				String destinationPath = unit.destinationPath;
					if (destinationPath == null) {
						destinationPath = this.main.destinationPath;
					}
					if (destinationPath != null && destinationPath != NONE) {
						if (File.separatorChar == '/') {
							this.parameters.put(Logger.OUTPUT, destinationPath);
						} else {
							this.parameters.put(Logger.OUTPUT, destinationPath.replace('/', File.separatorChar));
						}
					}
				}
				printTag(Logger.SOURCE, this.parameters, true, false);
			}
		}

		public void startLoggingSources() {
			if ((this.tagBits & Logger.XML) != 0) {
				printTag(Logger.SOURCES, null, true, false);
			}
		}

		public void startLoggingTasks(int tasks) {
			if ((this.tagBits & Logger.XML) != 0) {
				this.parameters.put(Logger.NUMBER_OF_TASKS, Integer.valueOf(tasks));
				printTag(Logger.TASKS, this.parameters, true, false);
			}
		}
	}

	/**
	 * Resource bundle factory to share bundles for the same locale
	 */
	public static class ResourceBundleFactory {
		private static HashMap<Locale, ResourceBundle> Cache = new HashMap<>();
		public static synchronized ResourceBundle getBundle(Locale locale) {
			ResourceBundle bundle = Cache.get(locale);
			if (bundle == null) {
				bundle = ResourceBundle.getBundle(Main.bundleName, locale);
				Cache.put(locale, bundle);
			}
			return bundle;
		}
	}

	// used with -annotationpath to declare that annotations should be read from the classpath:
	private static final String ANNOTATION_SOURCE_CLASSPATH = "CLASSPATH"; //$NON-NLS-1$

	// javadoc analysis tuning
	boolean enableJavadocOn;

	boolean warnJavadocOn;
	boolean warnAllJavadocOn;

	public Compiler batchCompiler;
	/* Bundle containing messages */
	public ResourceBundle bundle;
	protected FileSystem.Classpath[] checkedClasspaths;
	// For single module mode
	protected IModule module;
	// paths to external annotations:
	protected List<String> annotationPaths;
	protected boolean annotationsFromClasspath;

	private List<String> addonExports = Collections.EMPTY_LIST;
	private List<String> addonReads = Collections.EMPTY_LIST;
	public Set<String> rootModules = Collections.EMPTY_SET;
	public Set<String> limitedModules;

	public Locale compilerLocale;
	public CompilerOptions compilerOptions; // read-only
	public CompilationProgress progress;
	public String destinationPath;
	public String[] destinationPaths;
	// destination path for compilation units that get no more specific
	// one (through directory arguments or various classpath options);
	// coding is:
	// == null: unspecified, write class files close to their respective
	//          source files;
	// == Main.NONE: absorbent element, do not output class files;
	// else: use as the path of the directory into which class files must
	//       be written.
	protected boolean enablePreview;
	protected String releaseVersion;
	private boolean didSpecifySource;
	private boolean didSpecifyTarget;
	public String[] encodings;
	public int exportedClassFilesCounter;
	public String[] filenames;
	public String[] modNames;
	public String[] classNames;
	// overrides of destinationPath on a directory argument basis
	public int globalErrorsCount;
	public int globalProblemsCount;
	public int globalTasksCount;
	public int globalWarningsCount;
	public int globalInfoCount;

	private File javaHomeCache;

	private boolean javaHomeChecked = false;
	private boolean primaryNullAnnotationsSeen = false;
	public long lineCount0;

	public String log;

	public Logger logger;
	public int maxProblems;
	public Map<String, String> options;
	protected long complianceLevel;
	public char[][] ignoreOptionalProblemsFromFolders;
	protected PrintWriter out;
	public boolean proceed = true;
	public boolean proceedOnError = false;
	public boolean produceRefInfo = false;
	public int currentRepetition, maxRepetition;
	public boolean showProgress = false;
	public long startTime;
	public ArrayList<String> pendingErrors;
	public boolean systemExitWhenFinished = true;

	public static final int TIMING_DISABLED = 0;
	public static final int TIMING_ENABLED = 1;
	public static final int TIMING_DETAILED = 2;

	public int timing = TIMING_DISABLED;
	public CompilerStats[] compilerStats;
	public boolean verbose = false;
	private String[] expandedCommandLine;

	private PrintWriter err;

	protected ArrayList<CategorizedProblem> extraProblems;
	public final static String bundleName = "org.eclipse.jdt.internal.compiler.batch.messages"; //$NON-NLS-1$
	// two uses: recognize 'none' in options; code the singleton none
	// for the '-d none' option (wherever it may be found)
	public static final int DEFAULT_SIZE_CLASSPATH = 4;

	public static final String NONE = "none"; //$NON-NLS-1$

/**
 * @deprecated - use {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, CompilationProgress)} instead
 * 						  e.g. BatchCompiler.compile(commandLine, new PrintWriter(System.out), new PrintWriter(System.err), null);
 */
public static boolean compile(String commandLine) {
	return new Main(new PrintWriter(System.out), new PrintWriter(System.err), false /* systemExit */, null /* options */, null /* progress */).compile(tokenize(commandLine));
}

/**
 * @deprecated - use {@link BatchCompiler#compile(String, PrintWriter, PrintWriter, CompilationProgress)} instead
 *                       e.g. BatchCompiler.compile(commandLine, outWriter, errWriter, null);
 */
public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter) {
	return new Main(outWriter, errWriter, false /* systemExit */, null /* options */, null /* progress */).compile(tokenize(commandLine));
}

/*
 * Internal API for public API BatchCompiler#compile(String[], PrintWriter, PrintWriter, CompilationProgress)
 */
public static boolean compile(String[] commandLineArguments, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
	return new Main(outWriter, errWriter, false /* systemExit */, null /* options */, progress).compile(commandLineArguments);
}
public static File[][] getLibrariesFiles(File[] files) {
	FilenameFilter filter = new FilenameFilter() {
		@Override
		public boolean accept(File dir, String name) {
			return Util.archiveFormat(name) > -1;
		}
	};
	final int filesLength = files.length;
	File[][] result = new File[filesLength][];
	for (int i = 0; i < filesLength; i++) {
		File currentFile = files[i];
		if (currentFile.exists() && currentFile.isDirectory()) {
			result[i] = currentFile.listFiles(filter);
		}
	}
	return result;
}

public static void main(String[] argv) {
	new Main(new PrintWriter(System.out), new PrintWriter(System.err), true/*systemExit*/, null/*options*/, null/*progress*/).compile(argv);
}

public static String[] tokenize(String commandLine) {

	int count = 0;
	String[] arguments = new String[10];
	StringTokenizer tokenizer = new StringTokenizer(commandLine, " \"", true); //$NON-NLS-1$
	String token = Util.EMPTY_STRING;
	boolean insideQuotes = false;
	boolean startNewToken = true;

	// take care to quotes on the command line
	// 'xxx "aaa bbb";ccc yyy' --->  {"xxx", "aaa bbb;ccc", "yyy" }
	// 'xxx "aaa bbb;ccc" yyy' --->  {"xxx", "aaa bbb;ccc", "yyy" }
	// 'xxx "aaa bbb";"ccc" yyy' --->  {"xxx", "aaa bbb;ccc", "yyy" }
	// 'xxx/"aaa bbb";"ccc" yyy' --->  {"xxx/aaa bbb;ccc", "yyy" }
	while (tokenizer.hasMoreTokens()) {
		token = tokenizer.nextToken();

		if (token.equals(" ")) { //$NON-NLS-1$
			if (insideQuotes) {
				arguments[count - 1] += token;
				startNewToken = false;
			} else {
				startNewToken = true;
			}
		} else if (token.equals("\"")) { //$NON-NLS-1$
			if (!insideQuotes && startNewToken) {
				if (count == arguments.length)
					System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count);
				arguments[count++] = Util.EMPTY_STRING;
			}
			insideQuotes = !insideQuotes;
			startNewToken = false;
		} else {
			if (insideQuotes) {
				arguments[count - 1] += token;
			} else {
				if (token.length() > 0 && !startNewToken) {
					arguments[count - 1] += token;
				} else {
					if (count == arguments.length)
						System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count);
					String trimmedToken = token.trim();
					if (trimmedToken.length() != 0) {
						arguments[count++] = trimmedToken;
					}
				}
			}
			startNewToken = false;
		}
	}
	System.arraycopy(arguments, 0, arguments = new String[count], 0, count);
	return arguments;
}

/**
 * @deprecated - use {@link #Main(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
 *                       e.g. Main(outWriter, errWriter, systemExitWhenFinished, null, null)
 */
public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished) {
	this(outWriter, errWriter, systemExitWhenFinished, null /* options */, null /* progress */);
}

/**
 * @deprecated - use {@link #Main(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
 *                       e.g. Main(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null)
 */
public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map<String, String> customDefaultOptions) {
	this(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, null /* progress */);
}

public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished, Map<String, String> customDefaultOptions, CompilationProgress compilationProgress) {
	this.initialize(outWriter, errWriter, systemExitWhenFinished, customDefaultOptions, compilationProgress);
	this.relocalize();
}

public void addExtraProblems(CategorizedProblem problem) {
	if (this.extraProblems == null) {
		this.extraProblems = new ArrayList<>();
	}
	this.extraProblems.add(problem);
}
protected void addNewEntry(ArrayList<FileSystem.Classpath> paths, String currentClasspathName,
		ArrayList<String> currentRuleSpecs, String customEncoding,
		String destPath, boolean isSourceOnly,
		boolean rejectDestinationPathOnJars) {

	int rulesSpecsSize = currentRuleSpecs.size();
	AccessRuleSet accessRuleSet = null;
	if (rulesSpecsSize != 0) {
		AccessRule[] accessRules = new AccessRule[currentRuleSpecs.size()];
		boolean rulesOK = true;
		Iterator<String> i = currentRuleSpecs.iterator();
		int j = 0;
		while (i.hasNext()) {
			String ruleSpec = i.next();
			char key = ruleSpec.charAt(0);
			String pattern = ruleSpec.substring(1);
			if (pattern.length() > 0) {
				switch (key) {
					case '+':
						accessRules[j++] = new AccessRule(pattern
								.toCharArray(), 0);
						break;
					case '~':
						accessRules[j++] = new AccessRule(pattern
								.toCharArray(),
								IProblem.DiscouragedReference);
						break;
					case '-':
						accessRules[j++] = new AccessRule(pattern
								.toCharArray(),
								IProblem.ForbiddenReference);
						break;
					case '?':
						accessRules[j++] = new AccessRule(pattern
								.toCharArray(),
								IProblem.ForbiddenReference, true/*keep looking for accessible type*/);
						break;
					default:
						rulesOK = false;
				}
			} else {
				rulesOK = false;
			}
		}
		if (rulesOK) {
    		accessRuleSet = new AccessRuleSet(accessRules, AccessRestriction.COMMAND_LINE, currentClasspathName);
		} else {
			if (currentClasspathName.length() != 0) {
				// we go on anyway
				addPendingErrors(this.bind("configure.incorrectClasspath", currentClasspathName));//$NON-NLS-1$
			}
			return;
		}
	}
	if (NONE.equals(destPath)) {
		destPath = NONE; // keep == comparison valid
	}
	
	if (rejectDestinationPathOnJars && destPath != null &&
			Util.archiveFormat(currentClasspathName) > -1) {
		throw new IllegalArgumentException(
			this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$
						currentClasspathName));
	}
	FileSystem.Classpath currentClasspath = FileSystem.getClasspath(
			currentClasspathName,
			customEncoding,
			isSourceOnly,
			accessRuleSet,
			destPath, 
			this.options,
			this.releaseVersion);
	if (currentClasspath != null) {
		paths.add(currentClasspath);
	} else if (currentClasspathName.length() != 0) {
		// we go on anyway
		addPendingErrors(this.bind("configure.incorrectClasspath", currentClasspathName));//$NON-NLS-1$
	}
}
void addPendingErrors(String message) {
	if (this.pendingErrors == null) {
		this.pendingErrors = new ArrayList<>();
	}
	this.pendingErrors.add(message);
}
/*
 * Lookup the message with the given ID in this catalog
 */
public String bind(String id) {
	return bind(id, (String[]) null);
}
/*
 * Lookup the message with the given ID in this catalog and bind its
 * substitution locations with the given string.
 */
public String bind(String id, String binding) {
	return bind(id, new String[] { binding });
}

/*
 * Lookup the message with the given ID in this catalog and bind its
 * substitution locations with the given strings.
 */
public String bind(String id, String binding1, String binding2) {
	return bind(id, new String[] { binding1, binding2 });
}

/*
 * Lookup the message with the given ID in this catalog and bind its
 * substitution locations with the given string values.
 */
public String bind(String id, String[] arguments) {
	if (id == null)
		return "No message available"; //$NON-NLS-1$
	String message = null;
	try {
		message = this.bundle.getString(id);
	} catch (MissingResourceException e) {
		// If we got an exception looking for the message, fail gracefully by just returning
		// the id we were looking for.  In most cases this is semi-informative so is not too bad.
		return "Missing message: " + id + " in: " + Main.bundleName; //$NON-NLS-2$ //$NON-NLS-1$
	}
	return MessageFormat.format(message, (Object[]) arguments);
}
/**
 * Return true if and only if the running VM supports the given minimal version.
 *
 * <p>This only checks the major version, since the minor version is always 0 (at least for the useful cases).</p>
 * <p>The given minimalSupportedVersion is one of the constants:</p>
 * <ul>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_1</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_2</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_3</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_4</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_5</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_6</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK1_8</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK9</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK10</code></li>
 * <li><code>org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants.JDK11</code></li>
 * 
 * </ul>
 * @param minimalSupportedVersion the given minimal version
 * @return true if and only if the running VM supports the given minimal version, false otherwise
 */
private boolean checkVMVersion(long minimalSupportedVersion) {
	// the format of this property is supposed to be xx.x where x are digits.
	String classFileVersion = System.getProperty("java.class.version"); //$NON-NLS-1$
	if (classFileVersion == null) {
		// by default we don't support a class file version we cannot recognize
		return false;
	}
	int index = classFileVersion.indexOf('.');
	if (index == -1) {
		// by default we don't support a class file version we cannot recognize
		return false;
	}
	int majorVersion;
	try {
		majorVersion = Integer.parseInt(classFileVersion.substring(0, index));
	} catch (NumberFormatException e) {
		// by default we don't support a class file version we cannot recognize
		return false;
	}
	return ClassFileConstants.getComplianceLevelForJavaVersion(majorVersion) >=minimalSupportedVersion;
}
/*
 *  Low-level API performing the actual compilation
 */
public boolean compile(String[] argv) {
	// decode command line arguments
	try {
		configure(argv);
		if (this.progress != null)
			this.progress.begin(this.filenames == null ? 0 : this.filenames.length * this.maxRepetition);
		if (this.proceed) {
//				if (this.verbose) {
//					System.out.println(new CompilerOptions(this.options));
//				}
			if (this.showProgress) this.logger.compiling();
			for (this.currentRepetition = 0; this.currentRepetition < this.maxRepetition; this.currentRepetition++) {
				this.globalProblemsCount = 0;
				this.globalErrorsCount = 0;
				this.globalWarningsCount = 0;
				this.globalInfoCount = 0;
				this.globalTasksCount = 0;
				this.exportedClassFilesCounter = 0;

				if (this.maxRepetition > 1) {
					this.logger.flush();
					this.logger.logRepetition(this.currentRepetition, this.maxRepetition);
				}
				// request compilation
				performCompilation();
			}
			if (this.compilerStats != null) {
				this.logger.logAverage();
			}
			if (this.showProgress) this.logger.printNewLine();
		}
		if (this.systemExitWhenFinished) {
			this.logger.flush();
			this.logger.close();
			System.exit(this.globalErrorsCount > 0 ? -1 : 0);
		}
	} catch (IllegalArgumentException e) {
		this.logger.logException(e);
		if (this.systemExitWhenFinished) {
			this.logger.flush();
			this.logger.close();
			System.exit(-1);
		}
		return false;
	} catch (Exception e) { // internal compiler failure
		this.logger.logException(e);
		if (this.systemExitWhenFinished) {
			this.logger.flush();
			this.logger.close();
			System.exit(-1);
		}
		return false;
	} finally {
		this.logger.flush();
		this.logger.close();
		if (this.progress != null)
			this.progress.done();
	}
	if (this.globalErrorsCount == 0 && (this.progress == null || !this.progress.isCanceled()))
		return true;
	return false;
}

/*
Decode the command line arguments
 */
public void configure(String[] argv) {

	if ((argv == null) || (argv.length == 0)) {
		printUsage();
		return;
	}

	final int INSIDE_CLASSPATH_start = 1;
	final int INSIDE_DESTINATION_PATH = 3;
	final int INSIDE_TARGET = 4;
	final int INSIDE_LOG = 5;
	final int INSIDE_REPETITION = 6;
	final int INSIDE_SOURCE = 7;
	final int INSIDE_DEFAULT_ENCODING = 8;
	final int INSIDE_BOOTCLASSPATH_start = 9;
	final int INSIDE_MAX_PROBLEMS = 11;
	final int INSIDE_EXT_DIRS = 12;
	final int INSIDE_SOURCE_PATH_start = 13;
	final int INSIDE_ENDORSED_DIRS = 15;
	final int INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH = 16;
	final int INSIDE_PROCESSOR_PATH_start = 17;
	final int INSIDE_PROCESSOR_start = 18;
	final int INSIDE_S_start = 19;
	final int INSIDE_CLASS_NAMES = 20;
	final int INSIDE_WARNINGS_PROPERTIES = 21;
	final int INSIDE_ANNOTATIONPATH_start = 22;
	final int INSIDE_MODULEPATH_start = 23;
	final int INSIDE_MODULESOURCEPATH_start = 24;
	final int INSIDE_ADD_EXPORTS = 25;
	final int INSIDE_ADD_READS = 26;
	final int INSIDE_SYSTEM = 27;
	final int INSIDE_PROCESSOR_MODULE_PATH_start = 28;
	final int INSIDE_ADD_MODULES = 29;
	final int INSIDE_RELEASE = 30;
	final int INSIDE_LIMIT_MODULES = 31;

	final int DEFAULT = 0;
	ArrayList<String> bootclasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
	String sourcepathClasspathArg = null;
	String modulepathArg = null;
	String moduleSourcepathArg = null;
	ArrayList<String> sourcepathClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
	ArrayList<String> classpaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
	ArrayList<String> extdirsClasspaths = null;
	ArrayList<String> endorsedDirClasspaths = null;
	this.annotationPaths = null;
	this.annotationsFromClasspath = false;

	int index = -1;
	int filesCount = 0;
	int classCount = 0;
	int argCount = argv.length;
	int mode = DEFAULT;
	this.maxRepetition = 0;
	boolean printUsageRequired = false;
	String usageSection = null;
	boolean printVersionRequired = false;

	boolean didSpecifyDeprecation = false;
	boolean didSpecifyCompliance = false;
	boolean didSpecifyDisabledAnnotationProcessing = false;

	String customEncoding = null;
	String customDestinationPath = null;
	String currentSourceDirectory = null;
	String currentArg = Util.EMPTY_STRING;
	String moduleName = null;
	
	Set<String> specifiedEncodings = null;

	// expand the command line if necessary
	boolean needExpansion = false;
	loop: for (int i = 0; i < argCount; i++) {
			if (argv[i].startsWith("@")) { //$NON-NLS-1$
				needExpansion = true;
				break loop;
			}
	}

	String[] newCommandLineArgs = null;
	if (needExpansion) {
		newCommandLineArgs = new String[argCount];
		index = 0;
		for (int i = 0; i < argCount; i++) {
			String[] newArgs = null;
			String arg = argv[i].trim();
			if (arg.startsWith("@")) { //$NON-NLS-1$
				try {
					LineNumberReader reader = new LineNumberReader(new StringReader(new String(Util.getFileCharContent(new File(arg.substring(1)), null))));
					StringBuffer buffer = new StringBuffer();
					String line;
					while((line = reader.readLine()) != null) {
						line = line.trim();
						if (!line.startsWith("#")) { //$NON-NLS-1$
							buffer.append(line).append(" "); //$NON-NLS-1$
						}
					}
					newArgs = tokenize(buffer.toString());
				} catch(IOException e) {
					throw new IllegalArgumentException(
						this.bind("configure.invalidexpansionargumentname", arg)); //$NON-NLS-1$
				}
			}
			if (newArgs != null) {
				int newCommandLineArgsLength = newCommandLineArgs.length;
				int newArgsLength = newArgs.length;
				System.arraycopy(newCommandLineArgs, 0, (newCommandLineArgs = new String[newCommandLineArgsLength + newArgsLength - 1]), 0, index);
				System.arraycopy(newArgs, 0, newCommandLineArgs, index, newArgsLength);
				index += newArgsLength;
			} else {
				newCommandLineArgs[index++] = arg;
			}
		}
		index = -1;
	} else {
		newCommandLineArgs = argv;
		for (int i = 0; i < argCount; i++) {
			newCommandLineArgs[i] = newCommandLineArgs[i].trim();
		}
	}
	argCount = newCommandLineArgs.length;
	this.expandedCommandLine = newCommandLineArgs;
	while (++index < argCount) {

		if (customEncoding != null) {
			throw new IllegalArgumentException(
				this.bind("configure.unexpectedCustomEncoding", currentArg, customEncoding)); //$NON-NLS-1$
		}

		currentArg = newCommandLineArgs[index];

		switch(mode) {
			case DEFAULT :
				if (currentArg.startsWith("-nowarn")) { //$NON-NLS-1$
					switch (currentArg.length()) {
						case 7:
							disableAll(ProblemSeverities.Warning);
							break;
						case 8:
							throw new IllegalArgumentException(this.bind(
									"configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$
						default:
							int foldersStart = currentArg.indexOf('[') + 1;
							int foldersEnd = currentArg.lastIndexOf(']');
							if (foldersStart <= 8 || foldersEnd == -1 || foldersStart > foldersEnd
									|| foldersEnd < currentArg.length() - 1) {
								throw new IllegalArgumentException(this.bind(
										"configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$
							}
							String folders = currentArg.substring(foldersStart, foldersEnd);
							if (folders.length() > 0) {
								char[][] currentFolders = decodeIgnoreOptionalProblemsFromFolders(folders);
								if (this.ignoreOptionalProblemsFromFolders != null) {
									int length = this.ignoreOptionalProblemsFromFolders.length + currentFolders.length;
									char[][] tempFolders = new char[length][];
									System.arraycopy(this.ignoreOptionalProblemsFromFolders, 0, tempFolders, 0, this.ignoreOptionalProblemsFromFolders.length);
									System.arraycopy(currentFolders, 0, tempFolders, this.ignoreOptionalProblemsFromFolders.length, currentFolders.length);
									this.ignoreOptionalProblemsFromFolders = tempFolders;
								} else {
									this.ignoreOptionalProblemsFromFolders = currentFolders;
								}
							} else {
								throw new IllegalArgumentException(this.bind(
										"configure.invalidNowarnOption", currentArg)); //$NON-NLS-1$
							}
					}
					mode = DEFAULT;
					continue;
				}
				if (currentArg.startsWith("[")) { //$NON-NLS-1$
					throw new IllegalArgumentException(
						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
									currentArg));
				}

				if (currentArg.endsWith("]")) { //$NON-NLS-1$
					// look for encoding specification
					int encodingStart = currentArg.indexOf('[') + 1;
					if (encodingStart <= 1) {
						throw new IllegalArgumentException(
								this.bind("configure.unexpectedBracket", currentArg)); //$NON-NLS-1$
					}
					int encodingEnd = currentArg.length() - 1;
					if (encodingStart >= 1) {
						if (encodingStart < encodingEnd) {
							customEncoding = currentArg.substring(encodingStart, encodingEnd);
							try { // ensure encoding is supported
								new InputStreamReader(new ByteArrayInputStream(new byte[0]), customEncoding);
							} catch (UnsupportedEncodingException e) {
								throw new IllegalArgumentException(
									this.bind("configure.unsupportedEncoding", customEncoding), e); //$NON-NLS-1$
							}
						}
						currentArg = currentArg.substring(0, encodingStart - 1);
					}
				}

				if (currentArg.endsWith(SuffixConstants.SUFFIX_STRING_java)) {
					if (moduleName == null) {
						// If the module-info.java was supplied via command line, that will be the
						// de facto module for the other source files supplied via command line.
						// TODO: This needs revisit in case a source file specified in command line is
						// part of a --module-source-path
						IModule mod = extractModuleDesc(currentArg);
						if (mod != null) {
							moduleName = new String(mod.name());
							this.module = mod;
						}
					}
					if (this.filenames == null) {
						this.filenames = new String[argCount - index];
						this.encodings = new String[argCount - index];
						this.modNames = new String[argCount - index];
						this.destinationPaths = new String[argCount - index];
					} else if (filesCount == this.filenames.length) {
						int length = this.filenames.length;
						System.arraycopy(
							this.filenames,
							0,
							(this.filenames = new String[length + argCount - index]),
							0,
							length);
						System.arraycopy(
							this.encodings,
							0,
							(this.encodings = new String[length + argCount - index]),
							0,
							length);
						System.arraycopy(
							this.destinationPaths,
							0,
							(this.destinationPaths = new String[length + argCount - index]),
							0,
							length);
						System.arraycopy(
								this.modNames,
								0,
								(this.modNames = new String[length + argCount - index]),
								0,
								length);
					}
					this.filenames[filesCount] = currentArg;
					this.modNames[filesCount] = moduleName;
					this.encodings[filesCount++] = customEncoding;
					// destination path cannot be specified upon an individual file
					customEncoding = null;
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-log")) { //$NON-NLS-1$
					if (this.log != null)
						throw new IllegalArgumentException(
							this.bind("configure.duplicateLog", currentArg)); //$NON-NLS-1$
					mode = INSIDE_LOG;
					continue;
				}
				if (currentArg.equals("-repeat")) { //$NON-NLS-1$
					if (this.maxRepetition > 0)
						throw new IllegalArgumentException(
							this.bind("configure.duplicateRepeat", currentArg)); //$NON-NLS-1$
					mode = INSIDE_REPETITION;
					continue;
				}
				if (currentArg.equals("-maxProblems")) { //$NON-NLS-1$
					if (this.maxProblems > 0)
						throw new IllegalArgumentException(
							this.bind("configure.duplicateMaxProblems", currentArg)); //$NON-NLS-1$
					mode = INSIDE_MAX_PROBLEMS;
					continue;
				}
				if (currentArg.equals("--release")) { //$NON-NLS-1$
					mode = INSIDE_RELEASE;
					continue;
				}
				if (currentArg.equals("-source")) { //$NON-NLS-1$
					mode = INSIDE_SOURCE;
					continue;
				}
				if (currentArg.equals("-encoding")) { //$NON-NLS-1$
					mode = INSIDE_DEFAULT_ENCODING;
					continue;
				}
				if (currentArg.equals("-1.3")) { //$NON-NLS-1$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg));//$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-1.4")) { //$NON-NLS-1$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-1.5") || currentArg.equals("-5") || currentArg.equals("-5.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-1.6") || currentArg.equals("-6") || currentArg.equals("-6.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-1.7") || currentArg.equals("-7") || currentArg.equals("-7.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-1.8") || currentArg.equals("-8") || currentArg.equals("-8.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-1.9") || currentArg.equals("-9") || currentArg.equals("-9.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-10") || currentArg.equals("-10.0")) { //$NON-NLS-1$ //$NON-NLS-2$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-11") || currentArg.equals("-11.0")) { //$NON-NLS-1$ //$NON-NLS-2$
					if (didSpecifyCompliance) {
						throw new IllegalArgumentException(
							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
					}
					didSpecifyCompliance = true;
					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-d")) { //$NON-NLS-1$
					if (this.destinationPath != null) {
						StringBuffer errorMessage = new StringBuffer();
						errorMessage.append(currentArg);
						if ((index + 1) < argCount) {
							errorMessage.append(' ');
							errorMessage.append(newCommandLineArgs[index + 1]);
						}
						throw new IllegalArgumentException(
							this.bind("configure.duplicateOutputPath", errorMessage.toString())); //$NON-NLS-1$
					}
					mode = INSIDE_DESTINATION_PATH;
					continue;
				}
				if (currentArg.equals("-classpath") //$NON-NLS-1$
					|| currentArg.equals("-cp")) { //$NON-NLS-1$
					mode = INSIDE_CLASSPATH_start;
					continue;
				}
				if (currentArg.equals("-bootclasspath")) {//$NON-NLS-1$
					if (bootclasspaths.size() > 0) {
						StringBuffer errorMessage = new StringBuffer();
						errorMessage.append(currentArg);
						if ((index + 1) < argCount) {
							errorMessage.append(' ');
							errorMessage.append(newCommandLineArgs[index + 1]);
						}
						throw new IllegalArgumentException(
							this.bind("configure.duplicateBootClasspath", errorMessage.toString())); //$NON-NLS-1$
					}
					mode = INSIDE_BOOTCLASSPATH_start;
					continue;
				}
				if (currentArg.equals("--enable-preview")) { //$NON-NLS-1$
					this.enablePreview = true;
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("--system")) { //$NON-NLS-1$
					mode = INSIDE_SYSTEM;
					continue;
				}
				if (currentArg.equals("--module-path") || currentArg.equals("-p") || currentArg.equals("--processor-module-path")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					mode = INSIDE_MODULEPATH_start;
					continue;
				}
				if (currentArg.equals("--module-source-path")) { //$NON-NLS-1$
					if (sourcepathClasspathArg != null) {
						throw new IllegalArgumentException(this.bind("configure.OneOfModuleOrSourcePath")); //$NON-NLS-1$
					}
					mode = INSIDE_MODULESOURCEPATH_start;
					continue;
				}
				if (currentArg.equals("--add-exports")) { //$NON-NLS-1$
					mode = INSIDE_ADD_EXPORTS;
					continue;
				}
				if (currentArg.equals("--add-reads")) { //$NON-NLS-1$
					mode = INSIDE_ADD_READS;
					continue;
				}
				if (currentArg.equals("--add-modules")) { //$NON-NLS-1$
					mode = INSIDE_ADD_MODULES;
					continue;
				}
				if (currentArg.equals("--limit-modules")) { //$NON-NLS-1$
					mode = INSIDE_LIMIT_MODULES;
					continue;
				}
				if (currentArg.equals("-sourcepath")) {//$NON-NLS-1$
					if (sourcepathClasspathArg != null) {
						StringBuffer errorMessage = new StringBuffer();
						errorMessage.append(currentArg);
						if ((index + 1) < argCount) {
							errorMessage.append(' ');
							errorMessage.append(newCommandLineArgs[index + 1]);
						}
						throw new IllegalArgumentException(
							this.bind("configure.duplicateSourcepath", errorMessage.toString())); //$NON-NLS-1$
					}
					if (moduleSourcepathArg != null) {
						throw new IllegalArgumentException(this.bind("configure.OneOfModuleOrSourcePath")); //$NON-NLS-1$
					}
					mode = INSIDE_SOURCE_PATH_start;
					continue;
				}
				if (currentArg.equals("-extdirs")) {//$NON-NLS-1$
					if (extdirsClasspaths != null) {
						StringBuffer errorMessage = new StringBuffer();
						errorMessage.append(currentArg);
						if ((index + 1) < argCount) {
							errorMessage.append(' ');
							errorMessage.append(newCommandLineArgs[index + 1]);
						}
						throw new IllegalArgumentException(
							this.bind("configure.duplicateExtDirs", errorMessage.toString())); //$NON-NLS-1$
					}
					mode = INSIDE_EXT_DIRS;
					continue;
				}
				if (currentArg.equals("-endorseddirs")) { //$NON-NLS-1$
					if (endorsedDirClasspaths != null) {
						StringBuffer errorMessage = new StringBuffer();
						errorMessage.append(currentArg);
						if ((index + 1) < argCount) {
							errorMessage.append(' ');
							errorMessage.append(newCommandLineArgs[index + 1]);
						}
						throw new IllegalArgumentException(
							this.bind("configure.duplicateEndorsedDirs", errorMessage.toString())); //$NON-NLS-1$
					}
					mode = INSIDE_ENDORSED_DIRS;
					continue;
				}
				if (currentArg.equals("-progress")) { //$NON-NLS-1$
					mode = DEFAULT;
					this.showProgress = true;
					continue;
				}
				if (currentArg.startsWith("-proceedOnError")) { //$NON-NLS-1$
					mode = DEFAULT;
					int length = currentArg.length();
					if (length > 15) {
						if (currentArg.equals("-proceedOnError:Fatal")) { //$NON-NLS-1$
							this.options.put(CompilerOptions.OPTION_FatalOptionalError, CompilerOptions.ENABLED);
						} else {
							throw new IllegalArgumentException(
									this.bind("configure.invalidWarningConfiguration", currentArg)); //$NON-NLS-1$
						}
					} else {
						this.options.put(CompilerOptions.OPTION_FatalOptionalError, CompilerOptions.DISABLED);
					}
					this.proceedOnError = true;
					continue;
				}
				if (currentArg.equals("-time")) { //$NON-NLS-1$
					mode = DEFAULT;
					this.timing = TIMING_ENABLED;
					continue;
				}
				if (currentArg.equals("-time:detail")) { //$NON-NLS-1$
					mode = DEFAULT;
					this.timing = TIMING_ENABLED|TIMING_DETAILED;
					continue;
				}
				if (currentArg.equals("-version") //$NON-NLS-1$
						|| currentArg.equals("-v")) { //$NON-NLS-1$
					this.logger.logVersion(true);
					this.proceed = false;
					return;
				}
				if (currentArg.equals("-showversion")) { //$NON-NLS-1$
					printVersionRequired = true;
					mode = DEFAULT;
					continue;
				}
				if ("-deprecation".equals(currentArg)) { //$NON-NLS-1$
					didSpecifyDeprecation = true;
					this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-help") || currentArg.equals("-?")) { //$NON-NLS-1$ //$NON-NLS-2$
					printUsageRequired = true;
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-help:warn") || //$NON-NLS-1$
						currentArg.equals("-?:warn")) { //$NON-NLS-1$
					printUsageRequired = true;
					usageSection = "misc.usage.warn"; //$NON-NLS-1$
					continue;
				}
				if (currentArg.equals("-noExit")) { //$NON-NLS-1$
					this.systemExitWhenFinished = false;
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-verbose")) { //$NON-NLS-1$
					this.verbose = true;
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-referenceInfo")) { //$NON-NLS-1$
					this.produceRefInfo = true;
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-inlineJSR")) { //$NON-NLS-1$
					mode = DEFAULT;
					this.options.put(
							CompilerOptions.OPTION_InlineJsr,
							CompilerOptions.ENABLED);
					continue;
				}
				if (currentArg.equals("-parameters")) { //$NON-NLS-1$
					mode = DEFAULT;
					this.options.put(
							CompilerOptions.OPTION_MethodParametersAttribute,
							CompilerOptions.GENERATE);
					continue;
				}
				if (currentArg.equals("-genericsignature")) { //$NON-NLS-1$
					mode = DEFAULT;
					this.options.put(
							CompilerOptions.OPTION_LambdaGenericSignature,
							CompilerOptions.GENERATE);
					continue;
				}
				if (currentArg.startsWith("-g")) { //$NON-NLS-1$
					mode = DEFAULT;
					String debugOption = currentArg;
					int length = currentArg.length();
					if (length == 2) {
						this.options.put(
							CompilerOptions.OPTION_LocalVariableAttribute,
							CompilerOptions.GENERATE);
						this.options.put(
							CompilerOptions.OPTION_LineNumberAttribute,
							CompilerOptions.GENERATE);
						this.options.put(
							CompilerOptions.OPTION_SourceFileAttribute,
							CompilerOptions.GENERATE);
						continue;
					}
					if (length > 3) {
						this.options.put(
							CompilerOptions.OPTION_LocalVariableAttribute,
							CompilerOptions.DO_NOT_GENERATE);
						this.options.put(
							CompilerOptions.OPTION_LineNumberAttribute,
							CompilerOptions.DO_NOT_GENERATE);
						this.options.put(
							CompilerOptions.OPTION_SourceFileAttribute,
							CompilerOptions.DO_NOT_GENERATE);
						if (length == 7 && debugOption.equals("-g:" + NONE)) //$NON-NLS-1$
							continue;
						StringTokenizer tokenizer =
							new StringTokenizer(debugOption.substring(3, debugOption.length()), ","); //$NON-NLS-1$
						while (tokenizer.hasMoreTokens()) {
							String token = tokenizer.nextToken();
							if (token.equals("vars")) { //$NON-NLS-1$
								this.options.put(
									CompilerOptions.OPTION_LocalVariableAttribute,
									CompilerOptions.GENERATE);
							} else if (token.equals("lines")) { //$NON-NLS-1$
								this.options.put(
									CompilerOptions.OPTION_LineNumberAttribute,
									CompilerOptions.GENERATE);
							} else if (token.equals("source")) { //$NON-NLS-1$
								this.options.put(
									CompilerOptions.OPTION_SourceFileAttribute,
									CompilerOptions.GENERATE);
							} else {
								throw new IllegalArgumentException(
									this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
							}
						}
						continue;
					}
					throw new IllegalArgumentException(
						this.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
				}
				if (currentArg.startsWith("-info")) { //$NON-NLS-1$
					mode = DEFAULT;
					String infoOption = currentArg;
					int length = currentArg.length();
					if (length == 10 && infoOption.equals("-info:" + NONE)) { //$NON-NLS-1$
						disableAll(ProblemSeverities.Info);
						continue;
					}
					if (length <= 6) {
						throw new IllegalArgumentException(
							this.bind("configure.invalidInfoConfiguration", infoOption)); //$NON-NLS-1$
					}
					int infoTokenStart;
					boolean isEnabling;
					switch (infoOption.charAt(6)) {
						case '+' :
							infoTokenStart = 7;
							isEnabling = true;
							break;
						case '-' :
							infoTokenStart = 7;
							isEnabling = false; // specified warnings are disabled
							break;
						default:
							disableAll(ProblemSeverities.Info);
							infoTokenStart = 6;
							isEnabling = true;
					}

					StringTokenizer tokenizer =
						new StringTokenizer(infoOption.substring(infoTokenStart, infoOption.length()), ","); //$NON-NLS-1$
					int tokenCounter = 0;

					while (tokenizer.hasMoreTokens()) {
						String token = tokenizer.nextToken();
						tokenCounter++;
						switch(token.charAt(0)) {
							case '+' :
								isEnabling = true;
								token = token.substring(1);
								break;
							case '-' :
								isEnabling = false;
								token = token.substring(1);
						}
						handleInfoToken(token, isEnabling);
					}
					if (tokenCounter == 0) {
						throw new IllegalArgumentException(
							this.bind("configure.invalidInfoOption", currentArg)); //$NON-NLS-1$
					}
					continue;
				}
				if (currentArg.startsWith("-warn")) { //$NON-NLS-1$
					mode = DEFAULT;
					String warningOption = currentArg;
					int length = currentArg.length();
					if (length == 10 && warningOption.equals("-warn:" + NONE)) { //$NON-NLS-1$
						disableAll(ProblemSeverities.Warning);
						continue;
					}
					if (length <= 6) {
						throw new IllegalArgumentException(
							this.bind("configure.invalidWarningConfiguration", warningOption)); //$NON-NLS-1$
					}
					int warnTokenStart;
					boolean isEnabling;
					switch (warningOption.charAt(6)) {
						case '+' :
							warnTokenStart = 7;
							isEnabling = true;
							break;
						case '-' :
							warnTokenStart = 7;
							isEnabling = false; // specified warnings are disabled
							break;
						default:
							disableAll(ProblemSeverities.Warning);
							warnTokenStart = 6;
							isEnabling = true;
					}

					StringTokenizer tokenizer =
						new StringTokenizer(warningOption.substring(warnTokenStart, warningOption.length()), ","); //$NON-NLS-1$
					int tokenCounter = 0;

					if (didSpecifyDeprecation) {  // deprecation could have also been set through -deprecation option
						this.options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
					}

					while (tokenizer.hasMoreTokens()) {
						String token = tokenizer.nextToken();
						tokenCounter++;
						switch(token.charAt(0)) {
							case '+' :
								isEnabling = true;
								token = token.substring(1);
								break;
							case '-' :
								isEnabling = false;
								token = token.substring(1);
						}
						handleWarningToken(token, isEnabling);
					}
					if (tokenCounter == 0) {
						throw new IllegalArgumentException(
							this.bind("configure.invalidWarningOption", currentArg)); //$NON-NLS-1$
					}
					continue;
				}
				if (currentArg.startsWith("-err")) { //$NON-NLS-1$
					mode = DEFAULT;
					String errorOption = currentArg;
					int length = currentArg.length();
					if (length <= 5) {
						throw new IllegalArgumentException(
							this.bind("configure.invalidErrorConfiguration", errorOption)); //$NON-NLS-1$
					}
					int errorTokenStart;
					boolean isEnabling;
					switch (errorOption.charAt(5)) {
						case '+' :
							errorTokenStart = 6;
							isEnabling = true;
							break;
						case '-' :
							errorTokenStart = 6;
							isEnabling = false; // specified errors are disabled
							break;
						default:
							disableAll(ProblemSeverities.Error);
							errorTokenStart = 5;
							isEnabling = true;
					}

					StringTokenizer tokenizer =
						new StringTokenizer(errorOption.substring(errorTokenStart, errorOption.length()), ","); //$NON-NLS-1$
					int tokenCounter = 0;

					while (tokenizer.hasMoreTokens()) {
						String token = tokenizer.nextToken();
						tokenCounter++;
						switch(token.charAt(0)) {
							case '+' :
								isEnabling = true;
								token = token.substring(1);
								break;
							case '-' :
								isEnabling = false;
								token = token.substring(1);
								break;
						}
						handleErrorToken(token, isEnabling);
					}
					if (tokenCounter == 0) {
						throw new IllegalArgumentException(
							this.bind("configure.invalidErrorOption", currentArg)); //$NON-NLS-1$
					}
					continue;
				}
				if (currentArg.equals("-target")) { //$NON-NLS-1$
					mode = INSIDE_TARGET;
					continue;
				}
				if (currentArg.equals("-preserveAllLocals")) { //$NON-NLS-1$
					this.options.put(
						CompilerOptions.OPTION_PreserveUnusedLocal,
						CompilerOptions.PRESERVE);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-enableJavadoc")) {//$NON-NLS-1$
					mode = DEFAULT;
					this.enableJavadocOn = true;
					continue;
				}
				if (currentArg.equals("-Xemacs")) { //$NON-NLS-1$
					mode = DEFAULT;
					this.logger.setEmacs();
					continue;
				}
				// annotation processing
				if (currentArg.startsWith("-A")) { //$NON-NLS-1$
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-processorpath")) { //$NON-NLS-1$
					mode = INSIDE_PROCESSOR_PATH_start;
					continue;
				}
				if (currentArg.equals("-processor")) { //$NON-NLS-1$
					mode = INSIDE_PROCESSOR_start;
					continue;
				}
				if (currentArg.equals("--processor-module-path")) { //$NON-NLS-1$
					mode = INSIDE_PROCESSOR_MODULE_PATH_start;
					continue;
				}
				if (currentArg.equals("-proc:only")) { //$NON-NLS-1$
					this.options.put(
						CompilerOptions.OPTION_GenerateClassFiles,
						CompilerOptions.DISABLED);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-proc:none")) { //$NON-NLS-1$
					didSpecifyDisabledAnnotationProcessing = true;
					this.options.put(
						CompilerOptions.OPTION_Process_Annotations,
						CompilerOptions.DISABLED);
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-s")) { //$NON-NLS-1$
					mode = INSIDE_S_start;
					continue;
				}
				if (currentArg.equals("-XprintProcessorInfo") //$NON-NLS-1$
						|| currentArg.equals("-XprintRounds")) { //$NON-NLS-1$
					mode = DEFAULT;
					continue;
				}
				// tolerated javac options - quietly filtered out
				if (currentArg.startsWith("-X")) { //$NON-NLS-1$
					mode = DEFAULT;
					continue;
				}
				if (currentArg.startsWith("-J")) { //$NON-NLS-1$
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-O")) { //$NON-NLS-1$
					mode = DEFAULT;
					continue;
				}
				if (currentArg.equals("-classNames")) { //$NON-NLS-1$
					mode = INSIDE_CLASS_NAMES;
					continue;
				}
				if (currentArg.equals("-properties")) { //$NON-NLS-1$
					mode = INSIDE_WARNINGS_PROPERTIES;
					continue;
				}
				if (currentArg.equals("-missingNullDefault")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_ReportMissingNonNullByDefaultAnnotation, CompilerOptions.WARNING);
					continue;
				}
				if (currentArg.equals("-annotationpath")) { //$NON-NLS-1$
					mode = INSIDE_ANNOTATIONPATH_start;
					continue;
				}
				break;
			case INSIDE_TARGET :
				if (this.didSpecifyTarget) {
					throw new IllegalArgumentException(
						this.bind("configure.duplicateTarget", currentArg));//$NON-NLS-1$
				}
				if (this.releaseVersion != null) {
					throw new IllegalArgumentException(
							this.bind("configure.unsupportedWithRelease", "-target"));//$NON-NLS-1$ //$NON-NLS-2$
				}
				this.didSpecifyTarget = true;
				if (currentArg.equals("1.1")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
				} else if (currentArg.equals("1.2")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
				} else if (currentArg.equals("1.3")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
				} else if (currentArg.equals("1.4")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				} else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
				} else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
				} else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
				} else if (currentArg.equals("1.8") || currentArg.equals("8") || currentArg.equals("8.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
				} else if (currentArg.equals("1.9") || currentArg.equals("9") || currentArg.equals("9.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9);
				} else if (currentArg.equals("10") || currentArg.equals("10.0")) { //$NON-NLS-1$//$NON-NLS-2$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
				} else if (currentArg.equals("11") || currentArg.equals("11.0")) { //$NON-NLS-1$//$NON-NLS-2$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
				}
				else if (currentArg.equals("jsr14")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_JSR14);
				} else if (currentArg.equals("cldc1.1")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_CLDC1_1);
					this.options.put(CompilerOptions.OPTION_InlineJsr, CompilerOptions.ENABLED);
				}else {
					throw new IllegalArgumentException(this.bind("configure.targetJDK", currentArg)); //$NON-NLS-1$
				}
				mode = DEFAULT;
				continue;
			case INSIDE_LOG :
				this.log = currentArg;
				mode = DEFAULT;
				continue;
			case INSIDE_REPETITION :
				try {
					this.maxRepetition = Integer.parseInt(currentArg);
					if (this.maxRepetition <= 0) {
						throw new IllegalArgumentException(this.bind("configure.repetition", currentArg)); //$NON-NLS-1$
					}
				} catch (NumberFormatException e) {
					throw new IllegalArgumentException(this.bind("configure.repetition", currentArg), e); //$NON-NLS-1$
				}
				mode = DEFAULT;
				continue;
			case INSIDE_MAX_PROBLEMS :
				try {
					this.maxProblems = Integer.parseInt(currentArg);
					if (this.maxProblems <= 0) {
						throw new IllegalArgumentException(this.bind("configure.maxProblems", currentArg)); //$NON-NLS-1$
					}
					this.options.put(CompilerOptions.OPTION_MaxProblemPerUnit, currentArg);
				} catch (NumberFormatException e) {
					throw new IllegalArgumentException(this.bind("configure.maxProblems", currentArg), e); //$NON-NLS-1$
				}
				mode = DEFAULT;
				continue;
			case INSIDE_RELEASE:
				// If release is < 9, the following are diasllowed:
				// bootclasspath, -Xbootclasspath, -Xbootclasspath/a:, -Xbootclasspath/p:, 
				// -endorseddirs, -Djava.endorsed.dirs, -extdirs, -Djava.ext.dirs

				// If release >= 9, the following are disallowed
				// --system and --upgrade-module-path

				// -source and -target are disallowed for any --release
				this.releaseVersion = currentArg;
				long releaseToJDKLevel = CompilerOptions.releaseToJDKLevel(currentArg);
				if (releaseToJDKLevel == 0) {
					throw new IllegalArgumentException(
							this.bind("configure.unsupportedReleaseVersion", currentArg)); //$NON-NLS-1$
				}
				// Let's treat it as regular compliance mode
				this.complianceLevel = releaseToJDKLevel;
				String versionAsString = CompilerOptions.versionFromJdkLevel(releaseToJDKLevel);
				this.options.put(CompilerOptions.OPTION_Compliance, versionAsString);
				this.options.put(CompilerOptions.OPTION_Source, versionAsString);
				this.options.put(CompilerOptions.OPTION_TargetPlatform, versionAsString);
				mode = DEFAULT;
				continue;
			case INSIDE_SOURCE :
				if (this.didSpecifySource) {
					throw new IllegalArgumentException(
						this.bind("configure.duplicateSource", currentArg));//$NON-NLS-1$
				}
				if (this.releaseVersion != null) {
					throw new IllegalArgumentException(
							this.bind("configure.unsupportedWithRelease", "-source"));//$NON-NLS-1$ //$NON-NLS-2$
				}
				this.didSpecifySource = true;
				if (currentArg.equals("1.3")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
				} else if (currentArg.equals("1.4")) { //$NON-NLS-1$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
				} else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
				} else if (currentArg.equals("1.6") || currentArg.equals("6") || currentArg.equals("6.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
				} else if (currentArg.equals("1.7") || currentArg.equals("7") || currentArg.equals("7.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
				} else if (currentArg.equals("1.8") || currentArg.equals("8") || currentArg.equals("8.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
				} else if (currentArg.equals("1.9") || currentArg.equals("9") || currentArg.equals("9.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9);
				} else if (currentArg.equals("10") ||  currentArg.equals("10.0")) { //$NON-NLS-1$//$NON-NLS-2$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10);
				} else if (currentArg.equals("11") ||  currentArg.equals("11.0")) { //$NON-NLS-1$//$NON-NLS-2$
					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
				} else {
					throw new IllegalArgumentException(this.bind("configure.source", currentArg)); //$NON-NLS-1$
				}
				mode = DEFAULT;
				continue;
			case INSIDE_DEFAULT_ENCODING :
				if (specifiedEncodings != null) {
					// check already defined encoding
					if (!specifiedEncodings.contains(currentArg)) {
						if (specifiedEncodings.size() > 1) {
							this.logger.logWarning(
									this.bind("configure.differentencodings", //$NON-NLS-1$
									currentArg,
									getAllEncodings(specifiedEncodings)));
						} else {
							this.logger.logWarning(
									this.bind("configure.differentencoding", //$NON-NLS-1$
									currentArg,
									getAllEncodings(specifiedEncodings)));
						}
					}
				} else {
					specifiedEncodings = new HashSet<>();
				}
				try { // ensure encoding is supported
					new InputStreamReader(new ByteArrayInputStream(new byte[0]), currentArg);
				} catch (UnsupportedEncodingException e) {
					throw new IllegalArgumentException(
						this.bind("configure.unsupportedEncoding", currentArg), e); //$NON-NLS-1$
				}
				specifiedEncodings.add(currentArg);
				this.options.put(CompilerOptions.OPTION_Encoding, currentArg);
				mode = DEFAULT;
				continue;
			case INSIDE_DESTINATION_PATH :
				setDestinationPath(currentArg.equals(NONE) ? NONE : currentArg);
				mode = DEFAULT;
				continue;
			case INSIDE_SYSTEM:
				mode = DEFAULT;
				setJavaHome(currentArg);
				continue;
			case INSIDE_MODULEPATH_start:
				mode = DEFAULT;
				String[] modulepaths = new String[1];
				index += processPaths(newCommandLineArgs, index, currentArg, modulepaths);
				modulepathArg = modulepaths[0];
				continue;
			case INSIDE_MODULESOURCEPATH_start:
				mode = DEFAULT;
				String[] moduleSourcepaths = new String[1];
				index += processPaths(newCommandLineArgs, index, currentArg, moduleSourcepaths);
				moduleSourcepathArg = moduleSourcepaths[0];
				continue;
			case INSIDE_ADD_EXPORTS:
				mode = DEFAULT;
				// TODO: better to validate the option before processing it further?
				if (this.addonExports == Collections.EMPTY_LIST) {
					this.addonExports = new ArrayList<>();
				}
				this.addonExports.add(currentArg);
				continue;
			case INSIDE_ADD_READS:
				mode = DEFAULT;
				if (this.addonReads == Collections.EMPTY_LIST) {
					this.addonReads = new ArrayList<>();
				}
				this.addonReads.add(currentArg);
				continue;
			case INSIDE_ADD_MODULES:
				mode = DEFAULT;
				if (this.rootModules == Collections.EMPTY_SET) {
					this.rootModules = new HashSet<>();
				}
				StringTokenizer tokenizer = new StringTokenizer(currentArg, ","); //$NON-NLS-1$
				while (tokenizer.hasMoreTokens()) {
					this.rootModules.add(tokenizer.nextToken().trim());
				}
				continue;
			case INSIDE_LIMIT_MODULES:
				mode = DEFAULT;
				tokenizer = new StringTokenizer(currentArg, ","); //$NON-NLS-1$
				while (tokenizer.hasMoreTokens()) {
					if (this.limitedModules == null) {
						this.limitedModules = new HashSet<>();
					}
					this.limitedModules.add(tokenizer.nextToken().trim());
				}
				continue;
			case INSIDE_CLASSPATH_start:
				mode = DEFAULT;
				index += processPaths(newCommandLineArgs, index, currentArg, classpaths);
				continue;
			case INSIDE_BOOTCLASSPATH_start:
				mode = DEFAULT;
				index += processPaths(newCommandLineArgs, index, currentArg, bootclasspaths);
				continue;
			case INSIDE_SOURCE_PATH_start:
				mode = DEFAULT;
				String[] sourcePaths = new String[1];
				index += processPaths(newCommandLineArgs, index, currentArg, sourcePaths);
				sourcepathClasspathArg = sourcePaths[0];
				continue;
			case INSIDE_EXT_DIRS:
				if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$
					throw new IllegalArgumentException(
						this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$
							"-extdir")); //$NON-NLS-1$
				}
				tokenizer = new StringTokenizer(currentArg,	File.pathSeparator, false);
				extdirsClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
				while (tokenizer.hasMoreTokens())
					extdirsClasspaths.add(tokenizer.nextToken());
				mode = DEFAULT;
				continue;
			case INSIDE_ENDORSED_DIRS:
				if (currentArg.indexOf("[-d") != -1) { //$NON-NLS-1$
					throw new IllegalArgumentException(
						this.bind("configure.unexpectedDestinationPathEntry", //$NON-NLS-1$
							"-endorseddirs")); //$NON-NLS-1$
				}				tokenizer = new StringTokenizer(currentArg,	File.pathSeparator, false);
				endorsedDirClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
				while (tokenizer.hasMoreTokens())
					endorsedDirClasspaths.add(tokenizer.nextToken());
				mode = DEFAULT;
				continue;
			case INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH:
				if (currentArg.endsWith("]")) { //$NON-NLS-1$
					customDestinationPath = currentArg.substring(0,
						currentArg.length() - 1);
				} else {
					throw new IllegalArgumentException(
						this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
							"[-d " + currentArg)); //$NON-NLS-1$
				}
				break;
			case INSIDE_PROCESSOR_PATH_start :
				// nothing to do here. This is consumed again by the AnnotationProcessorManager
				mode = DEFAULT;
				continue;
			case INSIDE_PROCESSOR_start :
				// nothing to do here. This is consumed again by the AnnotationProcessorManager
				mode = DEFAULT;
				continue;
			case INSIDE_PROCESSOR_MODULE_PATH_start :
				mode = DEFAULT;
				continue;
			case INSIDE_S_start :
				// nothing to do here. This is consumed again by the AnnotationProcessorManager
				mode = DEFAULT;
				continue;
			case INSIDE_CLASS_NAMES :
				tokenizer = new StringTokenizer(currentArg, ","); //$NON-NLS-1$
				if (this.classNames == null) {
					this.classNames = new String[DEFAULT_SIZE_CLASSPATH];
				}
				while (tokenizer.hasMoreTokens()) {
					if (this.classNames.length == classCount) {
						// resize
						System.arraycopy(
							this.classNames,
							0,
							(this.classNames = new String[classCount * 2]),
							0,
							classCount);
					}
					this.classNames[classCount++] = tokenizer.nextToken();
				}
				mode = DEFAULT;
				continue;
			case INSIDE_WARNINGS_PROPERTIES :
				initializeWarnings(currentArg);
				mode = DEFAULT;
				continue;
			case INSIDE_ANNOTATIONPATH_start:
				mode = DEFAULT;
				if (currentArg.isEmpty() || currentArg.charAt(0) == '-')
					throw new IllegalArgumentException(this.bind("configure.missingAnnotationPath", currentArg)); //$NON-NLS-1$
				if (ANNOTATION_SOURCE_CLASSPATH.equals(currentArg)) {
					this.annotationsFromClasspath = true;
				} else {
					if (this.annotationPaths == null)
						this.annotationPaths = new ArrayList<String>();
					StringTokenizer tokens = new StringTokenizer(currentArg, File.pathSeparator);
					while (tokens.hasMoreTokens())
						this.annotationPaths.add(tokens.nextToken());
				}
				continue;
		}

		// default is input directory, if no custom destination path exists
		if (customDestinationPath == null) {
			if (File.separatorChar != '/') {
				currentArg = currentArg.replace('/', File.separatorChar);
			}
			if (currentArg.endsWith("[-d")) { //$NON-NLS-1$
				currentSourceDirectory = currentArg.substring(0,
					currentArg.length() - 3);
				mode = INSIDE_SOURCE_DIRECTORY_DESTINATION_PATH;
				continue;
			}
			currentSourceDirectory = currentArg;
		}
		File dir = new File(currentSourceDirectory);
		if (!dir.isDirectory()) {
			throw new IllegalArgumentException(
				this.bind("configure.unrecognizedOption", currentSourceDirectory)); //$NON-NLS-1$
		}
		String[] result = FileFinder.find(dir, SuffixConstants.SUFFIX_STRING_java);
		if (NONE.equals(customDestinationPath)) {
			customDestinationPath = NONE; // ensure == comparison
		}
		if (this.filenames != null) {
			// some source files were specified explicitly
			int length = result.length;
			System.arraycopy(
				this.filenames,
				0,
				(this.filenames = new String[length + filesCount]),
				0,
				filesCount);
			System.arraycopy(
				this.encodings,
				0,
				(this.encodings = new String[length + filesCount]),
				0,
				filesCount);
			System.arraycopy(
				this.destinationPaths,
				0,
				(this.destinationPaths = new String[length + filesCount]),
				0,
				filesCount);
			System.arraycopy(
					this.modNames,
					0,
					(this.modNames = new String[length + filesCount]),
					0,
					filesCount);
			System.arraycopy(result, 0, this.filenames, filesCount, length);
			for (int i = 0; i < length; i++) {
				this.encodings[filesCount + i] = customEncoding;
				this.destinationPaths[filesCount + i] = customDestinationPath;
				this.modNames[filesCount + i] = moduleName;
			}
			filesCount += length;
			customEncoding = null;
			customDestinationPath = null;
			currentSourceDirectory = null;
		} else {
			this.filenames = result;
			filesCount = this.filenames.length;
			this.encodings = new String[filesCount];
			this.destinationPaths = new String[filesCount];
			this.modNames = new String[filesCount];
			for (int i = 0; i < filesCount; i++) {
				this.encodings[i] = customEncoding;
				this.destinationPaths[i] = customDestinationPath;
			}
			customEncoding = null;
			customDestinationPath = null;
			currentSourceDirectory = null;
		}
		mode = DEFAULT;
		continue;
	}
	if (this.enablePreview) {
		this.options.put(
				CompilerOptions.OPTION_EnablePreviews,
				CompilerOptions.ENABLED);
	}

	// set DocCommentSupport, with appropriate side effects on defaults if
	// javadoc is not enabled
	if (this.enableJavadocOn) {
		this.options.put(
			CompilerOptions.OPTION_DocCommentSupport,
			CompilerOptions.ENABLED);
	} else if (this.warnJavadocOn || this.warnAllJavadocOn) {
		this.options.put(
			CompilerOptions.OPTION_DocCommentSupport,
			CompilerOptions.ENABLED);
		// override defaults: references that are embedded in javadoc are ignored
		// from the perspective of parameters and thrown exceptions usage
		this.options.put(
			CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference,
			CompilerOptions.DISABLED);
		this.options.put(
			CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference,
			CompilerOptions.DISABLED);
	}
	// configure warnings for javadoc contents
	if (this.warnJavadocOn) {
		this.options.put(
			CompilerOptions.OPTION_ReportInvalidJavadocTags,
			CompilerOptions.ENABLED);
		this.options.put(
			CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef,
			CompilerOptions.ENABLED);
		this.options.put(
			CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef,
			CompilerOptions.ENABLED);
		this.options.put(
			CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
			CompilerOptions.PRIVATE);
	}
	if (printUsageRequired || (filesCount == 0 && classCount == 0)) {
		if (usageSection ==  null) {
			printUsage(); // default
		} else {
			printUsage(usageSection);
		}
		this.proceed = false;
		return;
	}

	if (this.log != null) {
		this.logger.setLog(this.log);
	} else {
		this.showProgress = false;
	}
	this.logger.logVersion(printVersionRequired);

	validateOptions(didSpecifyCompliance);

	// Enable annotation processing by default in batch mode when compliance is at least 1.6
	// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=185768
	if (!didSpecifyDisabledAnnotationProcessing
			&& CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) >= ClassFileConstants.JDK1_6) {
		this.options.put(CompilerOptions.OPTION_Process_Annotations, CompilerOptions.ENABLED);
	}

	this.logger.logCommandLineArguments(newCommandLineArgs);
	this.logger.logOptions(this.options);

	if (this.maxRepetition == 0) {
		this.maxRepetition = 1;
	}
	if (this.maxRepetition >= 3 && (this.timing & TIMING_ENABLED) != 0) {
		this.compilerStats = new CompilerStats[this.maxRepetition];
	}

	if (filesCount != 0) {
		System.arraycopy(
			this.filenames,
			0,
			(this.filenames = new String[filesCount]),
			0,
			filesCount);
	}

	if (classCount != 0) {
		System.arraycopy(
			this.classNames,
			0,
			(this.classNames = new String[classCount]),
			0,
			classCount);
	}

	setPaths(bootclasspaths,
			sourcepathClasspathArg,
			sourcepathClasspaths,
			classpaths,
			modulepathArg,
			moduleSourcepathArg,
			extdirsClasspaths,
			endorsedDirClasspaths,
			customEncoding);

	if (specifiedEncodings != null && specifiedEncodings.size() > 1) {
		this.logger.logWarning(this.bind("configure.multipleencodings", //$NON-NLS-1$
				this.options.get(CompilerOptions.OPTION_Encoding),
				getAllEncodings(specifiedEncodings)));
	}
	if (this.pendingErrors != null) {
		for (Iterator<String> iterator = this.pendingErrors.iterator(); iterator.hasNext(); ) {
			String message = iterator.next();
			this.logger.logPendingError(message);
		}
		this.pendingErrors = null;
	}
}
private Parser getNewParser() {
	return new Parser(new ProblemReporter(getHandlingPolicy(), 
			new CompilerOptions(this.options), getProblemFactory()), false);
}
private IModule extractModuleDesc(String fileName) {
	IModule mod = null;
	// this.options may not be completely populated yet, and definitely not
	// validated. Make sure the source level is set for the parser
	Map<String,String> opts = new HashMap<String, String>(this.options);
	opts.put(CompilerOptions.OPTION_Source, this.options.get(CompilerOptions.OPTION_Compliance));
	Parser parser = new Parser(new ProblemReporter(getHandlingPolicy(), 
			new CompilerOptions(opts), getProblemFactory()), false);
	if (fileName.toLowerCase().endsWith(IModule.MODULE_INFO_JAVA)) {
		
		ICompilationUnit cu = new CompilationUnit(null, fileName, null);
		CompilationResult compilationResult = new CompilationResult(cu, 0, 1, 10);
		CompilationUnitDeclaration unit = parser.parse(cu, compilationResult);
		if (unit.isModuleInfo() && unit.moduleDeclaration != null) {
			mod = new BasicModule(unit.moduleDeclaration, null);
		}
	} else if (fileName.toLowerCase().endsWith(IModule.MODULE_INFO_CLASS)) {
		try {
			ClassFileReader reader = ClassFileReader.read(fileName); // Check the absolute path?
			mod = reader.getModuleDeclaration();
		} catch (ClassFormatException | IOException e) {
			e.printStackTrace();
			throw new IllegalArgumentException(
					this.bind("configure.invalidModuleDescriptor", fileName)); //$NON-NLS-1$
		}
	}
	return mod;
}

private static char[][] decodeIgnoreOptionalProblemsFromFolders(String folders) {
	StringTokenizer tokenizer = new StringTokenizer(folders, File.pathSeparator);
	char[][] result = new char[tokenizer.countTokens()][];
	int count = 0;
	while (tokenizer.hasMoreTokens()) {
		String fileName = tokenizer.nextToken();
		// relative folder names are created relative to the current user dir
		File file = new File(fileName);
		if (file.exists()) {
			// if the file exists, we should try to use its canonical path
			try {
				result[count++] = file.getCanonicalPath().toCharArray();
			} catch (IOException e) {
				// if we got exception during canonicalization, fall back to the name that was specified
				result[count++] = fileName.toCharArray();
			}
		} else {
			// if the file does not exist, use the name that was specified
			result[count++] = fileName.toCharArray();
		}
	}
	return result;
}

private static String getAllEncodings(Set<String> encodings) {
	int size = encodings.size();
	String[] allEncodings = new String[size];
	encodings.toArray(allEncodings);
	Arrays.sort(allEncodings);
	StringBuffer buffer = new StringBuffer();
	for (int i = 0; i < size; i++) {
		if (i > 0) {
			buffer.append(", "); //$NON-NLS-1$
		}
		buffer.append(allEncodings[i]);
	}
	return String.valueOf(buffer);
}
@SuppressWarnings("rawtypes")
private void initializeWarnings(String propertiesFile) {
	File file = new File(propertiesFile);
	if (!file.exists()) {
		throw new IllegalArgumentException(this.bind("configure.missingwarningspropertiesfile", propertiesFile)); //$NON-NLS-1$
	}
	BufferedInputStream stream = null;
	Properties properties = null;
	try {
		stream = new BufferedInputStream(new FileInputStream(propertiesFile));
		properties = new Properties();
		properties.load(stream);
	} catch(IOException e) {
		e.printStackTrace();
		throw new IllegalArgumentException(this.bind("configure.ioexceptionwarningspropertiesfile", propertiesFile)); //$NON-NLS-1$
	} finally {
		if (stream != null) {
			try {
				stream.close();
			} catch(IOException e) {
				// ignore
			}
		}
	}
	for(Iterator iterator = properties.entrySet().iterator(); iterator.hasNext(); ) {
		Map.Entry entry = (Map.Entry) iterator.next();
		final String key = entry.getKey().toString();
		if (key.startsWith("org.eclipse.jdt.core.compiler.")) { //$NON-NLS-1$
			this.options.put(key, entry.getValue().toString());
		}
	}
	// when using a properties file mimic relevant defaults from JavaCorePreferenceInitializer:
	if (!properties.containsKey(CompilerOptions.OPTION_LocalVariableAttribute)) {
		this.options.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
	}
	if (!properties.containsKey(CompilerOptions.OPTION_PreserveUnusedLocal)) {
		this.options.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE);
	}
	if (!properties.containsKey(CompilerOptions.OPTION_DocCommentSupport)) {
		this.options.put(CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED);
	}
	if (!properties.containsKey(CompilerOptions.OPTION_ReportForbiddenReference)) {
		this.options.put(CompilerOptions.OPTION_ReportForbiddenReference, CompilerOptions.ERROR);
	}
}
protected void enableAll(int severity) {
	String newValue = null;
	switch(severity) {
		case ProblemSeverities.Error :
			newValue = CompilerOptions.ERROR;
			break;
		case ProblemSeverities.Warning :
			newValue = CompilerOptions.WARNING;
			break;
	}
	Map.Entry<String, String>[] entries = this.options.entrySet().toArray(new Map.Entry[this.options.size()]);
	for (int i = 0, max = entries.length; i < max; i++) {
		Map.Entry<String, String> entry = entries[i];
		if (entry.getValue().equals(CompilerOptions.IGNORE)) {
			this.options.put(entry.getKey(), newValue);
		}
	}
	this.options.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
}
protected void disableAll(int severity) {
	String checkedValue = null;
	switch(severity) {
		case ProblemSeverities.Error :
			checkedValue = CompilerOptions.ERROR;
			break;
		case ProblemSeverities.Warning :
			checkedValue = CompilerOptions.WARNING;
			break;
		case ProblemSeverities.Info :
			checkedValue = CompilerOptions.INFO;
			break;
	}
	Set<Entry<String, String>> entrySet = this.options.entrySet();
	for (Entry<String, String> entry : entrySet) {
		if (entry.getValue().equals(checkedValue)) {
			this.options.put(entry.getKey(), CompilerOptions.IGNORE);
		}
	}
	if (severity == ProblemSeverities.Warning) {
		disableAll(ProblemSeverities.Info);
	}
}
public String extractDestinationPathFromSourceFile(CompilationResult result) {
	ICompilationUnit compilationUnit = result.compilationUnit;
	if (compilationUnit != null) {
		char[] fileName = compilationUnit.getFileName();
		int lastIndex = CharOperation.lastIndexOf(java.io.File.separatorChar, fileName);
		if (lastIndex != -1) {
			final String outputPathName = new String(fileName, 0, lastIndex);
			final File output = new File(outputPathName);
			if (output.exists() && output.isDirectory()) {
				return outputPathName;
			}
		}
	}
	return System.getProperty("user.dir"); //$NON-NLS-1$
}
/*
 * Answer the component to which will be handed back compilation results from the compiler
 */
public ICompilerRequestor getBatchRequestor() {
    return new BatchCompilerRequestor(this);
}
/*
 *  Build the set of compilation source units
 */
public CompilationUnit[] getCompilationUnits() {
	int fileCount = this.filenames.length;
	CompilationUnit[] units = new CompilationUnit[fileCount];
	HashtableOfObject knownFileNames = new HashtableOfObject(fileCount);

	String defaultEncoding = this.options.get(CompilerOptions.OPTION_Encoding);
	if (Util.EMPTY_STRING.equals(defaultEncoding))
		defaultEncoding = null;
	
	for (int round = 0; round < 2; round++) {
		for (int i = 0; i < fileCount; i++) {
			char[] charName = this.filenames[i].toCharArray();
			boolean isModuleInfo = CharOperation.endsWith(charName, TypeConstants.MODULE_INFO_FILE_NAME);
			if (isModuleInfo == (round==0)) { // 1st round: modules, 2nd round others (to ensure populating pathToModCU well in time)
				if (knownFileNames.get(charName) != null)
					throw new IllegalArgumentException(this.bind("unit.more", this.filenames[i])); //$NON-NLS-1$
				knownFileNames.put(charName, charName);
				File file = new File(this.filenames[i]);
				if (!file.exists())
					throw new IllegalArgumentException(this.bind("unit.missing", this.filenames[i])); //$NON-NLS-1$
				String encoding = this.encodings[i];
				if (encoding == null)
					encoding = defaultEncoding;
				String fileName;
				try {
					fileName = file.getCanonicalPath();
				} catch (IOException e) {
					// if we got exception during canonicalization, fall back to the name that was specified
					fileName = this.filenames[i];
				}
				units[i] = new CompilationUnit(null, fileName, encoding, this.destinationPaths[i],
						shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, fileName.toCharArray()), 
						this.modNames[i]);
			}
		}
	}
	return units;
}

/*
 *  Low-level API performing the actual compilation
 */
public IErrorHandlingPolicy getHandlingPolicy() {

	// passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
	return new IErrorHandlingPolicy() {
		@Override
		public boolean proceedOnErrors() {
			return Main.this.proceedOnError; // stop if there are some errors
		}
		@Override
		public boolean stopOnFirstError() {
			return false;
		}
		@Override
		public boolean ignoreAllErrors() {
			return false;
		}
	};
}
private void setJavaHome(String javaHome) {
	File release = new File(javaHome, "release"); //$NON-NLS-1$
	Properties prop = new Properties();
	try {
		prop.load(new FileReader(release));
		String ver = prop.getProperty("JAVA_VERSION"); //$NON-NLS-1$
		if (ver != null)
			ver = ver.replace("\"", "");  //$NON-NLS-1$//$NON-NLS-2$
		this.javaHomeCache = new File(javaHome);
		this.javaHomeChecked = true;
	} catch (IOException e) {
		throw new IllegalArgumentException(this.bind("configure.invalidSystem", javaHome)); //$NON-NLS-1$
	}
}
/*
 * External API
 */
public File getJavaHome() {
	if (!this.javaHomeChecked) {
		this.javaHomeChecked = true;
		this.javaHomeCache = Util.getJavaHome();
	}
	return this.javaHomeCache;
}

public FileSystem getLibraryAccess() {
	FileSystem nameEnvironment = new FileSystem(this.checkedClasspaths, this.filenames, 
					this.annotationsFromClasspath && CompilerOptions.ENABLED.equals(this.options.get(CompilerOptions.OPTION_AnnotationBasedNullAnalysis)),
					this.limitedModules);
	nameEnvironment.module = this.module;
	processAddonModuleOptions(nameEnvironment);
	return nameEnvironment;
}

/*
 *  Low-level API performing the actual compilation
 */
public IProblemFactory getProblemFactory() {
	return new DefaultProblemFactory(this.compilerLocale);
}

/*
 * External API
 */
protected ArrayList<Classpath> handleBootclasspath(ArrayList<String> bootclasspaths, String customEncoding) {
 	final int bootclasspathsSize;
 	ArrayList<Classpath> result = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
	if ((bootclasspaths != null)
		&& ((bootclasspathsSize = bootclasspaths.size()) != 0)) {
		result = new ArrayList<>(bootclasspathsSize);
		for (String path : bootclasspaths) {
			processPathEntries(DEFAULT_SIZE_CLASSPATH, result, path, customEncoding, false, true);
		}
	} else {
		try {
			Util.collectVMBootclasspath(result, this.javaHomeCache);
		} catch(IllegalStateException e) {
			throw new IllegalArgumentException(this.bind("configure.invalidSystem", this.javaHomeCache.toString())); //$NON-NLS-1$
		}
	}
	return result;
}
private void processAddonModuleOptions(FileSystem env) {
	Map<String, IPackageExport[]> exports = new HashMap<>();
	for (String option : this.addonExports) {
		AddExport addExport = ModuleFinder.extractAddonExport(option);
		if (addExport != null) {
			String modName = addExport.sourceModuleName;
			IPackageExport export = addExport.export;
			IPackageExport[] existing = exports.get(modName);
			if (existing == null) {
				existing = new IPackageExport[1];
				existing[0] = export;
				exports.put(modName, existing);
			} else {
				for (IPackageExport iPackageExport : existing) {
					if (CharOperation.equals(iPackageExport.name(), export.name())) {
						throw new IllegalArgumentException(this.bind("configure.duplicateExport")); //$NON-NLS-1$
					}
				}
				IPackageExport[] updated = new IPackageExport[existing.length + 1];
				System.arraycopy(existing, 0, updated, 0, existing.length);
				updated[existing.length] = export;
				exports.put(modName, updated);
			}
			env.addModuleUpdate(modName, m -> m.addExports(export.name(), export.targets()), UpdateKind.PACKAGE);
		} else {
			throw new IllegalArgumentException(this.bind("configure.invalidModuleOption", "--add-exports " + option)); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}
	for (String option : this.addonReads) {
		String[] result = ModuleFinder.extractAddonRead(option);
		if (result != null && result.length == 2) {
			env.addModuleUpdate(result[0], m -> m.addReads(result[1].toCharArray()), UpdateKind.MODULE);
		} else {
			throw new IllegalArgumentException(this.bind("configure.invalidModuleOption", "--add-reads " + option)); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}
}
protected ArrayList<FileSystem.Classpath> handleModulepath(String arg) {
	ArrayList<String> modulePaths = processModulePathEntries(arg);
	ArrayList<Classpath> result = new ArrayList<>();
	if ((modulePaths != null && modulePaths.size() > 0)) {
		for (String path : modulePaths) {
			File file = new File(path);
			if (file.isDirectory()) {
				result.addAll(
					ModuleFinder.findModules(file, null, getNewParser(), this.options, true, this.releaseVersion));
			} else {
				Classpath modulePath = ModuleFinder.findModule(file, null, getNewParser(), this.options, true, this.releaseVersion);
				if (modulePath != null)
					result.add(modulePath);
			}
		}
	}
	// TODO: What about chained jars from MANIFEST.MF? Check with spec
	return result;
}
protected ArrayList<FileSystem.Classpath> handleModuleSourcepath(String arg) {
	ArrayList<String> modulePaths = processModulePathEntries(arg);
	ArrayList<FileSystem.Classpath> result = new ArrayList<>();
	if ((modulePaths != null)
		&& (modulePaths.size() != 0)) {

		if (this.destinationPath == null) {
			addPendingErrors(this.bind("configure.missingDestinationPath"));//$NON-NLS-1$
		}
		String[] paths = new String[modulePaths.size()];
		modulePaths.toArray(paths);
		for (int i = 0; i < paths.length; i++) {
			File dir = new File(paths[i]);
			if (dir.isDirectory()) {
				// 1. Create FileSystem.Classpath for each module
				// 2. Iterator each module in case of directory for source files and add to this.fileNames

				List<Classpath> modules = ModuleFinder.findModules(dir, this.destinationPath, getNewParser(), this.options, false, this.releaseVersion);
				for (Classpath classpath : modules) {
					result.add(classpath);
					Path modLocation = Paths.get(classpath.getPath()).toAbsolutePath();
					String destPath = classpath.getDestinationPath();
					IModule mod = classpath.getModule();
					String moduleName = mod == null ? null : new String(mod.name());
					for(int j = 0; j < this.filenames.length; j++) {
						Path filePath;
						try {
							// Get canonical path just as the classpath location is stored with the same.
							// To avoid mismatch of /USER_JAY and /USE~1 in windows systems.
							filePath = new File(this.filenames[j]).getCanonicalFile().toPath();
							if (filePath.startsWith(modLocation)) {
								this.modNames[j] = moduleName;
								this.destinationPaths[j] = destPath;
							}
						} catch (IOException e) {
							// Files doesn't exist and perhaps doesn't belong in a module, move on to other files
							// Use empty module name to distinguish from missing module case
							this.modNames[j] = ""; //$NON-NLS-1$
						}
					}
				}
			}
		}
		for(int j = 0; j < this.filenames.length; j++) {
			if (this.modNames[j] == null) {
				throw new IllegalArgumentException(this.bind("configure.notOnModuleSourcePath", new String[] {this.filenames[j]})); //$NON-NLS-1$
			}
		}
	}
	return result;
}
/*
 * External API
 */
protected ArrayList<FileSystem.Classpath> handleClasspath(ArrayList<String> classpaths, String customEncoding) {
	ArrayList<FileSystem.Classpath> initial = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
	if (classpaths != null && classpaths.size() > 0) {
		for (String path : classpaths) {
			processPathEntries(DEFAULT_SIZE_CLASSPATH, initial, path, customEncoding, false, true);
		}
	} else {
		// no user classpath specified.
		String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
		if ((classProp == null) || (classProp.length() == 0)) {
			addPendingErrors(this.bind("configure.noClasspath")); //$NON-NLS-1$
			final Classpath classpath = FileSystem.getClasspath(System.getProperty("user.dir"), customEncoding, null, this.options, this.releaseVersion);//$NON-NLS-1$
			if (classpath != null) {
				initial.add(classpath);
			}
		} else {
			StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
			String token;
			while (tokenizer.hasMoreTokens()) {
				token = tokenizer.nextToken();
				FileSystem.Classpath currentClasspath = FileSystem
						.getClasspath(token, customEncoding, null, this.options, this.releaseVersion);
				if (currentClasspath != null) {
					initial.add(currentClasspath);
				} else if (token.length() != 0) {
					addPendingErrors(this.bind("configure.incorrectClasspath", token));//$NON-NLS-1$
				}
			}
		}
	}
	ArrayList<Classpath> result = new ArrayList<>();
	HashMap<String, Classpath> knownNames = new HashMap<>();
	FileSystem.ClasspathSectionProblemReporter problemReporter =
		new FileSystem.ClasspathSectionProblemReporter() {
			@Override
			public void invalidClasspathSection(String jarFilePath) {
				addPendingErrors(bind("configure.invalidClasspathSection", jarFilePath)); //$NON-NLS-1$
			}
			@Override
			public void multipleClasspathSections(String jarFilePath) {
				addPendingErrors(bind("configure.multipleClasspathSections", jarFilePath)); //$NON-NLS-1$
			}
		};
	while (! initial.isEmpty()) {
		Classpath current = initial.remove(0);
		String currentPath = current.getPath();
		if (knownNames.get(currentPath) == null) {
			knownNames.put(currentPath, current);
			result.add(current);
			List<Classpath> linkedJars = current.fetchLinkedJars(problemReporter);
			if (linkedJars != null) {
				initial.addAll(0, linkedJars);
			}
		}
	}
	return result;
}
/*
 * External API
 */
protected ArrayList<FileSystem.Classpath> handleEndorseddirs(ArrayList<String> endorsedDirClasspaths) {
 	final File javaHome = getJavaHome();
	/*
	 * Feed endorsedDirClasspath according to:
	 * - -endorseddirs first if present;
	 * - else java.endorsed.dirs if defined;
	 * - else default extensions directory for the platform. (/lib/endorsed)
	 */
	if (endorsedDirClasspaths == null) {
		endorsedDirClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
		String endorsedDirsStr = System.getProperty("java.endorsed.dirs"); //$NON-NLS-1$
		if (endorsedDirsStr == null) {
			if (javaHome != null) {
				endorsedDirClasspaths.add(javaHome.getAbsolutePath() + "/lib/endorsed"); //$NON-NLS-1$
			}
		} else {
			StringTokenizer tokenizer = new StringTokenizer(endorsedDirsStr, File.pathSeparator);
			while (tokenizer.hasMoreTokens()) {
				endorsedDirClasspaths.add(tokenizer.nextToken());
			}
		}
	}

	/*
	 * Feed extdirsClasspath with the entries found into the directories listed by
	 * extdirsNames.
	 */
	if (endorsedDirClasspaths.size() != 0) {
		ArrayList<FileSystem.Classpath> result = new ArrayList<>();
		File[] directoriesToCheck = new File[endorsedDirClasspaths.size()];
		for (int i = 0; i < directoriesToCheck.length; i++)
			directoriesToCheck[i] = new File(endorsedDirClasspaths.get(i));
		File[][] endorsedDirsJars = getLibrariesFiles(directoriesToCheck);
		if (endorsedDirsJars != null) {
			for (int i = 0, max = endorsedDirsJars.length; i < max; i++) {
				File[] current = endorsedDirsJars[i];
				if (current != null) {
					for (int j = 0, max2 = current.length; j < max2; j++) {
						FileSystem.Classpath classpath =
							FileSystem.getClasspath(
									current[j].getAbsolutePath(),
									null, null, this.options, this.releaseVersion);
						if (classpath != null) {
							result.add(classpath);
						}
					}
				} else if (directoriesToCheck[i].isFile()) {
					addPendingErrors(
						this.bind(
							"configure.incorrectEndorsedDirsEntry", //$NON-NLS-1$
							directoriesToCheck[i].getAbsolutePath()));
				}
			}
		}
		return result;
	}
	return FileSystem.EMPTY_CLASSPATH;
}

/*
 * External API
 * Handle extdirs processing
 */
protected ArrayList<FileSystem.Classpath> handleExtdirs(ArrayList<String> extdirsClasspaths) {
 	final File javaHome = getJavaHome();

	/*
	 * Feed extDirClasspath according to:
	 * - -extdirs first if present;
	 * - else java.ext.dirs if defined;
	 * - else default extensions directory for the platform.
	 */
	if (extdirsClasspaths == null) {
		extdirsClasspaths = new ArrayList<>(DEFAULT_SIZE_CLASSPATH);
		String extdirsStr = System.getProperty("java.ext.dirs"); //$NON-NLS-1$
		if (extdirsStr == null) {
			extdirsClasspaths.add(javaHome.getAbsolutePath() + "/lib/ext"); //$NON-NLS-1$
		} else {
			StringTokenizer tokenizer = new StringTokenizer(extdirsStr, File.pathSeparator);
			while (tokenizer.hasMoreTokens())
				extdirsClasspaths.add(tokenizer.nextToken());
		}
	}

	/*
	 * Feed extdirsClasspath with the entries found into the directories listed by
	 * extdirsNames.
	 */
	if (extdirsClasspaths.size() != 0) {
		ArrayList<FileSystem.Classpath> result = new ArrayList<>();
		File[] directoriesToCheck = new File[extdirsClasspaths.size()];
		for (int i = 0; i < directoriesToCheck.length; i++)
			directoriesToCheck[i] = new File(extdirsClasspaths.get(i));
		File[][] extdirsJars = getLibrariesFiles(directoriesToCheck);
		if (extdirsJars != null) {
			for (int i = 0, max = extdirsJars.length; i < max; i++) {
				File[] current = extdirsJars[i];
				if (current != null) {
					for (int j = 0, max2 = current.length; j < max2; j++) {
						FileSystem.Classpath classpath =
							FileSystem.getClasspath(
									current[j].getAbsolutePath(),
									null, null, this.options, this.releaseVersion);
						if (classpath != null) {
							result.add(classpath);
						}
					}
				} else if (directoriesToCheck[i].isFile()) {
					addPendingErrors(this.bind(
							"configure.incorrectExtDirsEntry", //$NON-NLS-1$
							directoriesToCheck[i].getAbsolutePath()));
				}
			}
		}
		return result; 
	}

	return FileSystem.EMPTY_CLASSPATH;
}

/*
 * External API
 * Handle a single warning token.
*/
protected void handleInfoToken(String token, boolean isEnabling) {
	handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Info);
}
protected void handleWarningToken(String token, boolean isEnabling) {
	handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Warning);
}
protected void handleErrorToken(String token, boolean isEnabling) {
	handleErrorOrWarningToken(token, isEnabling, ProblemSeverities.Error);
}
private void setSeverity(String compilerOptions, int severity, boolean isEnabling) {
	if (isEnabling) {
		switch(severity) {
			case ProblemSeverities.Error :
				this.options.put(compilerOptions, CompilerOptions.ERROR);
				break;
			case ProblemSeverities.Warning :
				this.options.put(compilerOptions, CompilerOptions.WARNING);
				break;
			case ProblemSeverities.Info :
				this.options.put(compilerOptions, CompilerOptions.INFO);
				break;
			default:
				this.options.put(compilerOptions, CompilerOptions.IGNORE);
		}
	} else {
		switch(severity) {
			case ProblemSeverities.Error :
				String currentValue = this.options.get(compilerOptions);
				if (CompilerOptions.ERROR.equals(currentValue)) {
					this.options.put(compilerOptions, CompilerOptions.IGNORE);
				}
				break;
			case ProblemSeverities.Warning :
				currentValue = this.options.get(compilerOptions);
				if (CompilerOptions.WARNING.equals(currentValue)) {
					this.options.put(compilerOptions, CompilerOptions.IGNORE);
				}
				break;
			case ProblemSeverities.Info :
				currentValue = this.options.get(compilerOptions);
				if (CompilerOptions.INFO.equals(currentValue)) {
					this.options.put(compilerOptions, CompilerOptions.IGNORE);
				}
				break;
			default:
				this.options.put(compilerOptions, CompilerOptions.IGNORE);
		}
	}
}
private void handleErrorOrWarningToken(String token, boolean isEnabling, int severity) {
	if (token.length() == 0) return;
	switch(token.charAt(0)) {
		case 'a' :
			if (token.equals("allDeprecation")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportDeprecation, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportTerminalDeprecation, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				this.options.put(
					CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("allJavadoc")) { //$NON-NLS-1$
				this.warnAllJavadocOn = this.warnJavadocOn = isEnabling;
				setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling);
				return;
			} else if (token.equals("assertIdentifier")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportAssertIdentifier, severity, isEnabling);
				return;
			} else if (token.equals("allDeadCode")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("allOver-ann")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingOverrideAnnotation, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("all-static-method")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMethodCanBeStatic, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportMethodCanBePotentiallyStatic, severity, isEnabling);
				return;
			} else if (token.equals("all")) { //$NON-NLS-1$
				if (isEnabling) {
					enableAll(severity);
				} else {
					disableAll(severity);
				}
				return;
			}
			break;
		case 'b' :
			if (token.equals("boxing")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportAutoboxing, severity, isEnabling);
				return;
			}
			break;
		case 'c' :
			if (token.equals("constructorName")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMethodWithConstructorName, severity, isEnabling);
				return;
			} else if (token.equals("conditionAssign")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, severity, isEnabling);
				return;
			} else if (token.equals("compareIdentical")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportComparingIdentical, severity, isEnabling);
				return;
			} else if (token.equals("charConcat") /*|| token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNoImplicitStringConversion, severity, isEnabling);
				return;
			}
			break;
		case 'd' :
			if (token.equals("deprecation")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportDeprecation, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
					CompilerOptions.DISABLED);
				this.options.put(
					CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
					CompilerOptions.DISABLED);
				return;
			} else if (token.equals("dep-ann")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingDeprecatedAnnotation, severity, isEnabling);
				return;
			} else if (token.equals("discouraged")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportDiscouragedReference, severity, isEnabling);
				return;
			} else if (token.equals("deadCode")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportDeadCode, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportDeadCodeInTrivialIfStatement,
					CompilerOptions.DISABLED);
				return;
			}
			break;
		case 'e' :
			if (token.equals("enumSwitch")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
				return;
			} else if (token.equals("enumSwitchPedantic")) { //$NON-NLS-1$
				if (isEnabling) {
					switch (severity) {
						case ProblemSeverities.Error:
							setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
							break;
						case ProblemSeverities.Warning:
							if (CompilerOptions.IGNORE.equals(this.options.get(CompilerOptions.OPTION_ReportIncompleteEnumSwitch))) {
								setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
							}
							break;
						default: // no severity update
					}
				}
				this.options.put(CompilerOptions.OPTION_ReportMissingEnumCaseDespiteDefault, 
								 isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("emptyBlock")) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUndocumentedEmptyBlock, severity, isEnabling);
				return;
			} else if (token.equals("enumIdentifier")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportEnumIdentifier, severity, isEnabling);
				return;
			} else if (token.equals("exports")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportAPILeak, severity, isEnabling);
				return;
			}
			break;
		case 'f' :
			if (token.equals("fieldHiding")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportFieldHiding, severity, isEnabling);
				return;
			} else if (token.equals("finalBound")) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportFinalParameterBound, severity, isEnabling);
				return;
			} else if (token.equals("finally")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally, severity, isEnabling);
				return;
			} else if (token.equals("forbidden")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportForbiddenReference, severity, isEnabling);
				return;
			} else if (token.equals("fallthrough")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportFallthroughCase, severity, isEnabling);
				return;
			}
			break;
		case 'h' :
			if (token.equals("hiding")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportHiddenCatchBlock, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportLocalVariableHiding, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportFieldHiding, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportTypeParameterHiding, severity, isEnabling);
				return;
			} else if (token.equals("hashCode")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingHashCodeMethod, severity, isEnabling);
				return;
			}
			break;
		case 'i' :
			if (token.equals("indirectStatic")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportIndirectStaticAccess, severity, isEnabling);
				return;
			} else if (token.equals("inheritNullAnnot")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_InheritNullAnnotations,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("intfNonInherited") || token.equals("interfaceNonInherited")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, severity, isEnabling);
				return;
			} else if (token.equals("intfAnnotation")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportAnnotationSuperInterface, severity, isEnabling);
				return;
			} else if (token.equals("intfRedundant") /*|| token.equals("redundantSuperinterface")*/) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling);
				return;
			} else if (token.equals("includeAssertNull")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_IncludeNullInfoFromAsserts,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("invalidJavadoc")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportInvalidJavadocTags,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				this.options.put(
					CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				this.options.put(
					CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				if (isEnabling) {
					this.options.put(
							CompilerOptions.OPTION_DocCommentSupport,
							CompilerOptions.ENABLED);
					this.options.put(
						CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility,
						CompilerOptions.PRIVATE);
				}
				return;
			} else if (token.equals("invalidJavadocTag")) { //$NON-NLS-1$
				this.options.put(
					CompilerOptions.OPTION_ReportInvalidJavadocTags,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("invalidJavadocTagDep")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("invalidJavadocTagNotVisible")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.startsWith("invalidJavadocTagVisibility")) { //$NON-NLS-1$
				int start = token.indexOf('(');
				int end = token.indexOf(')');
				String visibility = null;
				if (isEnabling && start >= 0 && end >= 0 && start < end){
					visibility = token.substring(start+1, end).trim();
				}
				if (visibility != null && visibility.equals(CompilerOptions.PUBLIC)
						|| visibility.equals(CompilerOptions.PRIVATE)
						|| visibility.equals(CompilerOptions.PROTECTED)
						|| visibility.equals(CompilerOptions.DEFAULT)) {
					this.options.put(
							CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility,
							visibility);
					return;
				} else {
					throw new IllegalArgumentException(this.bind("configure.invalidJavadocTagVisibility", token)); //$NON-NLS-1$
				}
			}
			break;
		case 'j' :
			if (token.equals("javadoc")) {//$NON-NLS-1$
				this.warnJavadocOn = isEnabling;
				setSeverity(CompilerOptions.OPTION_ReportInvalidJavadoc, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling);
				return;
			}
			break;
		case 'l' :
			if (token.equals("localHiding")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportLocalVariableHiding, severity, isEnabling);
				return;
			}
			break;
		case 'm' :
			if (token.equals("maskedCatchBlock") || token.equals("maskedCatchBlocks")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportHiddenCatchBlock, severity, isEnabling);
				return;
			} else if (token.equals("missingJavadocTags")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocTags, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				this.options.put(
					CompilerOptions.OPTION_ReportMissingJavadocTagsMethodTypeParameters,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				if (isEnabling) {
					this.options.put(
							CompilerOptions.OPTION_DocCommentSupport,
							CompilerOptions.ENABLED);
					this.options.put(
						CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
						CompilerOptions.PRIVATE);
				}
				return;
			} else if (token.equals("missingJavadocTagsOverriding")) { //$NON-NLS-1$
				this.options.put(
					CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("missingJavadocTagsMethod")) { //$NON-NLS-1$
				this.options.put(
					CompilerOptions.OPTION_ReportMissingJavadocTagsMethodTypeParameters,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.startsWith("missingJavadocTagsVisibility")) { //$NON-NLS-1$
				int start = token.indexOf('(');
				int end = token.indexOf(')');
				String visibility = null;
				if (isEnabling && start >= 0 && end >= 0 && start < end){
					visibility = token.substring(start+1, end).trim();
				}
				if (visibility != null && visibility.equals(CompilerOptions.PUBLIC)
						|| visibility.equals(CompilerOptions.PRIVATE)
						|| visibility.equals(CompilerOptions.PROTECTED)
						|| visibility.equals(CompilerOptions.DEFAULT)) {
					this.options.put(
							CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility,
							visibility);
					return;
				} else {
					throw new IllegalArgumentException(this.bind("configure.missingJavadocTagsVisibility", token)); //$NON-NLS-1$
				}
			} else if (token.equals("missingJavadocComments")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				if (isEnabling) {
					this.options.put(
							CompilerOptions.OPTION_DocCommentSupport,
							CompilerOptions.ENABLED);
					this.options.put(
						CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility,
						CompilerOptions.PRIVATE);
				}
				return;
			} else if (token.equals("missingJavadocCommentsOverriding")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingJavadocComments, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.startsWith("missingJavadocCommentsVisibility")) { //$NON-NLS-1$
				int start = token.indexOf('(');
				int end = token.indexOf(')');
				String visibility = null;
				if (isEnabling && start >= 0 && end >= 0 && start < end){
					visibility = token.substring(start+1, end).trim();
				}
				if (visibility != null && visibility.equals(CompilerOptions.PUBLIC)
						|| visibility.equals(CompilerOptions.PRIVATE)
						|| visibility.equals(CompilerOptions.PROTECTED)
						|| visibility.equals(CompilerOptions.DEFAULT)) {
					this.options.put(
							CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility,
							visibility);
					return;
				} else {
					throw new IllegalArgumentException(this.bind("configure.missingJavadocCommentsVisibility", token)); //$NON-NLS-1$
				}
			} else if (token.equals("module")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnstableAutoModuleName, severity, isEnabling);
				return;
			}
			break;
		case 'n' :
			if (token.equals("nls")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, severity, isEnabling);
				return;
			} else if (token.equals("noEffectAssign")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNoEffectAssignment, severity, isEnabling);
				return;
			} else if (/*token.equals("charConcat") ||*/ token.equals("noImplicitStringConversion")/*backward compatible*/) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNoImplicitStringConversion, severity, isEnabling);
				return;
			} else if (token.equals("null")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNullReference, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportPotentialNullReference, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, severity, isEnabling);
				return;
			} else if (token.equals("nullDereference")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNullReference, severity, isEnabling);
				if (!isEnabling) {
					setSeverity(CompilerOptions.OPTION_ReportPotentialNullReference, ProblemSeverities.Ignore, isEnabling);
					setSeverity(CompilerOptions.OPTION_ReportRedundantNullCheck, ProblemSeverities.Ignore, isEnabling);
				}
				return;
			}else if (token.equals("nullAnnotConflict")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNullAnnotationInferenceConflict, severity, isEnabling);
				return;
			} else if (token.equals("nullAnnotRedundant")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportRedundantNullAnnotation, severity, isEnabling);
				return;
			} else if (token.startsWith("nullAnnot")) { //$NON-NLS-1$
				String annotationNames = Util.EMPTY_STRING;
				int start = token.indexOf('(');
				int end = token.indexOf(')');
				String nonNullAnnotName = null, nullableAnnotName = null, nonNullByDefaultAnnotName = null;
				if (isEnabling && start >= 0 && end >= 0 && start < end){
					boolean isPrimarySet = !this.primaryNullAnnotationsSeen;
					annotationNames = token.substring(start+1, end).trim();
					int separator1 = annotationNames.indexOf('|');
					if (separator1 == -1) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
					nullableAnnotName = annotationNames.substring(0, separator1).trim();
					if (isPrimarySet && nullableAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
					int separator2 = annotationNames.indexOf('|', separator1 + 1);
					if (separator2 == -1) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
					nonNullAnnotName = annotationNames.substring(separator1 + 1, separator2).trim();
					if (isPrimarySet && nonNullAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
					nonNullByDefaultAnnotName = annotationNames.substring(separator2 + 1).trim();
					if (isPrimarySet && nonNullByDefaultAnnotName.length() == 0) throw new IllegalArgumentException(this.bind("configure.invalidNullAnnot", token)); //$NON-NLS-1$
					if (isPrimarySet) {
						this.primaryNullAnnotationsSeen = true;
						this.options.put(CompilerOptions.OPTION_NullableAnnotationName, nullableAnnotName);
						this.options.put(CompilerOptions.OPTION_NonNullAnnotationName, nonNullAnnotName);
						this.options.put(CompilerOptions.OPTION_NonNullByDefaultAnnotationName, nonNullByDefaultAnnotName);
					} else {
						if (nullableAnnotName.length() > 0) {
							String nullableList = this.options.get(CompilerOptions.OPTION_NullableAnnotationSecondaryNames);
							nullableList = nullableList.isEmpty() ? nullableAnnotName : nullableList + ',' + nullableAnnotName;
							this.options.put(CompilerOptions.OPTION_NullableAnnotationSecondaryNames, nullableList);
						}
						if (nonNullAnnotName.length() > 0) {
							String nonnullList = this.options.get(CompilerOptions.OPTION_NonNullAnnotationSecondaryNames);
							nonnullList = nonnullList.isEmpty() ? nonNullAnnotName : nonnullList + ',' + nonNullAnnotName;
							this.options.put(CompilerOptions.OPTION_NonNullAnnotationSecondaryNames, nonnullList);
						}
						if (nonNullByDefaultAnnotName.length() > 0) {
							String nnbdList = this.options.get(CompilerOptions.OPTION_NonNullByDefaultAnnotationSecondaryNames);
							nnbdList = nnbdList.isEmpty() ? nonNullByDefaultAnnotName : nnbdList + ',' + nonNullByDefaultAnnotName;
							this.options.put(CompilerOptions.OPTION_NonNullByDefaultAnnotationSecondaryNames, nnbdList);
						}
					}
				}
				this.options.put(
						CompilerOptions.OPTION_AnnotationBasedNullAnalysis,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				setSeverity(CompilerOptions.OPTION_ReportNullSpecViolation, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportNullAnnotationInferenceConflict, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportNullUncheckedConversion, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportRedundantNullAnnotation, severity, isEnabling);
				return;
			} else if (token.equals("nullUncheckedConversion")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNullUncheckedConversion, severity, isEnabling);
				return;
			} else if (token.equals("nonnullNotRepeated")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNonnullParameterAnnotationDropped, severity, isEnabling);
				return;
			}
			
			break;
		case 'o' :
			if (token.equals("over-sync") /*|| token.equals("syncOverride")*/) { //$NON-NLS-1$ 
				setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling);
				return;
			} else if (token.equals("over-ann")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingOverrideAnnotation, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportMissingOverrideAnnotationForInterfaceMethodImplementation,
					CompilerOptions.DISABLED);
				return;
			}
			break;
		case 'p' :
			if (token.equals("pkgDefaultMethod") || token.equals("packageDefaultMethod")/*backward compatible*/ ) { //$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod, severity, isEnabling);
				return;
			} else if (token.equals("paramAssign")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportParameterAssignment, severity, isEnabling);
				return;
			}
			break;
		case 'r' :
			if (token.equals("raw")) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportRawTypeReference, severity, isEnabling);
				return;
			} else if (/*token.equals("intfRedundant") ||*/ token.equals("redundantSuperinterface")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportRedundantSuperinterface, severity, isEnabling);
				return;
			} else if (token.equals("resource")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnclosedCloseable, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, severity, isEnabling);
				return;
			} else if (token.equals("removal")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportTerminalDeprecation, severity, isEnabling);
				this.options.put(
					CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode,
					CompilerOptions.DISABLED);
				this.options.put(
					CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod,
					CompilerOptions.DISABLED);
				return;
			}
			break;
		case 's' :
			if (token.equals("specialParamHiding")) { //$NON-NLS-1$
				this.options.put(
					CompilerOptions.OPTION_ReportSpecialParameterHidingField,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("syntheticAccess") || token.equals("synthetic-access")) { //$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, severity, isEnabling);
				return;
			} else if (token.equals("staticReceiver")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, severity, isEnabling);
				return;
			} else 	if (/*token.equals("over-sync") ||*/ token.equals("syncOverride")) { //$NON-NLS-1$ 
				setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling);
				return;
			} else if (token.equals("semicolon")) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportEmptyStatement, severity, isEnabling);
				return;
			} else if (token.equals("serial")) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingSerialVersion, severity, isEnabling);
				return;
			} else if (token.equals("suppress")) {//$NON-NLS-1$
				switch(severity) {
					case ProblemSeverities.Warning :
						this.options.put(
								CompilerOptions.OPTION_SuppressWarnings,
								isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
						this.options.put(
								CompilerOptions.OPTION_SuppressOptionalErrors,
								CompilerOptions.DISABLED);
						break;
					case ProblemSeverities.Error :
						this.options.put(
								CompilerOptions.OPTION_SuppressWarnings,
								isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
						this.options.put(
							CompilerOptions.OPTION_SuppressOptionalErrors,
							isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				}
				return;
			} else if (token.equals("static-access")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportIndirectStaticAccess, severity, isEnabling);
				return;
			} else if (token.equals("super")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation, severity, isEnabling);
				return;
			} else if (token.equals("static-method")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMethodCanBeStatic, severity, isEnabling);
				return;
			} else if (token.equals("switchDefault")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportMissingDefaultCase, severity, isEnabling);
				return;
			} else if (token.equals("syntacticAnalysis")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_SyntacticNullAnalysisForFields,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			}
			break;
		case 't' :
			if (token.startsWith("tasks")) { //$NON-NLS-1$
				String taskTags = Util.EMPTY_STRING;
				int start = token.indexOf('(');
				int end = token.indexOf(')');
				if (start >= 0 && end >= 0 && start < end){
					taskTags = token.substring(start+1, end).trim();
					taskTags = taskTags.replace('|',',');
				}
				if (taskTags.length() == 0){
					throw new IllegalArgumentException(this.bind("configure.invalidTaskTag", token)); //$NON-NLS-1$
				}
				this.options.put(
					CompilerOptions.OPTION_TaskTags,
					isEnabling ? taskTags : Util.EMPTY_STRING);
				
				setSeverity(CompilerOptions.OPTION_ReportTasks, severity, isEnabling);
				return;
			} else if (token.equals("typeHiding")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportTypeParameterHiding, severity, isEnabling);
				return;
			}
			break;
		case 'u' :
			if (token.equals("unusedLocal") || token.equals("unusedLocals")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling);
				return;
			} else if (token.equals("unusedArgument") || token.equals("unusedArguments")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
				return;
			} else if (token.equals("unusedExceptionParam")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedExceptionParameter, severity, isEnabling);
				return;
			} else if (token.equals("unusedImport") || token.equals("unusedImports")/*backward compatible*/) { //$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
				return;
			} else if (token.equals("unusedAllocation")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedObjectAllocation, severity, isEnabling);
				return;
			} else if (token.equals("unusedPrivate")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling);
				return;
			} else if (token.equals("unusedLabel")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
				return;
			} else if (token.equals("uselessTypeCheck")) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, severity, isEnabling);
				return;
			} else if (token.equals("unchecked") || token.equals("unsafe")) {//$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportUncheckedTypeOperation, severity, isEnabling);
				return;
			} else if (token.equals("unlikelyCollectionMethodArgumentType")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnlikelyCollectionMethodArgumentType, severity, isEnabling);
				return;
			} else if (token.equals("unlikelyEqualsArgumentType")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnlikelyEqualsArgumentType, severity, isEnabling);
				return;
			} else if (token.equals("unnecessaryElse")) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnnecessaryElse, severity, isEnabling);
				return;
			} else if (token.equals("unusedThrown")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
				return;
			} else if (token.equals("unusedThrownWhenOverriding")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("unusedThrownIncludeDocComment")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionIncludeDocCommentReference,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("unusedThrownExemptExceptionThrowable")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("unqualifiedField") || token.equals("unqualified-field-access")) { //$NON-NLS-1$ //$NON-NLS-2$
				setSeverity(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, severity, isEnabling);
				return;
			} else if (token.equals("unused")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedLocal, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportUnusedImport, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportUnusedPrivateMember, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeParameter, severity,isEnabling);
				return;
			} else if (token.equals("unusedParam")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedParameter, severity, isEnabling);
				return;
			} else if (token.equals("unusedTypeParameter")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeParameter, severity, isEnabling);
				return;
			} else if (token.equals("unusedParamIncludeDoc")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("unusedParamOverriding")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_ReportUnusedParameterWhenOverridingConcrete,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			} else if (token.equals("unusedParamImplementing")) { //$NON-NLS-1$
				this.options.put(
						CompilerOptions.OPTION_ReportUnusedParameterWhenImplementingAbstract,
						isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			}  else if (token.equals("unusedTypeArgs")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling);
				return;
			} else if (token.equals("unavoidableGenericProblems")) { //$NON-NLS-1$
				this.options.put(
					CompilerOptions.OPTION_ReportUnavoidableGenericTypeProblems,
					isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
				return;
			}
			break;
		case 'v' :
			if (token.equals("varargsCast")) { //$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportVarargsArgumentNeedCast, severity, isEnabling);
				return;
			}
			break;
		case 'w' :
			if (token.equals("warningToken")) {//$NON-NLS-1$
				setSeverity(CompilerOptions.OPTION_ReportUnhandledWarningToken, severity, isEnabling);
				setSeverity(CompilerOptions.OPTION_ReportUnusedWarningToken, severity, isEnabling);
				return;
			}
			break;
	}
	String message = null;
	switch(severity) {
		case ProblemSeverities.Info:
			message = this.bind("configure.invalidInfo", token); //$NON-NLS-1$
			break;
		case ProblemSeverities.Warning :
			message = this.bind("configure.invalidWarning", token); //$NON-NLS-1$
			break;
		case ProblemSeverities.Error :
			message = this.bind("configure.invalidError", token); //$NON-NLS-1$
	}
	addPendingErrors(message);
}
/**
 * @deprecated - use {@link #initialize(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
 *                       e.g. initialize(outWriter, errWriter, systemExit, null, null)
 */
protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit) {
	this.initialize(outWriter, errWriter, systemExit, null /* options */, null /* progress */);
}
/**
 * @deprecated - use {@link #initialize(PrintWriter, PrintWriter, boolean, Map, CompilationProgress)} instead
 *                       e.g. initialize(outWriter, errWriter, systemExit, customDefaultOptions, null)
 */
protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map<String, String> customDefaultOptions) {
	this.initialize(outWriter, errWriter, systemExit, customDefaultOptions, null /* progress */);
}
protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map<String, String> customDefaultOptions, CompilationProgress compilationProgress) {
	this.logger = new Logger(this, outWriter, errWriter);
	this.proceed = true;
	this.out = outWriter;
	this.err = errWriter;
	this.systemExitWhenFinished = systemExit;
	this.options = new CompilerOptions().getMap();
	this.ignoreOptionalProblemsFromFolders = null;

	this.progress = compilationProgress;
	if (customDefaultOptions != null) {
		this.didSpecifySource = customDefaultOptions.get(CompilerOptions.OPTION_Source) != null;
		this.didSpecifyTarget = customDefaultOptions.get(CompilerOptions.OPTION_TargetPlatform) != null;
		for (Iterator<Map.Entry<String, String>> iter = customDefaultOptions.entrySet().iterator(); iter.hasNext();) {
			Map.Entry<String, String> entry = iter.next();
			this.options.put(entry.getKey(), entry.getValue());
		}
	} else {
		this.didSpecifySource = false;
		this.didSpecifyTarget = false;
	}
	this.classNames = null;
}
protected void initializeAnnotationProcessorManager() {
	String className = "org.eclipse.jdt.internal.compiler.apt.dispatch.BatchAnnotationProcessorManager"; //$NON-NLS-1$
	try {
		Class<?> c = Class.forName(className);
		AbstractAnnotationProcessorManager annotationManager = (AbstractAnnotationProcessorManager) c.newInstance();
		annotationManager.configure(this, this.expandedCommandLine);
		annotationManager.setErr(this.err);
		annotationManager.setOut(this.out);
		this.batchCompiler.annotationProcessorManager = annotationManager;
	} catch (ClassNotFoundException | InstantiationException e) {
		this.logger.logUnavaibleAPT(className);
		throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
	} catch (IllegalAccessException e) {
		// should not happen
		throw new org.eclipse.jdt.internal.compiler.problem.AbortCompilation();
	} catch(UnsupportedClassVersionError e) {
		// report a warning
		this.logger.logIncorrectVMVersionForAnnotationProcessing();
	}
}
private static boolean isParentOf(char[] folderName, char[] fileName) {
	if (folderName.length >= fileName.length) {
		return false;
	}
	if (fileName[folderName.length] != '\\' && fileName[folderName.length] != '/') {
		return false;
	}
	for (int i = folderName.length - 1; i >= 0; i--) {
		if (folderName[i] != fileName[i]) {
			return false;
		}
	}
	return true;
}
// Dump classfiles onto disk for all compilation units that where successful
// and do not carry a -d none spec, either directly or inherited from Main.
public void outputClassFiles(CompilationResult unitResult) {
	if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
		ClassFile[] classFiles = unitResult.getClassFiles();
		String currentDestinationPath = null;
		boolean generateClasspathStructure = false;
		CompilationUnit compilationUnit =
			(CompilationUnit) unitResult.compilationUnit;
		if (compilationUnit.destinationPath == null) {
			if (this.destinationPath == null) {
				currentDestinationPath =
					extractDestinationPathFromSourceFile(unitResult);
			} else if (this.destinationPath != NONE) {
				currentDestinationPath = this.destinationPath;
				generateClasspathStructure = true;
			} // else leave currentDestinationPath null
		} else if (compilationUnit.destinationPath != NONE) {
			currentDestinationPath = compilationUnit.destinationPath;
			generateClasspathStructure = true;
		} // else leave currentDestinationPath null
		if (currentDestinationPath != null) {
			for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) {
				// retrieve the key and the corresponding classfile
				ClassFile classFile = classFiles[i];
				char[] filename = classFile.fileName();
				int length = filename.length;
				char[] relativeName = new char[length + 6];
				System.arraycopy(filename, 0, relativeName, 0, length);
				System.arraycopy(SuffixConstants.SUFFIX_class, 0, relativeName, length, 6);
				CharOperation.replace(relativeName, '/', File.separatorChar);
				String relativeStringName = new String(relativeName);
				try {
					if (this.compilerOptions.verbose)
						this.out.println(
							Messages.bind(
								Messages.compilation_write,
								new String[] {
									String.valueOf(this.exportedClassFilesCounter+1),
									relativeStringName
								}));
					Util.writeToDisk(
						generateClasspathStructure,
						currentDestinationPath,
						relativeStringName,
						classFile);
					this.logger.logClassFile(
						generateClasspathStructure,
						currentDestinationPath,
						relativeStringName);
					this.exportedClassFilesCounter++;
				} catch (IOException e) {
					this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e);
				}
			}
			this.batchCompiler.lookupEnvironment.releaseClassFiles(classFiles);
		}
	}
}
/*
 *  Low-level API performing the actual compilation
 */
public void performCompilation() {
	this.startTime = System.currentTimeMillis();

	FileSystem environment = getLibraryAccess();
	try {
		this.compilerOptions = new CompilerOptions(this.options);
		this.compilerOptions.performMethodsFullRecovery = false;
		this.compilerOptions.performStatementsRecovery = false;
		this.batchCompiler =
				new Compiler(
						environment,
						getHandlingPolicy(),
						this.compilerOptions,
						getBatchRequestor(),
						getProblemFactory(),
						this.out,
						this.progress);
		this.batchCompiler.remainingIterations = this.maxRepetition-this.currentRepetition/*remaining iterations including this one*/;
		// temporary code to allow the compiler to revert to a single thread
		String setting = System.getProperty("jdt.compiler.useSingleThread"); //$NON-NLS-1$
		this.batchCompiler.useSingleThread = setting != null && setting.equals("true"); //$NON-NLS-1$

		if (this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_6
				&& this.compilerOptions.processAnnotations) {
			if (checkVMVersion(ClassFileConstants.JDK1_6)) {
				initializeAnnotationProcessorManager();
				if (this.classNames != null) {
					this.batchCompiler.setBinaryTypes(processClassNames(this.batchCompiler.lookupEnvironment));
				}
			} else {
				// report a warning
				this.logger.logIncorrectVMVersionForAnnotationProcessing();
			}
			if (checkVMVersion(ClassFileConstants.JDK9)) {
				initRootModules(this.batchCompiler.lookupEnvironment, environment);
			}
		}

		// set the non-externally configurable options.
		this.compilerOptions.verbose = this.verbose;
		this.compilerOptions.produceReferenceInfo = this.produceRefInfo;
		try {
			this.logger.startLoggingSources();
			this.batchCompiler.compile(getCompilationUnits());
		} finally {
			this.logger.endLoggingSources();
		}

		if (this.extraProblems != null) {
			loggingExtraProblems();
			this.extraProblems = null;
		}
		if (this.compilerStats != null) {
			this.compilerStats[this.currentRepetition] = this.batchCompiler.stats;
		}
		this.logger.printStats();
	}
	finally {
	// cleanup
		environment.cleanup();
	}
}
protected void loggingExtraProblems() {
	this.logger.loggingExtraProblems(this);
}
public void printUsage() {
	printUsage("misc.usage"); //$NON-NLS-1$
}
private void printUsage(String sectionID) {
	this.logger.logUsage(
		this.bind(
			sectionID,
			new String[] {
				System.getProperty("path.separator"), //$NON-NLS-1$
				this.bind("compiler.name"), //$NON-NLS-1$
				this.bind("compiler.version"), //$NON-NLS-1$
				this.bind("compiler.copyright") //$NON-NLS-1$
			}));
	this.logger.flush();
}
private void initRootModules(LookupEnvironment environment, FileSystem fileSystem) {
	Map<String, String> map = new HashMap<>();
	for (String m : this.rootModules) {
		ModuleBinding mod = environment.getModule(m.toCharArray());
		if (mod == null) {
			throw new IllegalArgumentException(this.bind("configure.invalidModuleName", m)); //$NON-NLS-1$
		}
		PackageBinding[] exports = mod.getExports();
		for (PackageBinding packageBinding : exports) {
			String qName = CharOperation.toString(packageBinding.compoundName);
			String existing = map.get(qName);
			if (existing != null) {
				throw new IllegalArgumentException(this.bind("configure.packageConflict", new String[] {qName, existing, m})); //$NON-NLS-1$
				// report an error and bail out
			}
			map.put(qName, m);
		}
	}
	if (this.limitedModules != null) {
		for (String m : this.limitedModules) {
			ModuleBinding mod = environment.getModule(m.toCharArray());
			if (mod == null) {
				throw new IllegalArgumentException(this.bind("configure.invalidModuleName", m)); //$NON-NLS-1$
			}
		}
	}
}
private ReferenceBinding[] processClassNames(LookupEnvironment environment) {
	// check for .class file presence in case of apt processing
	int length = this.classNames.length;
	ReferenceBinding[] referenceBindings = new ReferenceBinding[length];
	ModuleBinding[] modules = new ModuleBinding[length];
	Set<ModuleBinding> modSet = new HashSet<>();
	String[] typeNames = new String[length];
	if (this.complianceLevel <= ClassFileConstants.JDK1_8) {
		typeNames = this.classNames;
	} else {
		for (int i = 0; i < length; i++) {
			String currentName = this.classNames[i];
			int idx = currentName.indexOf('/');
			ModuleBinding mod = null;
			if (idx > 0) {
				String m = currentName.substring(0, idx);
				mod = environment.getModule(m.toCharArray());
				if (mod == null) {
					throw new IllegalArgumentException(this.bind("configure.invalidModuleName", m)); //$NON-NLS-1$
				}
				modules[i] = mod;
				modSet.add(mod);
				currentName = currentName.substring(idx + 1);
			}
			typeNames[i] = currentName;
		}
		for (ModuleBinding mod : modSet) {
			mod.getExports();
			mod.getRequires();
			mod.getOpens();
			mod.getServices();
		}
	}

	for (int i = 0; i < length; i++) {
		char[][] compoundName = null;
		String cls = typeNames[i];
		if (cls.indexOf('.') != -1) {
			// consider names with '.' as fully qualified names
			char[] typeName = cls.toCharArray();
			compoundName = CharOperation.splitOn('.', typeName);
		} else {
			compoundName = new char[][] { cls.toCharArray() };
		}
		ModuleBinding mod = modules[i];
		ReferenceBinding type = mod != null ? environment.getType(compoundName, mod) : environment.getType(compoundName);
		if (type != null && type.isValidBinding()) {
			if (type.isBinaryBinding()) {
				referenceBindings[i] = type;
				type.superclass();
			}
		} else {
			throw new IllegalArgumentException(
					this.bind("configure.invalidClassName", this.classNames[i]));//$NON-NLS-1$
		}
	}
	return referenceBindings;
}
private ArrayList<String> processModulePathEntries(String arg) {
	ArrayList<String> paths = new ArrayList<>();
	if (arg == null)
		return paths;
	StringTokenizer tokenizer = new StringTokenizer(arg, File.pathSeparator, false);
	while (tokenizer.hasMoreTokens()) {
		paths.add(tokenizer.nextToken());
	}
	return paths;
}
/*
 * External API
 */
public void processPathEntries(final int defaultSize, final ArrayList<FileSystem.Classpath> paths,
			final String currentPath, String customEncoding, boolean isSourceOnly,
			boolean rejectDestinationPathOnJars) {
	String currentClasspathName = null;
	String currentDestinationPath = null;
	ArrayList<String> currentRuleSpecs = new ArrayList<>(defaultSize);
	StringTokenizer tokenizer = new StringTokenizer(currentPath,
			File.pathSeparator + "[]", true); //$NON-NLS-1$
	ArrayList<String> tokens = new ArrayList<>();
	while (tokenizer.hasMoreTokens()) {
		tokens.add(tokenizer.nextToken());
	}
	// state machine
	final int start = 0;
	final int readyToClose = 1;
	// 'path' 'path1[rule];path2'
	final int readyToCloseEndingWithRules = 2;
	// 'path[rule]' 'path1;path2[rule]'
	final int readyToCloseOrOtherEntry = 3;
	// 'path[rule];' 'path;' 'path1;path2;'
	final int rulesNeedAnotherRule = 4;
	// 'path[rule1;'
	final int rulesStart = 5;
	// 'path[' 'path1;path2['
	final int rulesReadyToClose = 6;
	// 'path[rule' 'path[rule1;rule2'
	final int destinationPathReadyToClose = 7;
	// 'path[-d bin'
	final int readyToCloseEndingWithDestinationPath = 8;
	// 'path[-d bin]' 'path[rule][-d bin]'
	final int destinationPathStart = 9;
	// 'path[rule]['
	final int bracketOpened = 10;
	// '.*[.*'
	final int bracketClosed = 11;
	// '.*([.*])+'

	final int error = 99;
	int state = start;
	String token = null;
	int cursor = 0, tokensNb = tokens.size(), bracket = -1;
	while (cursor < tokensNb && state != error) {
		token = tokens.get(cursor++);
		if (token.equals(File.pathSeparator)) {
			switch (state) {
			case start:
			case readyToCloseOrOtherEntry:
			case bracketOpened:
				break;
			case readyToClose:
			case readyToCloseEndingWithRules:
			case readyToCloseEndingWithDestinationPath:
				state = readyToCloseOrOtherEntry;
				addNewEntry(paths, currentClasspathName, currentRuleSpecs,
						customEncoding, currentDestinationPath, isSourceOnly,
						rejectDestinationPathOnJars);
				currentRuleSpecs.clear();
				break;
			case rulesReadyToClose:
				state = rulesNeedAnotherRule;
				break;
			case destinationPathReadyToClose:
				throw new IllegalArgumentException(
					this.bind("configure.incorrectDestinationPathEntry", //$NON-NLS-1$
						currentPath));
			case bracketClosed:
				cursor = bracket + 1;
				state = rulesStart;
				break;
			default:
				state = error;
			}
		} else if (token.equals("[")) { //$NON-NLS-1$
			switch (state) {
			case start:
				currentClasspathName = ""; //$NON-NLS-1$
				//$FALL-THROUGH$
				case readyToClose:
				bracket = cursor - 1;
				//$FALL-THROUGH$
				case bracketClosed:
				state = bracketOpened;
				break;
			case readyToCloseEndingWithRules:
				state = destinationPathStart;
				break;
			case readyToCloseEndingWithDestinationPath:
				state = rulesStart;
				break;
			case bracketOpened:
			default:
				state = error;
			}
		} else if (token.equals("]")) { //$NON-NLS-1$
			switch (state) {
			case rulesReadyToClose:
				state = readyToCloseEndingWithRules;
				break;
			case destinationPathReadyToClose:
				state = readyToCloseEndingWithDestinationPath;
				break;
			case bracketOpened:
				state = bracketClosed;
				break;
			case bracketClosed:
			default:
				state = error;
			}
		} else {
			// regular word
			switch (state) {
			case start:
			case readyToCloseOrOtherEntry:
				state = readyToClose;
				currentClasspathName = token;
				break;
			case rulesStart:
				if (token.startsWith("-d ")) { //$NON-NLS-1$
					if (currentDestinationPath != null) {
						throw new IllegalArgumentException(
								this.bind("configure.duplicateDestinationPathEntry", //$NON-NLS-1$
										currentPath));
					}
					currentDestinationPath = token.substring(3).trim();
					state = destinationPathReadyToClose;
					break;
				} // else we proceed with a rule
				//$FALL-THROUGH$
			case rulesNeedAnotherRule:
				if (currentDestinationPath != null) {
					throw new IllegalArgumentException(
							this.bind("configure.accessRuleAfterDestinationPath", //$NON-NLS-1$
								currentPath));
				}
				state = rulesReadyToClose;
				currentRuleSpecs.add(token);
				break;
			case destinationPathStart:
				if (!token.startsWith("-d ")) { //$NON-NLS-1$
					state = error;
				} else {
					currentDestinationPath = token.substring(3).trim();
					state = destinationPathReadyToClose;
				}
				break;
			case bracketClosed:
				for (int i = bracket; i < cursor ; i++) {
					currentClasspathName += tokens.get(i);
				}
				state = readyToClose;
				break;
			case bracketOpened:
				break;
			default:
				state = error;
			}
		}
		if (state == bracketClosed && cursor == tokensNb) {
			cursor = bracket + 1;
			state = rulesStart;
		}
	}
	switch(state) {
		case readyToCloseOrOtherEntry:
			break;
		case readyToClose:
		case readyToCloseEndingWithRules:
		case readyToCloseEndingWithDestinationPath:
			addNewEntry(paths, currentClasspathName, currentRuleSpecs,
				customEncoding, currentDestinationPath, isSourceOnly,
				rejectDestinationPathOnJars);
			break;
		case bracketOpened:
		case bracketClosed:
		default :
			// we go on anyway
			if (currentPath.length() != 0) {
				addPendingErrors(this.bind("configure.incorrectClasspath", currentPath));//$NON-NLS-1$
			}
	}
}

private int processPaths(String[] args, int index, String currentArg, ArrayList<String> paths) {
	int localIndex = index;
	int count = 0;
	for (int i = 0, max = currentArg.length(); i < max; i++) {
		switch(currentArg.charAt(i)) {
			case '[' :
				count++;
				break;
			case ']' :
				count--;
				break;
		}
	}
	if (count == 0) {
		paths.add(currentArg);
	} else if (count > 1) {
		throw new IllegalArgumentException(
				this.bind("configure.unexpectedBracket", //$NON-NLS-1$
							currentArg));
	} else {
		StringBuffer currentPath = new StringBuffer(currentArg);
		while (true) {
			if (localIndex >= args.length) {
				throw new IllegalArgumentException(
						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
								currentArg));
			}
			localIndex++;
			String nextArg = args[localIndex];
			for (int i = 0, max = nextArg.length(); i < max; i++) {
				switch(nextArg.charAt(i)) {
					case '[' :
						if (count > 1) {
							throw new IllegalArgumentException(
									this.bind("configure.unexpectedBracket", //$NON-NLS-1$
											nextArg));
						}
						count++;
						break;
					case ']' :
						count--;
						break;
				}
			}
			if (count == 0) {
				currentPath.append(' ');
				currentPath.append(nextArg);
				paths.add(currentPath.toString());
				return localIndex - index;
			} else if (count < 0) {
				throw new IllegalArgumentException(
						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
									nextArg));
			} else {
				currentPath.append(' ');
				currentPath.append(nextArg);
			}
		}

	}
	return localIndex - index;
}
private int processPaths(String[] args, int index, String currentArg, String[] paths) {
	int localIndex = index;
	int count = 0;
	for (int i = 0, max = currentArg.length(); i < max; i++) {
		switch(currentArg.charAt(i)) {
			case '[' :
				count++;
				break;
			case ']' :
				count--;
				break;
		}
	}
	if (count == 0) {
		paths[0] = currentArg;
	} else {
		StringBuffer currentPath = new StringBuffer(currentArg);
		while (true) {
			localIndex++;
			if (localIndex >= args.length) {
				throw new IllegalArgumentException(
						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
								currentArg));
			}
			String nextArg = args[localIndex];
			for (int i = 0, max = nextArg.length(); i < max; i++) {
				switch(nextArg.charAt(i)) {
					case '[' :
						if (count > 1) {
							throw new IllegalArgumentException(
									this.bind("configure.unexpectedBracket", //$NON-NLS-1$
											currentArg));
						}
						count++;
						break;
					case ']' :
						count--;
						break;
				}
			}
			if (count == 0) {
				currentPath.append(' ');
				currentPath.append(nextArg);
				paths[0] = currentPath.toString();
				return localIndex - index;
			} else if (count < 0) {
				throw new IllegalArgumentException(
						this.bind("configure.unexpectedBracket", //$NON-NLS-1$
									currentArg));
			} else {
				currentPath.append(' ');
				currentPath.append(nextArg);
			}
		}

	}
	return localIndex - index;
}
/**
 * Creates a NLS catalog for the given locale.
 */
public void relocalize() {
	relocalize(Locale.getDefault());
}

private void relocalize(Locale locale) {
	this.compilerLocale = locale;
	try {
		this.bundle = ResourceBundleFactory.getBundle(locale);
	} catch(MissingResourceException e) {
		System.out.println("Missing resource : " + Main.bundleName.replace('.', '/') + ".properties for locale " + locale); //$NON-NLS-1$//$NON-NLS-2$
		throw e;
	}
}
/*
 * External API
 */
public void setDestinationPath(String dest) {
	this.destinationPath = dest;
}
/*
 * External API
 */
public void setLocale(Locale locale) {
	relocalize(locale);
}
/*
 * External API
 */
protected void setPaths(ArrayList<String> bootclasspaths,
		String sourcepathClasspathArg,
		ArrayList<String> sourcepathClasspaths,
		ArrayList<String> classpaths,
		String modulePath,
		String moduleSourcepath,
		ArrayList<String> extdirsClasspaths,
		ArrayList<String> endorsedDirClasspaths,
		String customEncoding) {

	if (this.complianceLevel == 0) {
		String version = this.options.get(CompilerOptions.OPTION_Compliance);
		this.complianceLevel = CompilerOptions.versionToJdkLevel(version);
	}
	// process bootclasspath, classpath and sourcepaths
	ArrayList<Classpath> allPaths = null;
	long jdkLevel = validateClasspathOptions(bootclasspaths, endorsedDirClasspaths, extdirsClasspaths);

	if (this.releaseVersion != null && this.complianceLevel < jdkLevel) {
		// TODO: Revisit for access rules
		allPaths = new ArrayList<Classpath>();
		allPaths.add(
				FileSystem.getOlderSystemRelease(this.javaHomeCache.getAbsolutePath(), this.releaseVersion, null));
	} else {
		allPaths = handleBootclasspath(bootclasspaths, customEncoding);
	}

	List<FileSystem.Classpath> cp = handleClasspath(classpaths, customEncoding);

	List<FileSystem.Classpath> mp = handleModulepath(modulePath);

	List<FileSystem.Classpath> msp = handleModuleSourcepath(moduleSourcepath);

	ArrayList<FileSystem.Classpath> sourcepaths = new ArrayList<>();
	if (sourcepathClasspathArg != null) {
		processPathEntries(DEFAULT_SIZE_CLASSPATH, sourcepaths,
			sourcepathClasspathArg, customEncoding, true, false);
	}

	/*
	 * Feed endorsedDirClasspath according to:
	 * - -extdirs first if present;
	 * - else java.ext.dirs if defined;
	 * - else default extensions directory for the platform.
	 */
	List<FileSystem.Classpath> extdirs = handleExtdirs(extdirsClasspaths);

	List<FileSystem.Classpath> endorsed = handleEndorseddirs(endorsedDirClasspaths);

	/*
	 * Concatenate classpath entries
	 * We put the bootclasspath at the beginning of the classpath
	 * entries, followed by the extension libraries, followed by
	 * the sourcepath followed by the classpath.  All classpath
	 * entries are searched for both sources and binaries except
	 * the sourcepath entries which are searched for sources only.
	 */
	allPaths.addAll(0, endorsed);
	allPaths.addAll(extdirs);
	allPaths.addAll(sourcepaths);
	allPaths.addAll(cp);
	allPaths.addAll(mp);
	allPaths.addAll(msp);
	allPaths = FileSystem.ClasspathNormalizer.normalize(allPaths);
	this.checkedClasspaths = new FileSystem.Classpath[allPaths.size()];
	allPaths.toArray(this.checkedClasspaths);
	this.logger.logClasspath(this.checkedClasspaths);

	if (this.annotationPaths != null && CompilerOptions.ENABLED.equals(this.options.get(CompilerOptions.OPTION_AnnotationBasedNullAnalysis))) {
		for (FileSystem.Classpath c : this.checkedClasspaths) {
			if (c instanceof ClasspathJar)
				((ClasspathJar) c).annotationPaths = this.annotationPaths;
			else if (c instanceof ClasspathJrt)
				((ClasspathJrt) c).annotationPaths = this.annotationPaths;
		}
	}
}
protected final static boolean shouldIgnoreOptionalProblems(char[][] folderNames, char[] fileName) {
	if (folderNames == null || fileName == null) {
		return false;
	}
	for (int i = 0, max = folderNames.length; i < max; i++) {
		char[] folderName = folderNames[i];
		if (isParentOf(folderName, fileName)) {
			return true;
		}
	}
	return false;
}
protected long validateClasspathOptions(ArrayList<String> bootclasspaths, ArrayList<String> endorsedDirClasspaths, ArrayList<String> extdirsClasspaths) {
	if (this.complianceLevel > ClassFileConstants.JDK1_8) {
		if (bootclasspaths != null && bootclasspaths.size() > 0)
			throw new IllegalArgumentException(
				this.bind("configure.unsupportedOption", "-bootclasspath")); //$NON-NLS-1$ //$NON-NLS-2$
		if (extdirsClasspaths != null && extdirsClasspaths.size() > 0)
			throw new IllegalArgumentException(
				this.bind("configure.unsupportedOption", "-extdirs")); //$NON-NLS-1$ //$NON-NLS-2$
		if (endorsedDirClasspaths != null && endorsedDirClasspaths.size() > 0)
			throw new IllegalArgumentException(
				this.bind("configure.unsupportedOption", "-endorseddirs")); //$NON-NLS-1$ //$NON-NLS-2$
	}
	long jdkLevel = Util.getJDKLevel(getJavaHome());
	if (jdkLevel < ClassFileConstants.JDK9 && this.releaseVersion != null) {
		throw new IllegalArgumentException(
				this.bind("configure.unsupportedReleaseOption")); //$NON-NLS-1$
	}
	return jdkLevel;
}
protected void validateOptions(boolean didSpecifyCompliance) {
	if (didSpecifyCompliance) {
		String version = this.options.get(CompilerOptions.OPTION_Compliance);
		if (this.releaseVersion != null) {
			throw new IllegalArgumentException(
					this.bind("configure.unsupportedWithRelease", version));//$NON-NLS-1$
		}
		if (CompilerOptions.VERSION_1_3.equals(version)) {
			if (!this.didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
		} else if (CompilerOptions.VERSION_1_4.equals(version)) {
			if (this.didSpecifySource) {
				Object source = this.options.get(CompilerOptions.OPTION_Source);
				if (CompilerOptions.VERSION_1_3.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
				} else if (CompilerOptions.VERSION_1_4.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				}
			} else {
				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
			}
		} else if (CompilerOptions.VERSION_1_5.equals(version)) {
			if (this.didSpecifySource) {
				Object source = this.options.get(CompilerOptions.OPTION_Source);
				if (CompilerOptions.VERSION_1_3.equals(source)
						|| CompilerOptions.VERSION_1_4.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				} else if (CompilerOptions.VERSION_1_5.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
				}
			} else {
				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
			}
		} else if (CompilerOptions.VERSION_1_6.equals(version)) {
			if (this.didSpecifySource) {
				Object source = this.options.get(CompilerOptions.OPTION_Source);
				if (CompilerOptions.VERSION_1_3.equals(source)
						|| CompilerOptions.VERSION_1_4.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				} else if (CompilerOptions.VERSION_1_5.equals(source)
						|| CompilerOptions.VERSION_1_6.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
				}
			} else {
				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
			}
		} else if (CompilerOptions.VERSION_1_7.equals(version)) {
			if (this.didSpecifySource) {
				Object source = this.options.get(CompilerOptions.OPTION_Source);
				if (CompilerOptions.VERSION_1_3.equals(source)
						|| CompilerOptions.VERSION_1_4.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				} else if (CompilerOptions.VERSION_1_5.equals(source)
						|| CompilerOptions.VERSION_1_6.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
				} else if (CompilerOptions.VERSION_1_7.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
				}
			} else {
				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
			}
		} else if (CompilerOptions.VERSION_1_8.equals(version)) {
			if (this.didSpecifySource) {
				Object source = this.options.get(CompilerOptions.OPTION_Source);
				if (CompilerOptions.VERSION_1_3.equals(source)
						|| CompilerOptions.VERSION_1_4.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				} else if (CompilerOptions.VERSION_1_5.equals(source)
						|| CompilerOptions.VERSION_1_6.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
				} else if (CompilerOptions.VERSION_1_7.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
				} else if (CompilerOptions.VERSION_1_8.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
				}
			} else {
				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
			}
		} else if (CompilerOptions.VERSION_9.equals(version)) {
			if (this.didSpecifySource) {
				Object source = this.options.get(CompilerOptions.OPTION_Source);
				if (CompilerOptions.VERSION_1_3.equals(source)
						|| CompilerOptions.VERSION_1_4.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				} else if (CompilerOptions.VERSION_1_5.equals(source)
						|| CompilerOptions.VERSION_1_6.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
				} else if (CompilerOptions.VERSION_1_7.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
				} else if (CompilerOptions.VERSION_1_8.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
				} else if (CompilerOptions.VERSION_9.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9);
				}
			} else {
				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9);
				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9);
			}
		} else if (CompilerOptions.VERSION_10.equals(version)) {
			if (this.didSpecifySource) {
				Object source = this.options.get(CompilerOptions.OPTION_Source);
				if (CompilerOptions.VERSION_1_3.equals(source)
						|| CompilerOptions.VERSION_1_4.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				} else if (CompilerOptions.VERSION_1_5.equals(source)
						|| CompilerOptions.VERSION_1_6.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
				} else if (CompilerOptions.VERSION_1_7.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
				} else if (CompilerOptions.VERSION_1_8.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
				} else if (CompilerOptions.VERSION_9.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9);
				} else if (CompilerOptions.VERSION_10.equals(source)) {
					if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
				}
			} else {
				this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10);
				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
			}
		} else {
			if (!this.didSpecifyTarget) {
				if (this.didSpecifySource) {
					String source = this.options.get(CompilerOptions.OPTION_Source);
					if (CompilerOptions.VERSION_1_3.equals(source)
							|| CompilerOptions.VERSION_1_4.equals(source)) {
						if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
					} else if (CompilerOptions.VERSION_1_5.equals(source)
							|| CompilerOptions.VERSION_1_6.equals(source)) {
						this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
					} else {
						if (CompilerOptions.versionToJdkLevel(source) > 0)
							this.options.put(CompilerOptions.OPTION_TargetPlatform, source);
					}
				} else {
					if (CompilerOptions.versionToJdkLevel(version) > 0) {
						this.options.put(CompilerOptions.OPTION_Source, version);
						this.options.put(CompilerOptions.OPTION_TargetPlatform, version);
					}
				}
			}
		}

	} else if (this.didSpecifySource) {
		String version = this.options.get(CompilerOptions.OPTION_Source);
		// default is source 1.3 target 1.2 and compliance 1.4
		if (CompilerOptions.VERSION_1_4.equals(version)) {
			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
		} else if (CompilerOptions.VERSION_1_5.equals(version)) {
			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
		} else if (CompilerOptions.VERSION_1_6.equals(version)) {
			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
		} else if (CompilerOptions.VERSION_1_7.equals(version)) {
			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
		} else if (CompilerOptions.VERSION_1_8.equals(version)) {
			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
		} else if (CompilerOptions.VERSION_9.equals(version)) {
			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9);
			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9);
		} else if (CompilerOptions.VERSION_10.equals(version)) {
			if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10);
			if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
		} else {
			if (CompilerOptions.versionToJdkLevel(version) > 0) {
				if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, version);
				if (!this.didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, version);
			}
		}
	}

	final String sourceVersion = this.options.get(CompilerOptions.OPTION_Source);
	if (this.complianceLevel == 0) {
		final String compliance = this.options.get(CompilerOptions.OPTION_Compliance);
		this.complianceLevel = CompilerOptions.versionToJdkLevel(compliance);
	}
	if (sourceVersion.equals(CompilerOptions.VERSION_10)
			&& this.complianceLevel < ClassFileConstants.JDK10) {
		// compliance must be 10 if source is 10
		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_10)); //$NON-NLS-1$
	} else if (sourceVersion.equals(CompilerOptions.VERSION_9)
			&& this.complianceLevel < ClassFileConstants.JDK9) {
		// compliance must be 9 if source is 9
		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_9)); //$NON-NLS-1$
	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_8)
			&& this.complianceLevel < ClassFileConstants.JDK1_8) {
		// compliance must be 1.8 if source is 1.8
		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_8)); //$NON-NLS-1$
	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_7)
			&& this.complianceLevel < ClassFileConstants.JDK1_7) {
		// compliance must be 1.7 if source is 1.7
		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_7)); //$NON-NLS-1$
	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_6)
			&& this.complianceLevel < ClassFileConstants.JDK1_6) {
		// compliance must be 1.6 if source is 1.6
		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_6)); //$NON-NLS-1$
	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_5)
			&& this.complianceLevel < ClassFileConstants.JDK1_5) {
		// compliance must be 1.5 if source is 1.5
		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
	} else if (sourceVersion.equals(CompilerOptions.VERSION_1_4)
			&& this.complianceLevel < ClassFileConstants.JDK1_4) {
		// compliance must be 1.4 if source is 1.4
		throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
	} else {
		long ver = CompilerOptions.versionToJdkLevel(sourceVersion);
		if(this.complianceLevel < ver)
			throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForSource", this.options.get(CompilerOptions.OPTION_Compliance), sourceVersion)); //$NON-NLS-1$
	}
	if (this.enablePreview && this.complianceLevel != ClassFileConstants.getLatestJDKLevel()) {
		throw new IllegalArgumentException(this.bind("configure.unsupportedPreview")); //$NON-NLS-1$
	}

	// check and set compliance/source/target compatibilities
	if (this.didSpecifyTarget) {
		final String targetVersion = this.options.get(CompilerOptions.OPTION_TargetPlatform);
		// tolerate jsr14 target
		if (CompilerOptions.VERSION_JSR14.equals(targetVersion)) {
			// expecting source >= 1.5
			if (CompilerOptions.versionToJdkLevel(sourceVersion) < ClassFileConstants.JDK1_5) {
				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForGenericSource", targetVersion, sourceVersion)); //$NON-NLS-1$
			}
		} else if (CompilerOptions.VERSION_CLDC1_1.equals(targetVersion)) {
			if (this.didSpecifySource && CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4) {
				throw new IllegalArgumentException(this.bind("configure.incompatibleSourceForCldcTarget", targetVersion, sourceVersion)); //$NON-NLS-1$
			}
			if (this.complianceLevel >= ClassFileConstants.JDK1_5) {
				throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForCldcTarget", targetVersion, sourceVersion)); //$NON-NLS-1$
			}
		} else {
			// target must be 1.8 if source is 1.8
			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_8
					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_8){
				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_8)); //$NON-NLS-1$
			}
			// target must be 1.7 if source is 1.7
			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_7
					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_7){
				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_7)); //$NON-NLS-1$
			}
			// target must be 1.6 if source is 1.6
			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_6
					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_6){
				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_6)); //$NON-NLS-1$
			}
			// target must be 1.5 if source is 1.5
			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_5
					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_5){
				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
			}
			// target must be 1.4 if source is 1.4
			if (CompilerOptions.versionToJdkLevel(sourceVersion) >= ClassFileConstants.JDK1_4
					&& CompilerOptions.versionToJdkLevel(targetVersion) < ClassFileConstants.JDK1_4){
				throw new IllegalArgumentException(this.bind("configure.incompatibleTargetForSource", targetVersion, CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
			}
			// target cannot be greater than compliance level
			if (this.complianceLevel < CompilerOptions.versionToJdkLevel(targetVersion)){
				throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForTarget", this.options.get(CompilerOptions.OPTION_Compliance), targetVersion)); //$NON-NLS-1$
			}
		}
	}
}
}
