/*******************************************************************************
 * Copyright (c) 2013, 2016 Obeo 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:
 *     Obeo - initial API and implementation
 *     Martin Fleck - bug 483798
 *     Mathias Schaefer - preferences refactoring
 *******************************************************************************/
package org.eclipse.emf.compare.rcp;

import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.EMFC_APPENDER_NAME;
import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_BACKUP_COUNT_KEY;
import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_BACKUP_DEFAULT;
import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_FILENAME_KEY;
import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_FILE_MAX_SIZE_KEY;
import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_FILE_SIZE_DEFAULT;
import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_LEVEL_DEFAULT;
import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_LEVEL_KEY;
import static org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences.LOG_PATTERN;

import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.conflict.IConflictDetector;
import org.eclipse.emf.compare.diff.IDiffEngine;
import org.eclipse.emf.compare.equi.IEquiEngine;
import org.eclipse.emf.compare.graph.IGraphView;
import org.eclipse.emf.compare.internal.adapterfactory.RankedAdapterFactoryDescriptor;
import org.eclipse.emf.compare.internal.adapterfactory.RankedAdapterFactoryDescriptorRegistryImpl;
import org.eclipse.emf.compare.internal.utils.Graph;
import org.eclipse.emf.compare.match.IMatchEngine;
import org.eclipse.emf.compare.match.eobject.EqualityHelperExtensionProvider;
import org.eclipse.emf.compare.match.eobject.EqualityHelperExtensionProviderDescriptorRegistryImpl;
import org.eclipse.emf.compare.match.eobject.WeightProvider;
import org.eclipse.emf.compare.match.eobject.WeightProviderDescriptorRegistryImpl;
import org.eclipse.emf.compare.merge.IMerger;
import org.eclipse.emf.compare.postprocessor.IPostProcessor;
import org.eclipse.emf.compare.provider.EMFCompareEditPlugin;
import org.eclipse.emf.compare.rcp.extension.AbstractRegistryEventListener;
import org.eclipse.emf.compare.rcp.graph.IGraphConsumer;
import org.eclipse.emf.compare.rcp.internal.EMFCompareRCPMessages;
import org.eclipse.emf.compare.rcp.internal.adapterfactory.AdapterFactoryDescriptorRegistryListener;
import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry;
import org.eclipse.emf.compare.rcp.internal.extension.impl.DescriptorRegistryEventListener;
import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemRegistry;
import org.eclipse.emf.compare.rcp.internal.match.EqualityHelperExtensionProviderDescriptorRegistryListener;
import org.eclipse.emf.compare.rcp.internal.match.MatchEngineFactoryRegistryListener;
import org.eclipse.emf.compare.rcp.internal.match.MatchEngineFactoryRegistryWrapper;
import org.eclipse.emf.compare.rcp.internal.match.WeightProviderDescriptorRegistryListener;
import org.eclipse.emf.compare.rcp.internal.merger.MergerExtensionRegistryListener;
import org.eclipse.emf.compare.rcp.internal.policy.LoadOnDemandPolicyRegistryImpl;
import org.eclipse.emf.compare.rcp.internal.policy.LoadOnDemandPolicyRegistryListener;
import org.eclipse.emf.compare.rcp.internal.postprocessor.PostProcessorFactoryRegistryListener;
import org.eclipse.emf.compare.rcp.internal.postprocessor.PostProcessorRegistryImpl;
import org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences;
import org.eclipse.emf.compare.rcp.policy.ILoadOnDemandPolicy;
import org.eclipse.emf.compare.req.IReqEngine;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.osgi.framework.BundleContext;

/**
 * This is the central singleton for the EMF Compare RCP plugin.
 * 
 * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
 */
public class EMFCompareRCPPlugin extends Plugin {

	/** The plug-in ID. */
	public static final String PLUGIN_ID = "org.eclipse.emf.compare.rcp"; //$NON-NLS-1$

	/** The id of the post processor extension point. */
	public static final String POST_PROCESSOR_PPID = "postProcessor"; //$NON-NLS-1$

	/** The id of the diff engine extension point. */
	public static final String DIFF_ENGINE_PPID = "diffEngine"; //$NON-NLS-1$

	/** The id of the equi engine extension point. */
	public static final String EQUI_ENGINE_PPID = "equiEngine"; //$NON-NLS-1$

	/** The id of the req engine extension point. */
	public static final String REQ_ENGINE_PPID = "reqEngine"; //$NON-NLS-1$

	/** The id of the conflict engine extension point. */
	public static final String CONFLICT_DETECTOR_PPID = "conflictsDetector"; //$NON-NLS-1$

	/** The id of the weight provider extension point. */
	public static final String WEIGHT_PROVIDER_PPID = "weightProvider"; //$NON-NLS-1$

	/** The id of the equality helper extension provider extension point. */
	public static final String EQUALITY_HELPER_EXTENSION_PROVIDER_PPID = "equalityHelperExtensionProvider"; //$NON-NLS-1$

	/** The id of the load on demand policy extension point. */
	public static final String LOAD_ON_DEMAND_POLICY_PPID = "loadOnDemandPolicy"; //$NON-NLS-1$

	/** The id of the merger extension point. */
	public static final String MERGER_PPID = "merger"; //$NON-NLS-1$

	/** The id of the match extension point. */
	public static final String MATCH_ENGINE_PPID = "matchEngine"; //$NON-NLS-1$

	/** The id of the adapter factory extension point. */
	public static final String FACTORY_PPID = "adapterFactory"; //$NON-NLS-1$

	/**
	 * Log4j logger to use throughout EMFCompare for logging purposes.
	 */
	private static final Logger LOGGER = Logger.getLogger("org.eclipse.emf.compare"); //$NON-NLS-1$

	/** Number of bytes in a MiB. */
	private static final int MEGABYTE = 1024 * 1024;

	/** This plugin is a singleton, so it's quite ok to keep the plugin in a static field. */
	private static EMFCompareRCPPlugin plugin;

	/** The registry that will hold references to all mergers. */
	private IMerger.Registry mergerRegistry;

	/** The registry that will hold references to all differences engines. */
	private ItemRegistry<IDiffEngine> diffEngineRegistry;

	/** The registry that will hold references to all equivalences engines. */
	private ItemRegistry<IEquiEngine> equiEngineRegistry;

	/** The registry that will hold references to all requirements engines. */
	private ItemRegistry<IReqEngine> reqEngineRegistry;

	/** The registry that will hold references to all conflicts detector. */
	private ItemRegistry<IConflictDetector> conflictDetectorRegistry;

	/** The registry that will hold references to all weight providers. */
	private WeightProvider.Descriptor.Registry weightProviderRegistry;

	/** The registry that will hold references to all equality helper extension providers. */
	private EqualityHelperExtensionProvider.Descriptor.Registry equalityHelperExtensionProviderRegistry;

	/** The registry listener that will be used to react to merger changes. */
	private AbstractRegistryEventListener mergerRegistryListener;

	/** The registry that will hold references to all {@link ILoadOnDemandPolicy}. **/
	private ILoadOnDemandPolicy.Registry loadOnDemandRegistry;

	/** The registry listener that will be used to react to load on demand policy changes. */
	private AbstractRegistryEventListener loadOnDemandRegistryListener;

	/** The registry that will hold references to all post processors. */
	private IPostProcessor.Descriptor.Registry<String> postProcessorDescriptorsRegistry;

	/** The registry that will hold reference to all post processors descriptors. */
	private IItemRegistry<IPostProcessor.Descriptor> postProcessorItemDescriptorsRegistry;

	/** The registry listener that will be used to react to post processor changes. */
	private AbstractRegistryEventListener postProcessorFactoryRegistryListener;

	/** The registry that will hold references to all match engine factories. */
	private IItemRegistry<IMatchEngine.Factory> matchEngineFactoryRegistry;

	/** The registry that will hold references to all match engine factories. */
	private MatchEngineFactoryRegistryWrapper matchEngineFactoryRegistryWrapped;

	/** The registry listener that will be used to react to match engine changes. */
	private MatchEngineFactoryRegistryListener matchEngineFactoryRegistryListener;

	/** Backing multimap that will hold references to all adapter factory descriptors. */
	private Multimap<Collection<?>, RankedAdapterFactoryDescriptor> adapterFactoryRegistryBackingMultimap;

	/** Adapter factory registry that references all the EMF Compare adapter factories descriptors. */
	private RankedAdapterFactoryDescriptorRegistryImpl rankedAdapterFactoryRegistry;

	/** The registry listener that will be used to react to adapter factory descriptor changes. */
	private AbstractRegistryEventListener adapterFactoryRegistryListener;

	/** The registry listener that will be used to react to diff engine changes. */
	private DescriptorRegistryEventListener<IDiffEngine> diffEngineListener;

	/** The registry listener that will be used to react to equivalences engine changes. */
	private DescriptorRegistryEventListener<IEquiEngine> equiEngineListener;

	/** The registry listener that will be used to react to requirements engine changes. */
	private DescriptorRegistryEventListener<IReqEngine> reqEngineListener;

	/** The registry listener that will be used to react to conflict detector changes. */
	private DescriptorRegistryEventListener<IConflictDetector> conflictDetectorListener;

	/** The registry listener that will be used to react to weight provider changes. */
	private WeightProviderDescriptorRegistryListener weightProviderListener;

	/** The registry listener that will be used to react to equality helper extension provider changes. */
	private EqualityHelperExtensionProviderDescriptorRegistryListener equalityHelperExtensionProviderListener;

	/** Will listen to preference changes and update log4j configuration accordingly. */
	private LoggingPreferenceChangeListener preferenceChangeListener;

	/**
	 * Keep all resources graphs identified by their id.
	 */
	private Map<String, IGraphView<URI>> graphsById = new HashMap<String, IGraphView<URI>>();

	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
	 */
	@Override
	public void start(BundleContext bundleContext) throws Exception {
		super.start(bundleContext);
		EMFCompareRCPPlugin.plugin = this;

		final IExtensionRegistry registry = Platform.getExtensionRegistry();

		setUpAdapterFactoryRegistry(registry);

		setUpWeightProviderRegistry(registry);

		setUpMatchEngineFactoryRegistry(registry);

		setUpMergerRegistry(registry);

		setUpPostProcessorRegisty(registry);

		setUpLoadOnDemandRegistry(registry);

		setUpDiffEngineRegistry(registry);

		setUpEquiEngineRegistry(registry);

		setUpReqEngineRegistry(registry);

		setUpConflictDetectorRegistry(registry);

		setUpEqualityHelperExtensionProviderRegistry(registry);

		initLogging();
	}

	/**
	 * Set the Adapter Factory Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpAdapterFactoryRegistry(final IExtensionRegistry registry) {
		adapterFactoryRegistryBackingMultimap = Multimaps.synchronizedListMultimap(
				ArrayListMultimap.<Collection<?>, RankedAdapterFactoryDescriptor> create());
		adapterFactoryRegistryListener = new AdapterFactoryDescriptorRegistryListener(
				EMFCompareEditPlugin.PLUGIN_ID, FACTORY_PPID, getLog(),
				adapterFactoryRegistryBackingMultimap);
		registry.addListener(adapterFactoryRegistryListener,
				EMFCompareEditPlugin.PLUGIN_ID + '.' + FACTORY_PPID);
		adapterFactoryRegistryListener.readRegistry(registry);
		rankedAdapterFactoryRegistry = new RankedAdapterFactoryDescriptorRegistryImpl(
				ComposedAdapterFactory.Descriptor.Registry.INSTANCE,
				Multimaps.unmodifiableMultimap(adapterFactoryRegistryBackingMultimap));
	}

	/**
	 * Set the Match Engine Factory Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpMatchEngineFactoryRegistry(final IExtensionRegistry registry) {
		matchEngineFactoryRegistry = new ItemRegistry<IMatchEngine.Factory>();
		matchEngineFactoryRegistryListener = new MatchEngineFactoryRegistryListener(PLUGIN_ID,
				MATCH_ENGINE_PPID, getLog(), matchEngineFactoryRegistry);
		matchEngineFactoryRegistryListener.readRegistry(registry);
		matchEngineFactoryRegistryWrapped = new MatchEngineFactoryRegistryWrapper(matchEngineFactoryRegistry);
	}

	/**
	 * Set the Merger Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpMergerRegistry(final IExtensionRegistry registry) {
		mergerRegistry = new IMerger.RegistryImpl();
		mergerRegistryListener = new MergerExtensionRegistryListener(PLUGIN_ID, MERGER_PPID, getLog(),
				mergerRegistry);
		registry.addListener(mergerRegistryListener, PLUGIN_ID + '.' + MERGER_PPID);
		mergerRegistryListener.readRegistry(registry);
	}

	/**
	 * Set the Post Processor Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpPostProcessorRegisty(final IExtensionRegistry registry) {
		postProcessorItemDescriptorsRegistry = new ItemRegistry<IPostProcessor.Descriptor>();

		postProcessorFactoryRegistryListener = new PostProcessorFactoryRegistryListener(PLUGIN_ID,
				POST_PROCESSOR_PPID, getLog(), postProcessorItemDescriptorsRegistry);
		registry.addListener(postProcessorFactoryRegistryListener, PLUGIN_ID + '.' + POST_PROCESSOR_PPID);
		postProcessorFactoryRegistryListener.readRegistry(registry);
		postProcessorDescriptorsRegistry = new PostProcessorRegistryImpl(
				postProcessorItemDescriptorsRegistry);
	}

	/**
	 * Set the Load On Demand Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpLoadOnDemandRegistry(final IExtensionRegistry registry) {
		loadOnDemandRegistry = new LoadOnDemandPolicyRegistryImpl();
		loadOnDemandRegistryListener = new LoadOnDemandPolicyRegistryListener(loadOnDemandRegistry, PLUGIN_ID,
				LOAD_ON_DEMAND_POLICY_PPID, getLog());
		registry.addListener(loadOnDemandRegistryListener, PLUGIN_ID + '.' + LOAD_ON_DEMAND_POLICY_PPID);
		loadOnDemandRegistryListener.readRegistry(registry);
	}

	/**
	 * Set the Differences Engine Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpDiffEngineRegistry(final IExtensionRegistry registry) {
		diffEngineRegistry = new ItemRegistry<IDiffEngine>();
		diffEngineListener = new DescriptorRegistryEventListener<IDiffEngine>(PLUGIN_ID, DIFF_ENGINE_PPID,
				getLog(), diffEngineRegistry);
		registry.addListener(diffEngineListener);
		diffEngineListener.readRegistry(registry);
	}

	/**
	 * Set the Equivalences Engine Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpEquiEngineRegistry(final IExtensionRegistry registry) {
		equiEngineRegistry = new ItemRegistry<IEquiEngine>();
		equiEngineListener = new DescriptorRegistryEventListener<IEquiEngine>(PLUGIN_ID, EQUI_ENGINE_PPID,
				getLog(), equiEngineRegistry);
		registry.addListener(equiEngineListener);
		equiEngineListener.readRegistry(registry);
	}

	/**
	 * Set the Requirements Engine Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpReqEngineRegistry(final IExtensionRegistry registry) {
		reqEngineRegistry = new ItemRegistry<IReqEngine>();
		reqEngineListener = new DescriptorRegistryEventListener<IReqEngine>(PLUGIN_ID, REQ_ENGINE_PPID,
				getLog(), reqEngineRegistry);
		registry.addListener(reqEngineListener);
		reqEngineListener.readRegistry(registry);
	}

	/**
	 * Set the Conflicts Detector Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpConflictDetectorRegistry(final IExtensionRegistry registry) {
		conflictDetectorRegistry = new ItemRegistry<IConflictDetector>();
		conflictDetectorListener = new DescriptorRegistryEventListener<IConflictDetector>(PLUGIN_ID,
				CONFLICT_DETECTOR_PPID, getLog(), conflictDetectorRegistry);
		registry.addListener(conflictDetectorListener);
		conflictDetectorListener.readRegistry(registry);
	}

	/**
	 * Set the Weight Provider Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpWeightProviderRegistry(final IExtensionRegistry registry) {
		weightProviderRegistry = new WeightProviderDescriptorRegistryImpl();
		weightProviderListener = new WeightProviderDescriptorRegistryListener(PLUGIN_ID, WEIGHT_PROVIDER_PPID,
				getLog(), weightProviderRegistry);
		registry.addListener(weightProviderListener);
		weightProviderListener.readRegistry(registry);
	}

	/**
	 * Set the Matching And Distance Provider Registry.
	 * 
	 * @param registry
	 *            {@link IExtensionRegistry} to listen in order to fill the registry
	 */
	private void setUpEqualityHelperExtensionProviderRegistry(final IExtensionRegistry registry) {
		equalityHelperExtensionProviderRegistry = new EqualityHelperExtensionProviderDescriptorRegistryImpl();
		equalityHelperExtensionProviderListener = new EqualityHelperExtensionProviderDescriptorRegistryListener(
				PLUGIN_ID, EQUALITY_HELPER_EXTENSION_PROVIDER_PPID, getLog(),
				equalityHelperExtensionProviderRegistry);
		registry.addListener(equalityHelperExtensionProviderListener);
		equalityHelperExtensionProviderListener.readRegistry(registry);
	}

	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	@Override
	public void stop(BundleContext bundleContext) throws Exception {
		if (preferenceChangeListener != null) {
			InstanceScope.INSTANCE.getNode(EMFCompareRCPPlugin.PLUGIN_ID)
					.removePreferenceChangeListener(preferenceChangeListener);
		}

		final IExtensionRegistry registry = Platform.getExtensionRegistry();

		discardConflictDetectorRegistry(registry);

		discardReqEngineRegistry(registry);

		discardEquiEngineRegistry(registry);

		discardDiffEngineRegistry(registry);

		discardLoadOnDemandeRegistry(registry);

		discardPostProcessorfactoryRegistry(registry);

		discardMergerRegistry(registry);

		discardMatchEngineRegistry(registry);

		discardWeightProviderRegistry(registry);

		discardAdapterFactoryRegistry(registry);

		super.stop(bundleContext);
	}

	/**
	 * Discard Requirement Engine Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardReqEngineRegistry(final IExtensionRegistry registry) {
		registry.removeListener(reqEngineListener);
		reqEngineListener = null;
		reqEngineRegistry = null;
	}

	/**
	 * Discard Conflict Detector Engine Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardConflictDetectorRegistry(final IExtensionRegistry registry) {
		registry.removeListener(conflictDetectorListener);
		conflictDetectorListener = null;
		conflictDetectorRegistry = null;
	}

	/**
	 * Discard Weight Provider Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardWeightProviderRegistry(final IExtensionRegistry registry) {
		registry.removeListener(weightProviderListener);
		weightProviderListener = null;
		weightProviderRegistry = null;
	}

	/**
	 * Discard Equivalence Engine Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardEquiEngineRegistry(final IExtensionRegistry registry) {
		registry.removeListener(equiEngineListener);
		equiEngineListener = null;
		equiEngineRegistry = null;
	}

	/**
	 * Discard Difference Engine Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardDiffEngineRegistry(final IExtensionRegistry registry) {
		registry.removeListener(diffEngineListener);
		diffEngineListener = null;
		diffEngineRegistry = null;
	}

	/**
	 * Discard Adapter Factory Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardAdapterFactoryRegistry(final IExtensionRegistry registry) {
		rankedAdapterFactoryRegistry = null;
		registry.removeListener(adapterFactoryRegistryListener);
		adapterFactoryRegistryListener = null;
		adapterFactoryRegistryBackingMultimap = null;
	}

	/**
	 * Discard Match Engine Factory Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardMatchEngineRegistry(final IExtensionRegistry registry) {
		registry.removeListener(matchEngineFactoryRegistryListener);
		matchEngineFactoryRegistryListener = null;
		matchEngineFactoryRegistry = null;
		matchEngineFactoryRegistryWrapped = null;
	}

	/**
	 * Discard Merger Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardMergerRegistry(final IExtensionRegistry registry) {
		registry.removeListener(mergerRegistryListener);
		mergerRegistryListener = null;
		mergerRegistry = null;
	}

	/**
	 * Discard Post Processor Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardPostProcessorfactoryRegistry(final IExtensionRegistry registry) {
		registry.removeListener(postProcessorFactoryRegistryListener);
		postProcessorFactoryRegistryListener = null;
		postProcessorDescriptorsRegistry = null;
		postProcessorItemDescriptorsRegistry = null;
	}

	/**
	 * Discard Load On Demand Registry.
	 * 
	 * @param registry
	 *            IExtensionRegistry to remove listener
	 */
	private void discardLoadOnDemandeRegistry(final IExtensionRegistry registry) {
		registry.removeListener(loadOnDemandRegistryListener);
		loadOnDemandRegistryListener = null;
		loadOnDemandRegistry = null;
	}

	/**
	 * Returns the adapter factory descriptor registry to which extension will be registered.
	 * 
	 * @return the the adapter factory descriptor registry to which extension will be registered
	 * @since 3.0
	 */
	public RankedAdapterFactoryDescriptor.Registry getAdapterFactoryRegistry() {
		return rankedAdapterFactoryRegistry;
	}

	/**
	 * Returns a new instance of EMF Compare adapter factory descriptor registry to which extension will be
	 * registered. It filters available adapter factories using preferences.
	 * 
	 * @return the the adapter factory descriptor registry to which extension will be registered
	 * @since 2.3
	 * @deprecated Use {@link #createFilteredAdapterFactoryRegistry(Map)} to take the context into
	 *             consideration. Typically, you would provide the comparison as a context map by passing
	 *             <code>ImmutableMap.of(IContextTester.CTX_COMPARISON, comparison)</code> as an argument. If
	 *             no comparison context is available, use an empty context.
	 */
	@Deprecated
	public RankedAdapterFactoryDescriptor.Registry createFilteredAdapterFactoryRegistry() {
		return createFilteredAdapterFactoryRegistry(Maps.newLinkedHashMap());
	}

	/**
	 * Returns a new instance of EMF Compare adapter factory descriptor registry to which extension will be
	 * registered. It filters available adapter factories using preferences.
	 * 
	 * @param context
	 *            context for the adapter factories. This context cannot be null but may be empty.
	 * @return the adapter factory descriptor registry to which extension will be registered
	 * @since 2.5
	 */
	public RankedAdapterFactoryDescriptor.Registry createFilteredAdapterFactoryRegistry(
			Map<Object, Object> context) {
		final List<String> disabledAdapterFactories = EMFComparePreferences
				.getDisabledAdapterFactoryDescriptorIds();
		// Filters disabled adapter factories
		Multimap<Collection<?>, RankedAdapterFactoryDescriptor> filteredBackingMultimap = ImmutableMultimap
				.copyOf(Multimaps.filterValues(adapterFactoryRegistryBackingMultimap,
						new Predicate<RankedAdapterFactoryDescriptor>() {
							public boolean apply(RankedAdapterFactoryDescriptor input) {
								return !disabledAdapterFactories.contains(input.getId());
							}
						}));

		return new RankedAdapterFactoryDescriptorRegistryImpl(
				ComposedAdapterFactory.Descriptor.Registry.INSTANCE, filteredBackingMultimap, context);
	}

	/**
	 * Returns the merger registry to which extension will be registered.
	 * 
	 * @return the merger registry to which extension will be registered
	 * @since 3.0
	 */
	public IMerger.Registry getMergerRegistry() {
		return mergerRegistry;
	}

	/**
	 * Returns the post processor registry to which extension will be registered.
	 * 
	 * @return the post processor registry to which extension will be registered
	 */
	public IPostProcessor.Descriptor.Registry<String> getPostProcessorRegistry() {
		return postProcessorDescriptorsRegistry;
	}

	/**
	 * Get the {@link IItemRegistry} of {@link IPostProcessor.Descriptor}.
	 * 
	 * @return {@link IItemRegistry} of {@link IPostProcessor.Descriptor}.
	 * @since 2.2.0
	 */
	public IItemRegistry<IPostProcessor.Descriptor> getPostProcessorDescriptorRegistry() {
		return postProcessorItemDescriptorsRegistry;
	}

	/**
	 * Returns the registry of load on demand policies.
	 * 
	 * @return the registry of load on demand policies.
	 */
	public ILoadOnDemandPolicy.Registry getLoadOnDemandPolicyRegistry() {
		return loadOnDemandRegistry;
	}

	/**
	 * Returns the registry of Differences engines.
	 * 
	 * @return the registry of Differences engines
	 */
	public IItemRegistry<IDiffEngine> getDiffEngineDescriptorRegistry() {
		return diffEngineRegistry;
	}

	/**
	 * Returns the registry of Equivalences engines.
	 * 
	 * @return the registry of Equivalences engines
	 */
	public IItemRegistry<IEquiEngine> getEquiEngineDescriptorRegistry() {
		return equiEngineRegistry;
	}

	/**
	 * Returns the registry of Requirements engines.
	 * 
	 * @return the registry of Requirements engines
	 */
	public IItemRegistry<IReqEngine> getReqEngineDescriptorRegistry() {
		return reqEngineRegistry;
	}

	/**
	 * Returns the registry of Conflict detector.
	 * 
	 * @return the registry of Conflict detector
	 */
	public IItemRegistry<IConflictDetector> getConflictDetectorDescriptorRegistry() {
		return conflictDetectorRegistry;
	}

	/**
	 * Returns the registry of weight providers.
	 * 
	 * @return the registry of weight providers
	 */
	public WeightProvider.Descriptor.Registry getWeightProviderRegistry() {
		return weightProviderRegistry;
	}

	/**
	 * Returns the registry of equality helper extension providers.
	 * 
	 * @return the registry of equality helper extension providers
	 */
	public EqualityHelperExtensionProvider.Descriptor.Registry getEqualityHelperExtensionProviderRegistry() {
		return equalityHelperExtensionProviderRegistry;
	}

	/**
	 * Returns the match engine factory registry to which extension will be registered.
	 * 
	 * @return the match engine factory registry to which extension will be registered
	 * @since 3.0
	 */
	public IMatchEngine.Factory.Registry getMatchEngineFactoryRegistry() {
		return matchEngineFactoryRegistryWrapped;
	}

	/**
	 * Returns the match engine factory registry to which extension will be registered.
	 * 
	 * @return the match engine factory registry to which extension will be registered
	 * @since 3.0
	 */
	public IItemRegistry<IMatchEngine.Factory> getMatchEngineFactoryDescriptorRegistry() {
		return matchEngineFactoryRegistry;
	}

	/**
	 * Log the given message with the given severity to the logger of this plugin.
	 * 
	 * @param severity
	 *            the severity of the message.
	 * @param message
	 *            the message to log.
	 */
	public void log(int severity, String message) {
		getLog().log(new Status(severity, PLUGIN_ID, message));
	}

	/**
	 * Returns the shared instance.
	 * 
	 * @return the shared instance
	 */
	public static EMFCompareRCPPlugin getDefault() {
		return plugin;
	}

	/**
	 * Initializes log4j by reading the preferences.
	 */
	private void initLogging() {
		LOGGER.setLevel(Level.toLevel(Platform.getPreferencesService()
				.getString(EMFCompareRCPPlugin.PLUGIN_ID, LOG_LEVEL_KEY, LOG_LEVEL_DEFAULT, null)));
		if (!Level.OFF.equals(LOGGER.getLevel())) {
			RollingFileAppender appender = (RollingFileAppender)LOGGER.getAppender(EMFC_APPENDER_NAME);
			String logFileName = Platform.getPreferencesService().getString(EMFCompareRCPPlugin.PLUGIN_ID,
					LOG_FILENAME_KEY, "", null); //$NON-NLS-1$
			if (logFileName.length() > 0) {
				if (appender == null) {
					try {
						createLogAppender(logFileName);
					} catch (IOException e) {
						// Invalidate file name
						Platform.getPreferencesService().getString(EMFCompareRCPPlugin.PLUGIN_ID,
								LOG_FILENAME_KEY, "", null); //$NON-NLS-1$
					}
				} else {
					appender.setMaxBackupIndex(Platform.getPreferencesService().getInt(
							EMFCompareRCPPlugin.PLUGIN_ID, LOG_BACKUP_COUNT_KEY, LOG_BACKUP_DEFAULT, null));
					appender.setMaximumFileSize(
							(Platform.getPreferencesService().getInt(EMFCompareRCPPlugin.PLUGIN_ID,
									LOG_FILE_MAX_SIZE_KEY, LOG_FILE_SIZE_DEFAULT, null)) * MEGABYTE);
				}
			}
		}
		preferenceChangeListener = new LoggingPreferenceChangeListener();
		InstanceScope.INSTANCE.getNode(EMFCompareRCPPlugin.PLUGIN_ID)
				.addPreferenceChangeListener(preferenceChangeListener);
	}

	/**
	 * Creates the RollingFileAppender used to log with log4j.
	 * 
	 * @param newFileName
	 *            Path opf the log file
	 * @throws IOException
	 *             If an IO problem occurs, like the given path does not represent a file, or it cannot be
	 *             written;
	 */
	private void createLogAppender(String newFileName) throws IOException {
		RollingFileAppender appender;
		appender = new RollingFileAppender(new PatternLayout(LOG_PATTERN), newFileName, true);
		LOGGER.removeAllAppenders(); // We don't want to log elsewhere
		LOGGER.addAppender(appender);
		appender.setMaxBackupIndex(Platform.getPreferencesService().getInt(EMFCompareRCPPlugin.PLUGIN_ID,
				LOG_BACKUP_COUNT_KEY, LOG_BACKUP_DEFAULT, null));
		appender.setMaximumFileSize((Platform.getPreferencesService().getInt(EMFCompareRCPPlugin.PLUGIN_ID,
				LOG_FILE_MAX_SIZE_KEY, LOG_FILE_SIZE_DEFAULT, null)) * MEGABYTE);
	}

	/**
	 * Listens to logging preference changes to maintain the log4j configuration up-to-date.
	 * 
	 * @author <a href="mailto:laurent.delaigue@obeo.fr">Laurent Delaigue</a>
	 */
	private static class LoggingPreferenceChangeListener implements IPreferenceChangeListener {

		/**
		 * The path of the logging file.
		 */
		private String path;

		/**
		 * The level of the logger.
		 */
		private Level loggingLevel;

		/**
		 * Updates the log4j configuration when logging preferences change.
		 * 
		 * @param event
		 *            the preference change event.
		 */
		public void preferenceChange(PreferenceChangeEvent event) {
			final IPreferencesService prefs = Platform.getPreferencesService();

			path = prefs.getString(EMFCompareRCPPlugin.PLUGIN_ID, LOG_FILENAME_KEY, "", null); //$NON-NLS-1$
			if (LOG_LEVEL_KEY.equals(event.getKey())) {
				loggingLevel = Level.toLevel((String)event.getNewValue());
				LOGGER.setLevel(loggingLevel);
			} else if (LOG_FILENAME_KEY.equals(event.getKey())) {
				path = (String)event.getNewValue();
			} else if (LOG_BACKUP_COUNT_KEY.equals(event.getKey())) {
				RollingFileAppender appender = (RollingFileAppender)LOGGER.getAppender(EMFC_APPENDER_NAME);
				if (appender != null) {
					appender.setMaxBackupIndex(Integer.parseInt((String)event.getNewValue()));
				}
			} else if (LOG_FILE_MAX_SIZE_KEY.equals(event.getKey())) {
				RollingFileAppender appender = (RollingFileAppender)LOGGER.getAppender(EMFC_APPENDER_NAME);
				if (appender != null) {
					appender.setMaximumFileSize(Integer.parseInt((String)event.getNewValue()) * MEGABYTE);
				}
			}
			if (loggingLevel != null && !Level.OFF.equals(loggingLevel) && path != null
					&& path.length() > 0) {
				initFile();
			}
		}

		/**
		 * Create the logging file.
		 */
		private void initFile() {
			RollingFileAppender appender = (RollingFileAppender)LOGGER.getAppender(EMFC_APPENDER_NAME);
			if (appender == null) {
				try {
					EMFCompareRCPPlugin.getDefault().createLogAppender(path);
				} catch (IOException e) {
					// Force the value to be harmless
					InstanceScope.INSTANCE.getNode(EMFCompareRCPPlugin.PLUGIN_ID).put(LOG_FILENAME_KEY, ""); //$NON-NLS-1$
					getDefault().log(IStatus.ERROR,
							EMFCompareRCPMessages.getString("logging.appender.error", path, e.getMessage())); //$NON-NLS-1$
				}
			} else {
				appender.setFile(path);
			}
		}

	}

	/**
	 * This method creates a new Graph of URI, passes it to the given consumer and then keeps track of the
	 * given graph to be able to provide a read only view of it on demand.
	 * 
	 * @param consumer
	 *            An instance of graph consumer, for instance the ThreadedModelResolver instance.
	 * @throws IllegalArgumentException
	 *             if the consumer uses an ID that is already registered.
	 * @since 2.4
	 */
	public void register(IGraphConsumer consumer) {
		consumer.setGraph(new Graph<URI>());
		String id = consumer.getId();
		if (graphsById.containsKey(id)) {
			throw new IllegalArgumentException(EMFCompareRCPMessages.getString("duplicate.graph.id.msg", id)); //$NON-NLS-1$
		}
		graphsById.put(id, consumer.getGraphView());
	}

	/**
	 * Return the graph view associated with the given id, or null if it does not exist.
	 * 
	 * @param id
	 *            The id of the graph
	 * @return The graph view registered for the given ID, which can be null.
	 * @since 2.4
	 */
	public IGraphView<URI> getGraphView(String id) {
		return graphsById.get(id);
	}

}
