package org.eclipse.jdt.internal.compiler.batch;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.StringTokenizer;

import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.core.compiler.IProblem;
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.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.util.CharOperation;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;

public class Main implements ProblemSeverities {

	private boolean noWarn = false;

	PrintWriter out;
	boolean systemExitWhenFinished = true;
	boolean proceedOnError = false;

	boolean verbose = false;
	boolean produceRefInfo = false;
	boolean timer = false;
	boolean showProgress = false;
	public long time = 0;
	long lineCount;
	private boolean generatePackagesStructure;

	Hashtable options;
	String[] filenames;
	String[] encodings;
	String[] classpaths;
	String destinationPath;
	String log;
	int repetitions;
	int globalProblemsCount;
	int globalErrorsCount;
	int globalWarningsCount;
	int exportedClassFilesCounter;

	private static final char[] CLASS_FILE_EXTENSION = ".class".toCharArray(); //$NON-NLS-1$
	private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
	private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$

	/* Bundle containing messages */
	protected static ResourceBundle bundle;
	private final static String bundleName =
		"org.eclipse.jdt.internal.compiler.batch.messages"; 	//$NON-NLS-1$

	static {
		relocalize();
	}

	private boolean proceed = true;

	public Main(PrintWriter writer, boolean systemExitWhenFinished) {

		this.out = writer;
		this.systemExitWhenFinished = systemExitWhenFinished;
		exportedClassFilesCounter = 0;
		options = new Hashtable();
		options.put(
			CompilerOptions.OPTION_LocalVariableAttribute,
			CompilerOptions.DO_NOT_GENERATE);
		options.put(
			CompilerOptions.OPTION_LineNumberAttribute,
			CompilerOptions.DO_NOT_GENERATE);
		options.put(
			CompilerOptions.OPTION_SourceFileAttribute,
			CompilerOptions.DO_NOT_GENERATE);
		options.put(
			CompilerOptions.OPTION_PreserveUnusedLocal,
			CompilerOptions.OPTIMIZE_OUT);
		options.put(
			CompilerOptions.OPTION_ReportUnreachableCode,
			CompilerOptions.ERROR);
		options.put(CompilerOptions.OPTION_ReportInvalidImport, CompilerOptions.ERROR);
		options.put(
			CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod,
			CompilerOptions.WARNING);
		options.put(
			CompilerOptions.OPTION_ReportMethodWithConstructorName,
			CompilerOptions.WARNING);
		options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
		options.put(
			CompilerOptions.OPTION_ReportHiddenCatchBlock,
			CompilerOptions.WARNING);
		options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.IGNORE);
		options.put(
			CompilerOptions.OPTION_ReportUnusedParameter,
			CompilerOptions.IGNORE);
		options.put(
			CompilerOptions.OPTION_ReportSyntheticAccessEmulation,
			CompilerOptions.IGNORE);
		options.put(
			CompilerOptions.OPTION_ReportNonExternalizedStringLiteral,
			CompilerOptions.IGNORE);
		options.put(
			CompilerOptions.OPTION_ReportAssertIdentifier,
			CompilerOptions.IGNORE);
		options.put(
			CompilerOptions.OPTION_Compliance,
			CompilerOptions.VERSION_1_3);
		options.put(
			CompilerOptions.OPTION_Source,
			CompilerOptions.VERSION_1_3);
		options.put(
			CompilerOptions.OPTION_TargetPlatform,
			CompilerOptions.VERSION_1_1);
	}

	/*
	 *  Low-level API performing the actual compilation
	 */
	public boolean compile(String[] argv) {

		// decode command line arguments
		try {
			configure(argv);
			if (proceed) {
				if (showProgress)
					out.print(Main.bind("progress.compiling")); //$NON-NLS-1$
				for (int i = 0; i < repetitions; i++) {
					globalProblemsCount = 0;
					globalErrorsCount = 0;
					globalWarningsCount = 0;
					lineCount = 0;

					if (repetitions > 1) {
						out.flush();
						out.println(
							Main.bind(
								"compile.repetition", //$NON-NLS-1$
								String.valueOf(i + 1),
								String.valueOf(repetitions)));
					}
					long startTime = System.currentTimeMillis();
					// request compilation
					performCompilation();
					if (timer) {

						time = System.currentTimeMillis() - startTime;
						if (lineCount != 0) {
							out.println(
								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 {
							out.println(Main.bind("compile.totalTime", String.valueOf(time))); //$NON-NLS-1$
						}
					}
					if (globalProblemsCount > 0) {
						if (globalProblemsCount == 1) {
							out.print(Main.bind("compile.oneProblem")); //$NON-NLS-1$
						} else {
							out.print(
								Main.bind("compile.severalProblems", String.valueOf(globalProblemsCount))); 	//$NON-NLS-1$
						}
						out.print(" ("); //$NON-NLS-1$
						if (globalErrorsCount > 0) {
							if (globalErrorsCount == 1) {
								out.print(Main.bind("compile.oneError")); //$NON-NLS-1$
							} else {
								out.print(
									Main.bind("compile.severalErrors", String.valueOf(globalErrorsCount))); 	//$NON-NLS-1$
							}
						}
						if (globalWarningsCount > 0) {
							if (globalErrorsCount > 0) {
								out.print(", "); //$NON-NLS-1$
							}
							if (globalWarningsCount == 1) {
								out.print(Main.bind("compile.oneWarning")); //$NON-NLS-1$
							} else {
								out.print(
									Main.bind("compile.severalWarnings", String.valueOf(globalWarningsCount))); 	//$NON-NLS-1$
							}
						}
						out.println(")"); //$NON-NLS-1$
					}
					if (exportedClassFilesCounter != 0
						&& (this.showProgress || this.timer || this.verbose)) {
						if (exportedClassFilesCounter == 1) {
							out.print(Main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$
						} else {
							out.print(
								Main.bind(
									"compile.severalClassFilesGenerated", //$NON-NLS-1$
									String.valueOf(exportedClassFilesCounter)));
						}
					}
				}
				if (showProgress)
					System.out.println();
			}
			if (systemExitWhenFinished) {
				out.flush();
				System.exit(globalErrorsCount > 0 ? -1 : 0);
			}
		} catch (InvalidInputException e) {
			out.println(e.getMessage());
			out.println("------------------------"); //$NON-NLS-1$
			printUsage();
			if (systemExitWhenFinished) {
				System.exit(-1);
			}
		} catch (ThreadDeath e) { // do not stop this one
			throw e;
		} catch (Throwable e) { // internal compiler error
			if (systemExitWhenFinished) {
				out.flush();
				if (this.log != null) {
					out.close();
				}
				System.exit(-1);
			}
			//e.printStackTrace();
		} finally {
			out.flush();
			if (this.log != null) {
				out.close();
			}
		}
		if (globalErrorsCount == 0){
			return true;
		} else {
			return false;
		}
	}

	/*
	 * Internal IDE API
	 */
	public static boolean compile(String commandLine) {

		return compile(commandLine, new PrintWriter(System.out));
	}

	/*
	 * Internal IDE API for test harness purpose
	 */
	public static boolean compile(String commandLine, PrintWriter writer) {

		return new Main(writer, false).compile(tokenize(commandLine));
	}

	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 = "", lastToken; //$NON-NLS-1$
		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()) {
			lastToken = token;
			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) { //$NON-NLS-1$
					if (count == arguments.length)
						System.arraycopy(arguments, 0, (arguments = new String[count * 2]), 0, count);
					arguments[count++] = ""; //$NON-NLS-1$
				}
				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);
						arguments[count++] = token;
					}
				}
				startNewToken = false;
			}
		}
		System.arraycopy(arguments, 0, arguments = new String[count], 0, count);
		return arguments;
	}

	/*
	Decode the command line arguments 
	 */
	private void configure(String[] argv) throws InvalidInputException {
		
		if ((argv == null) || (argv.length == 0))
			throw new InvalidInputException(Main.bind("configure.noSourceFile")); //$NON-NLS-1$
		final int InsideClasspath = 1;
		final int InsideDestinationPath = 2;
		final int TargetSetting = 4;
		final int InsideLog = 8;
		final int InsideRepetition = 16;
		final int InsideSource = 32;
		final int InsideDefaultEncoding = 64;
		final int Default = 0;
		int DEFAULT_SIZE_CLASSPATH = 4;
		boolean warnOptionInUse = false;
		boolean noWarnOptionInUse = false;
		int pathCount = 0;
		int index = -1, filesCount = 0, argCount = argv.length;
		int mode = Default;
		repetitions = 0;
		boolean versionIDRequired = false;
		boolean printUsageRequired = false;

		boolean didSpecifyCompliance = false;
		boolean didSpecifySourceLevel = false;
		boolean didSpecifyDefaultEncoding = false;
		boolean didSpecifyTarget = false;

		String customEncoding = null;
		String currentArg = ""; //$NON-NLS-1$

		while (++index < argCount) {

			if (customEncoding != null) {
				throw new InvalidInputException(
					Main.bind("configure.unexpectedCustomEncoding", currentArg, customEncoding)); //$NON-NLS-1$
			}

			currentArg = argv[index].trim();

			customEncoding = null;
			if (currentArg.endsWith("]")) { //$NON-NLS-1$ 
				// look for encoding specification
				int encodingStart = currentArg.indexOf('[') + 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 InvalidInputException(
								Main.bind("configure.unsupportedEncoding", customEncoding)); //$NON-NLS-1$
						}
					}
					currentArg = currentArg.substring(0, encodingStart - 1);
				}
			}

			if (currentArg.endsWith(".java")) { //$NON-NLS-1$
				if (filenames == null) {
					filenames = new String[argCount - index];
					encodings = new String[argCount - index];
				} else if (filesCount == filenames.length) {
					int length = filenames.length;
					System.arraycopy(
						filenames,
						0,
						(filenames = new String[length + argCount - index]),
						0,
						length);
					System.arraycopy(
						encodings,
						0,
						(encodings = new String[length + argCount - index]),
						0,
						length);
				}
				filenames[filesCount] = currentArg;
				encodings[filesCount++] = customEncoding;
				customEncoding = null;
				mode = Default;
				continue;
			}
			if (currentArg.equals("-log")) { //$NON-NLS-1$
				if (log != null)
					throw new InvalidInputException(
						Main.bind("configure.duplicateLog", currentArg)); //$NON-NLS-1$
				mode = InsideLog;
				continue;
			}
			if (currentArg.equals("-repeat")) { //$NON-NLS-1$
				if (repetitions > 0)
					throw new InvalidInputException(
						Main.bind("configure.duplicateRepeat", currentArg)); //$NON-NLS-1$
				mode = InsideRepetition;
				continue;
			}
			if (currentArg.equals("-source")) { //$NON-NLS-1$
				mode = InsideSource;
				didSpecifySourceLevel = true;
				continue;
			}
			if (currentArg.equals("-encoding")) { //$NON-NLS-1$
				mode = InsideDefaultEncoding;
				continue;
			}
			if (currentArg.equals("-1.3")) { //$NON-NLS-1$
				if (didSpecifyCompliance) {
					throw new InvalidInputException(
						Main.bind("configure.duplicateCompliance", currentArg));//$NON-NLS-1$
				}
				didSpecifyCompliance = true;
				options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3);
				mode = Default;
				continue;
			}
			if (currentArg.equals("-1.4")) { //$NON-NLS-1$
				if (didSpecifyCompliance) {
					throw new InvalidInputException(
						Main.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
				}
				didSpecifyCompliance = true;
				options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
				mode = Default;
				continue;
			}
			if (currentArg.equals("-d")) { //$NON-NLS-1$
				if (destinationPath != null)
					throw new InvalidInputException(
						Main.bind("configure.duplicateOutputPath", currentArg)); //$NON-NLS-1$
				mode = InsideDestinationPath;
				generatePackagesStructure = true;
				continue;
			}
			if (currentArg.equals("-classpath") //$NON-NLS-1$
				|| currentArg.equals("-cp")) { //$NON-NLS-1$ //$NON-NLS-2$
				if (pathCount > 0)
					throw new InvalidInputException(
						Main.bind("configure.duplicateClasspath", currentArg)); //$NON-NLS-1$
				classpaths = new String[DEFAULT_SIZE_CLASSPATH];
				mode = InsideClasspath;
				continue;
			}
			if (currentArg.equals("-progress")) { //$NON-NLS-1$
				mode = Default;
				showProgress = true;
				continue;
			}
			if (currentArg.equals("-proceedOnError")) { //$NON-NLS-1$
				mode = Default;
				proceedOnError = true;
				continue;
			}
			if (currentArg.equals("-time")) { //$NON-NLS-1$
				mode = Default;
				timer = true;
				continue;
			}
			if (currentArg.equals("-version") //$NON-NLS-1$
				|| currentArg.equals("-v")) { //$NON-NLS-1$ //$NON-NLS-2$
				versionIDRequired = true;
				continue;
			}
			if ("-deprecation".equals(currentArg)) { //$NON-NLS-1$
				warnOptionInUse = true;
				if (noWarnOptionInUse)
					throw new InvalidInputException(
						Main.bind("configure.duplicateWarningConfiguration")); //$NON-NLS-1$				
				options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
				continue;
			}
			if (currentArg.equals("-help")) { //$NON-NLS-1$
				printUsageRequired = true;
				continue;
			}
			if (currentArg.equals("-noImportError")) { //$NON-NLS-1$
				mode = Default;
				options.put(
					CompilerOptions.OPTION_ReportInvalidImport,
					CompilerOptions.WARNING);
				continue;
			}
			if (currentArg.equals("-noExit")) { //$NON-NLS-1$
				mode = Default;
				systemExitWhenFinished = false;
				continue;
			}
			if (currentArg.equals("-verbose")) { //$NON-NLS-1$
				mode = Default;
				verbose = true;
				continue;
			}
			if (currentArg.equals("-referenceInfo")) { //$NON-NLS-1$
				mode = Default;
				produceRefInfo = true;
				continue;
			}
			if (currentArg.startsWith("-g")) { //$NON-NLS-1$
				mode = Default;
				String debugOption = currentArg;
				int length = currentArg.length();
				if (length == 2) {
					options.put(
						CompilerOptions.OPTION_LocalVariableAttribute,
						CompilerOptions.GENERATE);
					options.put(
						CompilerOptions.OPTION_LineNumberAttribute,
						CompilerOptions.GENERATE);
					options.put(
						CompilerOptions.OPTION_SourceFileAttribute,
						CompilerOptions.GENERATE);
					continue;
				}
				if (length > 3) {
					options.put(
						CompilerOptions.OPTION_LocalVariableAttribute,
						CompilerOptions.DO_NOT_GENERATE);
					options.put(
						CompilerOptions.OPTION_LineNumberAttribute,
						CompilerOptions.DO_NOT_GENERATE);
					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$
							options.put(
								CompilerOptions.OPTION_LocalVariableAttribute,
								CompilerOptions.GENERATE);
						} else if (token.equals("lines")) { //$NON-NLS-1$
							options.put(
								CompilerOptions.OPTION_LineNumberAttribute,
								CompilerOptions.GENERATE);
						} else if (token.equals("source")) { //$NON-NLS-1$
							options.put(
								CompilerOptions.OPTION_SourceFileAttribute,
								CompilerOptions.GENERATE);
						} else {
							throw new InvalidInputException(
								Main.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
							//$NON-NLS-1$
						}
					}
					continue;
				}
				throw new InvalidInputException(
					Main.bind("configure.invalidDebugOption", debugOption)); //$NON-NLS-1$
			}
			if (currentArg.startsWith("-nowarn")) { //$NON-NLS-1$
				noWarnOptionInUse = true;
				noWarn = true;
				if (warnOptionInUse)
					throw new InvalidInputException(
						Main.bind("configure.duplicateWarningConfiguration")); //$NON-NLS-1$
				mode = Default;
				continue;
			}
			if (currentArg.startsWith("-warn")) { //$NON-NLS-1$
				warnOptionInUse = true;
				if (noWarnOptionInUse)
					throw new InvalidInputException(
						Main.bind("configure.duplicateWarningConfiguration")); //$NON-NLS-1$
				mode = Default;
				String warningOption = currentArg;
				int length = currentArg.length();
				if (length == 10 && warningOption.equals("-warn:none")) { //$NON-NLS-1$
					noWarn = true;
					continue;
				}
				if (length < 6)
					throw new InvalidInputException(
						Main.bind("configure.invalidWarningConfiguration", warningOption)); //$NON-NLS-1$
				StringTokenizer tokenizer =
					new StringTokenizer(warningOption.substring(6, warningOption.length()), ","); //$NON-NLS-1$
				int tokenCounter = 0;

				options.put(
					CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod,
					CompilerOptions.IGNORE);
				options.put(
					CompilerOptions.OPTION_ReportMethodWithConstructorName,
					CompilerOptions.IGNORE);
				options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
				options.put(
					CompilerOptions.OPTION_ReportHiddenCatchBlock,
					CompilerOptions.IGNORE);
				options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.IGNORE);
				options.put(
					CompilerOptions.OPTION_ReportUnusedParameter,
					CompilerOptions.IGNORE);
				options.put(
					CompilerOptions.OPTION_ReportSyntheticAccessEmulation,
					CompilerOptions.IGNORE);
				options.put(
					CompilerOptions.OPTION_ReportNonExternalizedStringLiteral,
					CompilerOptions.IGNORE);
				options.put(
					CompilerOptions.OPTION_ReportAssertIdentifier,
					CompilerOptions.IGNORE);

				while (tokenizer.hasMoreTokens()) {
					String token = tokenizer.nextToken();
					tokenCounter++;
					if (token.equals("constructorName")) { //$NON-NLS-1$
						options.put(
							CompilerOptions.OPTION_ReportMethodWithConstructorName,
							CompilerOptions.WARNING);
					} else if (token.equals("packageDefaultMethod")) { //$NON-NLS-1$
						options.put(
							CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod,
							CompilerOptions.WARNING);
					} else if (token.equals("maskedCatchBlocks")) { //$NON-NLS-1$
						options.put(
							CompilerOptions.OPTION_ReportHiddenCatchBlock,
							CompilerOptions.WARNING);
					} else if (token.equals("deprecation")) { //$NON-NLS-1$
						options.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
					} else if (token.equals("unusedLocals")) { //$NON-NLS-1$
						options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.WARNING);
					} else if (token.equals("unusedArguments")) { //$NON-NLS-1$
						options.put(
							CompilerOptions.OPTION_ReportUnusedParameter,
							CompilerOptions.WARNING);
					} else if (token.equals("syntheticAccess")) { //$NON-NLS-1$
						options.put(
							CompilerOptions.OPTION_ReportSyntheticAccessEmulation,
							CompilerOptions.WARNING);
					} else if (token.equals("nls")) { //$NON-NLS-1$
						options.put(
							CompilerOptions.OPTION_ReportNonExternalizedStringLiteral,
							CompilerOptions.WARNING);
					} else if (token.equals("assertIdentifier")) { //$NON-NLS-1$
						options.put(
							CompilerOptions.OPTION_ReportAssertIdentifier,
							CompilerOptions.WARNING);
					} else {
						throw new InvalidInputException(Main.bind("configure.invalidWarning", token)); //$NON-NLS-1$
					}
				}
				if (tokenCounter == 0)
					throw new InvalidInputException(
						Main.bind("configure.invalidWarningOption", currentArg)); //$NON-NLS-1$
				continue;
			}
			if (currentArg.equals("-target")) { //$NON-NLS-1$
				didSpecifyTarget = true;
				mode = TargetSetting;
				continue;
			}
			if (currentArg.equals("-preserveAllLocals")) { //$NON-NLS-1$
				options.put(
					CompilerOptions.OPTION_PreserveUnusedLocal,
					CompilerOptions.PRESERVE);
				continue;
			}
			if (mode == TargetSetting) {
				if (currentArg.equals("1.1")) { //$NON-NLS-1$
					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
				} else if (currentArg.equals("1.2")) { //$NON-NLS-1$
					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
				} else if (currentArg.equals("1.3")) { //$NON-NLS-1$
					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
				} else if (currentArg.equals("1.4")) { //$NON-NLS-1$
					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
				} else {
					throw new InvalidInputException(Main.bind("configure.targetJDK", currentArg)); //$NON-NLS-1$
				}
				mode = Default;
				continue;
			}
			if (mode == InsideLog) {
				log = currentArg;
				mode = Default;
				continue;
			}
			if (mode == InsideRepetition) {
				try {
					repetitions = Integer.parseInt(currentArg);
					if (repetitions <= 0) {
						throw new InvalidInputException(Main.bind("configure.repetition", currentArg)); //$NON-NLS-1$
					}
				} catch (NumberFormatException e) {
					throw new InvalidInputException(Main.bind("configure.repetition", currentArg)); //$NON-NLS-1$
				}
				mode = Default;
				continue;
			}
			if (mode == InsideSource) {
				if (currentArg.equals("1.3")) { //$NON-NLS-1$
					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
				} else if (currentArg.equals("1.4")) { //$NON-NLS-1$
					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
				} else {
					throw new InvalidInputException(Main.bind("configure.source", currentArg)); //$NON-NLS-1$
				}
				mode = Default;
				continue;
			}
			if (mode == InsideDefaultEncoding) {
				if (didSpecifyDefaultEncoding) {
					throw new InvalidInputException(
						Main.bind("configure.duplicateDefaultEncoding", currentArg)); //$NON-NLS-1$
				}
				try { // ensure encoding is supported
					new InputStreamReader(new ByteArrayInputStream(new byte[0]), currentArg);
				} catch (UnsupportedEncodingException e) {
					throw new InvalidInputException(
						Main.bind("configure.unsupportedEncoding", currentArg)); //$NON-NLS-1$
				}
				options.put(CompilerOptions.OPTION_Encoding, currentArg);
				didSpecifyDefaultEncoding = true;
				mode = Default;
				continue;
			}
			if (mode == InsideDestinationPath) {
				destinationPath = currentArg;
				mode = Default;
				continue;
			}
			if (mode == InsideClasspath) {
				StringTokenizer tokenizer = new StringTokenizer(currentArg, File.pathSeparator);
				while (tokenizer.hasMoreTokens()) {
					int length;
					if ((length = classpaths.length) <= pathCount) {
						System.arraycopy(
							classpaths,
							0,
							(classpaths = new String[length * 2]),
							0,
							length);
					}
					classpaths[pathCount++] = tokenizer.nextToken();
				}
				mode = Default;
				continue;
			}
			//default is input directory
			currentArg = currentArg.replace('/', File.separatorChar);
			if (currentArg.endsWith(File.separator))
				currentArg =
					currentArg.substring(0, currentArg.length() - File.separator.length());
			File dir = new File(currentArg);
			if (!dir.isDirectory())
				throw new InvalidInputException(
					Main.bind("configure.directoryNotExist", currentArg)); //$NON-NLS-1$
			FileFinder finder = new FileFinder();
			try {
				finder.find(dir, ".JAVA", verbose); //$NON-NLS-1$
			} catch (Exception e) {
				throw new InvalidInputException(Main.bind("configure.IOError", currentArg)); //$NON-NLS-1$
			}
			if (filenames != null) {
				// some source files were specified explicitly
				String results[] = finder.resultFiles;
				int length = results.length;
				System.arraycopy(
					filenames,
					0,
					(filenames = new String[length + filesCount]),
					0,
					filesCount);
				System.arraycopy(
					encodings,
					0,
					(encodings = new String[length + filesCount]),
					0,
					filesCount);
				System.arraycopy(results, 0, filenames, filesCount, length);
				for (int i = 0; i < length; i++) {
					encodings[filesCount + i] = customEncoding;
				}
				filesCount += length;
				customEncoding = null;
			} else {
				filenames = finder.resultFiles;
				filesCount = filenames.length;
				encodings = new String[filesCount];
				for (int i = 0; i < filesCount; i++) {
					encodings[i] = customEncoding;
				}
				customEncoding = null;
			}
			mode = Default;
			continue;
		}

		if (noWarn) {
			// filter options which are related to the assist component
			Object[] entries = 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(CompilerOptions.WARNING)) {
					options.put((String) entry.getKey(), CompilerOptions.IGNORE);
				}
			}
		}
		/*
		 * Standalone options
		 */
		if (versionIDRequired) {
			out.println(Main.bind("configure.version", Main.bind("compiler.version"))); //$NON-NLS-1$ //$NON-NLS-2$
			out.println();
			proceed = false;
			return;
		}

		if (printUsageRequired) {
			printUsage();
			proceed = false;
			return;
		}

		if (filesCount != 0)
			System.arraycopy(
				filenames,
				0,
				(filenames = new String[filesCount]),
				0,
				filesCount);
		if (pathCount == 0) {
			String classProp = System.getProperty("DEFAULT_CLASSPATH"); //$NON-NLS-1$
			if ((classProp == null) || (classProp.length() == 0)) {
				out.println(Main.bind("configure.noClasspath")); //$NON-NLS-1$
				classProp = "."; //$NON-NLS-1$
			}
			StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
			classpaths = new String[tokenizer.countTokens()];
			while (tokenizer.hasMoreTokens()) {
				classpaths[pathCount++] = tokenizer.nextToken();
			}
		}

		if (classpaths == null)
			classpaths = new String[0];
		System.arraycopy(
			classpaths,
			0,
			(classpaths = new String[pathCount]),
			0,
			pathCount);
		for (int i = 0, max = classpaths.length; i < max; i++) {
			File file = new File(classpaths[i]);
			if (!file.exists()) // signal missing classpath entry file
				out.println(Main.bind("configure.incorrectClasspath", classpaths[i])); //$NON-NLS-1$
		}
		if (destinationPath == null) {
			generatePackagesStructure = false;
		} else if ("none".equals(destinationPath)) { //$NON-NLS-1$
			destinationPath = null;
		}

		if (filenames == null)
			throw new InvalidInputException(Main.bind("configure.noSource")); //$NON-NLS-1$

		// check and set compliance/source/target compatibilities
		if (!didSpecifyCompliance){
				if (options.get(CompilerOptions.OPTION_Source).equals(CompilerOptions.VERSION_1_4)){
					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
				} else {
					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3);
				}
		}
		String compliance = (String)options.get(CompilerOptions.OPTION_Compliance);
		if (CompilerOptions.VERSION_1_4.equals(compliance)){
			
			// default 1.4 settings
			if (!didSpecifySourceLevel){
				options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
			}
			if (!didSpecifyTarget){
				options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
			}
		} else if (CompilerOptions.VERSION_1_3.equals(compliance)){

			// default 1.4 settings
			if (!didSpecifySourceLevel){
				options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
			}
			if (!didSpecifyTarget){
				options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
			}
		}
		// compliance must be 1.4 if source is 1.4
		if (options.get(CompilerOptions.OPTION_Source).equals(CompilerOptions.VERSION_1_4)
				&& !options.get(CompilerOptions.OPTION_Compliance).equals(CompilerOptions.VERSION_1_4)){ 
				throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForSource14", (String)options.get(CompilerOptions.OPTION_Compliance))); //$NON-NLS-1$
		}
		
		// target must be 1.4 if source is 1.4
		if (options.get(CompilerOptions.OPTION_Source).equals(CompilerOptions.VERSION_1_4)
				&& !options.get(CompilerOptions.OPTION_TargetPlatform).equals(CompilerOptions.VERSION_1_4)){ 
				throw new InvalidInputException(Main.bind("configure.incompatibleTargetForSource14", (String)options.get(CompilerOptions.OPTION_TargetPlatform))); //$NON-NLS-1$
		}

		// target cannot be 1.4 if compliance is 1.3
		if (options.get(CompilerOptions.OPTION_TargetPlatform).equals(CompilerOptions.VERSION_1_4)
				&& !options.get(CompilerOptions.OPTION_Compliance).equals(CompilerOptions.VERSION_1_4)){ 
				throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget14", (String)options.get(CompilerOptions.OPTION_Compliance))); //$NON-NLS-1$
		}
		
		if (log != null) {
			try {
				out = new PrintWriter(new FileOutputStream(log, false));
			} catch (IOException e) {
				throw new InvalidInputException(Main.bind("configure.cannotOpenLog")); //$NON-NLS-1$
			}
		} else {
			showProgress = false;
		}

		if (repetitions == 0) {
			repetitions = 1;
		}
	}
	protected Map getOptions() {
		return this.options;
	}
	/*
	 * Answer the component to which will be handed back compilation results from the compiler
	 */
	protected ICompilerRequestor getBatchRequestor() {
		return new ICompilerRequestor() {
			int lineDelta = 0;
			public void acceptResult(CompilationResult compilationResult) {
				if (compilationResult.lineSeparatorPositions != null) {
					int unitLineCount = compilationResult.lineSeparatorPositions.length;
					lineCount += unitLineCount;
					lineDelta += unitLineCount;
					if (showProgress
						&& lineDelta > 2000) { // in -log mode, dump a dot every 2000 lines compiled
						System.out.print('.');
						lineDelta = 0;
					}
				}
				if (compilationResult.hasProblems()) {
					IProblem[] problems = compilationResult.getProblems();
					int count = problems.length;
					int localErrorCount = 0;
					for (int i = 0; i < count; i++) {
						if (problems[i] != null) {
							globalProblemsCount++;
							if (localErrorCount == 0)
								out.println("----------"); //$NON-NLS-1$
							out.print(
								globalProblemsCount
									+ ". "  //$NON-NLS-1$
									+ (problems[i].isError()
										? Main.bind("requestor.error")  //$NON-NLS-1$
										: Main.bind("requestor.warning")));  //$NON-NLS-1$
							if (problems[i].isError()) {
								globalErrorsCount++;
							} else {
								globalWarningsCount++;
							}
							out.print(" "); //$NON-NLS-1$
							out.print(
								Main.bind("requestor.in", new String(problems[i].getOriginatingFileName()))); //$NON-NLS-1$
							try {
								out.println(
									((DefaultProblem) problems[i]).errorReportSource(
										compilationResult.compilationUnit));
								out.println(problems[i].getMessage());
							} catch (Exception e) {
								out.println(
									Main.bind("requestor.notRetrieveErrorMessage", problems[i].toString())); //$NON-NLS-1$
							}
							out.println("----------"); //$NON-NLS-1$
							if (problems[i].isError())
								localErrorCount++;
						}
					};
					// exit?
					if (systemExitWhenFinished && !proceedOnError && (localErrorCount > 0)) {
						out.flush();
						System.exit(-1);
					}
				}
				outputClassFiles(compilationResult);
			}
		};
	}
	/*
	 *  Build the set of compilation source units
	 */
	protected CompilationUnit[] getCompilationUnits()
		throws InvalidInputException {
		int fileCount = filenames.length;
		CompilationUnit[] units = new CompilationUnit[fileCount];
		HashtableOfObject knownFileNames = new HashtableOfObject(fileCount);

		String defaultEncoding = (String) options.get(CompilerOptions.OPTION_Encoding);
		if ("".equals(defaultEncoding)) //$NON-NLS-1$
			defaultEncoding = null; //$NON-NLS-1$

		for (int i = 0; i < fileCount; i++) {
			char[] charName = filenames[i].toCharArray();
			if (knownFileNames.get(charName) != null) {
				throw new InvalidInputException(Main.bind("unit.more", filenames[i])); //$NON-NLS-1$
			} else {
				knownFileNames.put(charName, charName);
			}
			File file = new File(filenames[i]);
			if (!file.exists())
				throw new InvalidInputException(Main.bind("unit.missing", filenames[i])); //$NON-NLS-1$
			String encoding = encodings[i];
			if (encoding == null)
				encoding = defaultEncoding;
			units[i] = new CompilationUnit(null, filenames[i], encoding);
		}
		return units;
	}
	/*
	 *  Low-level API performing the actual compilation
	 */
	protected 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 stopOnFirstError() {
				return false;
			}
			public boolean proceedOnErrors() {
				return proceedOnError; // stop if there are some errors 
			}
		};
	}
	/*
	 *  Low-level API performing the actual compilation
	 */
	protected FileSystem getLibraryAccess() {

		String defaultEncoding = (String) options.get(CompilerOptions.OPTION_Encoding);
		if ("".equals(defaultEncoding)) //$NON-NLS-1$
			defaultEncoding = null; //$NON-NLS-1$	
		return new FileSystem(classpaths, filenames, defaultEncoding);
	}
	/*
	 *  Low-level API performing the actual compilation
	 */
	protected IProblemFactory getProblemFactory() {
		return new DefaultProblemFactory(Locale.getDefault());
	}
	/*
	 * External API
	 */

	public static void main(String[] argv) {
		new Main(new PrintWriter(System.out), true).compile(argv);
	}
	// Dump classfiles onto disk for all compilation units that where successfull.

	protected void outputClassFiles(CompilationResult unitResult) {

		if (!((unitResult == null) || (unitResult.hasErrors() && !proceedOnError))) {
			Enumeration classFiles = unitResult.compiledTypes.elements();
			if (!this.generatePackagesStructure) {
				while (classFiles.hasMoreElements()) {
					this.destinationPath = extractDestinationPathFromSourceFile(unitResult);
					// retrieve the key and the corresponding classfile
					ClassFile classFile = (ClassFile) classFiles.nextElement();
					char[] filename = classFile.fileName();
					int length = filename.length;
					char[] relativeName = new char[length + 6];
					System.arraycopy(filename, 0, relativeName, 0, length);
					System.arraycopy(CLASS_FILE_EXTENSION, 0, relativeName, length, 6);
					CharOperation.replace(relativeName, '/', File.separatorChar);
					try {
						ClassFile.writeToDisk(
							generatePackagesStructure,
							destinationPath,
							new String(relativeName),
							classFile.getBytes());
					} catch (IOException e) {
						String fileName = destinationPath + new String(relativeName);
						e.printStackTrace();
						System.out.println(Main.bind("output.noClassFileCreated", fileName));  //$NON-NLS-1$
					}
					exportedClassFilesCounter++;
				}
			} else if (destinationPath != null) {
				while (classFiles.hasMoreElements()) {
					// retrieve the key and the corresponding classfile
					ClassFile classFile = (ClassFile) classFiles.nextElement();
					char[] filename = classFile.fileName();
					int length = filename.length;
					char[] relativeName = new char[length + 6];
					System.arraycopy(filename, 0, relativeName, 0, length);
					System.arraycopy(CLASS_FILE_EXTENSION, 0, relativeName, length, 6);
					CharOperation.replace(relativeName, '/', File.separatorChar);
					try {
						ClassFile.writeToDisk(
							generatePackagesStructure,
							destinationPath,
							new String(relativeName),
							classFile.getBytes());
					} catch (IOException e) {
						String fileName = destinationPath + new String(relativeName);
						e.printStackTrace();
						System.out.println(Main.bind("output.noClassFileCreated", fileName)); //$NON-NLS-1$
					}
					exportedClassFilesCounter++;
				}
			}
		}
	}
	/*
	 *  Low-level API performing the actual compilation
	 */
	protected void performCompilation() throws InvalidInputException {

		INameEnvironment environment = getLibraryAccess();
		Compiler batchCompiler =
			new Compiler(
				environment,
				getHandlingPolicy(),
				getOptions(),
				getBatchRequestor(),
				getProblemFactory());
		CompilerOptions options = batchCompiler.options;

		// set the non-externally configurable options.
		options.setVerboseMode(verbose);
		options.produceReferenceInfo(produceRefInfo);
		batchCompiler.compile(getCompilationUnits());

		// cleanup
		environment.cleanup();
	}
	private void printUsage() {
		out.println(Main.bind("misc.usage", Main.bind("compiler.version"))); //$NON-NLS-1$ //$NON-NLS-2$
		out.flush();
	}

	/**
	 * Creates a NLS catalog for the given locale.
	 */
	public static void relocalize() {
		bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
	}

	/**
	 * Lookup the message with the given ID in this catalog 
	 */
	public static 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 values.
	 */
	public static String bind(String id, String[] bindings) {
		if (id == null)
			return "No message available"; //$NON-NLS-1$
		String message = null;
		try {
			message = 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: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
		}
		// for compatibility with MessageFormat which eliminates double quotes in original message
		char[] messageWithNoDoubleQuotes =
			CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
		message = new String(messageWithNoDoubleQuotes);

		if (bindings == null)
			return message;

		int length = message.length();
		int start = -1;
		int end = length;
		StringBuffer output = new StringBuffer(80);
		while (true) {
			if ((end = message.indexOf('{', start)) > -1) {
				output.append(message.substring(start + 1, end));
				if ((start = message.indexOf('}', end)) > -1) {
					int index = -1;
					try {
						index = Integer.parseInt(message.substring(end + 1, start));
						output.append(bindings[index]);
					} catch (NumberFormatException nfe) {
						output.append(message.substring(end + 1, start + 1));
					} catch (ArrayIndexOutOfBoundsException e) {
						output.append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$
					}
				} else {
					output.append(message.substring(end, length));
					break;
				}
			} else {
				output.append(message.substring(start + 1, length));
				break;
			}
		}
		return output.toString();
	}

	/**
	 * Lookup the message with the given ID in this catalog and bind its
	 * substitution locations with the given string.
	 */
	public static String bind(String id, String binding) {
		return bind(id, new String[] { binding });
	}

	/**
	 * Lookup the message with the given ID in this catalog and bind its
	 * substitution locations with the given strings.
	 */
	public static String bind(String id, String binding1, String binding2) {
		return bind(id, new String[] { binding1, binding2 });
	}

	private 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) {
				return System.getProperty("user.dir"); //$NON-NLS-1$
			}
			return new String(CharOperation.subarray(fileName, 0, lastIndex));
		}
		return System.getProperty("user.dir"); //$NON-NLS-1$
	}

}