/*******************************************************************************
 * Copyright (c) 2007, 2021 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation
 *    IBM Corporation - fix for 342936
 *    Kenneth Olson - Contribution for bug 188796 - [jsr199] Using JSR199 to extend ECJ
 *    Dennis Hendriks - Contribution for bug 188796 - [jsr199] Using JSR199 to extend ECJ
 *    Frits Jalvingh  - fix for bug 533830.
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.tool;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;

import javax.annotation.processing.Processor;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;

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.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.batch.ClasspathJrt;
import org.eclipse.jdt.internal.compiler.batch.ClasspathJsr199;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
import org.eclipse.jdt.internal.compiler.batch.Main;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit;
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.HashtableOfObject;
import org.eclipse.jdt.internal.compiler.util.Messages;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.compiler.util.Util;

public class EclipseCompilerImpl extends Main {
	private static final CompilationUnit[] NO_UNITS = new CompilationUnit[0];
	private static final String RELEASE_FILE = "release"; //$NON-NLS-1$
	private static final String JAVA_VERSION = "JAVA_VERSION"; //$NON-NLS-1$
	private HashMap<CompilationUnit, JavaFileObject> javaFileObjectMap;
	Iterable<? extends JavaFileObject> compilationUnits;
	public JavaFileManager fileManager;
	protected Processor[] processors;
	public DiagnosticListener<? super JavaFileObject> diagnosticListener;

	public EclipseCompilerImpl(PrintWriter out, PrintWriter err, boolean systemExitWhenFinished) {
		super(out, err, systemExitWhenFinished, null/*options*/, null/*progress*/);
	}

	public boolean call() {
		try {
			handleLocations();
			if (this.proceed) {
				this.globalProblemsCount = 0;
				this.globalErrorsCount = 0;
				this.globalWarningsCount = 0;
				this.globalTasksCount = 0;
				this.exportedClassFilesCounter = 0;
				// request compilation
				performCompilation();
			}
		} catch(IllegalArgumentException e) {
			this.diagnosticListener.report(new ExceptionDiagnostic(e));
			this.logger.logException(e);
			if (this.systemExitWhenFinished) {
				cleanup();
				System.exit(-1);
			}
			return false;
		} catch (RuntimeException e) { // internal compiler failure
			this.diagnosticListener.report(new ExceptionDiagnostic(e));
			this.logger.logException(e);
			return false;
		} finally {
			cleanup();
		}
		if (this.failOnWarning && this.globalWarningsCount > 0) {
			return false;
		}
		return this.globalErrorsCount == 0;
	}

	private void cleanup() {
		this.logger.flush();
		this.logger.close();
		this.processors = null;
		try {
			if (this.fileManager != null) {
				this.fileManager.flush();
			}
		} catch (IOException e) {
			// ignore
		}
	}

	@Override
	public CompilationUnit[] getCompilationUnits() {
		// This method is largely a copy of Main#getCompilationUnits()
		if (this.compilationUnits == null) return EclipseCompilerImpl.NO_UNITS;
		HashtableOfObject knownFileNames = new HashtableOfObject();
		ArrayList<CompilationUnit> units = new ArrayList<>();
		for (int round = 0; round < 2; round++) {
			int i = 0;
			for (final JavaFileObject javaFileObject : this.compilationUnits) {
				String name = javaFileObject.getName();
				char[] charName = name.toCharArray();
				boolean isModuleInfo = CharOperation.endsWith(charName, TypeConstants.MODULE_INFO_FILE_NAME);
				if (isModuleInfo == (round==0)) { // 1st round: modules, 2nd round others (to ensure populating pathToModCU well in time)
					if (knownFileNames.get(charName) != null)
						throw new IllegalArgumentException(this.bind("unit.more", name)); //$NON-NLS-1$
					knownFileNames.put(charName, charName);

					boolean found = false;
					try {
						if (this.fileManager.hasLocation(StandardLocation.SOURCE_PATH)) {
							found = this.fileManager.contains(StandardLocation.SOURCE_PATH, javaFileObject);
						}
						if (!found) {
							if (this.fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {
								found = this.fileManager.contains(StandardLocation.MODULE_SOURCE_PATH, javaFileObject);
							}
						}
					} catch (IOException e) {
						// Not found.
					}
					if (!found) {
						File file = new File(name);
						if (!file.exists())
							throw new IllegalArgumentException(this.bind("unit.missing", name)); //$NON-NLS-1$
					}

					CompilationUnit cu = new CompilationUnit(null,
							name,
							null,
							this.destinationPaths[i],
							shouldIgnoreOptionalProblems(this.ignoreOptionalProblemsFromFolders, name.toCharArray()), this.modNames[i]) {

							@Override
							public char[] getContents() {
								try {
									return javaFileObject.getCharContent(true).toString().toCharArray();
								} catch(IOException e) {
									e.printStackTrace();
									throw new AbortCompilationUnit(null, e, null);
								}
							}
						};
						units.add(cu);
						this.javaFileObjectMap.put(cu, javaFileObject);
				}
				i++;
			}
		}
		CompilationUnit[] result = new CompilationUnit[units.size()];
		units.toArray(result);
		return result;
	}
	/*
	 *  Low-level API performing the actual compilation
	 */
	@Override
	public IErrorHandlingPolicy getHandlingPolicy() {
		// passes the initial set of files to the batch oracle (to avoid finding more than once the same units when case insensitive match)
		return new IErrorHandlingPolicy() {
			@Override
			public boolean proceedOnErrors() {
				return false; // stop if there are some errors
			}
			@Override
			public boolean stopOnFirstError() {
				return false;
			}
			@Override
			public boolean ignoreAllErrors() {
				return false;
			}
		};
	}

	@Override
	public IProblemFactory getProblemFactory() {
		return new DefaultProblemFactory() {
			@Override
			public CategorizedProblem createProblem(
					final char[] originatingFileName,
					final int problemId,
					final String[] problemArguments,
					final String[] messageArguments,
					final int severity,
					final int startPosition,
					final int endPosition,
					final int lineNumber,
					final int columnNumber) {

				DiagnosticListener<? super JavaFileObject> diagListener = EclipseCompilerImpl.this.diagnosticListener;
				Diagnostic<JavaFileObject> diagnostic = null;
				if (diagListener != null) {
					diagnostic = new Diagnostic<>() {
						@Override
						public String getCode() {
							return Integer.toString(problemId);
						}
						@Override
						public long getColumnNumber() {
							return columnNumber;
						}
						@Override
						public long getEndPosition() {
							return endPosition;
						}
						@Override
						public Kind getKind() {
							if ((severity & ProblemSeverities.Error) != 0) {
								return Diagnostic.Kind.ERROR;
							}
							if ((severity & ProblemSeverities.Optional) != 0) {
								return Diagnostic.Kind.WARNING;
							}
							if ((severity & ProblemSeverities.Warning) != 0) {
								return Diagnostic.Kind.MANDATORY_WARNING;
							}
							return Diagnostic.Kind.OTHER;
						}
						@Override
						public long getLineNumber() {
							return lineNumber;
						}
						@Override
						public String getMessage(Locale locale) {
							if (locale != null) {
								setLocale(locale);
							}
							return getLocalizedMessage(problemId, problemArguments);
						}
						@Override
						public long getPosition() {
							return startPosition;
						}
						@Override
						public JavaFileObject getSource() {
							File f = new File(new String(originatingFileName));
							if (f.exists()) {
								return new EclipseFileObject(null, f.toURI(), JavaFileObject.Kind.SOURCE, null);
							}
							return null;
						}
						@Override
						public long getStartPosition() {
							return startPosition;
						}
					};
				}
				CategorizedProblem problem = super.createProblem(originatingFileName, problemId, problemArguments, messageArguments, severity, startPosition, endPosition, lineNumber, columnNumber);
				if (problem instanceof DefaultProblem && diagnostic != null) {
					return new Jsr199ProblemWrapper((DefaultProblem) problem, diagnostic, diagListener);
				}
				return problem;
			}
			@Override
			public CategorizedProblem createProblem(
					final char[] originatingFileName,
					final int problemId,
					final String[] problemArguments,
					final int elaborationID,
					final String[] messageArguments,
					final int severity,
					final int startPosition,
					final int endPosition,
					final int lineNumber,
					final int columnNumber) {

				DiagnosticListener<? super JavaFileObject> diagListener = EclipseCompilerImpl.this.diagnosticListener;
				Diagnostic<JavaFileObject> diagnostic = null;
				if (diagListener != null) {
					diagnostic = new Diagnostic<>() {
						@Override
						public String getCode() {
							return Integer.toString(problemId);
						}
						@Override
						public long getColumnNumber() {
							return columnNumber;
						}
						@Override
						public long getEndPosition() {
							return endPosition;
						}
						@Override
						public Kind getKind() {
							if ((severity & ProblemSeverities.Error) != 0) {
								return Diagnostic.Kind.ERROR;
							}
							if ((severity & ProblemSeverities.Info) != 0) {
								return Diagnostic.Kind.NOTE;
							}
							if ((severity & ProblemSeverities.Optional) != 0) {
								return Diagnostic.Kind.WARNING;
							}
							if ((severity & ProblemSeverities.Warning) != 0) {
								return Diagnostic.Kind.MANDATORY_WARNING;
							}
							return Diagnostic.Kind.OTHER;
						}
						@Override
						public long getLineNumber() {
							return lineNumber;
						}
						@Override
						public String getMessage(Locale locale) {
							if (locale != null) {
								setLocale(locale);
							}
							return getLocalizedMessage(problemId, problemArguments);
						}
						@Override
						public long getPosition() {
							return startPosition;
						}
						@Override
						public JavaFileObject getSource() {
							File f = new File(new String(originatingFileName));
							if (f.exists()) {
								return new EclipseFileObject(null, f.toURI(), JavaFileObject.Kind.SOURCE, null);
							}
							return null;
						}
						@Override
						public long getStartPosition() {
							return startPosition;
						}
					};
				}
				CategorizedProblem problem = super.createProblem(originatingFileName, problemId, problemArguments, elaborationID, messageArguments, severity, startPosition, endPosition, lineNumber, columnNumber);
				if (problem instanceof DefaultProblem && diagnostic != null) {
					return new Jsr199ProblemWrapper((DefaultProblem) problem, diagnostic, diagListener);
				}
				return problem;
			}
		};
	}

	@Override
	protected void initialize(PrintWriter outWriter, PrintWriter errWriter, boolean systemExit, Map<String, String> customDefaultOptions, CompilationProgress compilationProgress) {
		super.initialize(outWriter, errWriter, systemExit, customDefaultOptions, compilationProgress);
		this.javaFileObjectMap = new HashMap<>();
	}

	@Override
	protected void initializeAnnotationProcessorManager() {
		super.initializeAnnotationProcessorManager();
		if (this.batchCompiler.annotationProcessorManager != null && this.processors != null) {
			this.batchCompiler.annotationProcessorManager.setProcessors(this.processors);
		} else if (this.processors != null) {
			throw new UnsupportedOperationException("Cannot handle annotation processing"); //$NON-NLS-1$
		}
	}

	// 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.
	@Override
	public void outputClassFiles(CompilationResult unitResult) {
		if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
			ClassFile[] classFiles = unitResult.getClassFiles();
			boolean generateClasspathStructure = this.fileManager.hasLocation(StandardLocation.CLASS_OUTPUT);
			File outputLocation = null;
			String currentDestinationPath = unitResult.getCompilationUnit().getDestinationPath();
			if (currentDestinationPath == null)
				currentDestinationPath = this.destinationPath;
			if (currentDestinationPath != null) {
				outputLocation = new File(currentDestinationPath);
				outputLocation.mkdirs();
			}
			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);
				if (this.compilerOptions.verbose) {
					EclipseCompilerImpl.this.out.println(
						Messages.bind(
							Messages.compilation_write,
							new String[] {
								String.valueOf(this.exportedClassFilesCounter+1),
								relativeStringName
							}));
				}
				try {
					char[] modName = unitResult.compilationUnit.getModuleName();
					Location location = null;
					if (modName == null) {
						location = StandardLocation.CLASS_OUTPUT;
					} else {
						// TODO: Still possible to end up with a non-null module name without JDK 9 in build path
						location = this.fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT, new String(modName));
					}
					JavaFileObject javaFileForOutput =
						this.fileManager.getJavaFileForOutput(
								location,
								new String(filename),
								JavaFileObject.Kind.CLASS,
								this.javaFileObjectMap.get(unitResult.compilationUnit));

					if (generateClasspathStructure) {
						if (currentDestinationPath != null) {
							int index = CharOperation.lastIndexOf(File.separatorChar, relativeName);
							if (index != -1) {
								File currentFolder = new File(currentDestinationPath, relativeStringName.substring(0, index));
								currentFolder.mkdirs();
							}
						} else {
							// create the subfolfers is necessary
							// need a way to retrieve the folders to create
							String path = javaFileForOutput.toUri().getPath();
							int index = path.lastIndexOf('/');
							if (index != -1) {
								File file = new File(path.substring(0, index));
								file.mkdirs();
							}
						}
					}

					try (OutputStream openOutputStream = javaFileForOutput.openOutputStream(); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(openOutputStream)) {
						bufferedOutputStream.write(classFile.header, 0, classFile.headerOffset);
						bufferedOutputStream.write(classFile.contents, 0, classFile.contentsOffset);
						bufferedOutputStream.flush();
					}
				} catch (IOException e) {
					this.logger.logNoClassFileCreated(currentDestinationPath, relativeStringName, e);
				}
				this.logger.logClassFile(
					generateClasspathStructure,
					currentDestinationPath,
					relativeStringName);
				this.exportedClassFilesCounter++;
			}
			this.batchCompiler.lookupEnvironment.releaseClassFiles(classFiles);
		}
	}

	@Override
	protected void setPaths(ArrayList<String> bootclasspaths,
			String sourcepathClasspathArg,
			ArrayList<String> sourcepathClasspaths,
			ArrayList<String> classpaths,
			String modulePath,
			String moduleSourcepath,
			ArrayList<String> extdirsClasspaths,
			ArrayList<String> endorsedDirClasspaths,
			String customEncoding) {
		// Sometimes this gets called too early there by losing locations set after that point.
		// The code is now moved to handleLocations() which is invoked just before compilation
		validateClasspathOptions(bootclasspaths, endorsedDirClasspaths, extdirsClasspaths);
	}

	protected void handleLocations() {
		ArrayList<FileSystem.Classpath> fileSystemClasspaths = new ArrayList<>();
		EclipseFileManager eclipseJavaFileManager = null;
		StandardJavaFileManager standardJavaFileManager = null;
		JavaFileManager javaFileManager = null;
		boolean havePlatformPaths = false;
		boolean haveClassPaths = false;
		if (this.fileManager instanceof EclipseFileManager) {
			eclipseJavaFileManager = (EclipseFileManager) this.fileManager;
		}
		if (this.fileManager instanceof StandardJavaFileManager) {
			standardJavaFileManager = (StandardJavaFileManager) this.fileManager;
		}
		javaFileManager = this.fileManager;

		if (eclipseJavaFileManager != null) {
			if ((eclipseJavaFileManager.flags & EclipseFileManager.HAS_ENDORSED_DIRS) == 0
					&& (eclipseJavaFileManager.flags & EclipseFileManager.HAS_BOOTCLASSPATH) != 0) {
				fileSystemClasspaths.addAll(this.handleEndorseddirs(null));
			}
		}
		Iterable<? extends File> locationFiles = null;
		if (standardJavaFileManager != null) {
			locationFiles = standardJavaFileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH);
			if (locationFiles != null) {
				for (File file : locationFiles) {
					if (file.isDirectory()) {
						List<Classpath> platformLocations = getPlatformLocations(file);
						if (standardJavaFileManager instanceof EclipseFileManager) {
							if (platformLocations.size() == 1) {
								Classpath jrt = platformLocations.get(0);
								if (jrt instanceof ClasspathJrt) {
									ClasspathJrt classpathJrt = (ClasspathJrt) jrt;
									// TODO: double check, should it be platform or system module?
									try {
										EclipseFileManager efm = (EclipseFileManager) standardJavaFileManager;
										@SuppressWarnings("resource") // XXX EclipseFileManager should close jrtfs but it looks like standardJavaFileManager is never closed
										// Was leaking new JrtFileSystem(classpathJrt.file):
										JrtFileSystem jrtfs = efm.getJrtFileSystem(classpathJrt.file);
										efm.locationHandler.newSystemLocation(StandardLocation.SYSTEM_MODULES, jrtfs);
									} catch (IOException e) {
										e.printStackTrace();
									}
								}
							}
						}
						fileSystemClasspaths.addAll(platformLocations);
						break; // Only possible scenario is, we have one and only entry representing the Java home.
					} else {
						Classpath classpath = FileSystem.getClasspath(
								file.getAbsolutePath(),
								null,
								null,
								this.options,
								this.releaseVersion);
							if (classpath != null) {
								fileSystemClasspaths.add(classpath);
								havePlatformPaths = true;
							}
					}
				}
			}
		} else if (javaFileManager != null) {
			File javaHome = Util.getJavaHome();
			long jdkLevel = Util.getJDKLevel(javaHome);
			if (jdkLevel >= ClassFileConstants.JDK9) {
				Classpath systemClasspath = getSystemClasspath(javaHome, jdkLevel);
				Classpath classpath = new ClasspathJsr199(systemClasspath, this.fileManager, StandardLocation.SYSTEM_MODULES);
				fileSystemClasspaths.add(classpath);
				classpath = new ClasspathJsr199(systemClasspath, this.fileManager, StandardLocation.PLATFORM_CLASS_PATH);
				fileSystemClasspaths.add(classpath);
			} else {
				Classpath classpath = new ClasspathJsr199(this.fileManager, StandardLocation.PLATFORM_CLASS_PATH);
				fileSystemClasspaths.add(classpath);
			}
			havePlatformPaths = true;
		}
		if (eclipseJavaFileManager != null) {
			if ((eclipseJavaFileManager.flags & EclipseFileManager.HAS_EXT_DIRS) == 0
					&& (eclipseJavaFileManager.flags & EclipseFileManager.HAS_BOOTCLASSPATH) != 0) {
				fileSystemClasspaths.addAll(this.handleExtdirs(null));
			}
		}
		if (standardJavaFileManager != null) {
			locationFiles = standardJavaFileManager.getLocation(StandardLocation.SOURCE_PATH);
			if (locationFiles != null) {
				for (File file : locationFiles) {
					Classpath classpath = FileSystem.getClasspath(
							file.getAbsolutePath(),
							null,
							null,
							this.options,
							this.releaseVersion);
					if (classpath != null) {
						fileSystemClasspaths.add(classpath);
					}
				}
			}
			locationFiles = standardJavaFileManager.getLocation(StandardLocation.CLASS_PATH);
			if (locationFiles != null) {
				for (File file : locationFiles) {
					Classpath classpath = FileSystem.getClasspath(
						file.getAbsolutePath(),
						null,
						null,
						this.options,
						this.releaseVersion);
					if (classpath != null) {
						fileSystemClasspaths.add(classpath);
						haveClassPaths = true;
					}
				}
			}
			locationFiles = standardJavaFileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH);
			if (locationFiles != null) {
				for (File file : locationFiles) {
					if (file.isDirectory()) {
						String javaVersion = getJavaVersion(file);
						long jdkLevel = javaVersion.equals("") ? this.complianceLevel : CompilerOptions.versionToJdkLevel(javaVersion); //$NON-NLS-1$
						Classpath systemClasspath = getSystemClasspath(file, jdkLevel);
						Classpath classpath = new ClasspathJsr199(systemClasspath, this.fileManager, StandardLocation.PLATFORM_CLASS_PATH);
						fileSystemClasspaths.add(classpath);
						// Copy over to modules location as well
						if (standardJavaFileManager.getLocation(StandardLocation.SYSTEM_MODULES) == null) {
							classpath = new ClasspathJsr199(systemClasspath, this.fileManager, StandardLocation.SYSTEM_MODULES);
							fileSystemClasspaths.add(classpath);
						}
						haveClassPaths = true;
						break; //unlikely to have more than one path
					}
				}
			}
			locationFiles = standardJavaFileManager.getLocation(StandardLocation.SYSTEM_MODULES);
			if (locationFiles != null) {
				for (File file : locationFiles) {
					if (file.isDirectory()) {
						String javaVersion = getJavaVersion(file);
						long jdkLevel = javaVersion.equals("") ? this.complianceLevel : CompilerOptions.versionToJdkLevel(javaVersion); //$NON-NLS-1$
						Classpath systemClasspath = getSystemClasspath(file, jdkLevel);
						Classpath classpath = new ClasspathJsr199(systemClasspath, this.fileManager, StandardLocation.SYSTEM_MODULES);
						fileSystemClasspaths.add(classpath);
						// Copy over to platform location as well
						if (standardJavaFileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH) == null) {
							classpath = new ClasspathJsr199(systemClasspath, this.fileManager, StandardLocation.PLATFORM_CLASS_PATH);
							fileSystemClasspaths.add(classpath);
						}
						haveClassPaths = true;
						break; //unlikely to have more than one path
					}
				}
			}
			try {
				Iterable<? extends Path> locationAsPaths = standardJavaFileManager.getLocationAsPaths(StandardLocation.MODULE_SOURCE_PATH);
				if (locationAsPaths != null) {
					StringBuilder builder = new StringBuilder();
					for (Path path : locationAsPaths) {
						// Append all of them
						builder.append(path.toFile().getCanonicalPath());
						builder.append(File.pathSeparator);
					}
					ArrayList<Classpath> modulepaths = handleModuleSourcepath(builder.toString());
					for (Classpath classpath : modulepaths) {
						Collection<String> moduleNames = classpath.getModuleNames(null);
						for (String modName : moduleNames) {
							Path p = Paths.get(classpath.getPath());
							standardJavaFileManager.setLocationForModule(StandardLocation.MODULE_SOURCE_PATH, modName,
									Collections.singletonList(p));
							p = Paths.get(classpath.getDestinationPath());
						}
					}
					fileSystemClasspaths.addAll(modulepaths);
				}
			} catch (IllegalStateException e) {
				// Ignore this as JRE 9 throws IllegalStateException for getLocation returning null
			} catch (IllegalArgumentException e) {
				throw e;
			} catch (Exception e) {
				this.logger.logException(e);
			}
			try {
				locationFiles = standardJavaFileManager.getLocation(StandardLocation.MODULE_PATH);
				if (locationFiles != null) {
					for (File file : locationFiles) {
						try {
							ArrayList<Classpath> modulepaths = handleModulepath(file.getCanonicalPath());
							for (Classpath classpath : modulepaths) {
								Collection<String> moduleNames = classpath.getModuleNames(null);
								for (String string : moduleNames) {
									Path path = Paths.get(classpath.getPath());
									standardJavaFileManager.setLocationForModule(StandardLocation.MODULE_PATH, string,
											Collections.singletonList(path));
								}
							}
							fileSystemClasspaths.addAll(modulepaths);
						} catch (IOException e) {
							throw new AbortCompilationUnit(null, e, null);
						}
					}
				}
			} catch (IllegalStateException e) {
				// Ignore this as JRE 9 throws IllegalStateException for getLocation returning null
			} catch (IllegalArgumentException e) {
				throw e;
			} catch (Exception e) {
				this.logger.logException(e);
			}
		} else if (javaFileManager != null) {
			Classpath classpath = null;
			if (this.fileManager.hasLocation(StandardLocation.SOURCE_PATH)) {
				classpath = new ClasspathJsr199(this.fileManager, StandardLocation.SOURCE_PATH);
				fileSystemClasspaths.add(classpath);
			}
			// Add the locations to search for in specific order
			if (this.fileManager.hasLocation(StandardLocation.UPGRADE_MODULE_PATH)) {
				classpath = new ClasspathJsr199(this.fileManager, StandardLocation.UPGRADE_MODULE_PATH);
			}
			if (this.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) {
				classpath = new ClasspathJsr199(this.fileManager, StandardLocation.PATCH_MODULE_PATH);
				fileSystemClasspaths.add(classpath);
			}
			if (this.fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) {
				classpath = new ClasspathJsr199(this.fileManager, StandardLocation.MODULE_SOURCE_PATH);
				fileSystemClasspaths.add(classpath);
			}
			if (this.fileManager.hasLocation(StandardLocation.MODULE_PATH)) {
				classpath = new ClasspathJsr199(this.fileManager, StandardLocation.MODULE_PATH);
				fileSystemClasspaths.add(classpath);
			}
			classpath = new ClasspathJsr199(this.fileManager, StandardLocation.CLASS_PATH);
			fileSystemClasspaths.add(classpath);
			haveClassPaths = true;
		}
		if (this.checkedClasspaths == null) {
			// It appears to be necessary to handleBootclasspath() for IBM JVMs
			// in order to have visibility to java.lang.String (not present in rt.jar).
			// The jars returned by StandardFileManager.getLocation(PLATFORM_CLASS_PATH) are
			// not sufficient to resolve all standard classes.
			if (!havePlatformPaths) fileSystemClasspaths.addAll(this.handleBootclasspath(null, null));
			if (!haveClassPaths) fileSystemClasspaths.addAll(this.handleClasspath(null, null));
		}
		fileSystemClasspaths = FileSystem.ClasspathNormalizer.normalize(fileSystemClasspaths);
		final int size = fileSystemClasspaths.size();
		if (size != 0) {
			this.checkedClasspaths = new FileSystem.Classpath[size];
			int i = 0;
			for (FileSystem.Classpath classpath : fileSystemClasspaths) {
				this.checkedClasspaths[i++] = classpath;
			}
		}
	}
	private String getJavaVersion(File javaHome) {
		String version = ""; //$NON-NLS-1$
		if (Files.notExists(Paths.get(javaHome.getAbsolutePath(), RELEASE_FILE))) {
			return version;
		}
		try (Stream<String> lines = Files.lines(Paths.get(javaHome.getAbsolutePath(), RELEASE_FILE), Charset.defaultCharset()).filter(s -> s.contains(JAVA_VERSION))) {
			Optional<String> hasVersion = lines.findFirst();
			if (hasVersion.isPresent()) {
				String line = hasVersion.get();
				version = line.substring(14, line.length() - 1); // length of JAVA_VERSION + 2 in JAVA_VERSION="9"
			}
		}
		catch (Exception e) {
			// return default
		}
		return version;
	}
	private Classpath getSystemClasspath(File jdkHome, long jdkLevel) {
		Classpath system;
		if (this.releaseVersion != null && this.complianceLevel < jdkLevel) {
			String versionFromJdkLevel = CompilerOptions.versionFromJdkLevel(this.complianceLevel);
			if (versionFromJdkLevel.length() >= 3) {
				versionFromJdkLevel = versionFromJdkLevel.substring(2);
			}
			// TODO: Revisit for access rules
			system = FileSystem.getOlderSystemRelease(jdkHome.getAbsolutePath(), versionFromJdkLevel, null);
		} else {
			system = FileSystem.getJrtClasspath(jdkHome.toString(), null, null, null);
		}
		return system;
	}

	protected List<Classpath> getPlatformLocations(File file) {
		List<Classpath> platformLibraries = Util.collectPlatformLibraries(file);
		return platformLibraries;
	}
	@Override
	protected void loggingExtraProblems() {
		super.loggingExtraProblems();
		for (@SuppressWarnings("rawtypes")
			Iterator iterator = this.extraProblems.iterator(); iterator.hasNext(); ) {
			final CategorizedProblem problem = (CategorizedProblem) iterator.next();
			if (this.diagnosticListener != null && !isIgnored(problem)) {
				Diagnostic<JavaFileObject> diagnostic = new Diagnostic<>() {
					@Override
					public String getCode() {
						return null;
					}
					@Override
					public long getColumnNumber() {
						if (problem instanceof DefaultProblem) {
							return ((DefaultProblem) problem).column;
						}
						return Diagnostic.NOPOS;
					}
					@Override
					public long getEndPosition() {
						if (problem instanceof DefaultProblem) {
							return ((DefaultProblem) problem).getSourceEnd();
						}
						return Diagnostic.NOPOS;
					}
					@Override
					public Kind getKind() {
						if (problem.isError()) {
							return Diagnostic.Kind.ERROR;
						}
						if (problem.isWarning()) {
							return Diagnostic.Kind.WARNING;
						} else if (problem instanceof DefaultProblem && ((DefaultProblem) problem).isInfo()) {
							return Diagnostic.Kind.NOTE;
						}
						return Diagnostic.Kind.OTHER;
					}
					@Override
					public long getLineNumber() {
						if (problem instanceof DefaultProblem) {
							return ((DefaultProblem) problem).getSourceLineNumber();
						}
						return Diagnostic.NOPOS;
					}
					@Override
					public String getMessage(Locale locale) {
						return problem.getMessage();
					}
					@Override
					public long getPosition() {
						if (problem instanceof DefaultProblem) {
							return ((DefaultProblem) problem).getSourceStart();
						}
						return Diagnostic.NOPOS;
					}
					@Override
					public JavaFileObject getSource() {
						if (problem instanceof DefaultProblem) {
							char[] originatingName = ((DefaultProblem) problem).getOriginatingFileName();
							if (originatingName == null) {
								return null;
							}
							File f = new File(new String(originatingName));
							if (f.exists()) {
								Charset charset = (EclipseCompilerImpl.this.fileManager instanceof EclipseFileManager) ?
														((EclipseFileManager) EclipseCompilerImpl.this.fileManager).charset : Charset.defaultCharset();
								return new EclipseFileObject(null, f.toURI(), JavaFileObject.Kind.SOURCE, charset);
							}
							return null;
						}
						return null;
					}
					@Override
					public long getStartPosition() {
						return getPosition();
					}
				};
				this.diagnosticListener.report(diagnostic);
			}
		}
	}
	class Jsr199ProblemWrapper extends DefaultProblem {

		DefaultProblem original;
		DiagnosticListener<? super JavaFileObject> listener;
		Diagnostic<JavaFileObject> diagnostic;

		public Jsr199ProblemWrapper(DefaultProblem original, Diagnostic<JavaFileObject> diagnostic, DiagnosticListener<? super JavaFileObject> listener) {
			super(original.getOriginatingFileName(),
					original.getMessage(),
					original.getID(),
					original.getArguments(),
					original.severity,
					original.getSourceStart(),
					original.getSourceEnd(),
					original.getSourceLineNumber(),
					original.column);
			this.original = original;
			this.listener = listener;
			this.diagnostic = diagnostic;
		}
		@Override
		public void reportError() {
			this.listener.report(this.diagnostic);
		}

		@Override
		public String[] getArguments() {
			return this.original.getArguments();
		}

		@Override
		public int getID() {
			return this.original.getID();
		}

		@Override
		public String getMessage() {
			return this.original.getMessage();
		}

		@Override
		public char[] getOriginatingFileName() {
			return this.original.getOriginatingFileName();
		}

		@Override
		public int getSourceEnd() {
			return this.original.getSourceEnd();
		}

		@Override
		public int getSourceLineNumber() {
			return this.original.getSourceLineNumber();
		}

		@Override
		public int getSourceStart() {
			return this.original.getSourceStart();
		}

		@Override
		public boolean isError() {
			return this.original.isError();
		}

		@Override
		public boolean isWarning() {
			return this.original.isWarning();
		}

		@Override
		public boolean isInfo() {
			return this.original.isInfo();
		}

		@Override
		public void setSourceEnd(int sourceEnd) {
			this.original.setSourceEnd(sourceEnd);
		}

		@Override
		public void setSourceLineNumber(int lineNumber) {
			this.original.setSourceLineNumber(lineNumber);
		}

		@Override
		public void setSourceStart(int sourceStart) {
			this.original.setSourceStart(sourceStart);
		}

		@Override
		public int getCategoryID() {
			return this.original.getCategoryID();
		}

		@Override
		public String getMarkerType() {
			return this.original.getMarkerType();
		}

	}
}
