/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Serge Beauchamp (Freescale Semiconductor) - [229633] Project Path Variable Support
 *     Anton Leherbauer (Wind River) - [198591] Allow Builder to specify scheduling rule
 *     Francis Lynch (Wind River) - [301563] Save and load tree snapshots
 *     Markus Schorn (Wind River) - [306575] Save snapshot location with project
 *     Broadcom Corporation - ongoing development
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 473427
 *******************************************************************************/
package org.eclipse.core.internal.resources;

import java.net.URI;
import java.util.*;
import org.eclipse.core.filesystem.*;
import org.eclipse.core.internal.events.LifecycleEvent;
import org.eclipse.core.internal.utils.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.resources.team.IMoveDeleteHook;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.IContentTypeMatcher;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.osgi.util.NLS;

public class Project extends Container implements IProject {
	/**
	 * Option constant (value 2) indicating that the snapshot location shall be
	 * persisted with the project for autoloading the snapshot when the project
	 * is imported in another workspace.
	 * <p>
	 * <strong>EXPERIMENTAL</strong>. This constant has been added as
	 * part of a work in progress. There is no guarantee that this API will
	 * work or that it will remain the same. Please do not use this API without
	 * consulting with the Platform Core team.
	 * </p>
	 * @see #saveSnapshot(int, URI, IProgressMonitor)
	 * @since 3.6
	 */
	public static final int SNAPSHOT_SET_AUTOLOAD = 2;

	protected Project(IPath path, Workspace container) {
		super(path, container);
	}

	protected void assertCreateRequirements(IProjectDescription description) throws CoreException {
		checkDoesNotExist();
		checkDescription(this, description, false);
		URI location = description.getLocationURI();
		if (location != null)
			return;
		//if the project is in the default location, need to check for collision with existing folder of different case
		if (!Workspace.caseSensitive) {
			IFileStore store = getStore();
			IFileInfo localInfo = store.fetchInfo();
			if (localInfo.exists()) {
				String name = getLocalManager().getLocalName(store);
				if (name != null && !store.getName().equals(name)) {
					String msg = NLS.bind(Messages.resources_existsLocalDifferentCase, new Path(store.toString()).removeLastSegments(1).append(name).toOSString());
					throw new ResourceException(IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), msg, null);
				}
			}
		}
	}

	/*
	 * If the creation boolean is true then this method is being called on project creation.
	 * Otherwise it is being called via #setDescription. The difference is that we don't allow
	 * some description fields to change value after project creation. (e.g. project location)
	 */
	protected MultiStatus basicSetDescription(ProjectDescription description, int updateFlags) {
		String message = Messages.resources_projectDesc;
		MultiStatus result = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_WRITE_METADATA, message, null);
		ProjectDescription current = internalGetDescription();
		current.setComment(description.getComment());
		current.setSnapshotLocationURI(description.getSnapshotLocationURI());

		// set the build order before setting the references or the natures
		current.setBuildSpec(description.getBuildSpec(true));

		// set the references before the natures
		boolean flushOrder = false;
		IProject[] oldReferences = current.getReferencedProjects();
		IProject[] newReferences = description.getReferencedProjects();
		if (!Arrays.equals(oldReferences, newReferences)) {
			current.setReferencedProjects(newReferences);
			flushOrder = true;
		}
		// Update the dynamic state
		flushOrder |= current.updateDynamicState(description);

		if (flushOrder)
			workspace.flushBuildOrder();

		// the natures last as this may cause recursive calls to setDescription.
		if ((updateFlags & IResource.AVOID_NATURE_CONFIG) == 0)
			workspace.getNatureManager().configureNatures(this, current, description, result);
		else
			current.setNatureIds(description.getNatureIds(false));
		return result;
	}

	@Override
	public void build(int trigger, IProgressMonitor monitor) throws CoreException {
		if (!isAccessible())
			return;
		internalBuild(getActiveBuildConfig(), trigger, null, null, monitor);
	}

	@Override
	public void build(int trigger, String builderName, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(builderName);
		if (!isAccessible())
			return;
		internalBuild(getActiveBuildConfig(), trigger, builderName, args, monitor);
	}

	@Override
	public void build(IBuildConfiguration config, int trigger, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(config);
		// If project isn't accessible, or doesn't contain the build configuration, nothing to do.
		if (!isAccessible() || !hasBuildConfig(config.getName()))
			return;
		internalBuild(config, trigger, null, null, monitor);
	}

	/**
	 * Checks that this resource is accessible.  Typically this means that it
	 * exists.  In the case of projects, they must also be open.
	 * If phantom is true, phantom resources are considered.
	 *
	 * @exception CoreException if this resource is not accessible
	 */
	@Override
	public void checkAccessible(int flags) throws CoreException {
		super.checkAccessible(flags);
		if (!isOpen(flags)) {
			String message = NLS.bind(Messages.resources_mustBeOpen, getName());
			throw new ResourceException(IResourceStatus.PROJECT_NOT_OPEN, getFullPath(), message, null);
		}
	}

	/**
	 * Checks validity of the given project description.
	 */
	protected void checkDescription(IProject project, IProjectDescription desc, boolean moving) throws CoreException {
		URI location = desc.getLocationURI();
		String message = Messages.resources_invalidProjDesc;
		MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.INVALID_VALUE, message, null);
		status.merge(workspace.validateName(desc.getName(), IResource.PROJECT));
		if (moving) {
			// if we got here from a move call then we should check the location in the description since
			// its possible that we want to do a rename without moving the contents. (and we shouldn't
			// throw an Overlapping mapping exception in this case) So if the source description's location
			// is null (we are using the default) or if the locations aren't equal, then validate the location
			// of the new description. Otherwise both locations aren't null and they are equal so ignore validation.
			URI sourceLocation = internalGetDescription().getLocationURI();
			if (sourceLocation == null || !sourceLocation.equals(location))
				status.merge(workspace.validateProjectLocationURI(project, location));
		} else
			// otherwise continue on like before
			status.merge(workspace.validateProjectLocationURI(project, location));
		if (!status.isOK())
			throw new ResourceException(status);
	}

	@Override
	public void close(IProgressMonitor monitor) throws CoreException {
		String msg = NLS.bind(Messages.resources_closing_1, getName());
		SubMonitor subMonitor = SubMonitor.convert(monitor, msg, 100);
		final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this);
		try {
			workspace.prepareOperation(rule, subMonitor.newChild(1));
			ResourceInfo info = getResourceInfo(false, false);
			int flags = getFlags(info);
			checkExists(flags, true);
			subMonitor.subTask(msg);
			if (!isOpen(flags))
				return;
			// Signal that this resource is about to be closed.  Do this at the very
			// beginning so that infrastructure pieces have a chance to do clean up
			// while the resources still exist.
			workspace.beginOperation(true);
			workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_CLOSE, this));
			// flush the build order early in case there is a problem
			workspace.flushBuildOrder();
			IProgressMonitor sub = subMonitor.newChild(49, SubMonitor.SUPPRESS_SUBTASK);
			IStatus saveStatus = workspace.getSaveManager().save(ISaveContext.PROJECT_SAVE, this, sub);
			internalClose(subMonitor.newChild(49));
			if (saveStatus != null && !saveStatus.isOK())
				throw new ResourceException(saveStatus);
		} catch (OperationCanceledException e) {
			workspace.getWorkManager().operationCanceled();
			throw e;
		} finally {
			workspace.endOperation(rule, true);
		}
	}

	@Override
	public void copy(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
		// FIXME - the logic here for copying projects needs to be moved to Resource.copy
		//   so that IResource.copy(IPath,int,IProgressMonitor) works properly for
		//   projects and honours all update flags
		monitor = Policy.monitorFor(monitor);
		if (destination.segmentCount() == 1) {
			// copy project to project
			String projectName = destination.segment(0);
			IProjectDescription desc = getDescription();
			desc.setName(projectName);
			desc.setLocation(null);
			((ProjectDescription) desc).setSnapshotLocationURI(null);
			internalCopy(desc, updateFlags, monitor);
		} else {
			// will fail since we're trying to copy a project to a non-project
			checkCopyRequirements(destination, IResource.PROJECT, updateFlags);
		}
	}

	@Override
	public void copy(IProjectDescription destination, int updateFlags, IProgressMonitor monitor) throws CoreException {
		// FIXME - the logic here for copying projects needs to be moved to Resource.copy
		//   so that IResource.copy(IProjectDescription,int,IProgressMonitor) works properly for
		//   projects and honours all update flags
		Assert.isNotNull(destination);
		internalCopy(destination, updateFlags, monitor);
	}

	protected void copyMetaArea(IProject source, IProject destination, IProgressMonitor monitor) throws CoreException {
		IFileStore oldMetaArea = EFS.getFileSystem(EFS.SCHEME_FILE).getStore(workspace.getMetaArea().locationFor(source));
		IFileStore newMetaArea = EFS.getFileSystem(EFS.SCHEME_FILE).getStore(workspace.getMetaArea().locationFor(destination));
		oldMetaArea.copy(newMetaArea, EFS.NONE, monitor);
	}

	@Override
	public void create(IProgressMonitor monitor) throws CoreException {
		create(null, monitor);
	}

	@Override
	public void create(IProjectDescription description, IProgressMonitor monitor) throws CoreException {
		create(description, IResource.NONE, monitor);
	}

	@Override
	public void create(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {
		monitor = Policy.monitorFor(monitor);
		try {
			monitor.beginTask(Messages.resources_create, Policy.totalWork);
			checkValidPath(path, PROJECT, false);
			final ISchedulingRule rule = workspace.getRuleFactory().createRule(this);
			try {
				workspace.prepareOperation(rule, monitor);
				if (description == null) {
					description = new ProjectDescription();
					description.setName(getName());
				}
				assertCreateRequirements(description);
				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_CREATE, this));
				workspace.beginOperation(true);
				workspace.createResource(this, updateFlags);
				workspace.getMetaArea().create(this);
				ProjectInfo info = (ProjectInfo) getResourceInfo(false, true);

				// setup description to obtain project location
				ProjectDescription desc = (ProjectDescription) ((ProjectDescription) description).clone();
				desc.setLocationURI(FileUtil.canonicalURI(description.getLocationURI()));
				desc.setName(getName());
				internalSetDescription(desc, false);
				// see if there potentially are already contents on disk
				final boolean hasSavedDescription = getLocalManager().hasSavedDescription(this);
				boolean hasContent = hasSavedDescription;
				//if there is no project description, there might still be content on disk
				if (!hasSavedDescription)
					hasContent = getLocalManager().hasSavedContent(this);
				try {
					// look for a description on disk
					if (hasSavedDescription) {
						updateDescription();
						//make sure the .location file is written
						workspace.getMetaArea().writePrivateDescription(this);
					} else {
						//write out the project
						writeDescription(IResource.FORCE);
					}
				} catch (CoreException e) {
					workspace.deleteResource(this);
					throw e;
				}
				// inaccessible projects have a null modification stamp.
				// set this after setting the description as #setDescription
				// updates the stamp
				info.clearModificationStamp();
				//if a project already had content on disk, mark the project as having unknown children
				if (hasContent)
					info.set(ICoreConstants.M_CHILDREN_UNKNOWN);
				workspace.getSaveManager().requestSnapshot();
			} catch (OperationCanceledException e) {
				workspace.getWorkManager().operationCanceled();
				throw e;
			} finally {
				workspace.endOperation(rule, true);
			}
		} finally {
			monitor.done();
		}
	}

	@Override
	public void delete(boolean deleteContent, boolean force, IProgressMonitor monitor) throws CoreException {
		int updateFlags = force ? IResource.FORCE : IResource.NONE;
		updateFlags |= deleteContent ? IResource.ALWAYS_DELETE_PROJECT_CONTENT : IResource.NEVER_DELETE_PROJECT_CONTENT;
		delete(updateFlags, monitor);
	}

	@Override
	public void delete(boolean force, IProgressMonitor monitor) throws CoreException {
		int updateFlags = force ? IResource.FORCE : IResource.NONE;
		delete(updateFlags, monitor);
	}

	@Override
	public void deleteResource(boolean convertToPhantom, MultiStatus status) throws CoreException {
		super.deleteResource(convertToPhantom, status);
		// Clear the history store.
		clearHistory(null);
		// Delete the project metadata.
		workspace.getMetaArea().delete(this);
	}

	@Override
	protected void fixupAfterMoveSource() throws CoreException {
		workspace.deleteResource(this);
		// check if we deleted a preferences file
		ProjectPreferences.deleted(this);
	}

	@Override
	public IBuildConfiguration getActiveBuildConfig() throws CoreException {
		ResourceInfo info = getResourceInfo(false, false);
		int flags = getFlags(info);
		checkAccessible(flags);
		return internalGetActiveBuildConfig();
	}

	@Override
	public IBuildConfiguration getBuildConfig(String configName) throws CoreException {
		if (configName == null)
			return getActiveBuildConfig();
		ProjectInfo info = (ProjectInfo) getResourceInfo(false, false);
		checkAccessible(getFlags(info));
		IBuildConfiguration[] configs = internalGetBuildConfigs(false);
		for (int i = 0; i < configs.length; i++) {
			if (configs[i].getName().equals(configName)) {
				return configs[i];
			}
		}
		throw new ResourceException(IResourceStatus.BUILD_CONFIGURATION_NOT_FOUND, getFullPath(), null, null);
	}

	@Override
	public IBuildConfiguration[] getBuildConfigs() throws CoreException {
		ProjectInfo info = (ProjectInfo) getResourceInfo(false, false);
		checkAccessible(getFlags(info));
		return internalGetBuildConfigs(true);
	}

	@Override
	public IContentTypeMatcher getContentTypeMatcher() throws CoreException {
		return workspace.getContentDescriptionManager().getContentTypeMatcher(this);
	}

	@Override
	public String getDefaultCharset(boolean checkImplicit) {
		// non-existing resources default to parent's charset
		if (!exists())
			return checkImplicit ? ResourcesPlugin.getEncoding() : null;
		return workspace.getCharsetManager().getCharsetFor(getFullPath(), checkImplicit);
	}

	@Override
	public IProjectDescription getDescription() throws CoreException {
		ResourceInfo info = getResourceInfo(false, false);
		checkAccessible(getFlags(info));
		ProjectDescription description = ((ProjectInfo) info).getDescription();
		//if the project is currently in the middle of being created, the description might not be available yet
		if (description == null)
			checkAccessible(NULL_FLAG);
		return (IProjectDescription) description.clone();
	}

	@Override
	public IProjectNature getNature(String natureID) throws CoreException {
		// Has it already been initialized?
		ProjectInfo info = (ProjectInfo) getResourceInfo(false, false);
		checkAccessible(getFlags(info));
		IProjectNature nature = info.getNature(natureID);
		if (nature == null) {
			// Not initialized yet. Does this project have the nature?
			if (!hasNature(natureID))
				return null;
			nature = workspace.getNatureManager().createNature(this, natureID);
			info.setNature(natureID, nature);
		}
		return nature;
	}

	@Override
	public IContainer getParent() {
		return workspace.getRoot();
	}

	@Override
	@Deprecated
	public IPath getPluginWorkingLocation(IPluginDescriptor plugin) {
		if (plugin == null)
			return null;
		return getWorkingLocation(plugin.getUniqueIdentifier());
	}

	@Override
	public IProject getProject() {
		return this;
	}

	@Override
	public IPath getProjectRelativePath() {
		return Path.EMPTY;
	}

	@Override
	public IPath getRawLocation() {
		ProjectDescription description = internalGetDescription();
		return description == null ? null : description.getLocation();
	}

	@Override
	public URI getRawLocationURI() {
		ProjectDescription description = internalGetDescription();
		return description == null ? null : description.getLocationURI();
	}

	@Override
	public IBuildConfiguration[] getReferencedBuildConfigs(String configName, boolean includeMissing) throws CoreException {
		ResourceInfo info = getResourceInfo(false, false);
		checkAccessible(getFlags(info));
		ProjectDescription description = ((ProjectInfo) info).getDescription();
		//if the project is currently in the middle of being created, the description might not be available yet
		if (description == null)
			checkAccessible(NULL_FLAG);
		if (!hasBuildConfig(configName))
			throw new ResourceException(IResourceStatus.BUILD_CONFIGURATION_NOT_FOUND, getFullPath(), null, null);
		return internalGetReferencedBuildConfigs(configName, includeMissing);
	}

	@Override
	public IProject[] getReferencedProjects() throws CoreException {
		ResourceInfo info = getResourceInfo(false, false);
		checkAccessible(getFlags(info));
		ProjectDescription description = ((ProjectInfo) info).getDescription();
		//if the project is currently in the middle of being created, the description might not be available yet
		if (description == null)
			checkAccessible(NULL_FLAG);
		return description.getAllReferences(true);
	}

	@Override
	public void clearCachedDynamicReferences() {
		ResourceInfo info = getResourceInfo(false, false);
		if (info == null) {
			// If the project is not open there is no cached state and so there is nothing to do.
			return;
		}
		ProjectDescription description = ((ProjectInfo) info).getDescription();
		if (description == null) {
			// If the project is in the process of being created there is no cached state and nothing to do.
			return;
		}
		description.clearCachedDynamicReferences(null);
	}

	@Override
	public IProject[] getReferencingProjects() {
		IProject[] projects = workspace.getRoot().getProjects(IContainer.INCLUDE_HIDDEN);
		List<IProject> result = new ArrayList<>(projects.length);
		for (int i = 0; i < projects.length; i++) {
			Project project = (Project) projects[i];
			if (!project.isAccessible())
				continue;
			ProjectDescription description = project.internalGetDescription();
			if (description == null)
				continue;
			IProject[] references = description.getAllReferences(false);
			for (int j = 0; j < references.length; j++)
				if (references[j].equals(this)) {
					result.add(projects[i]);
					break;
				}
		}
		return result.toArray(new IProject[result.size()]);
	}

	@Override
	public int getType() {
		return PROJECT;
	}

	@Override
	public IPath getWorkingLocation(String id) {
		if (id == null || !exists())
			return null;
		IPath result = workspace.getMetaArea().getWorkingLocation(this, id);
		result.toFile().mkdirs();
		return result;
	}

	@Override
	public boolean hasBuildConfig(String configName) throws CoreException {
		ProjectInfo info = (ProjectInfo) getResourceInfo(false, false);
		checkAccessible(getFlags(info));
		return internalHasBuildConfig(configName);
	}

	@Override
	public boolean hasNature(String natureID) throws CoreException {
		checkAccessible(getFlags(getResourceInfo(false, false)));
		// use #internal method to avoid copy but still throw an
		// exception if the resource doesn't exist.
		IProjectDescription desc = internalGetDescription();
		if (desc == null)
			checkAccessible(NULL_FLAG);
		return desc.hasNature(natureID);
	}

	/**
	 * Implements all build methods on IProject.
	 */
	protected void internalBuild(final IBuildConfiguration config, final int trigger, final String builderName, final Map<String, String> args, IProgressMonitor monitor) throws CoreException {
		workspace.run(new ICoreRunnable() {
			@Override
			public void run(IProgressMonitor innerMonitor) throws CoreException {
				innerMonitor = Policy.monitorFor(innerMonitor);
				final ISchedulingRule rule = workspace.getRoot();
				try {
					innerMonitor.beginTask("", Policy.totalWork); //$NON-NLS-1$
					try {
						workspace.prepareOperation(rule, innerMonitor);
						if (!shouldBuild())
							return;
						workspace.beginOperation(true);
						workspace.aboutToBuild(Project.this, trigger);
					} finally {
						workspace.endOperation(rule, false);
					}
					final ISchedulingRule buildRule = workspace.getBuildManager().getRule(config, trigger, builderName, args);
					try {
						IStatus result;
						workspace.prepareOperation(buildRule, innerMonitor);
						//don't open the tree eagerly because it will be wasted if no build occurs
						workspace.beginOperation(false);
						result = workspace.getBuildManager().build(config, trigger, builderName, args, Policy.subMonitorFor(innerMonitor, Policy.opWork));
						if (!result.isOK())
							throw new ResourceException(result);
					} finally {
						workspace.endOperation(buildRule, false);
						try {
							workspace.prepareOperation(rule, innerMonitor);
							//don't open the tree eagerly because it will be wasted if no change occurs
							workspace.beginOperation(false);
							workspace.broadcastBuildEvent(Project.this, IResourceChangeEvent.POST_BUILD, trigger);
							//building may close the tree, so open it
							if (workspace.getElementTree().isImmutable())
								workspace.newWorkingTree();
						} finally {
							workspace.endOperation(rule, false);
						}
					}
				} finally {
					innerMonitor.done();
				}
			}

			/**
			 * Returns whether this project should be built for a given trigger.
			 * @return <code>true</code> if the build should proceed, and <code>false</code> otherwise.
			 */
			private boolean shouldBuild() {
				ResourceInfo info = getResourceInfo(false, false);
				int flags = getFlags(info);
				if (!exists(flags, true) || !isOpen(flags))
					return false;
				return true;
			}

		}, null, IWorkspace.AVOID_UPDATE, monitor);
	}

	/**
	 * Closes the project.  This is called during restore when there is a failure
	 * to read the project description.  Since it is called during workspace restore,
	 * it cannot start any operations.
	 */
	protected void internalClose(IProgressMonitor monitor) throws CoreException {
		SubMonitor subMonitor = SubMonitor.convert(monitor, 2);
		workspace.flushBuildOrder();
		getMarkerManager().removeMarkers(this, IResource.DEPTH_INFINITE);
		subMonitor.worked(1);
		// remove each member from the resource tree.
		// DO NOT use resource.delete() as this will delete it from disk as well.
		IResource[] members = members(IContainer.INCLUDE_PHANTOMS | IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
		subMonitor.setWorkRemaining(members.length);
		for (int i = 0; i < members.length; i++) {
			Resource member = (Resource) members[i];
			workspace.deleteResource(member);
			subMonitor.worked(1);
		}
		// finally mark the project as closed.
		ResourceInfo info = getResourceInfo(false, true);
		info.clear(M_OPEN);
		info.clearSessionProperties();
		info.clearModificationStamp();
		info.setSyncInfo(null);
	}

	protected void internalCopy(IProjectDescription destDesc, int updateFlags, IProgressMonitor monitor) throws CoreException {
		monitor = Policy.monitorFor(monitor);
		try {
			String message = NLS.bind(Messages.resources_copying, getFullPath());
			monitor.beginTask(message, Policy.totalWork);
			String destName = destDesc.getName();
			IPath destPath = new Path(destName).makeAbsolute();
			Project destination = (Project) workspace.getRoot().getProject(destName);
			final ISchedulingRule rule = workspace.getRuleFactory().copyRule(this, destination);
			try {
				workspace.prepareOperation(rule, monitor);
				// The following assert method throws CoreExceptions as stated in the IProject.copy API
				// and assert for programming errors. See checkCopyRequirements for more information.
				assertCopyRequirements(destPath, IResource.PROJECT, updateFlags);
				checkDescription(destination, destDesc, false);
				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_COPY, this, destination, updateFlags));

				workspace.beginOperation(true);
				getLocalManager().refresh(this, DEPTH_INFINITE, true, Policy.subMonitorFor(monitor, Policy.opWork * 20 / 100));

				// close the property store so incorrect info is not copied to the destination
				getPropertyManager().closePropertyStore(this);
				getLocalManager().getHistoryStore().closeHistoryStore(this);

				// copy the meta area for the project
				copyMetaArea(this, destination, Policy.subMonitorFor(monitor, Policy.opWork * 5 / 100));

				// copy just the project and not its children yet (tree node, properties)
				internalCopyProjectOnly(destination, destDesc, Policy.subMonitorFor(monitor, Policy.opWork * 5 / 100));

				// set the description
				destination.internalSetDescription(destDesc, false);

				//create the directory for the new project
				destination.getStore().mkdir(EFS.NONE, Policy.subMonitorFor(monitor, Policy.opWork * 5 / 100));

				// call super.copy for each child (excluding project description file)
				//make it a best effort copy
				message = Messages.resources_copyProblem;
				MultiStatus problems = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.INTERNAL_ERROR, message, null);

				IResource[] children = members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
				final int childCount = children.length;
				final int childWork = childCount > 1 ? Policy.opWork * 50 / 100 / (childCount - 1) : 0;
				for (int i = 0; i < childCount; i++) {
					IResource child = children[i];
					if (!isProjectDescriptionFile(child)) {
						try {
							child.copy(destPath.append(child.getName()), updateFlags, Policy.subMonitorFor(monitor, childWork));
						} catch (CoreException e) {
							problems.merge(e.getStatus());
						}
					}
				}

				// write out the new project description to the meta area
				try {
					destination.writeDescription(IResource.FORCE);
				} catch (CoreException e) {
					try {
						destination.delete((updateFlags & IResource.FORCE) != 0, null);
					} catch (CoreException e2) {
						// ignore and rethrow the exception that got us here
					}
					throw e;
				}
				monitor.worked(Policy.opWork * 5 / 100);

				// refresh local
				monitor.subTask(Messages.resources_updating);
				getLocalManager().refresh(destination, DEPTH_INFINITE, true, Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100));
				if (!problems.isOK())
					throw new ResourceException(problems);
			} catch (OperationCanceledException e) {
				workspace.getWorkManager().operationCanceled();
				throw e;
			} finally {
				workspace.endOperation(rule, true);
			}
		} finally {
			monitor.done();
		}
	}

	/*
	 * Copies just the project and no children. Does NOT copy the meta area.
	 */
	protected void internalCopyProjectOnly(IResource destination, IProjectDescription destDesc, IProgressMonitor monitor) throws CoreException {
		// close the property store so bogus values aren't copied to the destination
		getPropertyManager().closePropertyStore(this);
		getLocalManager().getHistoryStore().closeHistoryStore(this);
		// copy the tree and properties
		workspace.copyTree(this, destination.getFullPath(), IResource.DEPTH_ZERO, IResource.NONE, false);
		getPropertyManager().copy(this, destination, IResource.DEPTH_ZERO);

		ProjectInfo info = (ProjectInfo) ((Resource) destination).getResourceInfo(false, true);

		//copy the hidden metadata that we store in the project description
		ProjectDescription projectDesc = (ProjectDescription) destDesc;
		ProjectDescription internalDesc = ((Project) destination.getProject()).internalGetDescription();
		projectDesc.setLinkDescriptions(internalDesc.getLinks());
		projectDesc.setFilterDescriptions(internalDesc.getFilters());
		projectDesc.setVariableDescriptions(internalDesc.getVariables());

		//clear properties, markers, and description for the new project, because they shouldn't be copied.
		info.description = null;
		info.natures = null;
		info.setMarkers(null);
		info.clearSessionProperties();
	}

	/**
	 * Like {@link #getActiveBuildConfig()} but doesn't check accessibility.
	 * Project must be accessible.
	 * @see #getActiveBuildConfig()
	 */
	IBuildConfiguration internalGetActiveBuildConfig() {
		String configName = internalGetDescription().activeConfiguration;
		try {
			if (configName != null)
				return getBuildConfig(configName);
		} catch (CoreException e) {
			// Build configuration doesn't exist; treat the first as active.
		}
		return internalGetBuildConfigs(false)[0];
	}

	/**
	 * @return IBuildConfiguration[] always contains at least one build configuration
	 */
	public IBuildConfiguration[] internalGetBuildConfigs(boolean makeCopy) {
		ProjectDescription desc = internalGetDescription();
		if (desc == null)
			return new IBuildConfiguration[] {new BuildConfiguration(this, IBuildConfiguration.DEFAULT_CONFIG_NAME)};
		return desc.getBuildConfigs(this, makeCopy);
	}

	/**
	 * This is an internal helper method. This implementation is different from the API
	 * method getDescription(). This one does not check the project accessibility. It exists
	 * in order to prevent "chicken and egg" problems in places like the project creation.
	 * It may return null.
	 */
	public ProjectDescription internalGetDescription() {
		ProjectInfo info = (ProjectInfo) getResourceInfo(false, false);
		if (info == null)
			return null;
		return info.getDescription();
	}

	/**
	 * Returns the IBuildConfigurations referenced by the passed in build configuration
	 * @param configName to find references for
	 * @return IBuildConfiguration[] of referenced configurations; never null.
	 */
	public IBuildConfiguration[] internalGetReferencedBuildConfigs(String configName, boolean includeMissing) {
		ProjectDescription description = internalGetDescription();
		IBuildConfiguration[] refs = description.getAllBuildConfigReferences(configName, false);
		Collection<IBuildConfiguration> configs = new LinkedHashSet<>(refs.length);
		for (int i = 0; i < refs.length; i++) {
			try {
				configs.add((((BuildConfiguration) refs[i]).getBuildConfig()));
			} catch (CoreException e) {
				// The project isn't accessible, or the build configuration doesn't exist
				// on the project.  If requested return the full set of build references which may
				// be useful to API consumers
				if (includeMissing)
					configs.add(refs[i]);
			}
		}
		return configs.toArray(new IBuildConfiguration[configs.size()]);
	}

	boolean internalHasBuildConfig(String configName) {
		return internalGetDescription().hasBuildConfig(configName);
	}

	/**
	 * Sets this project's description to the given value.  This is the body of the
	 * corresponding API method but is needed separately since it is used
	 * during workspace restore (i.e., when you cannot do an operation)
	 */
	void internalSetDescription(IProjectDescription value, boolean incrementContentId) {
		// Project has been added / removed. Build order is out-of-step
		workspace.flushBuildOrder();

		ProjectInfo info = (ProjectInfo) getResourceInfo(false, true);
		info.setDescription((ProjectDescription) value);
		getLocalManager().setLocation(this, info, value.getLocationURI());
		if (incrementContentId) {
			info.incrementContentId();
			//if the project is not accessible, stamp will be null and should remain null
			if (info.getModificationStamp() != NULL_STAMP)
				workspace.updateModificationStamp(info);
		}
	}

	@Override
	public void internalSetLocal(boolean flag, int depth) throws CoreException {
		// do nothing for projects, but call for its children
		if (depth == IResource.DEPTH_ZERO)
			return;
		if (depth == IResource.DEPTH_ONE)
			depth = IResource.DEPTH_ZERO;
		// get the children via the workspace since we know that this
		// resource exists (it is local).
		IResource[] children = getChildren(IResource.NONE);
		for (int i = 0; i < children.length; i++)
			((Resource) children[i]).internalSetLocal(flag, depth);
	}

	@Override
	public boolean isAccessible() {
		return isOpen();
	}

	@Override
	public boolean isDerived(int options) {
		//projects are never derived
		return false;
	}

	@Override
	public boolean isLinked(int options) {
		return false;//projects are never linked
	}

	@Override
	public boolean isVirtual() {
		return false; // projects are never virtual
	}

	@Override
	public boolean isTeamPrivateMember(int options) {
		return false;//projects are never team private members
	}

	@Deprecated
	@Override
	public boolean isLocal(int depth) {
		// the flags parameter is ignored for projects so pass anything
		return isLocal(-1, depth);
	}

	@Deprecated
	@Override
	public boolean isLocal(int flags, int depth) {
		// don't check the flags....projects are always local
		if (depth == DEPTH_ZERO)
			return true;
		if (depth == DEPTH_ONE)
			depth = DEPTH_ZERO;
		// get the children via the workspace since we know that this
		// resource exists (it is local).
		IResource[] children = getChildren(IResource.NONE);
		for (int i = 0; i < children.length; i++)
			if (!children[i].isLocal(depth))
				return false;
		return true;
	}

	@Override
	public boolean isNatureEnabled(String natureId) throws CoreException {
		checkAccessible(getFlags(getResourceInfo(false, false)));
		return workspace.getNatureManager().isNatureEnabled(this, natureId);
	}

	@Override
	public boolean isOpen() {
		ResourceInfo info = getResourceInfo(false, false);
		return isOpen(getFlags(info));
	}

	public boolean isOpen(int flags) {
		return flags != NULL_FLAG && ResourceInfo.isSet(flags, M_OPEN);
	}

	/**
	 * Returns true if this resource represents the project description file, and
	 * false otherwise.
	 */
	protected boolean isProjectDescriptionFile(IResource resource) {
		return resource.getType() == IResource.FILE && resource.getFullPath().segmentCount() == 2 && resource.getName().equals(IProjectDescription.DESCRIPTION_FILE_NAME);
	}

	@Override
	public void loadSnapshot(int options, URI snapshotLocation, IProgressMonitor monitor) throws CoreException {
		// load a snapshot of refresh information when project is not opened
		if (isOpen()) {
			String message = Messages.resources_projectMustNotBeOpen;
			MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, null);
			throw new CoreException(status);
		}
		internalLoadSnapshot(options, snapshotLocation, monitor);
	}

	/**
	 * Loads a snapshot of project meta-data from the given location URI.
	 * Like {@link IProject#loadSnapshot(int, URI, IProgressMonitor)} but can be
	 * called when the project is open.
	 *
	 * @see IProject#saveSnapshot(int, URI, IProgressMonitor)
	 */
	private void internalLoadSnapshot(int options, URI snapshotLocation, IProgressMonitor monitor) throws CoreException {
		if ((options & SNAPSHOT_TREE) != 0) {
			// ensure that path variables are resolved: only ws accessible while project is closed
			snapshotLocation = workspace.getPathVariableManager().resolveURI(snapshotLocation);
			if (!snapshotLocation.isAbsolute()) {
				String message = NLS.bind(Messages.projRead_badSnapshotLocation, snapshotLocation.toString());
				throw new CoreException(new Status(IStatus.WARNING, ResourcesPlugin.PI_RESOURCES, message, null));
			}
			// copy the snapshot from the URI into the project metadata
			IPath snapshotPath = workspace.getMetaArea().getRefreshLocationFor(this);
			IFileStore snapshotFileStore = EFS.getStore(org.eclipse.core.filesystem.URIUtil.toURI(snapshotPath));
			EFS.getStore(snapshotLocation).copy(snapshotFileStore, EFS.OVERWRITE, monitor);
		}
	}

	@Override
	public void move(IProjectDescription destination, boolean force, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(destination);
		move(destination, force ? IResource.FORCE : IResource.NONE, monitor);
	}

	@Override
	public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(description);
		monitor = Policy.monitorFor(monitor);
		try {
			String message = NLS.bind(Messages.resources_moving, getFullPath());
			monitor.beginTask(message, Policy.totalWork);
			IProject destination = workspace.getRoot().getProject(description.getName());
			final ISchedulingRule rule = workspace.getRuleFactory().moveRule(this, destination);
			try {
				workspace.prepareOperation(rule, monitor);
				// The following assert method throws CoreExceptions as stated in the IResource.move API
				// and assert for programming errors. See checkMoveRequirements for more information.
				if (!getName().equals(description.getName())) {
					IPath destPath = Path.ROOT.append(description.getName());
					assertMoveRequirements(destPath, IResource.PROJECT, updateFlags);
				}
				checkDescription(destination, description, true);
				workspace.beginOperation(true);
				message = Messages.resources_moveProblem;
				MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, message, null);
				WorkManager workManager = workspace.getWorkManager();
				ResourceTree tree = new ResourceTree(getLocalManager(), workManager.getLock(), status, updateFlags);
				IMoveDeleteHook hook = workspace.getMoveDeleteHook();
				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_MOVE, this, destination, updateFlags));
				int depth = 0;
				try {
					depth = workManager.beginUnprotected();
					if (!hook.moveProject(tree, this, description, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork / 2)))
						tree.standardMoveProject(this, description, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork / 2));
				} finally {
					workManager.endUnprotected(depth);
				}
				// Invalidate the tree for further use by clients.
				tree.makeInvalid();
				if (!tree.getStatus().isOK())
					throw new ResourceException(tree.getStatus());
				// make sure the move operation is remembered
				workspace.getSaveManager().requestSnapshot();
			} catch (OperationCanceledException e) {
				workspace.getWorkManager().operationCanceled();
				throw e;
			} finally {
				workspace.endOperation(rule, true);
			}
		} finally {
			monitor.done();
		}
	}

	@Override
	public void open(int updateFlags, IProgressMonitor monitor) throws CoreException {
		monitor = Policy.monitorFor(monitor);
		try {
			String msg = NLS.bind(Messages.resources_opening_1, getName());
			monitor.beginTask(msg, Policy.totalWork);
			monitor.subTask(msg);
			final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this);
			try {
				workspace.prepareOperation(rule, monitor);
				ProjectInfo info = (ProjectInfo) getResourceInfo(false, false);
				int flags = getFlags(info);
				checkExists(flags, true);
				if (isOpen(flags))
					return;

				workspace.beginOperation(true);
				// flush the build order early in case there is a problem
				workspace.flushBuildOrder();
				info = (ProjectInfo) getResourceInfo(false, true);
				info.set(M_OPEN);
				//clear the unknown children immediately to avoid background refresh
				boolean unknownChildren = info.isSet(M_CHILDREN_UNKNOWN);
				if (unknownChildren)
					info.clear(M_CHILDREN_UNKNOWN);
				// the M_USED flag is used to indicate the difference between opening a project
				// for the first time and opening it from a previous close (restoring it from disk)
				boolean used = info.isSet(M_USED);
				boolean snapshotLoaded = false;
				if (!used && !workspace.getMetaArea().getRefreshLocationFor(this).toFile().exists()) {
					//auto-load a refresh snapshot if it is set
					final boolean hasSavedDescription = getLocalManager().hasSavedDescription(this);
					if (hasSavedDescription) {
						ProjectDescription updatedDesc = info.getDescription();
						if (updatedDesc != null) {
							URI autoloadURI = updatedDesc.getSnapshotLocationURI();
							if (autoloadURI != null) {
								try {
									autoloadURI = getPathVariableManager().resolveURI(autoloadURI);
									internalLoadSnapshot(SNAPSHOT_TREE, autoloadURI, Policy.subMonitorFor(monitor, Policy.opWork * 5 / 100));
									snapshotLoaded = true;
								} catch (CoreException ce) {
									//Log non-existing autoload snapshot as warning only
									String msgerr = NLS.bind(Messages.projRead_cannotReadSnapshot, getName(), ce.getLocalizedMessage());
									Policy.log(new Status(IStatus.WARNING, ResourcesPlugin.PI_RESOURCES, msgerr));
								}
							}
						}
					}
				}
				boolean minorIssuesDuringRestore = false;
				if (used) {
					minorIssuesDuringRestore = workspace.getSaveManager().restore(this, Policy.subMonitorFor(monitor, Policy.opWork * 20 / 100));
				} else {
					info.set(M_USED);
					//reconcile any links and groups in the project description
					IStatus result = reconcileLinksAndGroups(info.getDescription());
					if (!result.isOK())
						throw new CoreException(result);
					workspace.updateModificationStamp(info);
					monitor.worked(Policy.opWork * (snapshotLoaded ? 15 : 20) / 100);
				}
				startup();
				//request a refresh if the project is new and has unknown members on disk
				// or restore of the project is not fully successful
				if ((!used && unknownChildren) || !minorIssuesDuringRestore) {
					boolean refreshed = false;
					if (!used) {
						refreshed = workspace.getSaveManager().restoreFromRefreshSnapshot(this, Policy.subMonitorFor(monitor, Policy.opWork * 20 / 100));
						if (refreshed) { // account for the refresh work
							monitor.worked(Policy.opWork * 60 / 100);
						}
					}
					//refresh either in background or foreground
					if (!refreshed) {
						if ((updateFlags & IResource.BACKGROUND_REFRESH) != 0) {
							workspace.refreshManager.refresh(this);
							monitor.worked(Policy.opWork * 60 / 100);
						} else {
							refreshLocal(IResource.DEPTH_INFINITE, Policy.subMonitorFor(monitor, Policy.opWork * 60 / 100));
						}
					}
				}
				//creation of this project may affect overlapping resources
				workspace.getAliasManager().updateAliases(this, getStore(), IResource.DEPTH_INFINITE, monitor);
			} catch (OperationCanceledException e) {
				workspace.getWorkManager().operationCanceled();
				throw e;
			} finally {
				workspace.endOperation(rule, true);
			}
		} finally {
			monitor.done();
		}
	}

	@Override
	public void open(IProgressMonitor monitor) throws CoreException {
		open(IResource.NONE, monitor);
	}

	/**
	 * The project description file has changed on disk, resulting in a changed
	 * set of linked resources.  Perform the necessary creations and deletions of
	 * links to bring the links in sync with those described in the project description.
	 * @param newDescription the new project description that may have
	 * 	changed link descriptions.
	 * @return status ok if everything went well, otherwise an ERROR multi-status
	 * 	describing the problems encountered.
	 */
	public IStatus reconcileLinksAndGroups(ProjectDescription newDescription) {
		String msg = Messages.links_errorLinkReconcile;
		HashMap<IPath, LinkDescription> newLinks = newDescription.getLinks();
		MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.OPERATION_FAILED, msg, null);
		//walk over old linked resources and remove those that are no longer defined
		ProjectDescription oldDescription = internalGetDescription();
		if (oldDescription != null) {
			HashMap<IPath, LinkDescription> oldLinks = oldDescription.getLinks();
			if (oldLinks != null) {
				for (Iterator<LinkDescription> it = oldLinks.values().iterator(); it.hasNext();) {
					LinkDescription oldLink = it.next();
					Resource oldLinkResource = (Resource) findMember(oldLink.getProjectRelativePath());
					if (oldLinkResource == null || !oldLinkResource.isLinked())
						continue;
					LinkDescription newLink = null;
					if (newLinks != null)
						newLink = newLinks.get(oldLink.getProjectRelativePath());
					//if the new link is missing, or has different (raw) location or gender, then remove old link
					if (newLink == null || !newLink.getLocationURI().equals(oldLinkResource.getRawLocationURI()) || newLink.getType() != oldLinkResource.getType()) {
						try {
							oldLinkResource.delete(IResource.NONE, null);
							//refresh the resource, because removing a link can reveal a previously hidden resource in parent
							oldLinkResource.refreshLocal(IResource.DEPTH_INFINITE, null);
						} catch (CoreException e) {
							status.merge(e.getStatus());
						}
					}
				}
			}
		}
		// walk over new links and groups and create if necessary
		// Recreate them in order of the higher up in the tree hierarchy first,
		// so we don't have to create intermediate directories that would turn
		// out
		// to be groups or link folders.
		if (newLinks == null)
			return status;
		//sort links to avoid creating nested links before their parents
		TreeSet<LinkDescription> newLinksAndGroups = new TreeSet<>(new Comparator<LinkDescription>() {
			@Override
			public int compare(LinkDescription arg0, LinkDescription arg1) {
				int numberOfSegments0 = arg0.getProjectRelativePath().segmentCount();
				int numberOfSegments1 = arg1.getProjectRelativePath().segmentCount();
				if (numberOfSegments0 != numberOfSegments1)
					return numberOfSegments0 - numberOfSegments1;
				else if (arg0.equals(arg1))
					return 0;

				return -1;
			}

		});
		if (newLinks != null)
			newLinksAndGroups.addAll(newLinks.values());

		for (Iterator<LinkDescription> it = newLinksAndGroups.iterator(); it.hasNext();) {
			Object description = it.next();
			LinkDescription newLink = (LinkDescription) description;
			try {
				Resource toLink = workspace.newResource(getFullPath().append(newLink.getProjectRelativePath()), newLink.getType());
				IContainer parent = toLink.getParent();
				if (parent != null && !parent.exists() && parent.getType() == FOLDER)
					((Folder) parent).ensureExists(Policy.monitorFor(null));
				if (!toLink.exists() || !toLink.isLinked()) {
					if (newLink.isGroup())
						((Folder) toLink).create(IResource.REPLACE | IResource.VIRTUAL, true, null);
					else
						toLink.createLink(newLink.getLocationURI(), IResource.REPLACE | IResource.ALLOW_MISSING_LOCAL, null);
				}
			} catch (CoreException e) {
				status.merge(e.getStatus());
			}
		}
		return status;
	}

	@Override
	public void saveSnapshot(int options, URI snapshotLocation, IProgressMonitor monitor) throws CoreException {
		monitor = Policy.monitorFor(monitor);
		try {
			monitor.beginTask("", Policy.totalWork); //$NON-NLS-1$
			//Project must be open such that variables can be resolved
			checkAccessible(getFlags(getResourceInfo(false, false)));
			//URI must not be null and must not refer to undefined path variables
			URI resolvedSnapshotLocation = getPathVariableManager().resolveURI(snapshotLocation);
			if (resolvedSnapshotLocation == null || !resolvedSnapshotLocation.isAbsolute()) {
				String message = NLS.bind(Messages.projRead_badSnapshotLocation, resolvedSnapshotLocation);
				throw new CoreException(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, message, null));
			}
			if ((options & SNAPSHOT_TREE) != 0) {
				// write a snapshot of refresh information
				try {
					IProgressMonitor sub = Policy.subMonitorFor(monitor, Policy.opWork / 2);
					workspace.getSaveManager().saveRefreshSnapshot(this, resolvedSnapshotLocation, sub);
				} catch (OperationCanceledException e) {
					//workspace.getWorkManager().operationCanceled();
					throw e;
				}
			}
			if ((options & SNAPSHOT_SET_AUTOLOAD) != 0) {
				IProgressMonitor sub = Policy.subMonitorFor(monitor, Policy.opWork / 2);
				//Make absolute URI inside the project relative
				if (snapshotLocation != null && snapshotLocation.isAbsolute()) {
					snapshotLocation = getPathVariableManager().convertToRelative(snapshotLocation, false, "PROJECT_LOC"); //$NON-NLS-1$
				}
				IProjectDescription desc = getDescription();
				((ProjectDescription) desc).setSnapshotLocationURI(snapshotLocation);
				setDescription(desc, IResource.KEEP_HISTORY | IResource.AVOID_NATURE_CONFIG, sub);
			}
		} finally {
			monitor.done();
		}
	}

	@Override
	public void setDescription(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException {
		// FIXME - update flags should be honored:
		//    KEEP_HISTORY means capture .project file in local history
		//    FORCE means overwrite any existing .project file
		monitor = Policy.monitorFor(monitor);
		try {
			monitor.beginTask(Messages.resources_setDesc, Policy.totalWork);
			ISchedulingRule rule = null;
			if ((updateFlags & IResource.AVOID_NATURE_CONFIG) != 0)
				rule = workspace.getRuleFactory().modifyRule(this);
			else
				rule = workspace.getRoot();
			try {
				//need to use root rule because nature configuration calls third party code
				workspace.prepareOperation(rule, monitor);
				ResourceInfo info = getResourceInfo(false, false);
				checkAccessible(getFlags(info));
				//if nothing has changed, we don't need to do anything
				ProjectDescription oldDescription = internalGetDescription();
				ProjectDescription newDescription = (ProjectDescription) description;
				boolean hasPublicChanges = oldDescription.hasPublicChanges(newDescription);
				boolean hasPrivateChanges = oldDescription.hasPrivateChanges(newDescription);
				if (!hasPublicChanges && !hasPrivateChanges)
					return;
				checkDescription(this, newDescription, false);
				//If we're out of sync and !FORCE, then fail.
				//If the file is missing, we want to write the new description then throw an exception.
				boolean hadSavedDescription = true;
				if (((updateFlags & IResource.FORCE) == 0)) {
					hadSavedDescription = getLocalManager().hasSavedDescription(this);
					if (hadSavedDescription && !getLocalManager().isDescriptionSynchronized(this)) {
						String message = NLS.bind(Messages.resources_projectDescSync, getName());
						throw new ResourceException(IResourceStatus.OUT_OF_SYNC_LOCAL, getFullPath(), message, null);
					}
				}
				//see if we have an old .prj file
				if (!hadSavedDescription)
					hadSavedDescription = workspace.getMetaArea().hasSavedProject(this);
				workspace.beginOperation(true);
				MultiStatus status = basicSetDescription(newDescription, updateFlags);
				if (hadSavedDescription && !status.isOK())
					throw new CoreException(status);
				//write the new description to the .project file
				writeDescription(oldDescription, updateFlags, hasPublicChanges, hasPrivateChanges);
				//increment the content id even for private changes
				info = getResourceInfo(false, true);
				info.incrementContentId();
				workspace.updateModificationStamp(info);
				if (!hadSavedDescription) {
					String msg = NLS.bind(Messages.resources_missingProjectMetaRepaired, getName());
					status.merge(new ResourceStatus(IResourceStatus.MISSING_DESCRIPTION_REPAIRED, getFullPath(), msg));
				}
				if (!status.isOK())
					throw new CoreException(status);
			} finally {
				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.POST_PROJECT_CHANGE, this));
				workspace.endOperation(rule, true);
			}
		} finally {
			monitor.done();
		}
	}

	@Override
	public void setDescription(IProjectDescription description, IProgressMonitor monitor) throws CoreException {
		// funnel all operations to central method
		setDescription(description, IResource.KEEP_HISTORY, monitor);
	}

	/**
	 * Restore the non-persisted state for the project.  For example, read and set
	 * the description from the local meta area.  Also, open the property store etc.
	 * This method is used when an open project is restored and so emulates
	 * the behaviour of open().
	 */
	protected void startup() throws CoreException {
		if (!isOpen())
			return;
		workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.PRE_PROJECT_OPEN, this));
	}

	@Override
	public void touch(IProgressMonitor monitor) throws CoreException {
		monitor = Policy.monitorFor(monitor);
		try {
			String message = NLS.bind(Messages.resources_touch, getFullPath());
			monitor.beginTask(message, Policy.totalWork);
			final ISchedulingRule rule = workspace.getRuleFactory().modifyRule(this);
			try {
				workspace.prepareOperation(rule, monitor);
				workspace.beginOperation(true);
				super.touch(Policy.subMonitorFor(monitor, Policy.opWork));
			} catch (OperationCanceledException e) {
				workspace.getWorkManager().operationCanceled();
				throw e;
			} finally {
				workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.POST_PROJECT_CHANGE, this));
				workspace.endOperation(rule, true);
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * The project description file on disk is better than the description in memory.
	 * Make sure the project description in memory is synchronized with the
	 * description file contents.
	 */
	protected void updateDescription() throws CoreException {
		if (ProjectDescription.isWriting)
			return;
		ProjectDescription.isReading = true;
		try {
			ProjectDescription description = getLocalManager().read(this, false);
			//links can only be created if the project is open
			IStatus result = null;
			if (isOpen())
				result = reconcileLinksAndGroups(description);
			internalSetDescription(description, true);
			if (result != null && !result.isOK())
				throw new CoreException(result);
		} finally {
			workspace.broadcastEvent(LifecycleEvent.newEvent(LifecycleEvent.POST_PROJECT_CHANGE, this));
			ProjectDescription.isReading = false;
		}
	}

	/**
	 * Writes the project's current description file to disk.
	 */
	public void writeDescription(int updateFlags) throws CoreException {
		writeDescription(internalGetDescription(), updateFlags, true, true);
	}

	/**
	 * Writes the project description file to disk.  This is the only method
	 * that should ever be writing the description, because it ensures that
	 * the description isn't then immediately discovered as an incoming
	 * change and read back from disk.
	 * @param description The description to write
	 * @param updateFlags The write operation update flags
	 * @param hasPublicChanges Whether the public sections of the description have changed
	 * @param hasPrivateChanges Whether the private sections of the description have changed
	 * @exception CoreException On failure to write the description
	 */
	public void writeDescription(IProjectDescription description, int updateFlags, boolean hasPublicChanges, boolean hasPrivateChanges) throws CoreException {
		if (ProjectDescription.isReading)
			return;
		ProjectDescription.isWriting = true;
		try {
			getLocalManager().internalWrite(this, description, updateFlags, hasPublicChanges, hasPrivateChanges);
		} finally {
			ProjectDescription.isWriting = false;
		}
	}
}
