/*******************************************************************************
 * 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.IResourceStatus;
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()) {
			new ApiAnalysisMarkersJob(() -> cleanupMarkersInternally(resource)).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;
		if (isRunningAsJob()) {
			ApiAnalysisJob job = new ApiAnalysisJob(BuilderMessages.api_analysis_builder, currentproject, fullBuild,
					wbaseline, projects);
			job.cancelSimilarJobs(fullBuild);
			job.schedule(100);
			job.setPriority(Job.DECORATE);
		} 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$
		}
	}

	public 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) {
				IStatus status = e.getStatus();
				if (monitor.isCanceled()) {
					return Status.CANCEL_STATUS;
				} else {
					if (status.getCode() == IResourceStatus.RESOURCE_NOT_FOUND && project.isAccessible()) {
						waitForLockAndReschedule(monitor, e);
						return Status.OK_STATUS;
					} else {
						return status;
					}
				}
			}
			return Status.OK_STATUS;
		}

		/**
		 * In case the analysis job was interrupted by the build, let wait for the build
		 * and start analysis again
		 */
		private void waitForLockAndReschedule(IProgressMonitor monitor, CoreException e) {
			try {
				Job.getJobManager().beginRule(project, monitor);
				IStatus s = new Status(IStatus.INFO, ApiAnalysisBuilder.class,
						"Re-scheduling API analysis for " + project.getName(), e); //$NON-NLS-1$
				ApiPlugin.log(s);
				schedule();
			} catch (OperationCanceledException e1) {
				// nothing to do
			} finally {
				// release lock, we don't want to block workspace while analysis
				Job.getJobManager().endRule(project);
			}
		}

		@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;
	}

	public 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(NLS.bind(BuilderMessages.building_workspace_profile, currentproject.getName()));
				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("Updating API analysis 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 boolean shouldRun() {
			return !markersQueue.isEmpty();
		}

		@Override
		public boolean shouldSchedule() {
			return !markersQueue.isEmpty();
		}

		@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);
	}
}
