/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     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.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.text.DateFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
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.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.batch.FileSystem.Classpath;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
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.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.ReferenceBinding;
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;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class Main implements ProblemSeverities, SuffixConstants {

	public static class Logger {
		private PrintWriter err;
		private PrintWriter log;
		private Main main;
		private PrintWriter out;
		private HashMap 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 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$
		public static final int XML = 1;
		private static final String XML_DTD_DECLARATION = "<!DOCTYPE compiler PUBLIC \"-//Eclipse.org//DTD Eclipse JDT 3.2.004 Compiler//EN\" \"http://www.eclipse.org/jdt/core/compiler_32_004.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()) {
							if (Util.isPotentialZipArchive(classpath)) {
								id = Logger.CLASSPATH_JAR;
							} else {
								id = Logger.CLASSPATH_FILE;
							}
						} 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
				if (problem.isError()) {
					printErr(this.main.bind(
								"requestor.extraerror", //$NON-NLS-1$
								Integer.toString(globalErrorCount)));
				} else {
					// warning / mandatory warning / other
					printErr(this.main.bind(
							"requestor.extrawarning", //$NON-NLS-1$
							Integer.toString(globalErrorCount)));
				}
				printErr(" "); //$NON-NLS-1$
				this.printlnErr(problem.getMessage());
			} else {
				String fileName = new String(originatingFileName);
				if ((this.tagBits & Logger.EMACS) != 0) {
					String result = fileName
							+ ":" //$NON-NLS-1$
							+ problem.getSourceLineNumber()
							+ ": " //$NON-NLS-1$
							+ (problem.isError() ? this.main.bind("output.emacs.error") : this.main.bind("output.emacs.warning")) //$NON-NLS-1$ //$NON-NLS-2$
							+ ": " //$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$
					}
					printErr(problem.isError() ?
							this.main.bind(
									"requestor.error", //$NON-NLS-1$
									Integer.toString(globalErrorCount),
									new String(fileName))
									: this.main.bind(
											"requestor.warning", //$NON-NLS-1$
											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 problems = currentMain.extraProblems;
			final int count = problems.size();
			int localProblemCount = 0;
			if (count != 0) {
				int errors = 0;
				int warnings = 0;
				for (int i = 0; i < count; i++) {
					CategorizedProblem problem = (CategorizedProblem) problems.get(i);
					if (problem != null) {
						currentMain.globalProblemsCount++;
						logExtraProblem(problem, localProblemCount, currentMain.globalProblemsCount);
						localProblemCount++;
						if (problem.isError()) {
							errors++;
							currentMain.globalErrorsCount++;
						} else if (problem.isWarning()) {
							currentMain.globalWarningsCount++;
							warnings++;
						}
					}
				}
				if ((this.tagBits & Logger.XML) != 0) {
					if ((errors + warnings) != 0) {
						startLoggingExtraProblems(count);
						for (int i = 0; i < count; i++) {
							CategorizedProblem problem = (CategorizedProblem) 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>>() {
					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 result = (new String(problem.getOriginatingFileName())
						+ ":" //$NON-NLS-1$
						+ problem.getSourceLineNumber()
						+ ": " //$NON-NLS-1$
						+ (problem.isError() ? this.main.bind("output.emacs.error") : this.main.bind("output.emacs.warning")) //$NON-NLS-1$ //$NON-NLS-2$
						+ ": " //$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$
				}
				printErr(problem.isError() ?
						this.main.bind(
								"requestor.error", //$NON-NLS-1$
								Integer.toString(globalErrorCount),
								new String(problem.getOriginatingFileName()))
								: this.main.bind(
										"requestor.warning", //$NON-NLS-1$
										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 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 {
							currentMain.globalWarningsCount++;
							warnings++;
						}
					}
				}
				if ((this.tagBits & Logger.XML) != 0) {
					if ((errors + warnings) != 0) {
						startLoggingProblems(errors, warnings);
						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 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_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 {
					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;
				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 (errorMessage == null || warningMessage == null) {
					if (errorMessage == null) {
						printErr(this.main.bind(
							"compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
							String.valueOf(globalProblemsCount),
							warningMessage));
					} else {
						printErr(this.main.bind(
							"compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
							String.valueOf(globalProblemsCount),
							errorMessage));
					}
				} else {
					printErr(this.main.bind(
						"compile.severalProblemsErrorsAndWarnings", //$NON-NLS-1$
						new String[] {
							String.valueOf(globalProblemsCount),
							errorMessage,
							warningMessage
						}));
				}
			}
			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) {
			// New AspectJ Extension
			// old code:
			/*
			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();
			}
			*/
			// new code:
			if (printToOut) 	this.main.printVersion();
			// End AspectJ Extension
		}

		/**
		 * 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 : 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 : 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.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 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) {
			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));
			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 Cache = new HashMap();
		public static synchronized ResourceBundle getBundle(Locale locale) {
			ResourceBundle bundle = (ResourceBundle) 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;
	// paths to external annotations:
	protected List<String> annotationPaths;
	protected boolean annotationsFromClasspath;

	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.
	private boolean didSpecifySource;
	private boolean didSpecifyTarget;
	public String[] encodings;
	public int exportedClassFilesCounter;
	public String[] filenames;
	public String[] classNames;
	// overrides of destinationPath on a directory argument basis
	public int globalErrorsCount;
	public int globalProblemsCount;
	public int globalTasksCount;
	public int globalWarningsCount;

	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;
	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 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 extraProblems;
	// AspectJ Extension - made non final
	public 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() {
		public boolean accept(File dir, String name) {
			return Util.isPotentialZipArchive(name);
		}
	};
	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 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();
}
// New AspectJ Extension
public void printVersion() {
}
// End AspectJ Extension

public void addExtraProblems(CategorizedProblem problem) {
	if (this.extraProblems == null) {
		this.extraProblems = new ArrayList();
	}
	this.extraProblems.add(problem);
}
protected void addNewEntry(ArrayList paths, String currentClasspathName,
		ArrayList 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 i = currentRuleSpecs.iterator();
		int j = 0;
		while (i.hasNext()) {
			String ruleSpec = (String) 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.isPotentialZipArchive(currentClasspathName)) {
		throw new IllegalArgumentException(
			this.bind("configure.unexpectedDestinationPathEntryFile", //$NON-NLS-1$
						currentClasspathName));
	}
	FileSystem.Classpath currentClasspath = FileSystem.getClasspath(
			currentClasspathName,
			customEncoding,
			isSourceOnly,
			accessRuleSet,
			destPath, this.options);
	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 });
}
//AspectJ Extension - static form of bind that just uses the default locale
public static String _bind(String id,String []arguments) {
	if (id==null) return "No message available"; //$NON-NLS-1$
	String message = null;
	try {
	  message = ResourceBundleFactory.getBundle(Locale.getDefault()).getString(id);
	} catch (MissingResourceException mre) {
		// 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, arguments);
}
//End AspectJ Extension

/*
 * 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_7</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;
	}
	switch(majorVersion) {
		case ClassFileConstants.MAJOR_VERSION_1_1 : // 1.0 and 1.1
			return ClassFileConstants.JDK1_1 >= minimalSupportedVersion;
		case ClassFileConstants.MAJOR_VERSION_1_2 : // 1.2
			return ClassFileConstants.JDK1_2 >= minimalSupportedVersion;
		case ClassFileConstants.MAJOR_VERSION_1_3 : // 1.3
			return ClassFileConstants.JDK1_3 >= minimalSupportedVersion;
		case ClassFileConstants.MAJOR_VERSION_1_4 : // 1.4
			return ClassFileConstants.JDK1_4 >= minimalSupportedVersion;
		case ClassFileConstants.MAJOR_VERSION_1_5 : // 1.5
			return ClassFileConstants.JDK1_5 >= minimalSupportedVersion;
		case ClassFileConstants.MAJOR_VERSION_1_6 : // 1.6
			return ClassFileConstants.JDK1_6 >= minimalSupportedVersion;
		case ClassFileConstants.MAJOR_VERSION_1_7 : // 1.7
			return ClassFileConstants.JDK1_7 >= minimalSupportedVersion;
		case ClassFileConstants.MAJOR_VERSION_1_8: // 1.8
			return ClassFileConstants.JDK1_8 >= minimalSupportedVersion;
	}
	// unknown version
	return false;
}
/*
 *  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.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 (RuntimeException 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 DEFAULT = 0;
	ArrayList bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
	String sourcepathClasspathArg = null;
	ArrayList sourcepathClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
	ArrayList classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
	ArrayList extdirsClasspaths = null;
	ArrayList 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;
	
	Set 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 (this.filenames == null) {
						this.filenames = new String[argCount - index];
						this.encodings = 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);
					}
					this.filenames[filesCount] = currentArg;
					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("-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("-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("-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$
					}
					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("-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("-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$
				}
				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("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_SOURCE :
				if (this.didSpecifySource) {
					throw new IllegalArgumentException(
						this.bind("configure.duplicateSource", currentArg));//$NON-NLS-1$
				}
				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 {
					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_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$
				}
				StringTokenizer 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_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
		// AspectJ Extension 
		// see pr 60863.  All directories should have been dealt with at the AspectJ layer - if we have left
		// anything to be processed here it is an error.
		throw new IllegalArgumentException("unrecognized single argument: \""+currentArg+"\"");
/*
		// 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(result, 0, this.filenames, filesCount, length);
			for (int i = 0; i < length; i++) {
				this.encodings[filesCount + i] = customEncoding;
				this.destinationPaths[filesCount + i] = customDestinationPath;
			}
			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];
			for (int i = 0; i < filesCount; i++) {
				this.encodings[i] = customEncoding;
				this.destinationPaths[i] = customDestinationPath;
			}
			customEncoding = null;
			customDestinationPath = null;
			currentSourceDirectory = null;
		}
		// MERGECONFLICT!!
		throw new IllegalStateException(
			    "unrecognized single argument: \""+currentArg+"\"");
//		mode = DEFAULT;
//		continue;
 * */
 
	}

	// 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);
	}
//	// AspectJ Extension
//    // old code:
//    // if (printUsageRequired || (filesCount == 0 && classCount == 0)) {
//    // new code:
//	if (printUsageRequired || hasNoFiles(filesCount)) { // AspectJ Extension
//    // End AspectJ Extension
//			printUsage();
//		if (usageSection ==  null) {
//			printUsage(); // default
//		} else {
//			printUsage(usageSection);
//		}
//		this.proceed = false;
//		return;
//	}
//	// AspectJ Extension
//    // old code:
//    // if (printUsageRequired || (filesCount == 0 && classCount == 0)) {
//    // new code:
//	if (printUsageRequired || hasNoFiles(filesCount)) { // AspectJ Extension
//    // End AspectJ Extension
		
	if (printUsageRequired) { // AspectJ Extension remove trailing condition || (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,
			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 iterator = this.pendingErrors.iterator(); iterator.hasNext(); ) {
			String message = (String) iterator.next();
			this.logger.logPendingError(message);
		}
		this.pendingErrors = null;
	}
}

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 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);
}

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;
	}
	Object[] entries = this.options.entrySet().toArray();
	for (int i = 0, max = entries.length; i < max; i++) {
		Map.Entry entry = (Map.Entry) entries[i];
		if (!(entry.getKey() instanceof String))
			continue;
		if (!(entry.getValue() instanceof String))
			continue;
		if (((String) entry.getValue()).equals(checkedValue)) {
			this.options.put((String) entry.getKey(), CompilerOptions.IGNORE);
		}
	}
}
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 i = 0; i < fileCount; i++) {
		char[] charName = this.filenames[i].toCharArray();
		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()));
	}
	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() {
		public boolean proceedOnErrors() {
			return Main.this.proceedOnError; // stop if there are some errors
		}
		public boolean stopOnFirstError() {
			return false;
		}
		public boolean ignoreAllErrors() {
			return false;
		}
	};
}

/*
 * External API
 */
public File getJavaHome() {
	if (!this.javaHomeChecked) {
		this.javaHomeChecked = true;
		this.javaHomeCache = Util.getJavaHome();
	}
	return this.javaHomeCache;
}

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

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

/*
 * External API
 */
protected ArrayList handleBootclasspath(ArrayList bootclasspaths, String customEncoding) {
 	final int bootclasspathsSize;
	if ((bootclasspaths != null)
		&& ((bootclasspathsSize = bootclasspaths.size()) != 0))
	{
		String[] paths = new String[bootclasspathsSize];
		bootclasspaths.toArray(paths);
		bootclasspaths.clear();
		for (int i = 0; i < bootclasspathsSize; i++) {
			processPathEntries(DEFAULT_SIZE_CLASSPATH, bootclasspaths,
				paths[i], customEncoding, false, true);
		}
	} else {
		bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
		try {
			Util.collectRunningVMBootclasspath(bootclasspaths);
		} catch(IllegalStateException e) {
			this.logger.logWrongJDK();
			this.proceed = false;
			return null;
		}
	}
	return bootclasspaths;
}

/*
 * External API
 */
protected ArrayList handleClasspath(ArrayList classpaths, String customEncoding) {
	final int classpathsSize;
	if ((classpaths != null)
		&& ((classpathsSize = classpaths.size()) != 0))
	{
		String[] paths = new String[classpathsSize];
		classpaths.toArray(paths);
		classpaths.clear();
		for (int i = 0; i < classpathsSize; i++) {
			processPathEntries(DEFAULT_SIZE_CLASSPATH, classpaths, paths[i],
					customEncoding, false, true);
		}
	} else {
		// no user classpath specified.
		classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
		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);//$NON-NLS-1$
			if (classpath != null) {
				classpaths.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);
				if (currentClasspath != null) {
					classpaths.add(currentClasspath);
				} else if (token.length() != 0) {
					addPendingErrors(this.bind("configure.incorrectClasspath", token));//$NON-NLS-1$
				}
			}
		}
	}
	ArrayList result = new ArrayList();
	HashMap knownNames = new HashMap();
	FileSystem.ClasspathSectionProblemReporter problemReporter =
		new FileSystem.ClasspathSectionProblemReporter() {
			public void invalidClasspathSection(String jarFilePath) {
				addPendingErrors(bind("configure.invalidClasspathSection", jarFilePath)); //$NON-NLS-1$
			}
			public void multipleClasspathSections(String jarFilePath) {
				addPendingErrors(bind("configure.multipleClasspathSections", jarFilePath)); //$NON-NLS-1$
			}
		};
	while (! classpaths.isEmpty()) {
		Classpath current = (Classpath) classpaths.remove(0);
		String currentPath = current.getPath();
		if (knownNames.get(currentPath) == null) {
			knownNames.put(currentPath, current);
			result.add(current);
			List linkedJars = current.fetchLinkedJars(problemReporter);
			if (linkedJars != null) {
				classpaths.addAll(0, linkedJars);
			}
		}
	}
	return result;
}
/*
 * External API
 */
protected ArrayList handleEndorseddirs(ArrayList 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) {
		File[] directoriesToCheck = new File[endorsedDirClasspaths.size()];
		for (int i = 0; i < directoriesToCheck.length; i++)
			directoriesToCheck[i] = new File((String) endorsedDirClasspaths.get(i));
		endorsedDirClasspaths.clear();
		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);
						if (classpath != null) {
							endorsedDirClasspaths.add(classpath);
						}
					}
				} else if (directoriesToCheck[i].isFile()) {
					addPendingErrors(
						this.bind(
							"configure.incorrectEndorsedDirsEntry", //$NON-NLS-1$
							directoriesToCheck[i].getAbsolutePath()));
				}
			}
		}
	}
	return endorsedDirClasspaths;
}

/*
 * External API
 * Handle extdirs processing
 */
protected ArrayList handleExtdirs(ArrayList 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) {
		File[] directoriesToCheck = new File[extdirsClasspaths.size()];
		for (int i = 0; i < directoriesToCheck.length; i++)
			directoriesToCheck[i] = new File((String) extdirsClasspaths.get(i));
		extdirsClasspaths.clear();
		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);
						if (classpath != null) {
							extdirsClasspaths.add(classpath);
						}
					}
				} else if (directoriesToCheck[i].isFile()) {
					addPendingErrors(this.bind(
							"configure.incorrectExtDirsEntry", //$NON-NLS-1$
							directoriesToCheck[i].getAbsolutePath()));
				}
			}
		}
	}

	return extdirsClasspaths;
}

/*
 * External API
 * Handle a single warning token.
*/
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;
			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;
			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);
				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;
			}
			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$
				}
			}
			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;
			}
			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("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.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 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();
	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();
		}
	}

	// 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();

	// 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 ReferenceBinding[] processClassNames(LookupEnvironment environment) {
	// check for .class file presence in case of apt processing
	int length = this.classNames.length;
	ReferenceBinding[] referenceBindings = new ReferenceBinding[length];
	for (int i = 0; i < length; i++) {
		String currentName = this.classNames[i];
		char[][] compoundName = null;
		if (currentName.indexOf('.') != -1) {
			// consider names with '.' as fully qualified names
			char[] typeName = currentName.toCharArray();
			compoundName = CharOperation.splitOn('.', typeName);
		} else {
			compoundName = new char[][] { currentName.toCharArray() };
		}
		ReferenceBinding type = environment.getType(compoundName);
		if (type != null && type.isValidBinding()) {
			if (type.isBinaryBinding()) {
				referenceBindings[i] = type;
			}
		} else {
			throw new IllegalArgumentException(
					this.bind("configure.invalidClassName", currentName));//$NON-NLS-1$
		}
	}
	return referenceBindings;
}
/*
 * External API
 */
public void processPathEntries(final int defaultSize, final ArrayList paths,
			final String currentPath, String customEncoding, boolean isSourceOnly,
			boolean rejectDestinationPathOnJars) {
	String currentClasspathName = null;
	String currentDestinationPath = null;
	ArrayList currentRuleSpecs = new ArrayList(defaultSize);
	StringTokenizer tokenizer = new StringTokenizer(currentPath,
			File.pathSeparator + "[]", true); //$NON-NLS-1$
	ArrayList 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 = (String) 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 += (String) 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 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;
}

// AspectJ Extension
// For AspectJ we handle files in a separate arg parser, in the future make this a protected method for extension
private boolean hasNoFiles(int filesCount) {
	return false;
}
// End AspectJ Extension
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 bootclasspaths,
		String sourcepathClasspathArg,
		ArrayList sourcepathClasspaths,
		ArrayList classpaths,
		ArrayList extdirsClasspaths,
		ArrayList endorsedDirClasspaths,
		String customEncoding) {

	// process bootclasspath, classpath and sourcepaths
 	bootclasspaths = handleBootclasspath(bootclasspaths, customEncoding);

	classpaths = handleClasspath(classpaths, customEncoding);

	if (sourcepathClasspathArg != null) {
		processPathEntries(DEFAULT_SIZE_CLASSPATH, sourcepathClasspaths,
			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.
	 */
	extdirsClasspaths = handleExtdirs(extdirsClasspaths);

	endorsedDirClasspaths = 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.
	 */
	bootclasspaths.addAll(0, endorsedDirClasspaths);
	bootclasspaths.addAll(extdirsClasspaths);
	bootclasspaths.addAll(sourcepathClasspaths);
	bootclasspaths.addAll(classpaths);
	classpaths = bootclasspaths;
	classpaths = FileSystem.ClasspathNormalizer.normalize(classpaths);
	this.checkedClasspaths = new FileSystem.Classpath[classpaths.size()];
	classpaths.toArray(this.checkedClasspaths);
	this.logger.logClasspath(this.checkedClasspaths);

	if (this.annotationPaths != null && CompilerOptions.ENABLED.equals(this.options.get(CompilerOptions.OPTION_AnnotationBasedNullAnalysis))) {
		for (FileSystem.Classpath cp : this.checkedClasspaths) {
			if (cp instanceof ClasspathJar)
				((ClasspathJar) cp).annotationPaths = this.annotationPaths;
		}
	}
}
private 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 void validateOptions(boolean didSpecifyCompliance) {
	if (didSpecifyCompliance) {
		Object version = this.options.get(CompilerOptions.OPTION_Compliance);
		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 (this.didSpecifySource) {
		Object 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);
		}
	}

	final String sourceVersion = this.options.get(CompilerOptions.OPTION_Source);
	final String compliance = this.options.get(CompilerOptions.OPTION_Compliance);
	if (sourceVersion.equals(CompilerOptions.VERSION_1_8)
			&& CompilerOptions.versionToJdkLevel(compliance) < 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)
			&& CompilerOptions.versionToJdkLevel(compliance) < 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)
			&& CompilerOptions.versionToJdkLevel(compliance) < 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)
			&& CompilerOptions.versionToJdkLevel(compliance) < 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)
			&& CompilerOptions.versionToJdkLevel(compliance) < 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$
	}

	// 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 (CompilerOptions.versionToJdkLevel(compliance) >= 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 (CompilerOptions.versionToJdkLevel(compliance) < CompilerOptions.versionToJdkLevel(targetVersion)){
				throw new IllegalArgumentException(this.bind("configure.incompatibleComplianceForTarget", this.options.get(CompilerOptions.OPTION_Compliance), targetVersion)); //$NON-NLS-1$
			}
		}
	}
}
}
