/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *     Terry Parker <tparker@google.com> - [performance] Low hit rates in JavaModel caches - https://bugs.eclipse.org/421165
 *******************************************************************************/
package org.eclipse.jdt.internal.core.builder;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;

import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.jdt.internal.core.*;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;

import java.io.*;
import java.util.*;

@SuppressWarnings({"rawtypes", "unchecked"})
public class JavaBuilder extends IncrementalProjectBuilder {

IProject currentProject;
JavaProject javaProject;
IWorkspaceRoot workspaceRoot;
CompilationParticipant[] participants;
NameEnvironment nameEnvironment;
NameEnvironment testNameEnvironment;
SimpleLookupTable binaryLocationsPerProject; // maps a project to its binary resources (output folders, class folders, zip/jar files)
public State lastState;
BuildNotifier notifier;
char[][] extraResourceFileFilters;
String[] extraResourceFolderFilters;
public static final String SOURCE_ID = "JDT"; //$NON-NLS-1$

public static boolean DEBUG = false;
public static boolean SHOW_STATS = false;

/**
 * Bug 549457: In case auto-building on a JDT core settings change (e.g. compiler compliance) is not desired,
 * specify VM property: {@code -Dorg.eclipse.jdt.core.disableAutoBuildOnSettingsChange=true}
 */
private static final boolean DISABLE_AUTO_BUILDING_ON_SETTINGS_CHANGE = Boolean.getBoolean("org.eclipse.jdt.core.disableAutoBuildOnSettingsChange"); //$NON-NLS-1$
private static final IPath JDT_CORE_SETTINGS_PATH = Path.fromPortableString(JavaProject.DEFAULT_PREFERENCES_DIRNAME + IPath.SEPARATOR + JavaProject.JAVA_CORE_PREFS_FILE);

/**
 * A list of project names that have been built.
 * This list is used to reset the JavaModel.existingExternalFiles cache when a build cycle begins
 * so that deleted external jars are discovered.
 */
static LinkedHashSet<String> builtProjects;

public static IMarker[] getProblemsFor(IResource resource) {
	try {
		if (resource != null && resource.exists()) {
			IMarker[] markers = resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			Set markerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
			if (markerTypes.isEmpty()) return markers;
			ArrayList markerList = new ArrayList(5);
			for (int i = 0, length = markers.length; i < length; i++) {
				markerList.add(markers[i]);
			}
			Iterator iterator = markerTypes.iterator();
			while (iterator.hasNext()) {
				markers = resource.findMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
				for (int i = 0, length = markers.length; i < length; i++) {
					markerList.add(markers[i]);
				}
			}
			IMarker[] result;
			markerList.toArray(result = new IMarker[markerList.size()]);
			return result;
		}
	} catch (CoreException e) {
		// assume there are no problems
	}
	return new IMarker[0];
}

public static IMarker[] getTasksFor(IResource resource) {
	try {
		if (resource != null && resource.exists())
			return resource.findMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
	} catch (CoreException e) {
		// assume there are no tasks
	}
	return new IMarker[0];
}

/**
 * Hook allowing to initialize some static state before a complete build iteration.
 * This hook is invoked during PRE_AUTO_BUILD notification
 */
public static void buildStarting() {
	// build is about to start
}

/**
 * Hook allowing to reset some static state after a complete build iteration.
 * This hook is invoked during POST_AUTO_BUILD notification
 */
public static void buildFinished() {
	BuildNotifier.resetProblemCounters();
}

public static void removeProblemsFor(IResource resource) {
	try {
		if (resource != null && resource.exists()) {
			resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);

			// delete managed markers
			Set markerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
			if (markerTypes.size() == 0) return;
			Iterator iterator = markerTypes.iterator();
			while (iterator.hasNext())
				resource.deleteMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
		}
	} catch (CoreException e) {
		// assume there were no problems
	}
}

public static void removeTasksFor(IResource resource) {
	try {
		if (resource != null && resource.exists())
			resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);
	} catch (CoreException e) {
		// assume there were no problems
	}
}

public static void removeProblemsAndTasksFor(IResource resource) {
	try {
		if (resource != null && resource.exists()) {
			resource.deleteMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			resource.deleteMarkers(IJavaModelMarker.TASK_MARKER, false, IResource.DEPTH_INFINITE);

			// delete managed markers
			Set markerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
			if (markerTypes.size() == 0) return;
			Iterator iterator = markerTypes.iterator();
			while (iterator.hasNext())
				resource.deleteMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
		}
	} catch (CoreException e) {
		// assume there were no problems
	}
}

public static State readState(IProject project, DataInputStream in) throws IOException, CoreException {
	return State.read(project, in);
}

public static void writeState(Object state, DataOutputStream out) throws IOException {
	((State) state).write(out);
}

@Override
protected IProject[] build(int kind, Map ignored, IProgressMonitor monitor) throws CoreException {
	this.currentProject = getProject();
	if (this.currentProject == null || !this.currentProject.isAccessible()) return new IProject[0];

	if (DEBUG)
		System.out.println("\nJavaBuilder: Starting build of " + this.currentProject.getName() //$NON-NLS-1$
			+ " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
	this.notifier = new BuildNotifier(monitor, this.currentProject);
	this.notifier.begin();
	boolean ok = false;
	try {
		this.notifier.checkCancel();
		kind = initializeBuilder(kind, true);

		if (isWorthBuilding()) {
			if (kind == FULL_BUILD) {
				if (DEBUG)
					System.out.println("JavaBuilder: Performing full build as requested"); //$NON-NLS-1$
				buildAll();
			} else {
				if ((this.lastState = getLastState(this.currentProject)) == null) {
					if (DEBUG)
						System.out.println("JavaBuilder: Performing full build since last saved state was not found"); //$NON-NLS-1$
					buildAll();
				} else if (hasClasspathChanged()) {
					// if the output location changes, do not delete the binary files from old location
					// the user may be trying something
					if (DEBUG)
						System.out.println("JavaBuilder: Performing full build since classpath has changed"); //$NON-NLS-1$
					buildAll();
				} else if (this.nameEnvironment.sourceLocations.length > 0 || this.testNameEnvironment.sourceLocations.length > 0) {
					// if there is no source to compile & no classpath changes then we are done
					SimpleLookupTable deltas = findDeltas();
					if (deltas == null) {
						if (DEBUG)
							System.out.println("JavaBuilder: Performing full build since deltas are missing after incremental request"); //$NON-NLS-1$
						buildAll();
					} else if (deltas.elementSize > 0) {
						if (hasJdtCoreSettingsChange(deltas) && !DISABLE_AUTO_BUILDING_ON_SETTINGS_CHANGE) {
							if (DEBUG)
								System.out.println("JavaBuilder: Performing full build since project settings have changed"); //$NON-NLS-1$
							buildAll();
						} else {
							buildDeltas(deltas);
						}
					} else if (DEBUG) {
						System.out.println("JavaBuilder: Nothing to build since deltas were empty"); //$NON-NLS-1$
					}
				} else {
					if (hasStructuralDelta()) { // double check that a jar file didn't get replaced in a binary project
						if (DEBUG)
							System.out.println("JavaBuilder: Performing full build since there are structural deltas"); //$NON-NLS-1$
						buildAll();
					} else {
						if (DEBUG)
							System.out.println("JavaBuilder: Nothing to build since there are no source folders and no deltas"); //$NON-NLS-1$
						this.lastState.tagAsNoopBuild();
					}
				}
			}
			ok = true;
		}
	} catch (CoreException e) {
		Util.log(e, "JavaBuilder handling CoreException while building: " + this.currentProject.getName()); //$NON-NLS-1$
		createInconsistentBuildMarker(e);
	} catch (ImageBuilderInternalException e) {
		Util.log(e.getThrowable(), "JavaBuilder handling ImageBuilderInternalException while building: " + this.currentProject.getName()); //$NON-NLS-1$
		createInconsistentBuildMarker(e.coreException);
	} catch (MissingSourceFileException e) {
		// do not log this exception since its thrown to handle aborted compiles because of missing source files
		if (DEBUG)
			System.out.println(Messages.bind(Messages.build_missingSourceFile, e.missingSourceFile));
		removeProblemsAndTasksFor(this.currentProject); // make this the only problem for this project
		IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
		marker.setAttributes(
			new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IMarker.SOURCE_ID},
			new Object[] {
				Messages.bind(Messages.build_missingSourceFile, e.missingSourceFile),
				Integer.valueOf(IMarker.SEVERITY_ERROR),
				JavaBuilder.SOURCE_ID
			}
		);
//{ObjectTeams: do not prevent e.g. the saving of a file, simply because our compiler is buggy
	} catch (InternalCompilerError e) {
		Util.log(e, "Object Teams JavaBuilder handling InternalCompilerException while building: " + this.currentProject.getName()); //$NON-NLS-1$
//carp}
	} finally {
		for (int i = 0, l = this.participants == null ? 0 : this.participants.length; i < l; i++)
			this.participants[i].buildFinished(this.javaProject);
		if (!ok)
			// If the build failed, clear the previously built state, forcing a full build next time.
			clearLastState();
		this.notifier.done();
		cleanup();
	}
	IProject[] requiredProjects = getRequiredProjects(true);
	if (DEBUG)
		System.out.println("JavaBuilder: Finished build of " + this.currentProject.getName() //$NON-NLS-1$
			+ " @ " + new Date(System.currentTimeMillis()) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
	return requiredProjects;
}

private void buildAll() {
	this.notifier.checkCancel();
	this.notifier.subTask(Messages.bind(Messages.build_preparingBuild, this.currentProject.getName()));
	if (DEBUG && this.lastState != null)
		System.out.println("JavaBuilder: Clearing last state : " + this.lastState); //$NON-NLS-1$
	clearLastState();
	BatchImageBuilder imageBuilder = new BatchImageBuilder(this, true, CompilationGroup.MAIN);
	BatchImageBuilder testImageBuilder = new BatchImageBuilder(imageBuilder, true, CompilationGroup.TEST);
	imageBuilder.build();
	if (testImageBuilder.sourceLocations.length > 0) {
		// Note: testImageBuilder *MUST* have a separate output folder, or it will delete the files created by imageBuilder.build() 
		testImageBuilder.build();
	} else {
		testImageBuilder.cleanUp();
	}
	recordNewState(imageBuilder.newState);
}

private void buildDeltas(SimpleLookupTable deltas) {
	this.notifier.checkCancel();
	this.notifier.subTask(Messages.bind(Messages.build_preparingBuild, this.currentProject.getName()));
	if (DEBUG && this.lastState != null)
		System.out.println("JavaBuilder: Clearing last state : " + this.lastState); //$NON-NLS-1$
	clearLastState(); // clear the previously built state so if the build fails, a full build will occur next time
//	{ObjectTeams: ROFI use overridable factory method:
/* orig:
	IncrementalImageBuilder imageBuilder = new IncrementalImageBuilder(this);
   :giro */
	IncrementalImageBuilder imageBuilder = makeImageBuilder(deltas);
// SH}
	if (imageBuilder.build(deltas)) {
		recordNewState(imageBuilder.newState);
	} else {
		if (DEBUG)
			System.out.println("JavaBuilder: Performing full build since incremental build failed"); //$NON-NLS-1$
		buildAll();
	}
}

//{ObjectTeams: ROFI: factory method for matching image builder
protected IncrementalImageBuilder makeImageBuilder(SimpleLookupTable deltas) {
	return new IncrementalImageBuilder(this);
}
// SH}

@Override
protected void clean(IProgressMonitor monitor) throws CoreException {
	this.currentProject = getProject();
	if (this.currentProject == null || !this.currentProject.isAccessible()) return;

	if (DEBUG)
		System.out.println("\nJavaBuilder: Cleaning " + this.currentProject.getName() //$NON-NLS-1$
			+ " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
	this.notifier = new BuildNotifier(monitor, this.currentProject);
	this.notifier.begin();
	try {
		this.notifier.checkCancel();

		initializeBuilder(CLEAN_BUILD, true);
		if (DEBUG)
			System.out.println("JavaBuilder: Clearing last state as part of clean : " + this.lastState); //$NON-NLS-1$
		clearLastState();
		removeProblemsAndTasksFor(this.currentProject);
		new BatchImageBuilder(this, false, CompilationGroup.MAIN).cleanOutputFolders(false);
		new BatchImageBuilder(this, false, CompilationGroup.TEST).cleanOutputFolders(false);
	} catch (CoreException e) {
		Util.log(e, "JavaBuilder handling CoreException while cleaning: " + this.currentProject.getName()); //$NON-NLS-1$
		createInconsistentBuildMarker(e);
	} finally {
		this.notifier.done();
		cleanup();
	}
	if (DEBUG)
		System.out.println("JavaBuilder: Finished cleaning " + this.currentProject.getName() //$NON-NLS-1$
			+ " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$
}

private void createInconsistentBuildMarker(CoreException coreException) throws CoreException {
	String message = null;
	IStatus status = coreException.getStatus();
 	if (status.isMultiStatus()) {
 		IStatus[] children = status.getChildren();
 		if (children != null && children.length > 0)
 		    message = children[0].getMessage();
 	}
 	if (message == null)
 		message = coreException.getMessage();

	IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
	marker.setAttributes(
		new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID},
		new Object[] {
			Messages.bind(Messages.build_inconsistentProject, message),
			Integer.valueOf(IMarker.SEVERITY_ERROR),
			Integer.valueOf(CategorizedProblem.CAT_BUILDPATH),
			JavaBuilder.SOURCE_ID
		}
	);
}

private void cleanup() {
	this.participants = null;
	if(this.nameEnvironment != null) {
		this.nameEnvironment.cleanup();
		this.nameEnvironment = null;
	}
	if(this.testNameEnvironment != null) {
		this.testNameEnvironment.cleanup();
		this.testNameEnvironment = null;
	}
	this.binaryLocationsPerProject = null;
	this.lastState = null;
	this.notifier = null;
	this.extraResourceFileFilters = null;
	this.extraResourceFolderFilters = null;
}

private void clearLastState() {
	JavaModelManager.getJavaModelManager().setLastBuiltState(this.currentProject, null);
}

boolean filterExtraResource(IResource resource) {
	if (this.extraResourceFileFilters != null) {
		char[] name = resource.getName().toCharArray();
		for (int i = 0, l = this.extraResourceFileFilters.length; i < l; i++)
			if (CharOperation.match(this.extraResourceFileFilters[i], name, true))
				return true;
	}
	if (this.extraResourceFolderFilters != null) {
		IPath path = resource.getProjectRelativePath();
		String pathName = path.toString();
		int count = path.segmentCount();
		if (resource.getType() == IResource.FILE) count--;
		for (int i = 0, l = this.extraResourceFolderFilters.length; i < l; i++)
			if (pathName.indexOf(this.extraResourceFolderFilters[i]) != -1)
				for (int j = 0; j < count; j++)
					if (this.extraResourceFolderFilters[i].equals(path.segment(j)))
						return true;
	}
	return false;
}

private SimpleLookupTable findDeltas() {
	this.notifier.subTask(Messages.bind(Messages.build_readingDelta, this.currentProject.getName()));
	IResourceDelta delta = getDelta(this.currentProject);
	SimpleLookupTable deltas = new SimpleLookupTable(3);
	if (delta != null) {
		if (delta.getKind() != IResourceDelta.NO_CHANGE) {
			if (DEBUG)
				System.out.println("JavaBuilder: Found source delta for: " + this.currentProject.getName()); //$NON-NLS-1$
			deltas.put(this.currentProject, delta);
		}
	} else {
		if (DEBUG)
			System.out.println("JavaBuilder: Missing delta for: " + this.currentProject.getName()); //$NON-NLS-1$
		this.notifier.subTask(""); //$NON-NLS-1$
		return null;
	}

	Object[] keyTable = this.binaryLocationsPerProject.keyTable;
	Object[] valueTable = this.binaryLocationsPerProject.valueTable;
	nextProject : for (int i = 0, l = keyTable.length; i < l; i++) {
		IProject p = (IProject) keyTable[i];
		if (p != null && p != this.currentProject) {
			State s = getLastState(p);
			if (!this.lastState.wasStructurallyChanged(p, s)) { // see if we can skip its delta
				if (s.wasNoopBuild())
					continue nextProject; // project has no source folders and can be skipped
				ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) valueTable[i];
				boolean canSkip = true;
				for (int j = 0, m = classFoldersAndJars.length; j < m; j++) {
					if (classFoldersAndJars[j].isOutputFolder())
						classFoldersAndJars[j] = null; // can ignore output folder since project was not structurally changed
					else
						canSkip = false;
				}
				if (canSkip) continue nextProject; // project has no structural changes in its output folders
			}

			this.notifier.subTask(Messages.bind(Messages.build_readingDelta, p.getName()));
			delta = getDelta(p);
			if (delta != null) {
				if (delta.getKind() != IResourceDelta.NO_CHANGE) {
					if (DEBUG)
						System.out.println("JavaBuilder: Found binary delta for: " + p.getName()); //$NON-NLS-1$
					deltas.put(p, delta);
				}
			} else {
				if (DEBUG)
					System.out.println("JavaBuilder: Missing delta for: " + p.getName());	 //$NON-NLS-1$
				this.notifier.subTask(""); //$NON-NLS-1$
				return null;
			}
		}
	}
	this.notifier.subTask(""); //$NON-NLS-1$
	return deltas;
}

public State getLastState(IProject project) {
	return (State) JavaModelManager.getJavaModelManager().getLastBuiltState(project, this.notifier.monitor);
}

/* Return the list of projects for which it requires a resource delta. This builder's project
* is implicitly included and need not be specified. Builders must re-specify the list
* of interesting projects every time they are run as this is not carried forward
* beyond the next build. Missing projects should be specified but will be ignored until
* they are added to the workspace.
*/
private IProject[] getRequiredProjects(boolean includeBinaryPrerequisites) {
	if (this.javaProject == null || this.workspaceRoot == null) return new IProject[0];

	LinkedHashSet<IProject> projects = new LinkedHashSet<>();
	ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager();
	try {
		IClasspathEntry[] entries = this.javaProject.getExpandedClasspath();
		for (int i = 0, l = entries.length; i < l; i++) {
			IClasspathEntry entry = entries[i];
			IPath path = entry.getPath();
			IProject p = null;
			switch (entry.getEntryKind()) {
				case IClasspathEntry.CPE_PROJECT :
					p = this.workspaceRoot.getProject(path.lastSegment()); // missing projects are considered too
					if (((ClasspathEntry) entry).isOptional() && !JavaProject.hasJavaNature(p)) // except if entry is optional
						p = null;
					break;
				case IClasspathEntry.CPE_LIBRARY :
					if (includeBinaryPrerequisites && path.segmentCount() > 0) {
						// some binary resources on the class path can come from projects that are not included in the project references
						IResource resource = this.workspaceRoot.findMember(path.segment(0));
						if (resource instanceof IProject) {
							p = (IProject) resource;
						} else {
							resource = externalFoldersManager.getFolder(path);
							if (resource != null)
								p = resource.getProject();
						}
					}
			}
			if (p != null && !projects.contains(p))
				projects.add(p);
		}
	} catch(JavaModelException e) {
		return new IProject[0];
	}
	IProject[] result = new IProject[projects.size()];
	projects.toArray(result);
	return result;
}

boolean hasBuildpathErrors() throws CoreException {
	IMarker[] markers = this.currentProject.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
	for (int i = 0, l = markers.length; i < l; i++)
		if (markers[i].getAttribute(IJavaModelMarker.CATEGORY_ID, -1) == CategorizedProblem.CAT_BUILDPATH)
			return true;
	return false;
}

private boolean hasJdtCoreSettingsChange(SimpleLookupTable deltas) {
	Object resourceDelta = deltas.get(this.currentProject);
	if (resourceDelta instanceof IResourceDelta) {
		IResourceDelta delta = (IResourceDelta) resourceDelta;
		class CheckForJdtCoreSettingsFileChange implements IResourceDeltaVisitor {

			boolean hasJdtCoreSettingsChange = false;

			@Override
			public boolean visit(IResourceDelta childDelta) throws CoreException {
				IResource resource = childDelta.getResource();
				boolean isJdtCoreSettingsResource = isJdtCoreSettingsResource(resource);
				if (isJdtCoreSettingsResource) {
					this.hasJdtCoreSettingsChange = true;
					return false; // stop visiting, the JDT core settings file changed
				}
				return true;
			}
		}
		try {
			CheckForJdtCoreSettingsFileChange visitor = new CheckForJdtCoreSettingsFileChange();
			delta.accept(visitor);
			return visitor.hasJdtCoreSettingsChange;
		} catch (CoreException e) {
			Util.log(e, "Failed to check whether deltas contain JDT preference changes"); //$NON-NLS-1$
		}
	}
	return false;
}

static boolean isJdtCoreSettingsResource(IResource resource) {
	IPath resourcePath = resource.getProjectRelativePath();
	boolean isJdtCoreSettingsResource = JDT_CORE_SETTINGS_PATH.equals(resourcePath);
	return isJdtCoreSettingsResource;
}

private boolean hasClasspathChanged() {
	return hasClasspathChanged(CompilationGroup.MAIN) || hasClasspathChanged(CompilationGroup.TEST);	
}

private boolean hasClasspathChanged(CompilationGroup compilationGroup) {
	ClasspathMultiDirectory[] newSourceLocations = (compilationGroup == CompilationGroup.MAIN ? this.nameEnvironment : this.testNameEnvironment).sourceLocations;
	ClasspathMultiDirectory[] oldSourceLocations = compilationGroup == CompilationGroup.MAIN ? this.lastState.sourceLocations : this.lastState.testSourceLocations;
	int newLength = newSourceLocations.length;
	int oldLength = oldSourceLocations.length;
	int n, o;
	for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
		if (newSourceLocations[n].equals(oldSourceLocations[o])) continue; // checks source & output folders
		try {
			if (newSourceLocations[n].sourceFolder.members().length == 0) { // added new empty source folder
				o--;
				continue;
			} else if (this.lastState.isSourceFolderEmpty(oldSourceLocations[o].sourceFolder)) {
				n--;
				continue;
			}
		} catch (CoreException ignore) { // skip it
		}
		if (DEBUG) {
			System.out.println("JavaBuilder: New location: " + newSourceLocations[n] + "\n!= old location: " + oldSourceLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
			printLocations(newSourceLocations, oldSourceLocations);
		}
		return true;
	}
	while (n < newLength) {
		try {
			if (newSourceLocations[n].sourceFolder.members().length == 0) { // added new empty source folder
				n++;
				continue;
			}
		} catch (CoreException ignore) { // skip it
		}
		if (DEBUG) {
			System.out.println("JavaBuilder: Added non-empty source folder"); //$NON-NLS-1$
			printLocations(newSourceLocations, oldSourceLocations);
		}
		return true;
	}
	while (o < oldLength) {
		if (this.lastState.isSourceFolderEmpty(oldSourceLocations[o].sourceFolder)) {
			o++;
			continue;
		}
		if (DEBUG) {
			System.out.println("JavaBuilder: Removed non-empty source folder"); //$NON-NLS-1$
			printLocations(newSourceLocations, oldSourceLocations);
		}
		return true;
	}

	ClasspathLocation[] newBinaryLocations = (compilationGroup == CompilationGroup.MAIN ? this.nameEnvironment : this.testNameEnvironment).binaryLocations;
	ClasspathLocation[] oldBinaryLocations = compilationGroup == CompilationGroup.MAIN ? this.lastState.binaryLocations : this.lastState.testBinaryLocations;
	newLength = newBinaryLocations.length;
	oldLength = oldBinaryLocations.length;
	for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
		if (newBinaryLocations[n].equals(oldBinaryLocations[o])) continue;
		if (DEBUG) {
			System.out.println("JavaBuilder: New location: " + newBinaryLocations[n] + "\n!= old location: " + oldBinaryLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
			printLocations(newBinaryLocations, oldBinaryLocations);
		}
		return true;
	}
	if (n < newLength || o < oldLength) {
		if (DEBUG) {
			System.out.println("JavaBuilder: Number of binary folders/jar files has changed:"); //$NON-NLS-1$
			printLocations(newBinaryLocations, oldBinaryLocations);
		}
		return true;
	}
	return false;
}

private boolean hasJavaBuilder(IProject project) throws CoreException {
	ICommand[] buildCommands = project.getDescription().getBuildSpec();
	for (int i = 0, l = buildCommands.length; i < l; i++)
		if (buildCommands[i].getBuilderName().equals(JavaCore.BUILDER_ID))
			return true;
	return false;
}

private boolean hasStructuralDelta() {
	// handle case when currentProject has only .class file folders and/or jar files... no source/output folders
	IResourceDelta delta = getDelta(this.currentProject);
	if (delta != null && delta.getKind() != IResourceDelta.NO_CHANGE) {
		ClasspathLocation[] classFoldersAndJars = (ClasspathLocation[]) this.binaryLocationsPerProject.get(this.currentProject);
		if (classFoldersAndJars != null) {
			for (int i = 0, l = classFoldersAndJars.length; i < l; i++) {
				ClasspathLocation classFolderOrJar = classFoldersAndJars[i]; // either a .class file folder or a zip/jar file
				if (classFolderOrJar != null) {
					IPath p = classFolderOrJar.getProjectRelativePath();
					if (p != null) {
						IResourceDelta binaryDelta = delta.findMember(p);
						if (binaryDelta != null && binaryDelta.getKind() != IResourceDelta.NO_CHANGE)
							return true;
					}
				}
			}
		}
	}
	return false;
}

private int initializeBuilder(int kind, boolean forBuild) throws CoreException {
	// some calls just need the nameEnvironment initialized so skip the rest
	this.javaProject = (JavaProject) JavaCore.create(this.currentProject);
	this.workspaceRoot = this.currentProject.getWorkspace().getRoot();

	if (forBuild) {
		// cache the known participants for this project
		this.participants = JavaModelManager.getJavaModelManager().compilationParticipants.getCompilationParticipants(this.javaProject);
		if (this.participants != null)
			for (int i = 0, l = this.participants.length; i < l; i++)
				if (this.participants[i].aboutToBuild(this.javaProject) == CompilationParticipant.NEEDS_FULL_BUILD)
					kind = FULL_BUILD;

		// Flush the existing external files cache if this is the beginning of a build cycle
		String projectName = this.currentProject.getName();
		if (builtProjects == null || builtProjects.contains(projectName)) {
			builtProjects = new LinkedHashSet();
		}
		builtProjects.add(projectName);
	}

	this.binaryLocationsPerProject = new SimpleLookupTable(3);
	this.nameEnvironment = new NameEnvironment(this.workspaceRoot, this.javaProject, this.binaryLocationsPerProject, this.notifier, CompilationGroup.MAIN);
	this.testNameEnvironment = new NameEnvironment(this.workspaceRoot, this.javaProject, this.binaryLocationsPerProject, this.notifier, CompilationGroup.TEST);

	if (forBuild) {
		String filterSequence = this.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, true);
		char[][] filters = filterSequence != null && filterSequence.length() > 0
			? CharOperation.splitAndTrimOn(',', filterSequence.toCharArray())
			: null;
		if (filters == null) {
			this.extraResourceFileFilters = null;
			this.extraResourceFolderFilters = null;
		} else {
			int fileCount = 0, folderCount = 0;
			for (int i = 0, l = filters.length; i < l; i++) {
				char[] f = filters[i];
				if (f.length == 0) continue;
				if (f[f.length - 1] == '/') folderCount++; else fileCount++;
			}
			this.extraResourceFileFilters = new char[fileCount][];
			this.extraResourceFolderFilters = new String[folderCount];
			for (int i = 0, l = filters.length; i < l; i++) {
				char[] f = filters[i];
				if (f.length == 0) continue;
				if (f[f.length - 1] == '/')
					this.extraResourceFolderFilters[--folderCount] = new String(f, 0, f.length - 1);
				else
					this.extraResourceFileFilters[--fileCount] = f;
			}
		}
	}
	return kind;
}

private boolean isClasspathBroken(JavaProject jProj, boolean tryRepair) throws CoreException {
	IMarker[] markers = jProj.getProject().findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
	for (int i = 0, l = markers.length; i < l; i++) {
		if (markers[i].getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) {
			if (tryRepair) {
				Object code = markers[i].getAttribute(IJavaModelMarker.ID);
				if (code instanceof Integer && ((Integer)code) == IJavaModelStatusConstants.CP_INVALID_EXTERNAL_ANNOTATION_PATH) {
					new ClasspathValidation(jProj).validate();
					return isClasspathBroken(jProj, false);
				}
			}
			return true;
		}
	}
	return false;
}

private boolean isWorthBuilding() throws CoreException {
	boolean abortBuilds =
		JavaCore.ABORT.equals(this.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true));
	if (!abortBuilds) {
		if (DEBUG)
			System.out.println("JavaBuilder: Ignoring invalid classpath"); //$NON-NLS-1$
		return true;
	}

	// Abort build only if there are classpath errors
	if (isClasspathBroken(this.javaProject, true)) {
		if (DEBUG)
			System.out.println("JavaBuilder: Aborted build because project has classpath errors (incomplete or involved in cycle)"); //$NON-NLS-1$

		removeProblemsAndTasksFor(this.currentProject); // remove all compilation problems

		IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
		marker.setAttributes(
			new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID},
			new Object[] {
				Messages.build_abortDueToClasspathProblems,
				Integer.valueOf(IMarker.SEVERITY_ERROR),
				Integer.valueOf(CategorizedProblem.CAT_BUILDPATH),
				JavaBuilder.SOURCE_ID
			}
		);
		return false;
	}

	if (JavaCore.WARNING.equals(this.javaProject.getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true)))
		return true;

	// make sure all prereq projects have valid build states... only when aborting builds since projects in cycles do not have build states
	// except for projects involved in a 'warning' cycle (see below)
	IProject[] requiredProjects = getRequiredProjects(false);
	for (int i = 0, l = requiredProjects.length; i < l; i++) {
		IProject p = requiredProjects[i];
		if (getLastState(p) == null)  {
			// The prereq project has no build state: if this prereq project has a 'warning' cycle marker then allow build (see bug id 23357)
			JavaProject prereq = (JavaProject) JavaCore.create(p);
			if (prereq.hasCycleMarker() && JavaCore.WARNING.equals(this.javaProject.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) {
				if (DEBUG)
					System.out.println("JavaBuilder: Continued to build even though prereq project " + p.getName() //$NON-NLS-1$
						+ " was not built since its part of a cycle"); //$NON-NLS-1$
				continue;
			}
			if (!hasJavaBuilder(p)) {
				if (DEBUG)
					System.out.println("JavaBuilder: Continued to build even though prereq project " + p.getName() //$NON-NLS-1$
						+ " is not built by JavaBuilder"); //$NON-NLS-1$
				continue;
			}
			if (DEBUG)
				System.out.println("JavaBuilder: Aborted build because prereq project " + p.getName() //$NON-NLS-1$
					+ " was not built"); //$NON-NLS-1$

			removeProblemsAndTasksFor(this.currentProject); // make this the only problem for this project
			IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
			marker.setAttributes(
				new String[] {IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID},
				new Object[] {
					isClasspathBroken(prereq, true)
						? Messages.bind(Messages.build_prereqProjectHasClasspathProblems, p.getName())
						: Messages.bind(Messages.build_prereqProjectMustBeRebuilt, p.getName()),
					Integer.valueOf(IMarker.SEVERITY_ERROR),
					Integer.valueOf(CategorizedProblem.CAT_BUILDPATH),
					JavaBuilder.SOURCE_ID
				}
			);
			return false;
		}
	}
	return true;
}

/*
 * Instruct the build manager that this project is involved in a cycle and
 * needs to propagate structural changes to the other projects in the cycle.
 */
void mustPropagateStructuralChanges() {
	LinkedHashSet cycleParticipants = new LinkedHashSet(3);
	this.javaProject.updateCycleParticipants(new ArrayList(), cycleParticipants, this.workspaceRoot, new HashSet(3), null);
	IPath currentPath = this.javaProject.getPath();
	Iterator i= cycleParticipants.iterator();
	while (i.hasNext()) {
		IPath participantPath = (IPath) i.next();
		if (participantPath != currentPath) {
			IProject project = this.workspaceRoot.getProject(participantPath.segment(0));
			if (hasBeenBuilt(project)) {
				if (DEBUG)
					System.out.println("JavaBuilder: Requesting another build iteration since cycle participant " + project.getName() //$NON-NLS-1$
						+ " has not yet seen some structural changes"); //$NON-NLS-1$
				needRebuild();
				return;
			}
		}
	}
}

private void printLocations(ClasspathLocation[] newLocations, ClasspathLocation[] oldLocations) {
	System.out.println("JavaBuilder: New locations:"); //$NON-NLS-1$
	for (int i = 0, length = newLocations.length; i < length; i++)
		System.out.println("    " + newLocations[i].debugPathString()); //$NON-NLS-1$
	System.out.println("JavaBuilder: Old locations:"); //$NON-NLS-1$
	for (int i = 0, length = oldLocations.length; i < length; i++)
		System.out.println("    " + oldLocations[i].debugPathString()); //$NON-NLS-1$
}

private void recordNewState(State state) {
	Object[] keyTable = this.binaryLocationsPerProject.keyTable;
	for (int i = 0, l = keyTable.length; i < l; i++) {
		IProject prereqProject = (IProject) keyTable[i];
		if (prereqProject != null && prereqProject != this.currentProject)
			state.recordStructuralDependency(prereqProject, getLastState(prereqProject));
	}

	if (DEBUG)
		System.out.println("JavaBuilder: Recording new state : " + state); //$NON-NLS-1$
	// state.dump();
	JavaModelManager.getJavaModelManager().setLastBuiltState(this.currentProject, state);
}

/**
 * String representation for debugging purposes
 */
@Override
public String toString() {
	return this.currentProject == null
		? "JavaBuilder for unknown project" //$NON-NLS-1$
		: "JavaBuilder for " + this.currentProject.getName(); //$NON-NLS-1$
}

//{ObjectTeams:
/**
 * @param path
 */
public SourceFile findSourceByPath(IPath path) {
	path = path.removeFirstSegments(1); // chop off prj
	if (path.isEmpty()) // default package
		return null;

	IFile file = this.currentProject.getFile(path); // consider other projects?
	if (file.exists()) {
		for (int i = 0; i < this.nameEnvironment.sourceLocations.length; i++) {
			ClasspathMultiDirectory md = this.nameEnvironment.sourceLocations[i];
			// TODO (SH): find the md that actually contains path!
			return new SourceFile(file, md);
		}
	}
	return null;
}
// SH}
}
