/*******************************************************************************
 * Copyright (c) 2007, 2019 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
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 458995
 *******************************************************************************/
package org.eclipse.pde.api.tools.internal.builder;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.jar.JarFile;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.builder.State;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.api.tools.internal.ApiDescriptionManager;
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
import org.eclipse.pde.api.tools.internal.provisional.builder.IApiAnalyzer;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
import org.eclipse.pde.api.tools.internal.util.Util;
import org.eclipse.pde.core.build.IBuild;
import org.eclipse.pde.core.build.IBuildEntry;
import org.eclipse.pde.core.build.IBuildModel;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.eclipse.pde.internal.core.ICoreConstants;
import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.PDEPreferencesManager;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;

/**
 * Builder for creating API Tools resource markers
 *
 * @since 1.0.0
 */
public class ApiAnalysisBuilder extends IncrementalProjectBuilder {
	/**
	 * Project relative path to the .settings folder
	 *
	 * @since 1.0.1
	 */
	static final IPath SETTINGS_PATH = new Path(".settings"); //$NON-NLS-1$

	/**
	 * Project relative path to the build.properties file
	 */
	public static final IPath BUILD_PROPERTIES_PATH = new Path("build.properties"); //$NON-NLS-1$

	/**
	 * Project relative path to the manifest file.
	 */
	public static final IPath MANIFEST_PATH = new Path(JarFile.MANIFEST_NAME);

	/**
	 * {@link Comparator} to sort {@link ManifestElement}s
	 *
	 * @since 1.0.3
	 */
	static final Comparator<ManifestElement> fgManifestElementComparator = (o1, o2) -> o1.getValue().compareTo(o2.getValue());

	/**
	 * Array of header names that we care about when a manifest delta is
	 * discovered
	 *
	 * @since 1.0.3
	 */
	public static final HashSet<String> IMPORTANT_HEADERS = new HashSet<>(7);

	static {
		IMPORTANT_HEADERS.add(Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
		IMPORTANT_HEADERS.add(Constants.BUNDLE_VERSION);
		IMPORTANT_HEADERS.add(Constants.REQUIRE_BUNDLE);
		IMPORTANT_HEADERS.add(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
		IMPORTANT_HEADERS.add(Constants.EXPORT_PACKAGE);
		IMPORTANT_HEADERS.add(Constants.IMPORT_PACKAGE);
		IMPORTANT_HEADERS.add(Constants.BUNDLE_CLASSPATH);
	}

	/**
	 * Project relative path to the .api_filters file
	 */
	static final IPath FILTER_PATH = SETTINGS_PATH.append(IApiCoreConstants.API_FILTERS_XML_NAME);

	/**
	 * Empty listing of projects to be returned by the builder if there is
	 * nothing to do
	 */
	static final IProject[] NO_PROJECTS = new IProject[0];

	/**
	 * Constant representing the name of the 'source' attribute on API Tools
	 * markers. Value is <code>API Tools</code>
	 */
	static final String SOURCE = "API Tools"; //$NON-NLS-1$

	/**
	 * Boolean flag to disable the API builder (the builder will always return
	 * {@link #NO_PROJECTS}. Not accessible from the UI by default, but can be
	 * set by other tools. The behaviour is not API and may be changed or
	 * removed in a future release. See bug 221913.
	 */
	private static boolean buildDisabled = false;

	/**
	 * The current project for which this builder was defined
	 */
	private IProject currentproject = null;

	/**
	 * The API analyzer for this builder
	 */
	private IApiAnalyzer analyzer = null;

	/**
	 * Maps prerequisite projects to their output location(s)
	 */
	HashMap<IProject, HashSet<IPath>> output_locs = new HashMap<>();

	/**
	 * Maps prerequisite projects to their source locations
	 */
	HashMap<IProject, HashSet<IPath>> src_locs = new HashMap<>();

	/**
	 * Current build state
	 */
	private BuildState buildstate = null;

	private ConcurrentLinkedQueue<Runnable> markersQueue = new ConcurrentLinkedQueue<>();

	/**
	 * Bug 549838:  In case auto-building on a API tools settings change  is not desired,
	 * specify VM property: {@code -Dorg.eclipse.disableAutoBuildOnSettingsChange=true}
	 */
	private static final boolean DISABLE_AUTO_BUILDING_ON_SETTINGS_CHANGE = Boolean.getBoolean("org.eclipse.disableAutoBuildOnSettingsChange"); //$NON-NLS-1$

	/**
	 * Cleans up markers associated with API Tools on the given resource.
	 *
	 * @param resource
	 */
	void cleanupMarkers(IResource resource) {
		if (isRunningAsJob()) {
			ApiAnalysisMarkersJob job = new ApiAnalysisMarkersJob(() -> cleanupMarkersInternally(resource));
			job.schedule();
		} else {
			cleanupMarkersInternally(resource);
		}
	}

	/**
	 * Cleans up markers associated with API Tools on the given resource.
	 *
	 * @param resource
	 */
	void cleanupMarkersInternally(IResource resource) {
		cleanUnusedFilterMarkers(resource);
		cleanupUsageMarkers(resource);
		cleanupCompatibilityMarkers(resource);
		cleanupUnsupportedTagMarkers(resource);
		cleanupUnsupportedAnnotationMarkers(resource);
		cleanApiUseScanMarkers(resource);
		cleanupFatalMarkers(resource);
	}

	/**
	 * Cleans up API use scan breakage related markers on the specified resource
	 *
	 * @param resource
	 */
	void cleanApiUseScanMarkers(IResource resource) {
		try {
			if (resource != null && resource.isAccessible()) {
				if (ApiPlugin.DEBUG_BUILDER) {
					System.out.println("ApiAnalysisBuilder: cleaning api use problems"); //$NON-NLS-1$
				}
				resource.deleteMarkers(IApiMarkerConstants.API_USESCAN_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);

				IProject project = resource.getProject();
				IMarker[] markers = project.findMarkers(IApiMarkerConstants.API_USESCAN_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
				for (IMarker marker : markers) {
					String typeName = marker.getAttribute(IApiMarkerConstants.API_USESCAN_TYPE, null);
					IJavaElement adaptor = resource.getAdapter(IJavaElement.class);
					if (adaptor != null && adaptor instanceof ICompilationUnit) {
						IType typeroot = ((ICompilationUnit) adaptor).findPrimaryType();
						if (typeroot != null && typeName != null && typeName.startsWith(typeroot.getFullyQualifiedName())) {
							marker.delete();
						}
					}
				}
			}
		} catch (CoreException e) {
			ApiPlugin.log(e.getStatus());
		}
	}

	/**
	 * Cleans up unsupported Javadoc tag markers on the specified resource
	 *
	 * @param resource
	 */
	void cleanupUnsupportedTagMarkers(IResource resource) {
		try {
			if (resource != null && resource.isAccessible()) {
				if (ApiPlugin.DEBUG_BUILDER) {
					System.out.println("ApiAnalysisBuilder: cleaning unsupported tag problems"); //$NON-NLS-1$
				}
				resource.deleteMarkers(IApiMarkerConstants.UNSUPPORTED_TAG_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			}
		} catch (CoreException e) {
			ApiPlugin.log(e.getStatus());
		}
	}

	/**
	 * Removes all of the unsupported annotation markers from the given resource
	 * and all of its children
	 *
	 * @param resource
	 * @since 1.0.600
	 */
	void cleanupUnsupportedAnnotationMarkers(IResource resource) {
		try {
			if (resource != null && resource.isAccessible()) {
				if (ApiPlugin.DEBUG_BUILDER) {
					System.out.println("ApiAnalysisBuilder: cleaning unsupported annotation problems"); //$NON-NLS-1$
				}
				resource.deleteMarkers(IApiMarkerConstants.UNSUPPORTED_ANNOTATION_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			}
		} catch (CoreException e) {
			ApiPlugin.log(e.getStatus());
		}
	}

	/**
	 * Cleans up only API compatibility markers on the given {@link IResource}
	 *
	 * @param resource the given resource
	 */
	void cleanupCompatibilityMarkers(IResource resource) {
		try {
			if (resource != null && resource.isAccessible()) {
				resource.deleteMarkers(IApiMarkerConstants.COMPATIBILITY_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
				resource.deleteMarkers(IApiMarkerConstants.SINCE_TAGS_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
				if (resource.getType() == IResource.PROJECT) {
					// on full builds
					resource.deleteMarkers(IApiMarkerConstants.VERSION_NUMBERING_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
					resource.deleteMarkers(IApiMarkerConstants.DEFAULT_API_BASELINE_PROBLEM_MARKER, true, IResource.DEPTH_ZERO);
					resource.deleteMarkers(IApiMarkerConstants.API_COMPONENT_RESOLUTION_PROBLEM_MARKER, true, IResource.DEPTH_ZERO);
				}
			}
		} catch (CoreException e) {
			ApiPlugin.log(e.getStatus());
		}
	}

	/**
	 * cleans up only API usage markers from the given {@link IResource}
	 *
	 * @param resource
	 */
	void cleanupUsageMarkers(IResource resource) {
		try {
			if (resource != null && resource.isAccessible()) {
				resource.deleteMarkers(IApiMarkerConstants.API_USAGE_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
				if (resource.getType() != IResource.PROJECT) {
					IProject pj = resource.getProject();
					if (pj != null) {
						pj.deleteMarkers(IApiMarkerConstants.API_USAGE_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
					}
				}
			}
		} catch (CoreException e) {
			ApiPlugin.log(e.getStatus());
		}
	}

	/**
	 * cleans up only fatal problem markers from the given {@link IResource}
	 *
	 * @param resource
	 */
	void cleanupFatalMarkers(IResource resource) {
		try {
			if (resource != null && resource.isAccessible()) {
				resource.deleteMarkers(IApiMarkerConstants.FATAL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			}
		} catch (CoreException e) {
			ApiPlugin.log(e.getStatus());
		}
	}

	/**
	 * Cleans up the unused API filter problems from the given resource
	 *
	 * @param resource
	 */
	void cleanUnusedFilterMarkers(IResource resource) {
		try {
			if (resource != null && resource.isAccessible()) {
				resource.deleteMarkers(IApiMarkerConstants.UNUSED_FILTER_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			}
		} catch (CoreException ce) {
			ApiPlugin.log(ce.getStatus());
		}
	}

	@Override
	public ISchedulingRule getRule(int kind, Map<String, String> args) {
		// TODO probably we don't need even this and can return null if we are running as job
		// if(isRunningAsJob()) return null;
		return currentproject;
	}

	@Override
	protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
		PDEPreferencesManager prefs = PDECore.getDefault().getPreferencesManager();
		boolean disableAPIAnalysisBuilder = prefs.getBoolean(ICoreConstants.DISABLE_API_ANALYSIS_BUILDER);
		if (disableAPIAnalysisBuilder) {
			return NO_PROJECTS;
		}
		this.currentproject = getProject();
		if (buildDisabled || shouldAbort(this.currentproject)) {
			return NO_PROJECTS;
		}
		// update build time stamp
		BuildStamps.incBuildStamp(this.currentproject);
		if (ApiPlugin.DEBUG_BUILDER) {
			System.out.println("\nApiAnalysisBuilder: Starting build of " + this.currentproject.getName() + " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$ //$NON-NLS-2$
		}
		IApiBaseline wbaseline = ApiPlugin.getDefault().getApiBaselineManager().getWorkspaceBaseline();
		if (wbaseline == null) {
			if (ApiPlugin.DEBUG_BUILDER) {
				System.err.println("ApiAnalysisBuilder: Could not retrieve a workspace baseline"); //$NON-NLS-1$
			}
			return NO_PROJECTS;
		}
		final IProject[] projects = getRequiredProjects(true);
		if (kind != FULL_BUILD && kind != AUTO_BUILD && kind != INCREMENTAL_BUILD) {
			return projects;
		}
		boolean fullBuild = kind == FULL_BUILD;
		boolean runAsJob = prefs.getBoolean(ICoreConstants.RUN_API_ANALYSIS_AS_JOB);
		if (runAsJob) {
			ApiAnalysisJob job = new ApiAnalysisJob(BuilderMessages.api_analysis_builder, currentproject, fullBuild,
					wbaseline, projects);
			job.cancelSimilarJobs(fullBuild);
			job.schedule(100);
		} else {
			work(fullBuild, wbaseline, projects, monitor);
		}
		return projects;
	}

	protected void work(final boolean fullBuild, IApiBaseline wbaseline, IProject[] projects, IProgressMonitor monitor)
			throws CoreException {
		SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_builder, 8);

		IApiBaseline baseline = ApiPlugin.getDefault().getApiBaselineManager().getDefaultApiBaseline();
		try {
			SubMonitor switchMonitor = localMonitor.split(4);
			if (fullBuild) {
				if (ApiPlugin.DEBUG_BUILDER) {
					System.out.println("ApiAnalysisBuilder: Performing full build as requested"); //$NON-NLS-1$
				}
				buildAll(baseline, wbaseline, switchMonitor);
			} else {
				this.buildstate = BuildState.getLastBuiltState(currentproject);
				if (this.buildstate == null) {
					buildAll(baseline, wbaseline, switchMonitor);
				} else if (worthDoingFullBuild(projects)) {
					buildAll(baseline, wbaseline, switchMonitor);
				} else {
					IResourceDelta[] deltas = getDeltas(projects);
					if (deltas.length < 1) {
						buildAll(baseline, wbaseline, switchMonitor);
					} else {
						IResourceDelta filters = null;
						boolean full = false;
						for (IResourceDelta delta : deltas) {
							full = shouldFullBuild(delta);
							if (full) {
								break;
							}
							filters = delta.findMember(FILTER_PATH);
							if (filters != null) {
								switch (filters.getKind()) {
									case IResourceDelta.ADDED:
									case IResourceDelta.REMOVED: {
										full = true;
										break;
									}
									case IResourceDelta.CHANGED: {
										full = (filters.getFlags() & (IResourceDelta.REPLACED | IResourceDelta.CONTENT)) > 0;
										break;
									}
									default: {
										break;
									}
								}
								if (full) {
									break;
								}
							}
						}
						if (full) {
							if (ApiPlugin.DEBUG_BUILDER) {
								System.out.println("ApiAnalysisBuilder: Performing full build since MANIFEST.MF or .api_filters was modified"); //$NON-NLS-1$
							}
							buildAll(baseline, wbaseline, switchMonitor);
						} else {
							switchMonitor.setWorkRemaining(2);
							State state = (State) JavaModelManager.getJavaModelManager().getLastBuiltState(this.currentproject, switchMonitor.split(1));
							if (state == null) {
								buildAll(baseline, wbaseline, switchMonitor.split(1));
							} else {
								BuildState.setLastBuiltState(this.currentproject, null);
								IncrementalApiBuilder builder = new IncrementalApiBuilder(this);
								builder.build(baseline, wbaseline, deltas, state, this.buildstate, switchMonitor.split(1));
							}
						}
					}
				}
			}
			localMonitor.split(1);
		} catch (OperationCanceledException oce) {
			// do nothing, but don't forward it
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304315
			if (ApiPlugin.DEBUG_BUILDER) {
				System.out.println("ApiAnalysisBuilder: Trapped OperationCanceledException"); //$NON-NLS-1$
			}
		} catch (CoreException e) {
			IStatus status = e.getStatus();
			if (status == null || status.getCode() != ApiPlugin.REPORT_BASELINE_IS_DISPOSED) {
				throw e;
			}
			ApiPlugin.log(e);
		} finally {
			try {
				localMonitor.split(1);
				if (this.analyzer != null) {
					this.analyzer.dispose();
					this.analyzer = null;
				}
				if (projects.length < 1) {
					// if this build cycle indicates that more projects need to
					// be built do not close
					// the baselines yet, they might be re-read by another build
					// cycle
					// TODO: this seem to be not needed anymore.
					//	if (baseline != null) {
					//		baseline.close();
					//	}
				}
				localMonitor.split(1);
				if (this.buildstate != null) {
					for (IProject project : projects) {
						if (Util.isApiProject(project)) {
							this.buildstate.addApiToolingDependentProject(project.getName());
						}
					}
					this.buildstate.setBuildPathCRC(BuildState.computeBuildPathCRC(this.currentproject));
					IFile manifest = (IFile) currentproject.findMember(MANIFEST_PATH);
					if (manifest != null && manifest.exists()) {
						try {
							this.buildstate.setManifestState(ManifestElement.parseBundleManifest(manifest.getContents(), null));
						} catch (Exception e) {
							ApiPlugin
									.log(Status.error("Error parsing the manifest of: " + currentproject.getName(), e));//$NON-NLS-1$
						}
					}
					IPluginModelBase base = PluginRegistry.findModel(currentproject);
					if (base != null) {
						try {
							IBuildModel model = PluginRegistry.createBuildModel(base);
							if (model != null) {
								this.buildstate.setBuildPropertiesState(model);
							}
						} catch (CoreException ce) {
							ApiPlugin.log(ce);
						}
					}
					BuildState.saveBuiltState(this.currentproject, this.buildstate);
					this.buildstate = null;
					localMonitor.split(1);
				}
				SubMonitor.done(monitor);
			} catch (OperationCanceledException oce) {
				// do nothing, but don't forward it
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304315
				if (ApiPlugin.DEBUG_BUILDER) {
					System.out.println("ApiAnalysisBuilder: Trapped OperationCanceledException"); //$NON-NLS-1$
				}
			}
		}
		if (ApiPlugin.DEBUG_BUILDER) {
			System.out.println("ApiAnalysisBuilder: Finished build of " + this.currentproject.getName() + " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	class ApiAnalysisJob extends Job {

		private boolean fullBuild;
		private IApiBaseline wbaseline;
		private IProject[] projects;
		private IProject project;

		public ApiAnalysisJob(String name, IProject project, boolean fullBuild, IApiBaseline wbaseline,
				IProject[] projects) {
			super(name);
			this.project = project;
			this.fullBuild = fullBuild;
			this.wbaseline = wbaseline;
			this.projects = projects;
			// Intentionally no rule set to allow run in parallel with build locking entire workspace
			// setRule(project);
		}

		@Override
		public IStatus run(IProgressMonitor monitor) {
			try {
				work(fullBuild, wbaseline, projects, monitor);
			} catch (CoreException e) {
				return e.getStatus();
			}
			return Status.OK_STATUS;
		}

		@Override
		public boolean belongsTo(Object family) {
			return super.belongsTo(family) || ApiAnalysisJob.class == family;
		}

		void cancelSimilarJobs(boolean fullBuild) {
			Job[] jobs = Job.getJobManager().find(ApiAnalysisJob.class);
			for (Job job : jobs) {
				ApiAnalysisJob ajob = (ApiAnalysisJob) job;
				if (fullBuild == ajob.fullBuild && project.equals(ajob.project)) {
					job.cancel();
				}
			}
		}
	}

	/**
	 * Returns if the backing project should be fully built, based on the delta
	 *
	 * @param delta the {@link IResourceDelta} to examine
	 * @return <code>true</code> if the project should have a full build,
	 *         <code>false</code> otherwise
	 * @since 1.0.3
	 */
	boolean shouldFullBuild(IResourceDelta delta) {
		switch (delta.getKind()) {
			case IResourceDelta.CHANGED: {
				IResourceDelta subdelta = delta.findMember(MANIFEST_PATH);
				if (subdelta != null) {
					IFile file = (IFile) subdelta.getResource();
					return file.getProject().equals(currentproject) && compareManifest(file, buildstate);
				}
				subdelta = delta.findMember(BUILD_PROPERTIES_PATH);
				if (subdelta != null) {
					IFile file = (IFile) subdelta.getResource();
					return file.getProject().equals(currentproject) && compareBuildProperties(buildstate);
				}
				subdelta = delta.findMember(SETTINGS_PATH);
				if (subdelta != null) {
					if (!DISABLE_AUTO_BUILDING_ON_SETTINGS_CHANGE) {
						return true;
					}
				}
				break;
			}
			default: {
				break;
			}
		}
		return false;
	}

	/**
	 * Compares the current <code>MANIFEST.MF</code> against the saved state. If
	 * the {@link BuildState} is <code>null</code> or there is no saved state
	 * for the current project context a full build is assumed.
	 *
	 * @param manifest the handle to the <code>MANIFEST.MF</code> file
	 * @param state the current {@link BuildState} or <code>null</code>
	 * @return <code>true</code> if there are changes that require a full build,
	 *         <code>false</code> otherwise
	 * @since 1.0.3
	 */
	boolean compareManifest(IFile manifest, BuildState state) {
		if (state != null) {
			try {
				Map<String, String> stateheaders = state.getManifestState();
				if (stateheaders != null) {
					Map<String, String> headers = ManifestElement.parseBundleManifest(manifest.getContents(), null);
					Entry<String, String> entry = null;
					for (Iterator<Entry<String, String>> i = stateheaders.entrySet().iterator(); i.hasNext();) {
						entry = i.next();
						String key = entry.getKey();
						String value = headers.get(key);
						ManifestElement[] e1 = ManifestElement.parseHeader(key, value);
						ManifestElement[] e2 = ManifestElement.parseHeader(key, entry.getValue());
						if (e1 != null && e2 != null && e1.length == e2.length) {
							Arrays.sort(e1, fgManifestElementComparator);
							Arrays.sort(e2, fgManifestElementComparator);
							for (int j = 0; j < e1.length; j++) {
								String[] v1 = e1[j].getValueComponents();
								String[] v2 = e2[j].getValueComponents();
								// compare value bits
								if (v1.length == v2.length) {
									Arrays.sort(v1);
									Arrays.sort(v2);
									for (int k = 0; k < v2.length; k++) {
										if (!v1[k].equals(v2[k])) {
											return true;
										}
									}
								} else {
									return true;
								}
								// compare directives
								Enumeration<String> e = e1[j].getDirectiveKeys();
								if (e != null) {
									while (e.hasMoreElements()) {
										String key2 = e.nextElement();
										if (!Util.equalsOrNull(e1[j].getDirective(key2), e2[j].getDirective(key2))) {
											return true;
										}
									}
								}
								// compare attributes
								e = e1[j].getKeys();
								if (e != null) {
									while (e.hasMoreElements()) {
										String key2 = e.nextElement();
										if (!Util.equalsOrNull(e1[j].getAttribute(key2), e2[j].getAttribute(key2))) {
											return true;
										}
									}
								}
							}
						} else {
							return true;
						}
					}
					return false;
				}
			} catch (Exception e) {
				ApiPlugin.log(e);
				return false;
			}
		}
		return true;
	}

	/**
	 * Compares the current <code>build.properties</code> against the saved one.
	 * If the given {@link BuildState} is <code>null</code> or there is no saved
	 * state for the current project context a full build is assumed.
	 *
	 * @param state the current {@link BuildState} or <code>null</code>
	 * @return <code>true</code> if there are changes that require a full build,
	 *         <code>false</code> otherwise
	 * @since 1.0.3
	 */
	boolean compareBuildProperties(BuildState state) {
		if (state != null) {
			Map<String, String> map = state.getBuildPropertiesState();
			if (map != null) {
				IPluginModelBase base = PluginRegistry.findModel(currentproject);
				if (base != null) {
					try {
						IBuildModel model = PluginRegistry.createBuildModel(base);
						if (model != null) {
							IBuild ibuild = model.getBuild();
							Entry<String, String> entry;
							for (Iterator<Entry<String, String>> i = map.entrySet().iterator(); i.hasNext();) {
								entry = i.next();
								IBuildEntry be = ibuild.getEntry(entry.getKey());
								if (be != null && !entry.getValue().equals(Util.deepToString(be.getTokens()))) {
									return true;
								}
							}
						}
					} catch (CoreException ce) {
						ApiPlugin.log(ce);
						return false;
					}
				}
			}
			return false;
		}
		return true;
	}

	/**
	 * Returns if the builder should abort the build of the given project. The
	 * build decides to abort if one of the following are true:
	 * <ul>
	 * <li>The project is not accessible</li>
	 * <li>The project does not have the API tools nature</li>
	 * <li>The project has already been built - as decided by the build
	 * framework</li>
	 * <li>The project has fatal JDT errors that prevent the creation of class
	 * files</li>
	 * </ul>
	 *
	 * @param project
	 * @return true if the builder should abort building the given project,
	 *         false otherwise
	 * @throws CoreException
	 * @see {@link #hasBeenBuilt(IProject)}
	 * @see {@link #hasFatalProblems(IProject)}
	 * @since 1.1
	 */
	boolean shouldAbort(IProject project) throws CoreException {
		return !project.isAccessible() || !project.hasNature(ApiPlugin.NATURE_ID) || hasBeenBuilt(project) || hasFatalProblems(project);
	}

	/**
	 * Returns if the project we are about to build has fatal JDT problems that
	 * prevent class files from being built
	 *
	 * @param project
	 * @return true if the given project has fatal JDT problems
	 * @see
	 * @throws CoreException
	 * @see {@link org.eclipse.jdt.core.IJavaModelMarker#BUILDPATH_PROBLEM_MARKER}
	 * @since 1.1
	 */
	boolean hasFatalProblems(IProject project) throws CoreException {
		boolean hasFatalProblem = false;
		IMarker[] problems = project.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_ZERO);
		for (IMarker iMarker : problems) {
			Object att = iMarker.getAttribute(IMarker.SEVERITY);
			if (att != null && att instanceof Integer) {
				if (((Integer) att).intValue() == IMarker.SEVERITY_ERROR) {
					hasFatalProblem = true;
					break;
				}
			}
		}

		Runnable task;
		if (hasFatalProblem) {
			task = () -> {
				cleanupMarkers(project);
				IApiProblem problem = ApiProblemFactory.newFatalProblem(Path.EMPTY.toString(), new String[] { project.getName() }, IApiProblem.FATAL_JDT_BUILDPATH_PROBLEM);
				createMarkerForProblem(IApiProblem.CATEGORY_FATAL_PROBLEM, IApiMarkerConstants.FATAL_PROBLEM_MARKER, problem);
			};
		} else {
			task = () -> cleanupFatalMarkers(project);
		}

		boolean runAsJob = isRunningAsJob();
		if (runAsJob) {
			new ApiAnalysisMarkersJob(task).schedule();
		} else {
			task.run();
		}
		return hasFatalProblem;
	}

	private static boolean isRunningAsJob() {
		PDEPreferencesManager prefs = PDECore.getDefault().getPreferencesManager();
		boolean runAsJob = prefs.getBoolean(ICoreConstants.RUN_API_ANALYSIS_AS_JOB);
		return runAsJob;
	}

	/**
	 * if its worth doing a full build considering the given set if projects
	 *
	 * @param projects projects to check the build state for
	 * @return true if a full build should take place, false otherwise
	 */
	boolean worthDoingFullBuild(IProject[] projects) {
		Set<String> apiToolingDependentProjects = this.buildstate.getApiToolingDependentProjects();
		for (IProject currentProject : projects) {
			if (Util.isApiProject(currentProject)) {
				if (apiToolingDependentProjects.contains(currentProject.getName())) {
					continue;
				}
				return true;
			} else if (apiToolingDependentProjects.contains(currentProject.getName())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Performs a full build for the project
	 *
	 * @param baseline the default baseline
	 * @param wbaseline the workspace baseline
	 * @param monitor
	 */
	void buildAll(IApiBaseline baseline, IApiBaseline wbaseline, IProgressMonitor monitor) throws CoreException {
		PDEPreferencesManager prefs = PDECore.getDefault().getPreferencesManager();
		boolean disableAPIAnalysisBuilder = prefs.getBoolean(ICoreConstants.DISABLE_API_ANALYSIS_BUILDER);
		if (disableAPIAnalysisBuilder) {
			return;
		}
		SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 4);
		try {
			BuildState.setLastBuiltState(this.currentproject, null);
			this.buildstate = new BuildState();
			localMonitor.subTask(NLS.bind(BuilderMessages.ApiAnalysisBuilder_initializing_analyzer, currentproject.getName()));
			cleanupMarkers(this.currentproject);
			IPluginModelBase currentModel = getCurrentModel();
			if (currentModel != null) {
				localMonitor.subTask(BuilderMessages.building_workspace_profile);
				localMonitor.split(1);
				String id = currentModel.getBundleDescription().getSymbolicName();
				// Compatibility checks
				IApiComponent apiComponent = wbaseline.getApiComponent(id);
				Set<IApiComponent> apiComponentMultiple = wbaseline.getAllApiComponents(id);
				if (!apiComponentMultiple.isEmpty()) {
					// add the exact match
					for (Iterator<IApiComponent> iterator = apiComponentMultiple.iterator(); iterator.hasNext();) {
						IApiComponent iApiComponent = iterator.next();
						Version workspaceBaselineVersion = new Version(iApiComponent.getVersion());// removes
																									// qualifier
						Version currentProjectVersion = currentModel.getBundleDescription().getVersion();
						if (new Version(currentProjectVersion.getMajor(), currentProjectVersion.getMinor(), currentProjectVersion.getMicro()).compareTo(workspaceBaselineVersion) == 0) {
							apiComponent = iApiComponent;
							break;
						}
					}
				}
				if (apiComponent != null) {
					if (getAnalyzer() instanceof BaseApiAnalyzer) {
						((BaseApiAnalyzer)getAnalyzer()).checkBaselineMismatch(baseline, wbaseline);
					}
					getAnalyzer().analyzeComponent(this.buildstate, null, null, baseline, apiComponent, new BuildContext(), localMonitor.split(1));
					localMonitor.split(1);
					createMarkers();
					localMonitor.split(1);
				}
			}
		} finally {
			if (localMonitor != null) {
				localMonitor.done();
			}
		}
	}

	/**
	 * Creates or removes markers, uses the current project rule.
	 * The tasks to do are maintained by markersQueue and executed in the submission order
	 */
	class ApiAnalysisMarkersJob extends WorkspaceJob {

		public ApiAnalysisMarkersJob(Runnable task) {
			super("Creating markers on " + currentproject.getName()); //$NON-NLS-1$
			markersQueue.add(task);
			setRule(currentproject);
			setSystem(true);
		}

		@Override
		public boolean belongsTo(Object family) {
			return super.belongsTo(family) || ApiAnalysisMarkersJob.class == family;
		}

		@Override
		public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
			while (!markersQueue.isEmpty()) {
				Runnable task = markersQueue.poll();
				task.run();
			}
			return Status.OK_STATUS;
		}

	}

	/**
	 * Creates new markers are for the listing of problems added to this
	 * reporter. If no problems have been added to this reporter, or we are not
	 * running in the framework, no work is done.
	 */
	protected void createMarkers() {
		IApiProblem[] problems = getAnalyzer().getProblems();
		if (isRunningAsJob()) {
			new ApiAnalysisMarkersJob(() -> createMarkersInternally(problems)).schedule();
		} else {
			createMarkersInternally(problems);
		}
	}

	/**
	 * Creates new markers are for the listing of problems added to this reporter.
	 * If no problems have been added to this reporter, or we are not running in the
	 * framework, no work is done.
	 *
	 * @param problems
	 */
	protected void createMarkersInternally(IApiProblem[] problems) {
		try {
			IResource manifest = Util.getManifestFile(this.currentproject);
			if (manifest != null) {
				manifest.deleteMarkers(IApiMarkerConstants.VERSION_NUMBERING_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
			}
			this.currentproject.deleteMarkers(IApiMarkerConstants.DEFAULT_API_BASELINE_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
			this.currentproject.deleteMarkers(IApiMarkerConstants.API_COMPONENT_RESOLUTION_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
		} catch (CoreException e) {
			ApiPlugin.log(e);
		}
		String type = null;
		for (IApiProblem problem : problems) {
			int category = problem.getCategory();
			type = getProblemTypeFromCategory(category, problem.getKind());
			if (type == null) {
				continue;
			}
			if (ApiPlugin.DEBUG_BUILDER) {
				System.out.println("ApiAnalysisBuilder: creating marker for: " + problem.toString()); //$NON-NLS-1$
			}
			createMarkerForProblem(category, type, problem);
		}
	}

	/**
	 * Returns the {@link IApiMarkerConstants} problem type given the problem
	 * category
	 *
	 * @param category the problem category - see {@link IApiProblem} for
	 *            problem categories
	 * @param kind the kind of the problem - see {@link IApiProblem} for problem
	 *            kinds
	 * @return the problem type or <code>null</code>
	 */
	String getProblemTypeFromCategory(int category, int kind) {
		switch (category) {
			case IApiProblem.CATEGORY_API_COMPONENT_RESOLUTION: {
				return IApiMarkerConstants.API_COMPONENT_RESOLUTION_PROBLEM_MARKER;
			}
			case IApiProblem.CATEGORY_API_BASELINE: {
				return IApiMarkerConstants.DEFAULT_API_BASELINE_PROBLEM_MARKER;
			}
			case IApiProblem.CATEGORY_COMPATIBILITY: {
				return IApiMarkerConstants.COMPATIBILITY_PROBLEM_MARKER;
			}
			case IApiProblem.CATEGORY_SINCETAGS: {
				return IApiMarkerConstants.SINCE_TAGS_PROBLEM_MARKER;
			}
			case IApiProblem.CATEGORY_USAGE: {
				if (kind == IApiProblem.UNSUPPORTED_TAG_USE) {
					return IApiMarkerConstants.UNSUPPORTED_TAG_PROBLEM_MARKER;
				}
				if (kind == IApiProblem.UNSUPPORTED_ANNOTATION_USE) {
					return IApiMarkerConstants.UNSUPPORTED_ANNOTATION_PROBLEM_MARKER;
				}
				if (kind == IApiProblem.UNUSED_PROBLEM_FILTERS) {
					return IApiMarkerConstants.UNUSED_FILTER_PROBLEM_MARKER;
				}
				return IApiMarkerConstants.API_USAGE_PROBLEM_MARKER;
			}
			case IApiProblem.CATEGORY_VERSION: {
				return IApiMarkerConstants.VERSION_NUMBERING_PROBLEM_MARKER;
			}
			case IApiProblem.CATEGORY_API_USE_SCAN_PROBLEM: {
				return IApiMarkerConstants.API_USESCAN_PROBLEM_MARKER;
			}
			default: {
				return null;
			}
		}
	}

	/**
	 * Creates an {@link IMarker} on the resource specified in the problem (via
	 * its path) with the given problem attributes
	 *
	 * @param category the category of the problem - see {@link IApiProblem} for
	 *            categories
	 * @param type the marker type to create - see {@link IApiMarkerConstants}
	 *            for types
	 * @param problem the problem to create a marker from
	 */
	void createMarkerForProblem(int category, String type, IApiProblem problem) {
		IResource resource = resolveResource(problem);
		if (resource == null) {
			return;
		}
		try {
			if (category == IApiProblem.CATEGORY_API_USE_SCAN_PROBLEM) {
				IMarker[] markers = resource.findMarkers(type, true, IResource.DEPTH_ZERO);
				for (IMarker marker : markers) {
					String msg = marker.getAttribute(IMarker.MESSAGE, null);
					if (msg == null || msg.equalsIgnoreCase(problem.getMessage())) {
						int markerSeverity = marker.getAttribute(IMarker.SEVERITY, 0);
						int problemSeverity = ApiPlugin.getDefault().getSeverityLevel(ApiProblemFactory.getProblemSeverityId(problem), this.currentproject);
						if (markerSeverity == problemSeverity) {
							return; // Marker already exists
						}
					} else {
						marker.delete(); // create the marker afresh
					}
				}
			}
			IMarker marker = null;
			if (problem.getKind() == IApiProblem.API_BASELINE_MISMATCH
					&& category == IApiProblem.CATEGORY_API_BASELINE) {
				// need a workspace marker
				IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
				IMarker[] findMarkers = root.findMarkers(type, false, IResource.DEPTH_ZERO);
				if (findMarkers.length == 0) {
					marker = root.createMarker(type);
				}
				else {
					marker = findMarkers[0];
				}
			} else {
				marker = resource.createMarker(type);
			}

			int line = problem.getLineNumber();
			switch (category)
				{
				case IApiProblem.CATEGORY_VERSION:
				case IApiProblem.CATEGORY_API_BASELINE:
				case IApiProblem.CATEGORY_API_COMPONENT_RESOLUTION:
				case IApiProblem.CATEGORY_API_USE_SCAN_PROBLEM: {
					break;
				}
				default: {
					line++;
				}
			}
			marker.setAttributes(new String[] {
					IMarker.MESSAGE, IMarker.SEVERITY, IMarker.LINE_NUMBER,
					IMarker.CHAR_START, IMarker.CHAR_END, IMarker.SOURCE_ID,
					IApiMarkerConstants.MARKER_ATTR_PROBLEM_ID }, new Object[] {
					problem.getMessage(),
					Integer.valueOf(ApiPlugin.getDefault().getSeverityLevel(ApiProblemFactory.getProblemSeverityId(problem), this.currentproject)),
					Integer.valueOf(line), Integer.valueOf(problem.getCharStart()),
					Integer.valueOf(problem.getCharEnd()),
					ApiAnalysisBuilder.SOURCE, Integer.valueOf(problem.getId()) });
			// add message arguments, if any
			String[] args = problem.getMessageArguments();
			if (args.length > 0) {
				marker.setAttribute(IApiMarkerConstants.MARKER_ATTR_MESSAGE_ARGUMENTS, createArgAttribute(args));
			}
			String typeName = problem.getTypeName();
			if (typeName != null) {
				marker.setAttribute(IApiMarkerConstants.MARKER_ATTR_PROBLEM_TYPE_NAME, typeName);
			}
			// add all other extra arguments, if any
			if (problem.getExtraMarkerAttributeIds().length > 0) {
				marker.setAttributes(problem.getExtraMarkerAttributeIds(), problem.getExtraMarkerAttributeValues());
			}
			if (ApiPlugin.DEBUG_BUILDER) {
				System.out.println("ApiAnalysisBuilder: Created the marker: " + marker.getId() + " - " + marker.getAttributes().entrySet()); //$NON-NLS-1$ //$NON-NLS-2$
			}
		} catch (CoreException e) {
			ApiPlugin.log(e);
			return;
		}
	}

	/**
	 * Resolves the resource from the path in the problem, returns
	 * <code>null</code> in the following cases:
	 * <ul>
	 * <li>The resource is not found in the parent project (findMember() returns
	 * null)</li>
	 * <li>The resource is not accessible (isAccessible() returns false</li>
	 * </ul>
	 *
	 * @param problem the problem to get the resource for
	 * @return the resource or <code>null</code>
	 */
	IResource resolveResource(IApiProblem problem) {
		String resourcePath = problem.getResourcePath();
		if (resourcePath == null) {
			return null;
		}
		IResource resource = currentproject.findMember(new Path(resourcePath));
		if (resource == null) {
			// might be re-exported try to look it up
			IJavaProject jp = JavaCore.create(currentproject);
			try {
				IType type = jp.findType(problem.getTypeName());
				if (type != null) {
					return type.getResource();
				}
			} catch (JavaModelException jme) {
				// do nothing
			}
			return null;
		}
		if (!resource.isAccessible()) {
			return null;
		}
		return resource;
	}

	/**
	 * Creates a single string attribute from an array of strings. Uses the '#'
	 * char as a delimiter
	 *
	 * @param args
	 * @return a single string attribute from an array or arguments
	 */
	String createArgAttribute(String[] args) {
		StringBuilder buff = new StringBuilder();
		for (int i = 0; i < args.length; i++) {
			buff.append(args[i]);
			if (i < args.length - 1) {
				buff.append("#"); //$NON-NLS-1$
			}
		}
		return buff.toString();
	}

	@Override
	protected void clean(IProgressMonitor monitor) throws CoreException {
		this.currentproject = getProject();
		SubMonitor localmonitor = SubMonitor.convert(monitor, MessageFormat.format(BuilderMessages.CleaningAPIDescription, this.currentproject.getName()), 2);
		try {
			// clean up all existing markers
			cleanupUsageMarkers(this.currentproject);
			cleanupCompatibilityMarkers(this.currentproject);
			cleanupUnsupportedTagMarkers(this.currentproject);
			cleanupUnsupportedAnnotationMarkers(this.currentproject);
			this.currentproject.deleteMarkers(IApiMarkerConstants.UNUSED_FILTER_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			localmonitor.split(1);
			// clean up the .api_settings
			cleanupApiDescription(this.currentproject);
			localmonitor.split(1);
		} finally {
			BuildState.setLastBuiltState(this.currentproject, null);
			localmonitor.done();
		}
	}

	/**
	 * Cleans the .api_settings file for the given project
	 *
	 * @param project
	 */
	void cleanupApiDescription(IProject project) {
		if (project != null && project.exists()) {
			ApiDescriptionManager.getManager().clean(JavaCore.create(project), true, false);
		}
	}

	/**
	 * @return the current {@link IPluginModelBase} based on the current project
	 *         for this builder
	 */
	IPluginModelBase getCurrentModel() {
		IPluginModelBase[] workspaceModels = PluginRegistry.getWorkspaceModels();
		IPath location = this.currentproject.getLocation();
		IPluginModelBase currentModel = null;
		BundleDescription desc = null;
		loop: for (int i = 0, max = workspaceModels.length; i < max; i++) {
			desc = workspaceModels[i].getBundleDescription();
			if (desc != null) {
				Path path = new Path(desc.getLocation());
				if (path.equals(location)) {
					currentModel = workspaceModels[i];
					break loop;
				}
			} else if (ApiPlugin.DEBUG_BUILDER) {
				System.out.println("ApiAnalysisBuilder: Tried to look up bundle description for: " + workspaceModels[i].toString()); //$NON-NLS-1$
			}
		}
		return currentModel;
	}

	/**
	 * Returns a listing of deltas for this project and for dependent projects
	 *
	 * @param projects
	 * @return
	 */
	IResourceDelta[] getDeltas(IProject[] projects) {
		if (ApiPlugin.DEBUG_BUILDER) {
			System.out.println("ApiAnalysisBuilder: Searching for deltas for build of project: " + this.currentproject.getName()); //$NON-NLS-1$
		}
		ArrayList<IResourceDelta> deltas = new ArrayList<>();
		IResourceDelta delta = getDelta(this.currentproject);
		if (delta != null) {
			if (ApiPlugin.DEBUG_BUILDER) {
				System.out.println("ApiAnalysisBuilder: Found a delta: " + delta); //$NON-NLS-1$
			}
			deltas.add(delta);
		}
		for (IProject project : projects) {
			delta = getDelta(project);
			if (delta != null) {
				if (ApiPlugin.DEBUG_BUILDER) {
					System.out.println("ApiAnalysisBuilder: Found a delta: " + delta); //$NON-NLS-1$
				}
				deltas.add(delta);
			}
		}
		return deltas.toArray(new IResourceDelta[deltas.size()]);
	}

	/**
	 * Returns the API analyzer to use with this instance of the builder
	 *
	 * @return the API analyzer to use
	 */
	protected synchronized IApiAnalyzer getAnalyzer() {
		if (this.analyzer == null) {
			this.analyzer = new BaseApiAnalyzer();
		}
		return this.analyzer;
	}

	/**
	 * Returns the complete listing of required projects from the classpath of
	 * the backing project
	 *
	 * @param includeBinaryPrerequisites
	 * @return the list of projects required
	 * @throws CoreException
	 */
	IProject[] getRequiredProjects(boolean includebinaries) throws CoreException {
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		if (this.currentproject == null || workspaceRoot == null) {
			return new IProject[0];
		}
		ArrayList<IProject> projects = new ArrayList<>();
		try {
			IJavaProject javaProject = JavaCore.create(this.currentproject);
			HashSet<IPath> blocations = new HashSet<>();
			blocations.add(javaProject.getOutputLocation());
			this.output_locs.put(this.currentproject, blocations);
			HashSet<IPath> slocations = new HashSet<>();
			IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
			for (IPackageFragmentRoot root : roots) {
				if (root.isArchive()) {
					continue;
				}
				slocations.add(root.getPath());
			}
			this.src_locs.put(this.currentproject, slocations);
			IClasspathEntry[] entries = javaProject.getResolvedClasspath(true);
			for (IClasspathEntry entry : entries) {
				IPath path = entry.getPath();
				IProject p = null;
				switch (entry.getEntryKind()) {
					case IClasspathEntry.CPE_PROJECT: {
						p = workspaceRoot.getProject(path.lastSegment()); // missing
																			// projects
																			// are
																			// considered
																			// too
						if (isOptional(entry) && !p.hasNature(ApiPlugin.NATURE_ID)) {// except
																						// if
																						// entry
																						// is
																						// optional
							p = null;
						}
						break;
					}
					case IClasspathEntry.CPE_LIBRARY: {
						if (includebinaries && path.segmentCount() > 1) {
							// some binary resources on the class path can come
							// from projects that are not included in the
							// project references
							IResource resource = workspaceRoot.findMember(path.segment(0));
							if (resource instanceof IProject) {
								p = (IProject) resource;
							}
						}
						break;
					}
					case IClasspathEntry.CPE_SOURCE: {
						IPath entrypath = entry.getOutputLocation();
						if (entrypath != null) {
							blocations.add(entrypath);
						}
						break;
					}
					default: {
						break;
					}
				}
				if (p != null && !projects.contains(p)) {
					projects.add(p);
					// try to derive all of the output locations for each of the
					// projects
					javaProject = JavaCore.create(p);
					HashSet<IPath> bins = new HashSet<>();
					HashSet<IPath> srcs = new HashSet<>();
					if (javaProject.exists()) {
						bins.add(javaProject.getOutputLocation());
						IClasspathEntry[] source = javaProject.getRawClasspath();
						IPath entrypath = null;
						for (IClasspathEntry element : source) {
							if (element.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
								srcs.add(element.getPath());
								entrypath = element.getOutputLocation();
								if (entrypath != null) {
									bins.add(entrypath);
								}
							}
						}
						this.output_locs.put(p, bins);
						this.src_locs.put(p, srcs);
					}
				}
			}
		} catch (JavaModelException e) {
			return new IProject[0];
		}
		IProject[] result = new IProject[projects.size()];
		projects.toArray(result);
		return result;
	}

	/**
	 * Returns the output paths of the given project or <code>null</code> if
	 * none have been computed
	 *
	 * @param project
	 * @return the output paths for the given project or <code>null</code>
	 */
	HashSet<IPath> getProjectOutputPaths(IProject project) {
		return this.output_locs.get(project);
	}

	/**
	 * Returns is the given classpath entry is optional or not
	 *
	 * @param entry
	 * @return true if the specified {@link IClasspathEntry} is optional, false
	 *         otherwise
	 */
	boolean isOptional(IClasspathEntry entry) {
		IClasspathAttribute[] attribs = entry.getExtraAttributes();
		for (IClasspathAttribute attribute : attribs) {
			if (IClasspathAttribute.OPTIONAL.equals(attribute.getName()) && "true".equals(attribute.getValue())) { //$NON-NLS-1$
				return true;
			}
		}
		return false;
	}

	@Override
	public String toString() {
		return NLS.bind(BuilderMessages.ApiAnalysisBuilder_builder_for_project, this.currentproject != null ? this.currentproject.getName() : null);
	}
}
