package org.eclipse.jdt.internal.compiler.batch;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.jdt.internal.compiler.Compiler;

import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.env.*;

import org.eclipse.jdt.internal.compiler.codegen.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.*;
import org.eclipse.jdt.internal.compiler.problem.*;
import org.eclipse.jdt.internal.compiler.util.*;
import org.eclipse.jdt.internal.compiler.impl.*;

import java.io.*;
import java.util.*;

public class Main implements ConfigurableProblems, ProblemSeverities {
	PrintWriter out;
	boolean systemExitWhenFinished = true;
	boolean proceedOnError = false;
	int warningMask =
		ParsingOptionalError |
		MethodWithConstructorName | OverriddenPackageDefaultMethod |
		UsingDeprecatedAPI | MaskedCatchBlock |
		UnusedLocalVariable | UnusedArgument |
		TemporaryWarning | OverriddenPackageDefaultMethod |
		AccessEmulation;
			
	int debugMask = CompilerOptions.Lines | CompilerOptions.Source;
	int targetJDK = CompilerOptions.JDK1_1;
	boolean verbose = false;
	boolean produceRefInfo = false;
	boolean importProblemIsError = true;
	boolean timer = false;
	boolean showProgress = false;
	public long time = 0;
	long lineCount;
	boolean preserveAllLocalVariables = false; // The unused and final local variables will be optimized

	String[] filenames;
	String[] classpaths;
	String destinationPath;
	String log;
	int repetitions;
	int globalProblemsCount;
	int globalErrorsCount;
	int globalWarningsCount;

	String versionID = "1.0NL"/*nonNLS*/;
	private static final char[] CLASS_FILE_EXTENSION = ".class"/*nonNLS*/.toCharArray();

	int exportedClassFilesCounter;

	/**
	 * Are we running JDK 1.1?
	 */
	private static boolean JDK1_1 = false;

	/* Bundle containing messages */
	protected static ResourceBundle bundle;
	private final static String bundleName = "org.eclipse.jdt.internal.compiler.batch.Messages"/*nonNLS*/;
	static {
		String ver = System.getProperty("java.version"/*nonNLS*/);
		JDK1_1 = ((ver != null) && ver.startsWith("1.1"/*nonNLS*/));
		relocalize();
	}
protected Main(PrintWriter writer, boolean systemExitWhenFinished) {
	this.out = writer;
	this.systemExitWhenFinished = systemExitWhenFinished;
	exportedClassFilesCounter = 0;
}
/*
 *  Low-level API performing the actual compilation
 */
protected void compile(String[] argv) {
	// decode command line arguments
	try {
		configure(argv);
		if (showProgress) System.out.print(Main.bind("progress.compiling"/*nonNLS*/));
		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"/*nonNLS*/,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"/*nonNLS*/,new String[]{String.valueOf(lineCount),String.valueOf(time),String.valueOf((((int)((lineCount*10000.0)/time))/10.0))}));
				} else {
					out.println(Main.bind("compile.totalTime"/*nonNLS*/,String.valueOf(time)));
					
				}
			}
			if (globalProblemsCount > 0) {
				if (globalProblemsCount == 1) {
					out.print(Main.bind("compile.oneProblem"/*nonNLS*/));
				} else {
					out.print(Main.bind("compile.severalProblems"/*nonNLS*/,String.valueOf(globalProblemsCount)));
				}
				out.print(" ("/*nonNLS*/);
				if (globalErrorsCount > 0) {
					if (globalErrorsCount == 1) {
						out.print(Main.bind("compile.oneError"/*nonNLS*/));
					} else {
						out.print(Main.bind("compile.severalErrors"/*nonNLS*/,String.valueOf(globalErrorsCount)));
					}
				}
				if (globalWarningsCount > 0) {
					if (globalErrorsCount > 0) {
						out.print(", "/*nonNLS*/);
					}
					if (globalWarningsCount == 1) {
						out.print(Main.bind("compile.oneWarning"/*nonNLS*/));
					} else {
						out.print(Main.bind("compile.severalWarnings"/*nonNLS*/,String.valueOf(globalWarningsCount)));
					}
				}
				out.println(")"/*nonNLS*/);
			}
			if (exportedClassFilesCounter != 0 && (this.showProgress || this.timer || this.verbose)) {
				if (exportedClassFilesCounter == 1) {
					out.print(Main.bind("compile.oneClassFileGenerated"/*nonNLS*/));
				} else {
					out.print(Main.bind("compile.severalClassFilesGenerated"/*nonNLS*/,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("------------------------"/*nonNLS*/);
		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();
			System.exit(-1);
		}
	} finally {
		out.flush();
	}
}
/*
 * Internal IDE API
 */
public static void compile(String commandLine) {
	compile(commandLine, new PrintWriter(System.out));
}
/*
 * Internal IDE API for test harness purpose
 */
public static void compile(String commandLine, PrintWriter writer) {
	int count = 0;
	String[] argv = new String[10];
	int startIndex = 0;
	int lastIndex = commandLine.indexOf('"');
	boolean insideQuotes = false;
	boolean insideClasspath = false;
	StringTokenizer tokenizer;
	while (lastIndex != -1) {
		if (insideQuotes) {
			if (count == argv.length) {
				System.arraycopy(argv, 0, (argv = new String[count * 2]), 0, count);
			}
			if (insideClasspath) {
				argv[count-1] += commandLine.substring(startIndex, lastIndex);
				insideClasspath = false;
			} else {
				argv[count++] = commandLine.substring(startIndex, lastIndex);
			}
		} else {
			String subCommandLine = commandLine.substring(startIndex, lastIndex);
			if (subCommandLine.equals(File.pathSeparator)) {
				argv[count-1] += File.pathSeparator;
				insideClasspath = true;
			} else {
				tokenizer = new StringTokenizer(subCommandLine, File.pathSeparator + " "/*nonNLS*/);
				while (tokenizer.hasMoreTokens()) {
					if (count == argv.length) {
						System.arraycopy(argv, 0, (argv = new String[count * 2]), 0, count);
					}
					argv[count++] = tokenizer.nextToken();
				}
			}
		}
		startIndex = lastIndex + 1;
		lastIndex = commandLine.indexOf('"', startIndex);
		insideQuotes = !insideQuotes;
	}
	if (startIndex == 0) {
		tokenizer = new StringTokenizer(commandLine);
		while (tokenizer.hasMoreTokens()) {
			if (count == argv.length) {
				System.arraycopy(argv, 0, (argv = new String[count * 2]), 0, count);
			}
			argv[count++] = tokenizer.nextToken();
		}
	} else {
		if (startIndex + 1 <= commandLine.length()) {
			if (insideQuotes) {
				if (count == argv.length) {
					System.arraycopy(argv, 0, (argv = new String[count * 2]), 0, count);
				}
				argv[count++] = commandLine.substring(startIndex, commandLine.length());
			} else {
				tokenizer = new StringTokenizer(commandLine.substring(startIndex, commandLine.length()), File.pathSeparator + " "/*nonNLS*/);
				while (tokenizer.hasMoreTokens()) {
					if (count == argv.length) {
						System.arraycopy(argv, 0, (argv = new String[count * 2]), 0, count);
					}
					argv[count++] = tokenizer.nextToken();
				}
			}
		}
	}
	System.arraycopy(argv, 0, argv = new String[count], 0, count);
	new Main(writer, false).compile(argv);
}
/*
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"/*nonNLS*/));
	final int InsideClasspath = 1;
	final int InsideDestinationPath = 2;
	final int TargetSetting = 4;
	final int InsideLog = 8;
	final int InsideRepetition = 16;
	final int Default = 0;
	int DEFAULT_SIZE_CLASSPATH = 4;
	boolean noWarnOptionInUsed = false;
	boolean warnOptionInUsed = false;
	int pathCount = 0;
	int index = -1, filesCount = 0, argCount = argv.length;
	int mode = Default;
	repetitions = 0;
	boolean versionIDRequired = false;
	boolean printUsageRequired = false;
	
	while (++index < argCount) {
		String currentArg = argv[index].trim();
		if (currentArg.endsWith(".java"/*nonNLS*/)) {
			if (filenames == null) {
				filenames = 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);
			}
			filenames[filesCount++] = currentArg;
			mode = Default;
			continue;
		}
		if (currentArg.equals("-log"/*nonNLS*/)) {
			if (log != null)
				throw new InvalidInputException(Main.bind("configure.duplicateLog"/*nonNLS*/,currentArg));
			mode = InsideLog;
			continue;
		}
		if (currentArg.equals("-repeat"/*nonNLS*/)) {
			if (repetitions > 0)
				throw new InvalidInputException(Main.bind("configure.duplicateRepeat"/*nonNLS*/,currentArg));
			mode = InsideRepetition;
			continue;
		}
		if (currentArg.equals("-d"/*nonNLS*/)) {
			if (destinationPath != null)
				throw new InvalidInputException(Main.bind("configure.duplicateOutputPath"/*nonNLS*/,currentArg));
			mode = InsideDestinationPath;
			continue;
		}
		if (currentArg.equals("-classpath"/*nonNLS*/)) {
			if (pathCount > 0)
				throw new InvalidInputException(Main.bind("configure.duplicateClasspath"/*nonNLS*/,currentArg));
			classpaths = new String[DEFAULT_SIZE_CLASSPATH];
			mode = InsideClasspath;
			continue;
		}
		if (currentArg.equals("-progress"/*nonNLS*/)) {
			mode = Default;
			showProgress = true;
			continue;
		}
		if (currentArg.equals("-proceedOnError"/*nonNLS*/)) {
			mode = Default;
			proceedOnError = true;
			continue;
		}
		if (currentArg.equals("-time"/*nonNLS*/)) {
			mode = Default;
			timer = true;
			continue;
		}
		if (currentArg.equals("-version"/*nonNLS*/) || currentArg.equals("-v"/*nonNLS*/)) {
			versionIDRequired = true;
			continue;
		}
		if (currentArg.equals("-help"/*nonNLS*/)) {
			printUsageRequired = true;
			continue;
		}		
		if (currentArg.equals("-noImportError"/*nonNLS*/)) {
			mode = Default;
			importProblemIsError = false;
			continue;
		}
		if (currentArg.equals("-noExit"/*nonNLS*/)) {
			mode = Default;
			systemExitWhenFinished = false;
			continue;
		}		
		if (currentArg.equals("-verbose"/*nonNLS*/)) {
			mode = Default;
			verbose = true;
			continue;
		}
		if (currentArg.equals("-referenceInfo"/*nonNLS*/)) {
			mode = Default;
			produceRefInfo = true;
			continue;
		}
		if (currentArg.startsWith("-g"/*nonNLS*/)) {
			mode = Default;
			debugMask = 0; // reinitialize the default value
			String debugOption = currentArg;
			int length = currentArg.length();
			if (length == 2) {
				debugMask = CompilerOptions.Lines | CompilerOptions.Vars | CompilerOptions.Source;
				continue;
			}
			if (length > 3) {
				if (length == 7 && debugOption.equals("-g:none"/*nonNLS*/))
					continue;
				StringTokenizer tokenizer = new StringTokenizer(debugOption.substring(3, debugOption.length()), ","/*nonNLS*/);
				while (tokenizer.hasMoreTokens()) {
					String token = tokenizer.nextToken();
					if (token.equals("vars"/*nonNLS*/)) {
						debugMask |= CompilerOptions.Vars;
					} else if (token.equals("lines"/*nonNLS*/)) {
						debugMask |= CompilerOptions.Lines;
					} else if (token.equals("source"/*nonNLS*/)) {
						debugMask |= CompilerOptions.Source;
					} else {
						throw new InvalidInputException(Main.bind("configure.invalidDebugOption"/*nonNLS*/,debugOption));
					}
				}
				continue;
			}
			throw new InvalidInputException(Main.bind("configure.invalidDebugOption"/*nonNLS*/,debugOption));
		}
		if (currentArg.startsWith("-nowarn"/*nonNLS*/)) {
			noWarnOptionInUsed = true;
			if (warnOptionInUsed)
				throw new InvalidInputException(Main.bind("configure.duplicateWarningConfiguration"/*nonNLS*/));
			mode = Default;
			warningMask = TemporaryWarning; // reinitialize the default value (still see TemporaryWarning)		
			continue;
		}
		if (currentArg.startsWith("-warn"/*nonNLS*/)) {
			warnOptionInUsed = true;
			if (noWarnOptionInUsed)
				throw new InvalidInputException(Main.bind("configure.duplicateWarningConfiguration"/*nonNLS*/));
			mode = Default;
			String warningOption = currentArg;
			int length = currentArg.length();
			if (length == 10 && warningOption.equals("-warn:none"/*nonNLS*/)) {
				warningMask = TemporaryWarning; // reinitialize the default value (still see TemporaryWarning)
				continue;
			}
			if (length < 6)
				throw new InvalidInputException(Main.bind("configure.invalidWarningConfiguration"/*nonNLS*/,warningOption));
			StringTokenizer tokenizer = new StringTokenizer(warningOption.substring(6, warningOption.length()), ","/*nonNLS*/);
			int tokenCounter = 0;
			warningMask = 0; // reinitialize the default value				
			while (tokenizer.hasMoreTokens()) {
				String token = tokenizer.nextToken();
				tokenCounter++;
				if (token.equals("constructorName"/*nonNLS*/)) {
					warningMask |= CompilerOptions.MethodWithConstructorName;
				} else if (token.equals("packageDefaultMethod"/*nonNLS*/)) {
					warningMask |= CompilerOptions.OverriddenPackageDefaultMethod;
				} else if (token.equals("maskedCatchBlocks"/*nonNLS*/)) {
					warningMask |= CompilerOptions.MaskedCatchBlock;
				} else if (token.equals("deprecation"/*nonNLS*/)) {
					warningMask |= CompilerOptions.UsingDeprecatedAPI;
				} else if (token.equals("unusedLocals"/*nonNLS*/)) {
					warningMask |= CompilerOptions.UnusedLocalVariable;
				} else if (token.equals("unusedArguments"/*nonNLS*/)) {
					warningMask |= CompilerOptions.UnusedArgument;
				} else if (token.equals("syntheticAccess"/*nonNLS*/)){
					warningMask |= CompilerOptions.AccessEmulation;
				} else if (token.equals("nls"/*nonNLS*/)){
					warningMask |= CompilerOptions.NonExternalizedString;
				} else {
					throw new InvalidInputException(Main.bind("configure.invalidWarning"/*nonNLS*/,token));
				}
			}
			if (tokenCounter == 0)
				throw new InvalidInputException(Main.bind("configure.invalidWarningOption"/*nonNLS*/,currentArg));
			continue;
		}
		if (currentArg.equals("-target"/*nonNLS*/)) {
			mode = TargetSetting;
			continue;
		}
		if (currentArg.equals("-preserveAllLocals"/*nonNLS*/)) {
			preserveAllLocalVariables = true;
			continue;
		}
		if (mode == TargetSetting) {
			if (currentArg.equals("1.1"/*nonNLS*/)) {
				targetJDK = CompilerOptions.JDK1_1;
			} else if (currentArg.equals("1.2"/*nonNLS*/)) {
				targetJDK = CompilerOptions.JDK1_2;
			} else {
				throw new InvalidInputException(Main.bind("configure.targetJDK"/*nonNLS*/,currentArg));
			}
			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"/*nonNLS*/,currentArg));
				}
			} catch(NumberFormatException e){
				throw new InvalidInputException(Main.bind("configure.repetition"/*nonNLS*/,currentArg));
			}
			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"/*nonNLS*/,currentArg));
		FileFinder finder = new FileFinder();
		try{
			finder.find(dir, ".JAVA"/*nonNLS*/, verbose);
		} catch(Exception e){
			throw new InvalidInputException(Main.bind("configure.IOError"/*nonNLS*/,currentArg));		
		}
		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(results, 0, filenames, filesCount, length);
			filesCount += length;
		} else {
			filenames = finder.resultFiles;
			filesCount = filenames.length;
		}
		mode = Default;
		continue;
	}

	/*
	 * Standalone options
	 */
	if (versionIDRequired) {
		out.println(Main.bind("configure.version"/*nonNLS*/,this.versionID));
		out.println();
		return;
	}
		
	if (printUsageRequired) {
		printUsage();
		return;
	}	
	
	if (filesCount != 0)
		System.arraycopy(filenames, 0, (filenames = new String[filesCount]), 0, filesCount);
	if (pathCount == 0) {
		String classProp = System.getProperty("LFclasspath"/*nonNLS*/);
		if ((classProp == null) || (classProp.length() == 0)) {
			out.println(Main.bind("configure.noClasspath"/*nonNLS*/));
			classProp = "."/*nonNLS*/;
		}
		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())
			throw new InvalidInputException(Main.bind("configure.incorrectClasspath"/*nonNLS*/,classpaths[i]));
	}
	if (destinationPath == null) {
		destinationPath = System.getProperty("user.dir"/*nonNLS*/);
	} else if ("none"/*nonNLS*/.equals(destinationPath)) {
		destinationPath = null;
	}
		
	if (filenames == null)
		throw new InvalidInputException(Main.bind("configure.noSource"/*nonNLS*/));

	if (log != null){
		try {
			out = new PrintWriter(new FileOutputStream(log, false));
		} catch(IOException e){
			throw new InvalidInputException(Main.bind("configure.cannotOpenLog"/*nonNLS*/));
		}
	} else {
		showProgress = false;
	}
	if (repetitions == 0) {
		repetitions = 1;
	}
}
/*
 * 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("----------"/*nonNLS*/);
						out.print(globalProblemsCount + ". "/*nonNLS*/ + (problems[i].isError() ? Main.bind("requestor.error"/*nonNLS*/) : Main.bind("requestor.warning"/*nonNLS*/)));
						if (problems[i].isError()) {
							globalErrorsCount++;
						} else {
							globalWarningsCount++;
						}
						out.print(" "/*nonNLS*/);
						out.print(Main.bind("requestor.in"/*nonNLS*/,new String(problems[i].getOriginatingFileName())));
						try {
							out.println(((DefaultProblem)problems[i]).errorReportSource(compilationResult.compilationUnit));
							out.println(problems[i].getMessage());
						} catch (Exception e) {
							out.println(Main.bind("requestor.notRetrieveErrorMessage"/*nonNLS*/,problems[i].toString()));
						}
						out.println("----------"/*nonNLS*/);
						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);
	
	for (int i = 0; i < fileCount; i++) {
		char[] charName = filenames[i].toCharArray();
		if (knownFileNames.get(charName) != null){
			throw new InvalidInputException(Main.bind("unit.more"/*nonNLS*/,filenames[i]));			
		} else {
			knownFileNames.put(charName, charName);
		}
		File file = new File(filenames[i]);
		if (!file.exists())
			throw new InvalidInputException(Main.bind("unit.missing"/*nonNLS*/,filenames[i]));
		units[i] = new CompilationUnit(null, filenames[i]);
	}
	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() {
	return new FileSystem(classpaths, filenames);
}
/*
 *  Low-level API performing the actual compilation
 */
protected ConfigurableOption[] getOptions() {
	CompilerOptions options = new CompilerOptions();
	options.produceDebugAttributes(debugMask);
	options.preserveAllLocalVariables(preserveAllLocalVariables);
	options.handleImportProblemAsError(importProblemIsError);
	options.setWarningThreshold(warningMask);
	options.setTargetJDK(targetJDK);
	return options.getConfigurableOptions(Locale.getDefault());
}
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 (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(
						destinationPath,
						new String(relativeName),
						classFile.getBytes());
				} catch (IOException e) {
					String fileName = destinationPath + new String(relativeName);
					e.printStackTrace();
					System.out.println(Main.bind("output.noClassFileCreated"/*nonNLS*/,fileName));
				}
				exportedClassFilesCounter++;
			}
		}
	}
}
/*
 *  Low-level API performing the actual compilation
 */
protected void performCompilation() throws InvalidInputException {
	Compiler batchCompiler =
			new Compiler(
				getLibraryAccess(),
				getHandlingPolicy(),
				getOptions(),
		 		getBatchRequestor(),
				getProblemFactory());

	CompilerOptions options = batchCompiler.options;
	// set the non-externally configurable options.
	options.setVerboseMode(verbose);
	options.produceReferenceInfo(produceRefInfo);
	
	batchCompiler.compile(getCompilationUnits());
}
private void printUsage() {
	out.println(Main.bind("misc.usage"/*nonNLS*/,this.versionID));
	/*out.println(
		"Eclipse Java Compiler "+ this.versionID + ", Copyright IBM Corp 2000\n\n" +
		"Usage: <options> <source files | directories>\n\n" +
					"where options include:\n" +
					"-version or -v\tdisplays the version number (standalone option)\n" +
					"-help\tdisplay this help message (standalone option)\n" +
					"-noExit\tPrevent the compiler to call System.exit at the end of the compilation process\n" +					
					"-classpath <dir 1>;<dir 2>;...;<dir P>\n" +
					"-d <dir>\tdestination directory\n\t\t, specified '-d none' if you don't want to dump files\n" +
					"-verbose\tprint accessed/processed compilation units \n" +
					"-time\t\tdisplay total compilation time" +
							"\n\t\tand speed if line attributes are enabled\n" +
					"-log <filename>\tspecify a log file for recording problems\n" +
					"-progress\t\tshow progress (only in -log mode)\n" +
					"-g[:<level>]\tspecify the level of details for debug attributes" +
							"\n\t\t-g\tgenerate all debug info"+
							"\n\t\t-g:none\tno debug info"+
							"\n\t\t-g:{lines,vars,source}\tonly some debug info\n" +
					"-nowarn\t\tdo not report warnings \n" +
					"-warn:<mask>\tspecify the level of details for warnings\n" +
							"\t\t-warn:none no warning\n"+
							"\t\t-warn:{constructorName, packageDefaultMethod, deprecation,\n" +
							"\t\t\tmaskedCatchBlocks, unusedLocals, unusedArguments, \n" +
							"\t\t\tsyntheticAccess}\n" +					
					"-noImportError\tdo not report errors on incorrect imports\n" +
					"-proceedOnError\tkeep compiling when error, \n\t\tdumping class files with problem methods\n" +
					"-referenceInfo\tcompute reference info\n" +
					"-preserveAllLocals\trequest code gen preserve all local variables\n" +
					"-repeat <n>\trepeat compilation process for performance analysis\n");*/
	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"/*nonNLS*/;
	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: "/*nonNLS*/+id+" in: "/*nonNLS*/+bundleName;
	}
	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 "/*nonNLS*/ + Integer.toString(index) + "}"/*nonNLS*/);
				}
			} 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});
}

}
