/*******************************************************************************
 * Copyright (c) 2015 Obeo.
 * 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 and/or initial documentation
 *    ...
 *******************************************************************************/
package org.eclipse.intent.mapping;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import name.fraser.neil.plaintext.diff_match_patch;
import name.fraser.neil.plaintext.diff_match_patch.Diff;

import org.eclipse.intent.mapping.base.BaseElementFactory.IFactoryDescriptor;
import org.eclipse.intent.mapping.base.ContainerProviderFactory;
import org.eclipse.intent.mapping.base.IBase;
import org.eclipse.intent.mapping.base.IBaseRegistry;
import org.eclipse.intent.mapping.base.IBaseRegistryListener;
import org.eclipse.intent.mapping.base.ILink;
import org.eclipse.intent.mapping.base.ILocation;
import org.eclipse.intent.mapping.base.ILocationContainer;
import org.eclipse.intent.mapping.base.ILocationDescriptor;
import org.eclipse.intent.mapping.base.IReport;
import org.eclipse.intent.mapping.connector.IConnectorRegistry;
import org.eclipse.intent.mapping.content.IFileTypeRegistry;
import org.eclipse.intent.mapping.internal.base.BaseRegistry;
import org.eclipse.intent.mapping.internal.connector.ConnectorRegistry;
import org.eclipse.intent.mapping.internal.content.FileTypeRegistry;

/**
 * Mapping utility class.
 *
 * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
 */
public final class MappingUtils {

	/**
	 * Diff and match wrapping class.
	 *
	 * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
	 */
	public static final class DiffMatch {

		/**
		 * The list of differences.
		 */
		final LinkedList<Diff> diffs;

		/**
		 * Constructor.
		 * 
		 * @param txt1
		 *            the first text
		 * @param txt2
		 *            the second text
		 */
		private DiffMatch(String txt1, String txt2) {
			diffs = DIFF_MATCH_PATCH.diff_main(txt1, txt2);
		}

		/**
		 * Reduce the number of edits by eliminating operationally trivial equalities.
		 */
		public void cleanupEfficdiency() {
			DIFF_MATCH_PATCH.diff_cleanupEfficiency(diffs);
		}

		/**
		 * Reorder and merge like edit sections. Merge equalities. Any edit section can move as long as it
		 * doesn't cross an equality.
		 */
		public void cleanupMerge() {
			DIFF_MATCH_PATCH.diff_cleanupMerge(diffs);
		}

		/**
		 * Reduce the number of edits by eliminating semantically trivial equalities.
		 */
		public void cleanupSemantic() {
			DIFF_MATCH_PATCH.diff_cleanupSemantic(diffs);
		}

		/**
		 * Look for single edits surrounded on both sides by equalities which can be shifted sideways to align
		 * the edit to a word boundary. e.g: "The c<ins>at c</ins>ame." -> "The <ins>cat </ins>came".
		 */
		public void cleanupSemanticLossless() {
			DIFF_MATCH_PATCH.diff_cleanupSemanticLossless(diffs);
		}

		/**
		 * Gets the <a href="https://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein Distance</a>.
		 * 
		 * @return the <a href="https://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein Distance</a>
		 */
		public int getLevenshteinDistance() {
			return DIFF_MATCH_PATCH.diff_levenshtein(diffs);
		}

		/**
		 * Gets the index in text2 from corresponding to the index in text1.
		 * 
		 * @param index
		 *            the index in text1
		 * @return the index in text2 from corresponding to the index in text1
		 */
		public int getIndex(int index) {
			return DIFF_MATCH_PATCH.diff_xIndex(diffs, index);
		}

	}

	/**
	 * The {@link IBaseRegistry}.
	 */
	private static final BaseRegistry BASE_REGISTRY = initBaseRegistry();

	/**
	 * The {@link IConnectorRegistry}.
	 */
	private static final ConnectorRegistry CONNECTOR_REGISTRY = new ConnectorRegistry();

	/**
	 * {@link IBase} kind to {@link ILocation} interface/implementation mapping.
	 */
	private static final Map<Class<? extends IBase>, Map<Class<? extends ILocation>, IFactoryDescriptor<? extends ILocation>>> LOCATION_IMPLEMENTATIONS = new HashMap<Class<? extends IBase>, Map<Class<? extends ILocation>, IFactoryDescriptor<? extends ILocation>>>();

	/**
	 * Diff match patch instance.
	 */
	private static final diff_match_patch DIFF_MATCH_PATCH = new diff_match_patch();

	/**
	 * The {@link ContainerProviderFactory}.
	 */
	private static final ContainerProviderFactory CONTAINER_PROVIDER_FACTORY = new ContainerProviderFactory();

	/**
	 * The {@link IFileTypeRegistry}.
	 */
	private static IFileTypeRegistry fileTypeRegistry = new FileTypeRegistry();

	/**
	 * Constructor.
	 */
	private MappingUtils() {
		// nothing to do here
	}

	/**
	 * Initialize the {@link BaseRegistry}.
	 * 
	 * @return the {@link BaseRegistry}
	 */
	private static BaseRegistry initBaseRegistry() {
		final BaseRegistry res = new BaseRegistry();

		res.addListener(new IBaseRegistryListener.Stub() {

			@Override
			@SuppressWarnings("unchecked")
			public void baseRegistred(IBase base) {
				for (Entry<Class<? extends IBase>, Map<Class<? extends ILocation>, IFactoryDescriptor<? extends ILocation>>> entry : LOCATION_IMPLEMENTATIONS
						.entrySet()) {
					if (entry.getKey().isAssignableFrom(base.getClass())) {
						for (Entry<Class<? extends ILocation>, IFactoryDescriptor<? extends ILocation>> locationEntry : entry
								.getValue().entrySet()) {
							base.getFactory().addDescriptor((Class<ILocation>)locationEntry.getKey(),
									locationEntry.getValue());
						}
					}
				}
			}

		});

		return res;
	}

	/**
	 * Gets a {@link DiffMatch} for the two given {@link String}.
	 * 
	 * @param txt1
	 *            the first text
	 * @param txt2
	 *            the second text
	 * @return a {@link DiffMatch} for the two given {@link String}
	 */
	public static DiffMatch getDiffMatch(String txt1, String txt2) {
		return new DiffMatch(txt1, txt2);
	}

	/**
	 * Gets the {@link IBaseRegistry}.
	 * 
	 * @return the {@link IBaseRegistry}
	 */
	public static IBaseRegistry getMappingRegistry() {
		return BASE_REGISTRY;
	}

	/**
	 * Gets the {@link IConnectorRegistry}.
	 * 
	 * @return the {@link IConnectorRegistry}
	 */
	public static IConnectorRegistry getConnectorRegistry() {
		return CONNECTOR_REGISTRY;
	}

	/**
	 * Registers the given {@link ILocation} implementation to instantiate the given {@link ILocation}
	 * interface for the given {@link IBase} kind.
	 * 
	 * @param baseClass
	 *            the {@link IBase} kind
	 * @param locationInterface
	 *            the {@link ILocation} interface
	 * @param descriptor
	 *            the {@link ILocation} implementation for the {@link IBase} kind
	 * @param <L>
	 *            the {@link ILocation} interface kind
	 */
	public static <L extends ILocation> void registerLocationImplementation(Class<? extends IBase> baseClass,
			Class<L> locationInterface, IFactoryDescriptor<? extends L> descriptor) {
		synchronized(getMappingRegistry()) {
			Map<Class<? extends ILocation>, IFactoryDescriptor<? extends ILocation>> implementations = LOCATION_IMPLEMENTATIONS
					.get(baseClass);
			if (implementations == null) {
				implementations = new HashMap<Class<? extends ILocation>, IFactoryDescriptor<? extends ILocation>>();
				LOCATION_IMPLEMENTATIONS.put(baseClass, implementations);
			}
			implementations.put(locationInterface, descriptor);
			for (IBase base : getMappingRegistry().getBases()) {
				if (baseClass.isAssignableFrom(base.getClass())) {
					base.getFactory().addDescriptor(locationInterface, descriptor);
				}
			}
		}
	}

	/**
	 * Removes the given {@link ILocation} interface instantiation {@link Class} for the given {@link IBase}.
	 * 
	 * @param baseClass
	 *            the {@link IBase} kind
	 * @param locationInterface
	 *            the {@link ILocation} interface
	 */
	public static void unregisterLocationImplementation(Class<? extends IBase> baseClass,
			Class<? extends ILocation> locationInterface) {
		synchronized(getMappingRegistry()) {
			Map<Class<? extends ILocation>, IFactoryDescriptor<? extends ILocation>> implementations = LOCATION_IMPLEMENTATIONS
					.get(baseClass);
			if (implementations != null) {
				implementations.remove(locationInterface);
			}
			for (IBase base : getMappingRegistry().getBases()) {
				if (baseClass.isAssignableFrom(base.getClass())) {
					base.getFactory().removeDescriptor(locationInterface);
				}
			}
		}
	}

	/**
	 * Gets the {@link IBase} containing the given {@link ILocation}.
	 * 
	 * @param location
	 *            the {@link ILocation}
	 * @return the {@link IBase} containing the given {@link ILocation} if nay, <code>null</code> otherwise
	 */
	public static IBase getBase(ILocation location) {
		IBase res = null;

		ILocationContainer conainer = location.getContainer();
		while (conainer != null) {
			if (conainer instanceof IBase) {
				res = (IBase)conainer;
				break;
			} else if (conainer instanceof ILocation) {
				conainer = ((ILocation)conainer).getContainer();
			} else {
				break;
			}
		}

		return res;
	}

	/**
	 * Gets the containing {@link IBase} of the given {@link ILocationContainer}.
	 * 
	 * @param container
	 *            the {@link ILocationContainer}
	 * @return the containing {@link IBase} of the given {@link ILocationContainer} if any, <code>null</code>
	 *         otherwise
	 */
	public static IBase getBase(ILocationContainer container) {
		final IBase res;

		if (container instanceof IBase) {
			res = (IBase)container;
		} else if (container instanceof ILocation) {
			res = getBase((ILocation)container);
		} else {
			throw new IllegalStateException("new ILocationContainer sub type ?");
		}

		return res;
	}

	/**
	 * Gets the {@link ILink} between {@link ILocation source} and {@link ILocation target}.
	 * 
	 * @param source
	 *            the {@link ILocation source}
	 * @param target
	 *            the {@link ILocation target}
	 * @return the {@link ILink} between {@link ILocation source} and {@link ILocation target} if any,
	 *         <code>null</code> otherwise
	 */
	public static ILink getLink(ILocation source, ILocation target) {
		ILink res = null;

		if (source.getTargetLinks().size() > target.getSourceLinks().size()) {
			for (ILink link : target.getSourceLinks()) {
				if (source.equals(link.getSource())) {
					res = link;
					break;
				}
			}
		} else {
			for (ILink link : source.getTargetLinks()) {
				if (target.equals(link.getTarget())) {
					res = link;
					break;
				}
			}
		}

		return res;
	}

	/**
	 * Tells if an {@link ILink} can be {@link MappingUtils#createLink(ILocation, ILocation) created} between
	 * the given {@link ILocation source} and {@link ILocation target}.
	 * 
	 * @param source
	 *            the source {@link ILocation}
	 * @param target
	 *            the target {@link ILocation}
	 * @return <code>true</code> if an {@link ILink} can be
	 *         {@link MappingUtils#createLink(ILocation, ILocation) created} between the given
	 *         {@link ILocation source} and {@link ILocation target}, <code>false</code> otherwise
	 */
	public static boolean canCreateLink(ILocation source, ILocation target) {
		return !source.isMarkedAsDeleted() && !target.isMarkedAsDeleted() && !source.equals(target)
				&& MappingUtils.getLink(source, target) == null;
	}

	/**
	 * Tells if an {@link ILink} can be
	 * {@link MappingUtils#createLink(ILocationDescriptor, ILocationDescriptor) created} between the given
	 * {@link ILocationDescriptor sourceDescriptor} and {@link ILocationDescriptor targetDescriptor}.
	 * 
	 * @param sourceDescriptor
	 *            the source {@link ILocationDescriptor}
	 * @param targetDescriptor
	 *            the target {@link ILocationDescriptor}
	 * @return <code>true</code> if an {@link ILink} can be
	 *         {@link MappingUtils#createLink(ILocationDescriptor, ILocationDescriptor) created} between the
	 *         given {@link ILocationDescriptor sourceDescriptor} and {@link ILocationDescriptor
	 *         targetDescriptor}, <code>false</code> otherwise
	 */
	public static boolean canCreateLink(ILocationDescriptor sourceDescriptor,
			ILocationDescriptor targetDescriptor) {
		return !sourceDescriptor.exists() || !targetDescriptor.exists() || MappingUtils.canCreateLink(
				sourceDescriptor.getLocation(), targetDescriptor.getLocation());
	}

	/**
	 * Creates an {@link ILink} between the given {@link ILink#getSource() source} and
	 * {@link ILink#getTarget() target}.
	 * 
	 * @param source
	 *            the {@link ILink#getSource() source} {@link ILocation}
	 * @param target
	 *            the {@link ILink#getTarget() target} {@link ILocation}
	 * @return the created {@link ILink}
	 * @throws IllegalAccessException
	 *             if the class or its nullary constructor is not accessible
	 * @throws InstantiationException
	 *             if this Class represents an abstract class, an interface, an array class, a primitive type,
	 *             or void; or if the class has no nullary constructor; or if the instantiation fails for some
	 *             other reason
	 * @throws ClassNotFoundException
	 *             if the {@link Class} can't be found
	 */
	public static ILink createLink(ILocation source, ILocation target) throws InstantiationException,
			IllegalAccessException, ClassNotFoundException {
		final ILink res;

		if (canCreateLink(source, target)) {
			final IBase base = getBase(source);
			res = base.getFactory().createElement(ILink.class);
			res.setSource(source);
			res.setTarget(target);
		} else {
			throw new IllegalStateException("can't create the Link.");
		}

		return res;
	}

	/**
	 * Creates an {@link ILink} between the given {@link ILink#getSource() source} and
	 * {@link ILink#getTarget() target}.
	 * 
	 * @param sourceDescriptor
	 *            the {@link ILink#getSource() source} {@link ILocationDescriptor}
	 * @param targetDescriptor
	 *            the {@link ILink#getTarget() target} {@link ILocationDescriptor}
	 * @return the created {@link ILink}
	 * @throws IllegalAccessException
	 *             if the class or its nullary constructor is not accessible
	 * @throws InstantiationException
	 *             if this Class represents an abstract class, an interface, an array class, a primitive type,
	 *             or void; or if the class has no nullary constructor; or if the instantiation fails for some
	 *             other reason
	 * @throws ClassNotFoundException
	 *             if the {@link Class} can't be found
	 */
	public static ILink createLink(ILocationDescriptor sourceDescriptor, ILocationDescriptor targetDescriptor)
			throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		final ILink res;

		if (canCreateLink(sourceDescriptor, targetDescriptor)) {
			res = MappingUtils.createLink(sourceDescriptor.getOrCreate(), targetDescriptor.getOrCreate());
		} else {
			throw new IllegalStateException("can't create the Link.");
		}

		return res;
	}

	/**
	 * Gets the content of the given {@link File}.
	 * 
	 * @param file
	 *            the {@link File}
	 * @param charsetName
	 *            The name of a supported {@link java.nio.charset.Charset </code>charset<code>}
	 * @return a {@link String} of the content of the given {@link File}
	 * @throws IOException
	 *             if the {@link File} can't be read
	 */
	public static String getContent(File file, String charsetName) throws IOException {
		if (!file.exists()) {
			throw new IOException(file.getAbsolutePath() + " doesn't exists.");
		} else if (file.isDirectory()) {
			throw new IOException(file.getAbsolutePath() + " is a directory.");
		} else if (!file.canRead()) {
			throw new IOException(file.getAbsolutePath() + " is not readable.");
		}
		int len = (int)file.length();
		final String res;
		if (len != 0) {
			res = getContent(len, new FileInputStream(file));
		} else {
			res = "";
		}
		return res;
	}

	/**
	 * Gets the content of the given {@link File}.
	 * 
	 * @param length
	 *            the {@link InputStream} size
	 * @param inputStream
	 *            the {@link InputStream}
	 * @return a {@link String} of the content of the given {@link File}
	 * @throws IOException
	 *             if the {@link InputStream} can't be read
	 */
	public static String getContent(int length, InputStream inputStream) throws IOException {
		final StringBuilder res = new StringBuilder(length);
		final InputStreamReader input = new InputStreamReader(new BufferedInputStream(inputStream));

		final char[] buffer = new char[length];
		int len = input.read(buffer);
		while (len != -1) {
			res.append(buffer, 0, len);
			len = input.read(buffer);
		}
		input.close();

		return res.toString();
	}

	/**
	 * Tells if the given {@link ILink} can be deleted.
	 * 
	 * @param link
	 *            the {@link ILink} to check
	 * @return <code>true</code> if the given {@link ILink} can be deleted, <code>false</code> otherwise
	 */
	public static boolean canDeleteLink(ILink link) {
		return link.getReports().isEmpty();
	}

	/**
	 * Deletes the given {@link ILink}.
	 * 
	 * @param link
	 *            the {@link ILink} to delete
	 */
	public static void deleteLink(ILink link) {
		if (canDeleteLink(link)) {
			final ILocation source = link.getSource();
			link.setSource(null);
			if (source != null && source.isMarkedAsDeleted() && canDeleteLocation(source)) {
				deleteLocation(source);
			}
			final ILocation target = link.getTarget();
			link.setTarget(null);
			if (target != null && target.isMarkedAsDeleted() && canDeleteLocation(target)) {
				deleteLocation(target);
			}
		} else {
			throw new IllegalStateException("can't delete a link with report.");
		}
	}

	/**
	 * Tells if the given {@link ILocation} can be deleted.
	 * 
	 * @param location
	 *            the {@link ILocation} to check
	 * @return <code>true</code> if the given {@link ILocation} can be deleted, <code>false</code> otherwise
	 */
	public static boolean canDeleteLocation(ILocation location) {
		return location.getSourceLinks().isEmpty() && location.getTargetLinks().isEmpty() && location
				.getContents().isEmpty();
	}

	/**
	 * Deletes the given {@link ILocation}.
	 * 
	 * @param location
	 *            the {@link ILocation} to delete
	 */
	public static void deleteLocation(ILocation location) {
		if (canDeleteLocation(location)) {
			final ILocationContainer container = location.getContainer();
			location.setContainer(null);
			if (container instanceof ILocation && ((ILocation)container).isMarkedAsDeleted()
					&& canDeleteLocation((ILocation)container)) {
				deleteLocation((ILocation)container);
			}
		} else {
			throw new IllegalStateException("can't delete a location with links or contained locations.");
		}
	}

	/**
	 * Deletes the given {@link IReport}.
	 * 
	 * @param report
	 *            the {@link IReport} to delete
	 */
	public static void deleteReport(IReport report) {
		final IBase base = getBase(report.getLink().getSource());
		base.getReports().remove(report);
		report.setLink(null);
	}

	/**
	 * {@link MappingUtils#deleteLocation(ILocation) Deletes} if
	 * {@link MappingUtils#canDeleteLocation(ILocation) possible} or
	 * {@link ILocation#setMarkedAsDeleted(boolean) mark as deleted} the given location. In the latest case an
	 * {@link IReport} is created with the given {@link IReport#getDescription() description}.
	 * 
	 * @param location
	 *            the {@link ILocation}
	 * @param reportDescription
	 *            the {@link IReport} {@link IReport#getDescription() description}
	 * @return the {@link List} of creates {@link IReport}
	 * @throws IllegalAccessException
	 *             if the class or its nullary constructor is not accessible.
	 * @throws InstantiationException
	 *             if this Class represents an abstract class, an interface, an array class, a primitive type,
	 *             or void; or if the class has no nullary constructor; or if the instantiation fails for some
	 *             other reason.
	 * @throws ClassNotFoundException
	 *             if the {@link Class} can't be found
	 */
	public static List<IReport> markAsDeletedOrDelete(ILocation location, String reportDescription)
			throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		final List<IReport> res;

		if (MappingUtils.canDeleteLocation(location)) {
			MappingUtils.deleteLocation(location);
			res = Collections.emptyList();
		} else {
			location.setMarkedAsDeleted(true);
			res = createReportsForLinks(location, reportDescription);
		}

		return res;
	}

	/**
	 * Marks the given location as changed and {@link IReport} are created.
	 * 
	 * @param location
	 *            the {@link ILocation}
	 * @param reportDescription
	 *            the {@link IReport} {@link IReport#getDescription() description}
	 * @return the {@link List} of creates {@link IReport}
	 * @throws IllegalAccessException
	 *             if the class or its nullary constructor is not accessible.
	 * @throws InstantiationException
	 *             if this Class represents an abstract class, an interface, an array class, a primitive type,
	 *             or void; or if the class has no nullary constructor; or if the instantiation fails for some
	 *             other reason.
	 * @throws ClassNotFoundException
	 *             if the {@link Class} can't be found
	 */
	public static List<IReport> markAsChanged(ILocation location, String reportDescription)
			throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		location.change(reportDescription);
		return createReportsForLinks(location, reportDescription);
	}

	/**
	 * Creates {@link IReport} for the given {@link ILocation} with the given {@link IReport}
	 * {@link IReport#getDescription() description}.
	 * 
	 * @param location
	 *            the {@link ILocation}
	 * @param reportDescription
	 *            the {@link IReport} {@link IReport#getDescription() description}
	 * @return the {@link List} of creates {@link IReport}
	 * @throws IllegalAccessException
	 *             if the class or its nullary constructor is not accessible.
	 * @throws InstantiationException
	 *             if this Class represents an abstract class, an interface, an array class, a primitive type,
	 *             or void; or if the class has no nullary constructor; or if the instantiation fails for some
	 *             other reason.
	 * @throws ClassNotFoundException
	 *             if the {@link Class} can't be found
	 */
	private static List<IReport> createReportsForLinks(ILocation location, String reportDescription)
			throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		final List<IReport> res = new ArrayList<IReport>();

		final IBase base = MappingUtils.getBase(location);
		for (ILink link : location.getSourceLinks()) {
			res.add(createReport(base, link, reportDescription));
		}
		for (ILink link : location.getTargetLinks()) {
			res.add(createReport(base, link, reportDescription));
		}

		return res;
	}

	/**
	 * Creates an {@link IReport} for the given {@link ILink} with the given description.
	 * 
	 * @param link
	 *            the {@link ILink}
	 * @param reportDescription
	 *            the {@link IReport} {@link IReport#getDescription() description}
	 * @return the created {@link IReport}
	 * @throws IllegalAccessException
	 *             if the class or its nullary constructor is not accessible.
	 * @throws InstantiationException
	 *             if this Class represents an abstract class, an interface, an array class, a primitive type,
	 *             or void; or if the class has no nullary constructor; or if the instantiation fails for some
	 *             other reason.
	 * @throws ClassNotFoundException
	 *             if the {@link Class} can't be found
	 */
	public static IReport createReport(ILink link, String reportDescription) throws InstantiationException,
			IllegalAccessException, ClassNotFoundException {
		final IBase base = MappingUtils.getBase(link.getSource());

		return createReport(base, link, reportDescription);
	}

	/**
	 * Creates an {@link IReport} for the given {@link ILink} with the given description.
	 * 
	 * @param base
	 *            the {@link IBase}
	 * @param link
	 *            the {@link ILink}
	 * @param reportDescription
	 *            the {@link IReport} {@link IReport#getDescription() description}
	 * @return the created {@link IReport}
	 * @throws IllegalAccessException
	 *             if the class or its nullary constructor is not accessible.
	 * @throws InstantiationException
	 *             if this Class represents an abstract class, an interface, an array class, a primitive type,
	 *             or void; or if the class has no nullary constructor; or if the instantiation fails for some
	 *             other reason.
	 * @throws ClassNotFoundException
	 *             if the {@link Class} can't be found
	 */
	private static IReport createReport(final IBase base, ILink link, String reportDescription)
			throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		final IReport res = base.getFactory().createElement(IReport.class);

		res.setLink(link);
		res.setDescription(reportDescription);
		base.getReports().add(res);

		return res;
	}

	/**
	 * Gets the {@link IFileTypeRegistry}.
	 * 
	 * @return the {@link IFileTypeRegistry}
	 */
	public static IFileTypeRegistry getFileTypeRegistry() {
		return fileTypeRegistry;
	}

	/**
	 * Sets the {@link IFileTypeRegistry}.
	 * 
	 * @param registry
	 *            the new {@link IFileTypeRegistry}
	 */
	public static void setFileTypeRegistry(IFileTypeRegistry registry) {
		fileTypeRegistry = registry;
	}

	/**
	 * Gets the {@link ContainerProviderFactory}.
	 * 
	 * @return the {@link ContainerProviderFactory}
	 */
	public static ContainerProviderFactory getContainerProviderFactory() {
		return CONTAINER_PROVIDER_FACTORY;
	}

}
