/*******************************************************************************
 * Copyright (c) 2005, 2016 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
 *******************************************************************************/
package org.eclipse.ltk.internal.core.refactoring.history;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.ibm.icu.text.DateFormat;

import org.xml.sax.InputSource;

import org.eclipse.core.commands.operations.IOperationHistoryListener;
import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.commands.operations.OperationHistoryEvent;
import org.eclipse.core.commands.operations.OperationHistoryFactory;
import org.eclipse.core.commands.operations.TriggeredOperations;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.preferences.IScopeContext;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.ltk.core.refactoring.ChangeDescriptor;
import org.eclipse.ltk.core.refactoring.IRefactoringCoreStatusCodes;
import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
import org.eclipse.ltk.core.refactoring.RefactoringSessionDescriptor;
import org.eclipse.ltk.core.refactoring.history.IRefactoringExecutionListener;
import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryListener;
import org.eclipse.ltk.core.refactoring.history.IRefactoringHistoryService;
import org.eclipse.ltk.core.refactoring.history.RefactoringExecutionEvent;
import org.eclipse.ltk.core.refactoring.history.RefactoringHistory;
import org.eclipse.ltk.core.refactoring.history.RefactoringHistoryEvent;
import org.eclipse.ltk.internal.core.refactoring.IRefactoringSerializationConstants;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCorePlugin;
import org.eclipse.ltk.internal.core.refactoring.RefactoringPreferenceConstants;
import org.eclipse.ltk.internal.core.refactoring.RefactoringSessionReader;
import org.eclipse.ltk.internal.core.refactoring.UndoableOperation2ChangeAdapter;

/**
 * Default implementation of a refactoring history service.
 *
 * @since 3.2
 */
public final class RefactoringHistoryService implements IRefactoringHistoryService {

	/** The null refactoring history */
	private static final class NullRefactoringHistory extends RefactoringHistory {

		/** The no proxies constant */
		private static final RefactoringDescriptorProxy[] NO_PROXIES= {};

		@Override
		public RefactoringDescriptorProxy[] getDescriptors() {
			return NO_PROXIES;
		}

		@Override
		public boolean isEmpty() {
			return true;
		}

		@Override
		public RefactoringHistory removeAll(final RefactoringHistory history) {
			return this;
		}
	}

	/** The singleton history */
	private static RefactoringHistoryService fInstance= null;

	/** The refactoring history file */
	public static final String NAME_HISTORY_FILE= "refactorings.history"; //$NON-NLS-1$

	/** The refactoring history folder */
	public static final String NAME_HISTORY_FOLDER= ".refactorings"; //$NON-NLS-1$

	/** The refactoring history index file name */
	public static final String NAME_INDEX_FILE= "refactorings.index"; //$NON-NLS-1$

	/** The name of the special workspace project */
	public static final String NAME_WORKSPACE_PROJECT= ".workspace"; //$NON-NLS-1$

	/** The no history constant */
	private static final NullRefactoringHistory NO_HISTORY= new NullRefactoringHistory();

	/**
	 * Filters the given array of refactoring proxies and returns the result in
	 * the specified refactoring descriptor proxy set.
	 * <p>
	 * Clients wishing to benefit from the resolving of refactoring descriptors
	 * to determine its flags can set resolve to <code>true</code> if they
	 * would like to have resolved refactoring descriptor proxies as result.
	 * </p>
	 *
	 * @param proxies
	 *            the refactoring descriptor proxies
	 * @param set
	 *            the result set
	 * @param resolve
	 *            <code>true</code> to return the filtered refactoring
	 *            descriptors as resolved refactoring proxies,
	 *            <code>false</code> otherwise
	 * @param flags
	 *            the refactoring descriptor flags which must be present in
	 *            order to be returned in the refactoring history object
	 * @param monitor
	 *            the progress monitor to use
	 */
	private static void filterRefactoringDescriptors(final RefactoringDescriptorProxy[] proxies, final Set<RefactoringDescriptorProxy> set, final boolean resolve, final int flags, final IProgressMonitor monitor) {
		Assert.isTrue(flags > RefactoringDescriptor.NONE);
		try {
			monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_retrieving_history, proxies.length);
			for (RefactoringDescriptorProxy proxy : proxies) {
				final RefactoringDescriptor descriptor= proxy.requestDescriptor(new SubProgressMonitor(monitor, 1));
				if (descriptor != null) {
					final int filter= descriptor.getFlags();
					if ((filter | flags) == filter) {
						if (resolve) {
							set.add(new RefactoringDescriptorProxyAdapter(descriptor));
						} else {
							set.add(proxy);
						}
					}
				}
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Returns the singleton instance of the refactoring history.
	 *
	 * @return the singleton instance
	 */
	public static RefactoringHistoryService getInstance() {
		if (fInstance == null)
			fInstance= new RefactoringHistoryService();
		return fInstance;
	}

	/**
	 * Returns whether a project has a shared refactoring history.
	 *
	 * @param project
	 *            the project to test
	 * @return <code>true</code> if the project has a shared project history,
	 *         <code>false</code> otherwise
	 */
	public static boolean hasSharedRefactoringHistory(final IProject project) {
		Assert.isNotNull(project);
		final IScopeContext[] contexts= new IScopeContext[] { new ProjectScope(project)};
		final String preference= Platform.getPreferencesService().getString(RefactoringCorePlugin.getPluginId(), RefactoringPreferenceConstants.PREFERENCE_SHARED_REFACTORING_HISTORY, Boolean.FALSE.toString(), contexts);
		if (preference != null)
			return Boolean.valueOf(preference).booleanValue();
		return false;
	}

	/**
	 * Determines whether a project has a shared refactoring history.
	 * <p>
	 * If a shared refactoring history is enabled, refactorings executed on that
	 * particular project are stored in a hidden refactoring history folder of
	 * the project folder. If no shared refactoring history is enabled, all
	 * refactorings are tracked as well, but persisted internally in a
	 * plugin-specific way without altering the project.
	 * </p>
	 * <p>
	 * Note: this method simply copies the content of the refactoring history
	 * folder to the location corresponding to the shared history setting.
	 * Clients wishing to programmatically change the refactoring history
	 * location have to update the preference
	 * {@link RefactoringPreferenceConstants#PREFERENCE_SHARED_REFACTORING_HISTORY}
	 * located in the preference store of the
	 * <code>org.eclipse.ltk.core.refactoring</code> plugin accordingly.
	 * </p>
	 *
	 * @param project
	 *            the project to set the shared refactoring history property
	 * @param enable
	 *            <code>true</code> to enable a shared refactoring history,
	 *            <code>false</code> otherwise
	 * @param monitor
	 *            the progress monitor to use, or <code>null</code>
	 * @throws CoreException
	 *             if an error occurs while changing the shared refactoring
	 *             history property. Reasons include:
	 *             <ul>
	 *             <li>An I/O error occurs while changing the shared
	 *             refactoring history property.</li>
	 *             </ul>
	 */
	public static void setSharedRefactoringHistory(final IProject project, final boolean enable, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(project);
		Assert.isTrue(project.isAccessible());
		if (monitor == null)
			monitor= new NullProgressMonitor();
		try {
			monitor.beginTask("", 300); //$NON-NLS-1$
			final String name= project.getName();
			final URI uri= project.getLocationURI();
			if (uri != null) {
				try {
					final IFileStore history= EFS.getLocalFileSystem().getStore(RefactoringCorePlugin.getDefault().getStateLocation()).getChild(NAME_HISTORY_FOLDER);
					if (enable) {
						final IFileStore source= history.getChild(name);
						if (source.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 20)).exists()) {
							IFileStore destination= EFS.getStore(uri).getChild(NAME_HISTORY_FOLDER);
							if (destination.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 20)).exists())
								destination.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
							destination.mkdir(EFS.NONE, new SubProgressMonitor(monitor, 20));
							source.copy(destination, EFS.OVERWRITE, new SubProgressMonitor(monitor, 20));
							source.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
						}
					} else {
						final IFileStore source= EFS.getStore(uri).getChild(NAME_HISTORY_FOLDER);
						if (source.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 20)).exists()) {
							IFileStore destination= history.getChild(name);
							if (destination.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 20)).exists())
								destination.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
							destination.mkdir(EFS.NONE, new SubProgressMonitor(monitor, 20));
							source.copy(destination, EFS.OVERWRITE, new SubProgressMonitor(monitor, 20));
							source.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
						}
					}
				} finally {
					if (enable)
						project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 30));
					else {
						final IFolder folder= project.getFolder(NAME_HISTORY_FOLDER);
						if (folder.exists())
							folder.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 30));
					}
				}
			}
		} finally {
			monitor.done();
		}
	}

	/** The execution listeners */
	private final ListenerList<IRefactoringExecutionListener> fExecutionListeners= new ListenerList<>(ListenerList.EQUALITY);

	/** The history listeners */
	private final ListenerList<IRefactoringHistoryListener> fHistoryListeners= new ListenerList<>(ListenerList.EQUALITY);

	/** The operation listener, or <code>null</code> */
	private IOperationHistoryListener fOperationListener= null;

	/** The override time stamp */
	private long fOverrideTimeStamp= -1;

	/** The history reference count */
	private int fReferenceCount= 0;

	/** The resource listener, or <code>null</code> */
	private IResourceChangeListener fResourceListener= null;

	/** Maximal number of refactoring managers */
	private static final int MAX_MANAGERS= 2;

	/** The refactoring history manager cache */
	private final Map<IFileStore, RefactoringHistoryManager> fManagerCache= new LinkedHashMap<IFileStore, RefactoringHistoryManager>(MAX_MANAGERS, 0.75f, true) {

		private static final long serialVersionUID= 1L;

		@Override
		protected boolean removeEldestEntry(Map.Entry<IFileStore, RefactoringHistoryManager> entry) {
			return size() > MAX_MANAGERS;
		}
	};

	/**
	 * Creates a new refactoring history.
	 */
	private RefactoringHistoryService() {
		// Do nothing
	}

	@Override
	public void addExecutionListener(final IRefactoringExecutionListener listener) {
		Assert.isNotNull(listener);
		fExecutionListeners.add(listener);
	}

	@Override
	public void addHistoryListener(final IRefactoringHistoryListener listener) {
		Assert.isNotNull(listener);
		fHistoryListeners.add(listener);
	}

	/**
	 * Adds the specified refactoring descriptor to the corresponding
	 * refactoring history.
	 * <p>
	 * If a descriptor with the same timestamp already exists, nothing happens.
	 * </p>
	 *
	 * @param proxy
	 *            the refactoring descriptor proxy
	 * @param monitor
	 *            the progress monitor to use, or <code>null</code>
	 */
	public void addRefactoringDescriptor(final RefactoringDescriptorProxy proxy, IProgressMonitor monitor) {
		Assert.isNotNull(proxy);
		if (monitor == null)
			monitor= new NullProgressMonitor();
		try {
			fireRefactoringHistoryEvent(proxy, RefactoringHistoryEvent.ADDED);
		} finally {
			monitor.done();
		}
	}

	@Override
	public void connect() {
		fReferenceCount++;
		if (fReferenceCount == 1) {
			fOperationListener= new IOperationHistoryListener() {
				@Override
				public void historyNotification(final OperationHistoryEvent event) {
					performHistoryNotification(event);
				}
			};
			OperationHistoryFactory.getOperationHistory().addOperationHistoryListener(fOperationListener);

			fResourceListener= new IResourceChangeListener() {
				@Override
				public void resourceChanged(final IResourceChangeEvent event) {
					peformResourceChanged(event);
				}
			};
			ResourcesPlugin.getWorkspace().addResourceChangeListener(fResourceListener, IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.POST_CHANGE);
		}
	}

	/**
	 * Deletes the specified refactoring descriptors from their associated
	 * refactoring histories.
	 *
	 * @param proxies
	 *            the refactoring descriptor proxies
	 * @param monitor
	 *            the progress monitor to use, or <code>null</code>
	 * @throws CoreException
	 *             if an error occurs while deleting the refactoring
	 *             descriptors. Reasons include:
	 *             <ul>
	 *             <li>The refactoring history has an illegal format, contains
	 *             illegal arguments or otherwise illegal information.</li>
	 *             <li>An I/O error occurs while deleting the refactoring
	 *             descriptors from the refactoring history.</li>
	 *             </ul>
	 *
	 * @see IRefactoringCoreStatusCodes#REFACTORING_HISTORY_FORMAT_ERROR
	 * @see IRefactoringCoreStatusCodes#REFACTORING_HISTORY_IO_ERROR
	 */
	public void deleteRefactoringDescriptors(final RefactoringDescriptorProxy[] proxies, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(proxies);
		if (monitor == null)
			monitor= new NullProgressMonitor();
		try {
			monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings, proxies.length + 300);
			final Map<String, Collection<RefactoringDescriptorProxy>> projects= new HashMap<>();
			for (RefactoringDescriptorProxy proxy : proxies) {
				String project= proxy.getProject();
				if (project == null || "".equals(project)) //$NON-NLS-1$
					project= RefactoringHistoryService.NAME_WORKSPACE_PROJECT;
				Collection<RefactoringDescriptorProxy> collection= projects.get(project);
				if (collection == null) {
					collection= new ArrayList<>();
					projects.put(project, collection);
				}
				collection.add(proxy);
				monitor.worked(1);
			}
			final SubProgressMonitor subMonitor= new SubProgressMonitor(monitor, 300);
			try {
				final Set<Entry<String, Collection<RefactoringDescriptorProxy>>> entries= projects.entrySet();
				subMonitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings, entries.size());
				for (final Iterator<Entry<String, Collection<RefactoringDescriptorProxy>>> iterator= entries.iterator(); iterator.hasNext();) {
					final Entry<String, Collection<RefactoringDescriptorProxy>> entry= iterator.next();
					final Collection<RefactoringDescriptorProxy> collection= entry.getValue();
					String project= entry.getKey();
					if (project.equals(RefactoringHistoryService.NAME_WORKSPACE_PROJECT))
						project= null;
					final RefactoringHistoryManager manager= getManager(project);
					if (manager != null)
						manager.removeRefactoringDescriptors(collection.toArray(new RefactoringDescriptorProxy[collection.size()]), new SubProgressMonitor(subMonitor, 1), RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings);
					else
						subMonitor.worked(1);
				}
			} finally {
				subMonitor.done();
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Deletes the specified refactoring descriptors from their associated
	 * refactoring histories.
	 *
	 * @param proxies
	 *            the refactoring descriptor proxies
	 * @param query
	 *            the refactoring descriptor delete query to use
	 * @param monitor
	 *            the progress monitor to use, or <code>null</code>
	 * @throws CoreException
	 *             if an error occurs while deleting the refactoring
	 *             descriptors. Reasons include:
	 *             <ul>
	 *             <li>The refactoring history has an illegal format, contains
	 *             illegal arguments or otherwise illegal information.</li>
	 *             <li>An I/O error occurs while deleting the refactoring
	 *             descriptors from the refactoring history.</li>
	 *             </ul>
	 *
	 * @see IRefactoringCoreStatusCodes#REFACTORING_HISTORY_FORMAT_ERROR
	 * @see IRefactoringCoreStatusCodes#REFACTORING_HISTORY_IO_ERROR
	 */
	public void deleteRefactoringDescriptors(final RefactoringDescriptorProxy[] proxies, final IRefactoringDescriptorDeleteQuery query, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(proxies);
		Assert.isNotNull(query);
		if (monitor == null)
			monitor= new NullProgressMonitor();
		try {
			monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings, proxies.length + 300);
			final Set<RefactoringDescriptorProxy> set= new HashSet<>(proxies.length);
			for (RefactoringDescriptorProxy proxy : proxies) {
				if (query.proceed(proxy).isOK()) {
					set.add(proxy);
				}
				monitor.worked(1);
			}
			if (!set.isEmpty()) {
				final RefactoringDescriptorProxy[] delete= set.toArray(new RefactoringDescriptorProxy[set.size()]);
				deleteRefactoringDescriptors(delete, new SubProgressMonitor(monitor, 300));
				for (RefactoringDescriptorProxy d : delete) {
					fireRefactoringHistoryEvent(d, RefactoringHistoryEvent.DELETED);
				}
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Deletes the refactoring history of a project. Refactorings associated
	 * with the workspace are not deleted.
	 * <p>
	 * If a refactoring history is deleted, all files stored in the hidden
	 * refactoring history folder of the project folder are removed. If no
	 * shared refactoring history is enabled, the refactoring history
	 * information is removed from the internal workspace refactoring history.
	 * </p>
	 *
	 * @param project
	 *            the project to delete its history
	 * @param monitor
	 *            the progress monitor to use, or <code>null</code>
	 * @throws CoreException
	 *             if an error occurs while deleting the refactoring history.
	 *             Reasons include:
	 *             <ul>
	 *             <li>An I/O error occurs while deleting the refactoring
	 *             history.</li>
	 *             </ul>
	 */
	public void deleteRefactoringHistory(final IProject project, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(project);
		if (monitor == null)
			monitor= new NullProgressMonitor();
		try {
			monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_deleting_refactorings, 100);
			final String name= project.getName();
			final IFileStore stateStore= EFS.getLocalFileSystem().getStore(RefactoringCorePlugin.getDefault().getStateLocation());
			if (name.equals(NAME_WORKSPACE_PROJECT)) {
				final IFileStore metaStore= stateStore.getChild(NAME_HISTORY_FOLDER).getChild(name);
				metaStore.delete(EFS.NONE, new SubProgressMonitor(monitor, 100));
			} else {
				final URI uri= project.getLocationURI();
				if (uri != null && project.isAccessible()) {
					try {
						final IFileStore metaStore= stateStore.getChild(NAME_HISTORY_FOLDER).getChild(name);
						metaStore.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
						final IFileStore projectStore= EFS.getStore(uri).getChild(NAME_HISTORY_FOLDER);
						projectStore.delete(EFS.NONE, new SubProgressMonitor(monitor, 20));
					} finally {
						project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 60));
					}
				}
			}
		} finally {
			monitor.done();
		}
	}

	@Override
	public void disconnect() {
		if (fReferenceCount > 0) {
			fManagerCache.clear();
			fReferenceCount--;
		}
		if (fReferenceCount == 0) {
			if (fOperationListener != null)
				OperationHistoryFactory.getOperationHistory().removeOperationHistoryListener(fOperationListener);
			if (fResourceListener != null)
				ResourcesPlugin.getWorkspace().removeResourceChangeListener(fResourceListener);
			fOperationListener= null;
		}
	}

	private void fireRefactoringExecutionEvent(final RefactoringDescriptorProxy proxy, final int eventType) {
		Assert.isNotNull(proxy);
		for (final IRefactoringExecutionListener listener : fExecutionListeners) {
			SafeRunner.run(new ISafeRunnable() {

				@Override
				public void handleException(final Throwable throwable) {
					RefactoringCorePlugin.log(throwable);
				}

				@Override
				public void run() throws Exception {
					listener.executionNotification(new RefactoringExecutionEvent(RefactoringHistoryService.this, eventType, proxy));
				}
			});
		}
	}

	private void fireRefactoringHistoryEvent(final RefactoringDescriptorProxy proxy, final int eventType) {
		Assert.isNotNull(proxy);
		for (final IRefactoringHistoryListener listener : fHistoryListeners) {
			SafeRunner.run(new ISafeRunnable() {

				@Override
				public void handleException(final Throwable throwable) {
					RefactoringCorePlugin.log(throwable);
				}

				@Override
				public void run() throws Exception {
					listener.historyNotification(new RefactoringHistoryEvent(RefactoringHistoryService.this, eventType, proxy));
				}
			});
		}
	}

	private boolean checkDescriptor(RefactoringDescriptor descriptor, IUndoableOperation operation) {
		Assert.isNotNull(descriptor);
		try {
			final Map<String, String> arguments= RefactoringHistoryManager.getArgumentMap(descriptor);
			if (arguments != null)
				RefactoringHistoryManager.checkArgumentMap(arguments);
		} catch (CoreException exception) {
			final IStatus status= exception.getStatus();
			if (status.getCode() == IRefactoringCoreStatusCodes.REFACTORING_HISTORY_FORMAT_ERROR) {
				final String time= DateFormat.getDateTimeInstance().format(new Date(descriptor.getTimeStamp()));
				final String message= "The refactoring executed at " + time + " contributed a refactoring descriptor with invalid format:"; //$NON-NLS-1$//$NON-NLS-2$
				final IStatus comment= new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), descriptor.getComment());
				RefactoringCorePlugin.log(new MultiStatus(RefactoringCorePlugin.getPluginId(), 0, new IStatus[] { comment}, message, null));
			}
			RefactoringCorePlugin.log(exception);

			if (operation instanceof TriggeredOperations) {
				operation= ((TriggeredOperations) operation).getTriggeringOperation();
			}
			if (operation instanceof UndoableOperation2ChangeAdapter) {
				((UndoableOperation2ChangeAdapter) operation).setChangeDescriptor(null);
			}
			return false;
		}
		return true;
	}

	@Override
	public RefactoringHistory getProjectHistory(final IProject project, IProgressMonitor monitor) {
		return getProjectHistory(project, 0, Long.MAX_VALUE, RefactoringDescriptor.NONE, monitor);
	}

	@Override
	public RefactoringHistory getProjectHistory(final IProject project, final long start, final long end, final int flags, IProgressMonitor monitor) {
		Assert.isNotNull(project);
		Assert.isTrue(project.exists());
		Assert.isTrue(start >= 0);
		Assert.isTrue(end >= 0);
		Assert.isTrue(flags >= RefactoringDescriptor.NONE);
		if (project.isOpen()) {
			if (monitor == null)
				monitor= new NullProgressMonitor();
			try {
				monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_retrieving_history, 120);
				final String name= project.getName();
				final RefactoringHistoryManager manager= getManager(name);
				if (manager != null) {
					RefactoringHistory history= manager.readRefactoringHistory(start, end, new SubProgressMonitor(monitor, 20));
					if (flags > RefactoringDescriptor.NONE) {
						final Set<RefactoringDescriptorProxy> set= new HashSet<>();
						filterRefactoringDescriptors(history.getDescriptors(), set, false, flags, new SubProgressMonitor(monitor, 100));
						history= new RefactoringHistoryImplementation(set.toArray(new RefactoringDescriptorProxy[set.size()]));
					}
					return history;
				}
			} finally {
				monitor.done();
			}
		}
		return NO_HISTORY;
	}

	@Override
	public RefactoringHistory getRefactoringHistory(final IProject[] projects, final IProgressMonitor monitor) {
		return getRefactoringHistory(projects, 0, Long.MAX_VALUE, RefactoringDescriptor.NONE, monitor);
	}

	@Override
	public RefactoringHistory getRefactoringHistory(final IProject[] projects, final long start, final long end, final int flags, IProgressMonitor monitor) {
		Assert.isNotNull(projects);
		Assert.isTrue(start >= 0);
		Assert.isTrue(end >= start);
		Assert.isTrue(flags >= RefactoringDescriptor.NONE);
		if (monitor == null)
			monitor= new NullProgressMonitor();
		try {
			monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_retrieving_history, 3 * projects.length);
			final Set<RefactoringDescriptorProxy> set= new HashSet<>();
			if (flags > RefactoringDescriptor.NONE) {
				for (IProject project : projects) {
					if (project.isAccessible()) {
						final RefactoringDescriptorProxy[] proxies= getProjectHistory(project, start, end, flags, new SubProgressMonitor(monitor, 1)).getDescriptors();
						filterRefactoringDescriptors(proxies, set, false, flags, new SubProgressMonitor(monitor, 2));
					}
				}
			} else {
				for (IProject project : projects) {
					if (project.isAccessible()) {
						final RefactoringDescriptorProxy[] proxies= getProjectHistory(project, start, end, RefactoringDescriptor.NONE, new SubProgressMonitor(monitor, 3)).getDescriptors();
						set.addAll(Arrays.asList(proxies));
					}
				}
			}
			final RefactoringDescriptorProxy[] proxies= new RefactoringDescriptorProxy[set.size()];
			set.toArray(proxies);
			return new RefactoringHistoryImplementation(proxies);
		} finally {
			monitor.done();
		}
	}

	@Override
	public RefactoringHistory getWorkspaceHistory(IProgressMonitor monitor) {
		return getWorkspaceHistory(0, Long.MAX_VALUE, monitor);
	}

	@Override
	public RefactoringHistory getWorkspaceHistory(final long start, final long end, IProgressMonitor monitor) {
		return getRefactoringHistory(ResourcesPlugin.getWorkspace().getRoot().getProjects(), start, end, RefactoringDescriptor.NONE, monitor);
	}

	/**
	 * Reads refactoring descriptor proxies from the input stream.
	 * <p>
	 * Note that calling this method with a flag argument unequal to
	 * <code>RefactoringDescriptor#NONE</code> may result in a performance
	 * degradation, since the actual descriptors have to be eagerly resolved.
	 * This in turn results in faster execution of any subsequent calls to
	 * {@link RefactoringDescriptorProxy#requestDescriptor(IProgressMonitor)}
	 * which try to request a descriptor from the returned refactoring history.
	 * </p>
	 *
	 * @param stream
	 *            the input stream to read from
	 * @return the refactoring descriptor proxies
	 * @throws CoreException
	 *             if an error occurs while reading the refactoring descriptor
	 *             proxies
	 */
	public RefactoringDescriptorProxy[] readRefactoringDescriptorProxies(final InputStream stream) throws CoreException {
		Assert.isNotNull(stream);
		try {
			return RefactoringHistoryManager.readRefactoringDescriptorProxies(stream, null, 0, Long.MAX_VALUE);
		} catch (IOException exception) {
			throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(), 0, exception.getLocalizedMessage(), null));
		}
	}

	@Override
	public RefactoringHistory readRefactoringHistory(final InputStream stream, final int flags) throws CoreException {
		Assert.isNotNull(stream);
		Assert.isTrue(flags >= RefactoringDescriptor.NONE);
		final List<RefactoringDescriptor> list= new ArrayList<>();
		final RefactoringSessionDescriptor descriptor= new RefactoringSessionReader(false, null).readSession(new InputSource(stream));
		if (descriptor != null) {
			final RefactoringDescriptor[] descriptors= descriptor.getRefactorings();
			if (flags > RefactoringDescriptor.NONE) {
				for (RefactoringDescriptor d : descriptors) {
					final int current= d.getFlags();
					if ((current | flags) == current) {
						list.add(d);
					}
				}
			} else
				list.addAll(Arrays.asList(descriptors));
		}
		final RefactoringDescriptorProxy[] proxies= new RefactoringDescriptorProxy[list.size()];
		for (int index= 0; index < list.size(); index++)
			proxies[index]= new RefactoringDescriptorProxyAdapter(list.get(index));
		return new RefactoringHistoryImplementation(proxies);
	}

	@Override
	public void removeExecutionListener(final IRefactoringExecutionListener listener) {
		Assert.isNotNull(listener);
		fExecutionListeners.remove(listener);
	}

	@Override
	public void removeHistoryListener(final IRefactoringHistoryListener listener) {
		Assert.isNotNull(listener);
		fHistoryListeners.remove(listener);
	}

	/**
	 * Returns the resolved refactoring descriptor associated with the specified
	 * proxy.
	 * <p>
	 * The refactoring history must be in connected state.
	 * </p>
	 *
	 * @param proxy
	 *            the refactoring descriptor proxy
	 * @param monitor
	 *            the progress monitor to use, or <code>null</code>
	 *
	 * @return the resolved refactoring descriptor, or <code>null</code>
	 */
	public RefactoringDescriptor requestDescriptor(final RefactoringDescriptorProxy proxy, IProgressMonitor monitor) {
		Assert.isNotNull(proxy);
		if (monitor == null)
			monitor= new NullProgressMonitor();
		try {
			final RefactoringHistoryManager manager= getManager(proxy.getProject());
			if (manager != null)
				return manager.requestDescriptor(proxy, monitor);
		} finally {
			monitor.done();
		}
		return null;
	}

	/**
	 * Sets the override time stamp for the next refactoring performed.
	 *
	 * @param stamp
	 *            the override time stamp, or <code>-1</code> to clear it
	 */
	public void setOverrideTimeStamp(final long stamp) {
		Assert.isTrue(stamp == -1 || stamp >= 0);
		fOverrideTimeStamp= stamp;
	}

	@Override
	public void writeRefactoringDescriptors(final RefactoringDescriptorProxy[] proxies, final OutputStream stream, final int flags, final boolean time, IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(proxies);
		Assert.isNotNull(stream);
		Assert.isTrue(flags >= RefactoringDescriptor.NONE);
		if (monitor == null)
			monitor= new NullProgressMonitor();
		try {
			monitor.beginTask("", 100 * proxies.length); //$NON-NLS-1$
			connect();
			final List<RefactoringDescriptor> list= new ArrayList<>(proxies.length);
			for (RefactoringDescriptorProxy proxy : proxies) {
				final RefactoringDescriptor descriptor= proxy.requestDescriptor(new SubProgressMonitor(monitor, 100));
				if (descriptor != null) {
					final int current= descriptor.getFlags();
					if ((current | flags) == current)
						list.add(descriptor);
				}
			}
			final RefactoringDescriptor[] descriptors= new RefactoringDescriptor[list.size()];
			list.toArray(descriptors);
			RefactoringHistoryManager.writeRefactoringSession(stream, new RefactoringSessionDescriptor(descriptors, IRefactoringSerializationConstants.CURRENT_VERSION, null), time);
		} finally {
			disconnect();
		}
	}

	@Override
	public void writeRefactoringSession(final RefactoringSessionDescriptor descriptor, final OutputStream stream, final boolean time) throws CoreException {
		Assert.isNotNull(descriptor);
		Assert.isNotNull(stream);
		RefactoringHistoryManager.writeRefactoringSession(stream, descriptor, time);
	}

	/**
	 * Moves the project history from the old project to the new one.
	 *
	 * @param oldProject
	 *            the old project, which does not exist anymore
	 * @param newProject
	 *            the new project, which already exists
	 * @param monitor
	 *            the progress monitor to use
	 */
	private void moveHistory(final IProject oldProject, final IProject newProject, final IProgressMonitor monitor) {
		try {
			monitor.beginTask(RefactoringCoreMessages.RefactoringHistoryService_updating_history, 60);
			final IFileStore historyStore= EFS.getLocalFileSystem().getStore(RefactoringCorePlugin.getDefault().getStateLocation()).getChild(NAME_HISTORY_FOLDER);
			final String oldName= oldProject.getName();
			final String newName= newProject.getName();
			final IFileStore oldStore= historyStore.getChild(oldName);
			if (oldStore.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)).exists()) {
				final IFileStore newStore= historyStore.getChild(newName);
				if (newStore.fetchInfo(EFS.NONE, new SubProgressMonitor(monitor, 10, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)).exists())
					newStore.delete(EFS.NONE, new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
				oldStore.move(newStore, EFS.OVERWRITE, new SubProgressMonitor(monitor, 20, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
			}
		} catch (CoreException exception) {
			RefactoringCorePlugin.log(exception);
		} finally {
			monitor.done();
		}
	}

	private void peformResourceChanged(final IResourceChangeEvent event) {
		final int type= event.getType();
		if ((type & IResourceChangeEvent.POST_CHANGE) != 0) {
			final IResourceDelta delta= event.getDelta();
			if (delta != null) {
				final IResourceDelta[] deltas= delta.getAffectedChildren();
				if (deltas.length == 2) {
					final IPath toPath= deltas[0].getMovedToPath();
					final IPath fromPath= deltas[1].getMovedFromPath();
					if (fromPath != null && toPath != null) {
						final IResource oldResource= deltas[0].getResource();
						final IResource newResource= deltas[1].getResource();
						if (oldResource.getType() == IResource.PROJECT && newResource.getType() == IResource.PROJECT)
							moveHistory((IProject) oldResource, (IProject) newResource, new NullProgressMonitor());
					} else {
						if (deltas[0].getKind() == IResourceDelta.ADDED && deltas[1].getKind() == IResourceDelta.REMOVED) {
							final IResource newResource= deltas[0].getResource();
							final IResource oldResource= deltas[1].getResource();
							if (oldResource.getType() == IResource.PROJECT && newResource.getType() == IResource.PROJECT)
								moveHistory((IProject) oldResource, (IProject) newResource, new NullProgressMonitor());
						}
					}
				}
			}
		}
	}

	private RefactoringDescriptor getRefactoringDescriptor(IUndoableOperation operation) {
		if (operation instanceof TriggeredOperations) {
			operation= ((TriggeredOperations) operation).getTriggeringOperation();
		}
		if (operation instanceof UndoableOperation2ChangeAdapter) {
			ChangeDescriptor changeDescriptor= ((UndoableOperation2ChangeAdapter) operation).getChangeDescriptor();
			if (changeDescriptor instanceof RefactoringChangeDescriptor) {
				return ((RefactoringChangeDescriptor) changeDescriptor).getRefactoringDescriptor();
			}
		}
		return null;
	}

	private void performHistoryNotification(final OperationHistoryEvent event) {
		RefactoringDescriptor descriptor= getRefactoringDescriptor(event.getOperation());
		if (descriptor != null) {
			RefactoringDescriptorProxyAdapter proxy= new RefactoringDescriptorProxyAdapter(descriptor);
			switch (event.getEventType()) {
				case OperationHistoryEvent.ABOUT_TO_EXECUTE: {
					if (checkDescriptor(descriptor, event.getOperation())) {
						fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.ABOUT_TO_PERFORM);
					}
					break;
				}
				case OperationHistoryEvent.DONE: {
					if (!RefactoringDescriptor.ID_UNKNOWN.equals(descriptor.getID())) {
						long timeStamp= fOverrideTimeStamp >= 0 ? fOverrideTimeStamp : System.currentTimeMillis();
						descriptor.setTimeStamp(timeStamp);
					}

					fireRefactoringHistoryEvent(proxy, RefactoringHistoryEvent.PUSHED);
					fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.PERFORMED);
					break;
				}
				case OperationHistoryEvent.ABOUT_TO_UNDO: {
					fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.ABOUT_TO_UNDO);
					break;
				}
				case OperationHistoryEvent.UNDONE: {
					fireRefactoringHistoryEvent(proxy, RefactoringHistoryEvent.POPPED);
					fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.UNDONE);
					break;
				}
				case OperationHistoryEvent.ABOUT_TO_REDO: {
					fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.ABOUT_TO_REDO);
					break;
				}
				case OperationHistoryEvent.REDONE: {
					fireRefactoringHistoryEvent(proxy, RefactoringHistoryEvent.PUSHED);
					fireRefactoringExecutionEvent(proxy, RefactoringExecutionEvent.REDONE);
					break;
				}
			}
		}
	}

	/**
	 * Returns the refactoring history manager corresponding to the project
	 * with the specified name.
	 *
	 * @param name
	 *            the name of the project, or <code>null</code> for the
	 *            workspace
	 * @return the refactoring history manager, or <code>null</code>
	 */
	private RefactoringHistoryManager getManager(final String name) {
		final IFileStore store= EFS.getLocalFileSystem().getStore(RefactoringCorePlugin.getDefault().getStateLocation()).getChild(NAME_HISTORY_FOLDER);
		if (name != null && !"".equals(name)) {//$NON-NLS-1$
			try {
				final IProject project= ResourcesPlugin.getWorkspace().getRoot().getProject(name);
				if (project.isAccessible()) {
					if (hasSharedRefactoringHistory(project)) {
						final URI uri= project.getLocationURI();
						if (uri != null)
							return getManager(EFS.getStore(uri).getChild(RefactoringHistoryService.NAME_HISTORY_FOLDER), name);
					} else
						return getManager(store.getChild(name), name);
				}
			} catch (CoreException exception) {
				// Do nothing
			}
		} else
			return getManager(store.getChild(NAME_WORKSPACE_PROJECT), null);
		return null;
	}

	/**
	 * Returns the cached refactoring history manager for the specified
	 * history location.
	 *
	 * @param store
	 *            the file store describing the history location
	 * @param name
	 *            the non-empty project name, or <code>null</code> for the
	 *            workspace
	 * @return the refactoring history manager
	 */
	private RefactoringHistoryManager getManager(final IFileStore store, final String name) {
		Assert.isNotNull(store);
		RefactoringHistoryManager manager= fManagerCache.get(store);
		if (manager == null) {
			manager= new RefactoringHistoryManager(store, name);
			fManagerCache.put(store, manager);
		}
		return manager;
	}

}
