/**
 * <copyright>
 *
 * Copyright (c) 2008-2019 BMW Car IT, See4sys, itemis 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:
 *     See4sys - Initial API and implementation
 *     BMW Car IT - Added/Updated javadoc
 *     itemis - [346715] IMetaModelDescriptor methods of MetaModelDescriptorRegistry taking EObject or Resource arguments should not start new EMF transactions
 *     itemis - [357962] Make sure that problems occurring when saving model elements in a new resource are not recorded as errors/warnings on resource
 *     BMW Car IT - [374883] Improve handling of out-of-sync workspace files during descriptor initialization
 *     itemis - [393021] ClassCastExceptions raised during loading model resources with Sphinx are ignored
 *     itemis - [400897] ExtendedResourceAdapter's approach of reflectively clearing all EObject fields when performing memory-optimized unloads bears the risk of leaving some EObjects leaked
 *     itemis - [409510] Enable resource scope-sensitive proxy resolutions without forcing metamodel implementations to subclass EObjectImpl
 *     itemis - [418005] Add support for model files with multiple root elements
 *	   itemis - [425175] Resources that produce exceptions while being loaded should not get unloaded by Sphinx thereafter
 *     itemis - [442342] Sphinx doen't trim context information from proxy URIs when serializing proxyfied cross-document references
 *     itemis - [458862] Navigation from problem markers in Check Validation view to model editors and Model Explorer view broken
 *     itemis - [458976] Validators are not singleton when they implement checks for different EPackages
 *     itemis - [460534] Make sure that EcoreResourceUtil creates a ResourceSetImpl rather than a ScopingResourceSetImpl when no resource set is provided by the caller
 *     itemis - [460260] Expanded paths are collapsed on resource reload
 *     itemis - [485407] Enable eager post-load proxy resolution to support manifold URI fragments referring to the same object
 *     itemis - [487564] Provide a reusable base implementation of an IURIChangeDetectorDelegate for URIs with hierarchical fragments
 *
 * </copyright>
 */
package org.eclipse.sphinx.emf.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.ContentHandler;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.xmi.XMIException;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.IWrapperItemProvider;
import org.eclipse.osgi.util.NLS;
import org.eclipse.sphinx.emf.Activator;
import org.eclipse.sphinx.emf.edit.TransientItemProvider;
import org.eclipse.sphinx.emf.internal.messages.Messages;
import org.eclipse.sphinx.emf.resource.ExtendedResource;
import org.eclipse.sphinx.emf.resource.ExtendedResourceAdapterFactory;
import org.eclipse.sphinx.platform.util.ExtendedPlatform;
import org.eclipse.sphinx.platform.util.PlatformLogUtil;
import org.eclipse.sphinx.platform.util.XMLRootElementHandler;
import org.xml.sax.SAXException;

/**
 * Utility class for resource management.
 */
public final class EcoreResourceUtil {

	// Prevent from instantiation
	private EcoreResourceUtil() {
	}

	/**
	 * Returns an instance of {@link ExtensibleURIConverterImpl} where the URI mappings are initialized in such a way
	 * that normalization of non-platform:/resource {@link URI}s which reference resources inside the workspace yields
	 * the corresponding platform:/resource {@link URI}s.
	 *
	 * @return An instance of {@link ExtensibleURIConverterImpl} containing URI mappings for normalizing
	 *         non-platform:/resource {@link URI}s referencing workspace resources to corresponding platform:/resource
	 *         {@link URI}s.
	 */
	public static URIConverter getURIConverter() {
		return getURIConverter(null);
	}

	/**
	 * Returns the {@link URIConverter URI converter} of given {@link ResourceSet resource set}. If no
	 * {@link ResourceSet resource set} is provided an instance of {@link ExtensibleURIConverterImpl} is returned
	 * instead. In both cases, the {@link URIConverter URI converter}'s URI mappings are initialized in such a way that
	 * normalization of non-platform:/resource {@link URI}s which reference resources inside the workspace yields the
	 * corresponding platform:/resource {@link URI}s.
	 *
	 * @param resourceSet
	 *            The {@link ResourceSet resource set} whose {@link URIConverter URI converter} is to be retrieved.
	 * @return The {@link URIConverter URI converter} of given {@link ResourceSet resource set}, or an instance of
	 *         {@link ExtensibleURIConverterImpl} if no such is provided, containing URI mappings for normalizing
	 *         non-platform:/resource {@link URI}s referencing workspace resources to corresponding platform:/resource
	 *         {@link URI}s.
	 */
	public static URIConverter getURIConverter(ResourceSet resourceSet) {
		// Retrieve or create URI converter
		URIConverter uriConverter;
		if (resourceSet != null) {
			uriConverter = resourceSet.getURIConverter();
		} else {
			uriConverter = new ExtensibleURIConverterImpl();
		}
		if (ExtendedPlatform.IS_PLATFORM_RUNNING && ExtendedPlatform.IS_WORKSPACE_AVAILABLE) {
			// Initialize URI mappings
			IPath workspaceRootPath = ResourcesPlugin.getWorkspace().getRoot().getFullPath().addTrailingSeparator();
			URI workspaceRootURI = URI.createPlatformResourceURI(workspaceRootPath.toString(), true);

			IPath workspaceRootLocation = ResourcesPlugin.getWorkspace().getRoot().getLocation().addTrailingSeparator();
			URI workspaceRootLocationURI = URI.createURI(workspaceRootLocation.toString(), true);
			URI workspaceRootLocationFileURI = URI.createFileURI(workspaceRootLocation.toString());

			uriConverter.getURIMap().put(workspaceRootLocationURI, workspaceRootURI);
			uriConverter.getURIMap().put(workspaceRootLocationFileURI, workspaceRootURI);
		}
		return uriConverter;
	}

	/**
	 * Converts given {@link URI} into an absolute file {@link URI}.
	 *
	 * @param uri
	 *            The {@link URI} to be converted.
	 * @return Absolute file {@link URI} for the given {@link URI} or given {@link URI} if no conversion is possible.
	 */
	public static URI convertToAbsoluteFileURI(URI uri) {
		Assert.isNotNull(uri);

		// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=423286: manually convert URIs that start with a
		// Windows drive letter
		if (!uri.isRelative() && uri.scheme().matches("[A-Za-z]")) { //$NON-NLS-1$
			uri = URI.createFileURI(uri.toString());
		}

		// Try to convert given URI to absolute file URI right away
		URI convertedURI = CommonPlugin.asLocalURI(uri);

		// Resulting URI still relative?
		if (convertedURI.isRelative()) {
			// Normalize given URI and try to convert it again
			uri = getURIConverter().normalize(uri);
			convertedURI = CommonPlugin.asLocalURI(uri);
		}

		return convertedURI;
	}

	/**
	 * Converts given URI into a platform resource URI.
	 *
	 * @param uri
	 *            The {@link URI} to be converted.
	 * @return platform resource URI for the given URI or given URI if it references a location outside the workspace or
	 *         platform is not available.
	 */
	public static URI convertToPlatformResourceURI(URI uri) {
		Assert.isNotNull(uri);

		// Already a platform resource URI?
		if (uri.isPlatformResource()) {
			return uri;
		}

		// Try to convert absolute file URIs to platform resource URIs
		if (uri.isFile() && !uri.isRelative() && ExtendedPlatform.IS_PLATFORM_RUNNING && ExtendedPlatform.IS_WORKSPACE_AVAILABLE) {
			/*
			 * !! Important Note !! Use IWorkspaceRoot#getFileForLocation(IPath) rather than trying to match the given
			 * URI against the workspace root location. This enables cases to be covered where the given URI references
			 * a resource that is part of the workspace but physically (i.e., at file system level) not located under
			 * the workspace root.
			 */
			IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(uri.toFileString()));
			if (file != null) {
				return URI.createPlatformResourceURI(file.getFullPath().toString(), true);
			}
		}

		return getURIConverter().normalize(uri);
	}

	/**
	 * Proves if resource specified by an URI exists.
	 *
	 * @param uri
	 *            The URI to prove Returns <b>true</b> only if the URI represents a file and if this file exists.
	 */
	public static boolean exists(URI uri) {
		if (uri != null) {
			return getURIConverter().exists(uri, null);
		}
		return false;
	}

	/**
	 * Check if provided URI representing a file or object is an EMF model or not.
	 *
	 * @param uri
	 *            the URI representing a model file or model object.
	 * @return <code>true</code> if provided URI correspond to an EMF model. Otherwise <code>false</code>.
	 */
	public static boolean isEMFModelURI(URI uri) {
		String namespace = readModelNamespace(null, uri);
		return EPackage.Registry.INSTANCE.get(namespace) != null;
	}

	/**
	 * Returns the {@link URI} representing given {@link EObject object}.
	 *
	 * @param eObject
	 *            The object to be handled.
	 * @return The URI representing the provided object.
	 */
	public static URI getURI(EObject eObject) {
		return getURI(null, null, eObject, false);
	}

	/**
	 * Returns the {@link URI} representing given {@link EObject object}. The resulting URI can optionally be resolved
	 * against the URI of the resource which contains the object in question.
	 *
	 * @param eObject
	 *            The object to be handled.
	 * @param resolve
	 *            Indicates whether the object's URI should be resolved against the URI of the resource which contains
	 *            the provided model object. This is useful is cases where the native model object URI evaluates in some
	 *            sort of fragment-based URI which does not contain any information about the resource that contains the
	 *            model object (e.g., hb:/#//MyComponent/MyParameterValue). By setting resolve to true, such
	 *            fragment-based URIs will be automatically expanded to a URI that starts with the URI of the model
	 *            object's resource and is followed by the fragment of the model object's native URI (e.g.,
	 *            platform:/resource/MyProject/MyResource/#//MyComponent/MyParameterValue).
	 * @return The URI representing the provided object.
	 */
	public static URI getURI(EObject eObject, boolean resolve) {
		return getURI(null, null, eObject, resolve);
	}

	/**
	 * Returns the {@link URI} representing given {@link EObject object}. If the object is removed (i.e., not contained
	 * in any {@link Resource resource}) its URI is determined by appending the URI fragment segments obtained from the
	 * removed object and its potential direct and indirect removed containers to the base URI obtained from the
	 * provided {@link EObject old owner} and {@link EStructuralFeature old feature}. If the object is still contained
	 * in a resource its URI is computed as usual and the old owner and old feature are ignored.
	 *
	 * @param oldOwner
	 *            The owner object that is assumed to having contained the given object before it was removed.
	 * @param oldFeature
	 *            The feature through which the old owner did contain the given object before it was removed.
	 * @param eObject
	 *            The object to be handled.
	 * @return The URI representing the provided object.
	 */
	public static URI getURI(EObject oldOwner, EStructuralFeature oldFeature, EObject eObject) {
		return getURI(oldOwner, oldFeature, eObject, false);
	}

	/**
	 * Returns the {@link URI} representing given {@link EObject object}. If the object is removed (i.e., not contained
	 * in any {@link Resource resource}) its URI is determined by appending the URI fragment segments obtained from the
	 * removed object and its potential direct and indirect removed containers to the base URI obtained from the
	 * provided {@link EObject old owner} and {@link EStructuralFeature old feature}. If the object is still contained
	 * in a resource its URI is computed as usual and the old owner and old feature are ignored. In both cases, the
	 * resulting URI can optionally be resolved against the URI of the resource which does or did contain the object in
	 * question.
	 *
	 * @param oldOwner
	 *            The owner object that is assumed to having contained the given object before it was removed.
	 * @param oldFeature
	 *            The feature through which the old owner did contain the given object before it was removed.
	 * @param eObject
	 *            The object to be handled.
	 * @param resolve
	 *            Indicates whether the object's URI should be resolved against the URI of the resource which contains
	 *            the provided model object. This is useful is cases where the native model object URI evaluates in some
	 *            sort of fragment-based URI which does not contain any information about the resource that contains the
	 *            model object (e.g., hb:/#//MyComponent/MyParameterValue). By setting resolve to true, such
	 *            fragment-based URIs will be automatically expanded to a URI that starts with the URI of the model
	 *            object's resource and is followed by the fragment of the model object's native URI (e.g.,
	 *            platform:/resource/MyProject/MyResource/#//MyComponent/MyParameterValue).
	 * @return The URI representing the provided object.
	 */
	public static URI getURI(EObject oldOwner, EStructuralFeature oldFeature, EObject eObject, boolean resolve) {
		Assert.isNotNull(eObject);

		ExtendedResource extendedResource = ExtendedResourceAdapterFactory.INSTANCE.getExtendedResource(oldOwner != null ? oldOwner : eObject);
		if (extendedResource != null) {
			return extendedResource.getURI(oldOwner, oldFeature, eObject, resolve);
		} else {
			return EcoreUtil.getURI(eObject);
		}
	}

	/**
	 * Returns the id of the content type of the file behind given {@link URI}.
	 *
	 * @param uri
	 *            The {@link URI} whose content type id is to be established.
	 * @return The id of the content type of the file behind given {@link URI}, or <code>null</code> if given
	 *         {@link URI} references a resource which is no file (e.g., a folder or project), or a file that does not
	 *         exist or has no content type.
	 */
	public static String getContentTypeId(URI uri) {
		if (uri != null) {
			try {
				Map<String, ?> contentDescription = getURIConverter().contentDescription(uri, null);
				return (String) contentDescription.get(ContentHandler.CONTENT_TYPE_PROPERTY);
			} catch (Exception ex) {
				PlatformLogUtil.logAsError(Activator.getPlugin(), ex);
			}
		}
		return null;
	}

	/**
	 * Determines if {@link Resource resource} behind specified {@link URI} is read-only. Returns <code>false</code> if
	 * this resource does not exist.
	 *
	 * @param uri
	 *            The {@link URI} identifying the {@link Resource resource} to be investigated.
	 * @return <code>true</code> if {@link Resource resource} behind specified {@link URI} is read-only, and
	 *         <code>false</code> otherwise.
	 */
	public static boolean isReadOnly(URI uri) {
		if (uri != null) {
			Map<String, ?> attributes = getURIConverter().getAttributes(uri, null);
			Object readOnly = attributes.get(URIConverter.ATTRIBUTE_READ_ONLY);
			return readOnly instanceof Boolean && (Boolean) readOnly;
		}
		return false;
	}

	/**
	 * Creates the normalized form of the given {@link URI} fragment using the provided {@link Resource resource}.
	 * <p>
	 * This may, in theory, do absolutely anything. The general idea behind this feature is to support resources in
	 * which the URI fragments used to identify objects can have manifold forms. The URI fragments that refer to a given
	 * object can then no longer be assumed to be always the same. Instead they may have alternative forms and look
	 * differently from case to case (e.g., have an additional postfix in simple cases, or a completely different format
	 * in more advanced cases). The URI fragment normalization enables such manifold URI fragments to be converted into
	 * a common base form and make them comparable. There is no general assumption of what normalized URI fragments
	 * should look like except for that they always must evaluate to the same string when the original URI fragments
	 * refer to the same object.
	 * </p>
	 * <p>
	 * It is important to emphasize that normalization can result in loss of information. The normalized URI fragment
	 * should generally be used only for the comparison of the identities of the objects being referred to.
	 * </p>
	 *
	 * @param resource
	 *            The resource that contains or may contain cross-document references including the given URI fragment.
	 * @param uriFragment
	 *            The URI fragment to normalize.
	 * @return The URI fragment in its normalized form, or the original URI fragment in case it already was normalized
	 *         or the underlying resource type does not support alternative forms of URI fragments.
	 */
	public static String normalizeURIFragment(Resource resource, String uriFragment) {
		ExtendedResource extendedResource = ExtendedResourceAdapterFactory.INSTANCE.adapt(resource);
		if (extendedResource != null) {
			return extendedResource.nomalizeURIFragment(uriFragment);
		} else {
			return uriFragment;
		}
	}

	private static XMLRootElementHandler readRootElement(URIConverter uriConverter, URI uri, XMLRootElementHandler handler,
			boolean useLexicalHandler) {
		if (handler == null) {
			handler = new XMLRootElementHandler();
		}
		if (exists(uri)) {
			InputStream inputStream = null;
			try {
				uriConverter = uriConverter != null ? uriConverter : new ExtensibleURIConverterImpl();
				inputStream = uriConverter.createInputStream(uri);
				handler.parseContents(inputStream, useLexicalHandler);
			} catch (SAXException ex) {
				// Ignore parse exceptions because we might be face to non-XML files or XML files
				// which are not well-formed - that's o.k. simply return null
			} catch (IOException ex) {
				// Ignore I/O exceptions because we might be face to non-XML files or XML files
				// which are not well-formed - that's o.k. simply return null
			} catch (Exception ex) {
				PlatformLogUtil.logAsWarning(Activator.getPlugin(), ex);
			} finally {
				ExtendedPlatform.safeClose(inputStream);
			}
		}
		return handler;
	}

	/**
	 * Reads the model namespace (i.e. XML namespace) of given {@link Resource resource}. Returns a meaningful result
	 * only if given {@link Resource resource} is an XML document.
	 *
	 * @param resource
	 *            The {@link Resource resource} to investigate.
	 * @return The model namespace denoted in given {@link Resource resource} or <code>null</code> if the
	 *         {@link Resource resource} is either a non-XML file or an XML file which is not well-formed or has no
	 *         model namespace.
	 */
	public static String readModelNamespace(Resource resource) {
		if (resource != null) {
			return readModelNamespace(getURIConverter(resource.getResourceSet()), resource.getURI());
		}
		return null;
	}

	/**
	 * Reads the model namespace (i.e. XML namespace) of resource behind given {@link URI}. Returns a meaningful result
	 * only if the resource in question is an XML document.
	 *
	 * @param uriConverter
	 *            The {@link URIConverter uriConverter} used to create {@link InputStream inputstream} . May be
	 *            <code>null</code>.
	 * @param uri
	 *            The {@link URI uri} of the resource to investigate.
	 * @return The model namespace denoted in resource behind given {@link URI} or <code>null</code> if the resource in
	 *         question is either a non-XML file or an XML file which is not well-formed or has no model namespace.
	 */
	public static String readModelNamespace(URIConverter uriConverter, URI uri) {
		XMLRootElementHandler handler = readRootElement(uriConverter, uri, null, false);
		return handler.getRootElementNamespace();
	}

	/**
	 * Reads the target namespace of given {@link Resource resource}. Returns a meaningful result only if given
	 * {@link Resource resource} is an XML document.
	 *
	 * @param resource
	 *            The {@link Resource resource} to investigate.
	 * @return The target namespace denoted in given {@link Resource resource} or <code>null</code> if the
	 *         {@link Resource resource} is either a not an XML file or an XML file which is not well-formed or has no
	 *         target namespace.
	 */
	public static String readTargetNamespace(Resource resource) {
		return readTargetNamespace(resource, (String[]) null);
	}

	public static String readTargetNamespace(Resource resource, String... targetNamespaceExcludePatterns) {
		if (resource != null) {
			return readTargetNamespace(getURIConverter(resource.getResourceSet()), resource.getURI(), targetNamespaceExcludePatterns);
		}
		return null;
	}

	/**
	 * Reads the target namespace of the resource behind given {@link URI}. Returns a meaningful result only if the
	 * resource in question is an XML document.
	 *
	 * @param uriConverter
	 *            The {@link URIConverter uriConverter} used to create {@link InputStream input stream} . May be
	 *            <code>null</code>.
	 * @param uri
	 *            The {@link URI uri} of the resource to investigate.
	 * @return The target namespace denoted in resource behind given {@link URI} or <code>null</code> if the resource in
	 *         question is either a not an XML file or an XML file which is not well-formed or has no target namespace.
	 */
	public static String readTargetNamespace(URIConverter uriConverter, URI uri) {
		return readTargetNamespace(uriConverter, uri, (String[]) null);
	}

	public static String readTargetNamespace(URIConverter uriConverter, URI uri, String... targetNamespaceExcludePatterns) {
		XMLRootElementHandler handler = new XMLRootElementHandler();
		if (targetNamespaceExcludePatterns != null) {
			handler.setTargetNamespaceExcludePatterns(targetNamespaceExcludePatterns);
		}
		readRootElement(uriConverter, uri, handler, false);
		return handler.getTargetNamespace();
	}

	/**
	 * Retrieves the XML comments located above the root element in given {@link Resource resource}. Returns a
	 * meaningful result only if given {@link Resource resource} is an XML document.
	 *
	 * @param resource
	 *            The {@link Resource resource} to investigate.
	 * @return Collection of strings representing the retrieved XML comments or empty collection if no such could be
	 *         found.
	 */
	public static Collection<String> readRootElementComments(Resource resource) {
		if (resource != null) {
			return readRootElementComments(getURIConverter(resource.getResourceSet()), resource.getURI());
		}
		return Collections.emptyList();
	}

	/**
	 * Retrieves the XML comments located above the root element in resource behind given {@link URI}. Returns a
	 * meaningful result only if the resource in question is an XML document.
	 *
	 * @param uriConverter
	 *            The {@link URIConverter uriConverter} used to create {@link InputStream input stream} . May be
	 *            <code>null</code>.
	 * @param uri
	 *            The {@link URI uri} of the resource to investigate.
	 * @return Collection of strings representing the retrieved XML comments or empty collection if no such could be
	 *         found.
	 */
	public static Collection<String> readRootElementComments(URIConverter uriConverter, URI uri) {
		XMLRootElementHandler handler = readRootElement(uriConverter, uri, null, true);
		return handler.getRootElementComments();
	}

	/**
	 * Reads the XSI schema location of given {@link Resource resource} and extracts pairs of namespace and schema URIs
	 * from it (see http://www.w3.org/TR/xmlschema-0/#schemaLocation for details). Returns a meaningful result only if
	 * given {@link Resource resource} is an XML document.
	 *
	 * @param resource
	 *            The {@link Resource resource} to investigate.
	 * @return Pairs of namespace and schema URIs in given {@link Resource resource} or an empty map if the
	 *         {@link Resource resource} is either a non-XML file or an XML file which is not well-formed or has no XSI
	 *         schema location.
	 */
	public static Map<String, String> readSchemaLocationEntries(Resource resource) {
		if (resource != null) {
			return readSchemaLocationEntries(getURIConverter(resource.getResourceSet()), resource.getURI());
		}
		return Collections.emptyMap();
	}

	/**
	 * Reads the XSI schema location of the resource behind given {@link URI} and extracts pairs of namespace and schema
	 * URIs from it (see http://www.w3.org/TR/xmlschema-0/#schemaLocation for details). Returns a meaningful result only
	 * if the resource in question is an XML document.
	 *
	 * @param uriConverter
	 *            The {@link URIConverter uriConverter} used to create {@link InputStream input stream} . May be
	 *            <code>null</code>.
	 * @param uri
	 *            The {@link URI uri} of the {@link Resource resource} to investigate.
	 * @return Pairs of namespace and schema URIs in resource behind given {@link URI} or an empty map if the resource
	 *         in question is either a non-XML file or an XML file which is not well-formed or has no XSI schema
	 *         location.
	 */
	public static Map<String, String> readSchemaLocationEntries(URIConverter uriConverter, URI uri) {
		XMLRootElementHandler handler = readRootElement(uriConverter, uri, null, false);
		String schemaLocation = handler.getSchemaLocation();
		Map<String, String> schemaLocationEntries = new HashMap<String, String>();
		if (schemaLocation != null) {
			String[] schemaLocationTokens = schemaLocation.split(" "); //$NON-NLS-1$
			for (int i = 0; i + 1 < schemaLocationTokens.length; i = i + 2) {
				schemaLocationEntries.put(schemaLocationTokens[i], schemaLocationTokens[i + 1]);
			}
		}
		return schemaLocationEntries;
	}

	/**
	 * Returns a set of default options which can be used for loading a Resource.
	 *
	 * @return A set of default options for loading a Resource.
	 */
	public static Map<?, ?> getDefaultLoadOptions() {
		HashMap<Object, Object> options = new HashMap<Object, Object>(1);

		// Be fault-tolerant and enable files which are partially broken to be loaded
		options.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);

		return options;
	}

	/**
	 * Returns a map with the default options for resource saving.
	 *
	 * @return This method will return an empty map.
	 */
	public static Map<?, ?> getDefaultSaveOptions() {
		return Collections.emptyMap();
	}

	/**
	 * Retrieves the root {@link EObject object} contained by given resource.
	 *
	 * @param resource
	 *            Some model resource
	 * @return The root object contained by given resource or <code>null</code> if the resource has not been loaded yet
	 *         or contains no or multiple root objects.
	 * @deprecated Inline this method in client code and adapt it as needed.
	 */
	@Deprecated
	public static EObject getModelRoot(Resource resource) {
		if (resource != null) {
			EList<EObject> contents = resource.getContents();
			if (contents.size() > 0) {
				return resource.getContents().get(0);
			}
		}
		return null;
	}

	/**
	 * Returns the root element of the model owned by the resource specified by the given URI. Does not explicitly ask
	 * the loading of the resource if it has not already been loaded in resource set.
	 *
	 * @param resourceSet
	 *            The resource set into which model resource must be loaded.
	 * @param uri
	 *            The URI to resolve; i.e. the URI of the model resource to load.
	 * @return The root object contained by underlying resource or <code>null</code> if the resource has not been loaded
	 *         yet or contains no or multiple root objects.
	 * @deprecated Use {@link ResourceSet#getResource(URI, boolean)} or {@link #getEObject(ResourceSet, URI)} instead.
	 */
	@Deprecated
	public static EObject getModelRoot(ResourceSet resourceSet, URI uri) {
		return loadModelRoot(resourceSet, uri, null, false);
	}

	/**
	 * Returns the root element of the model owned by the resource specified by the given URI.
	 *
	 * @param resourceSet
	 *            The resource set into which model resource must be loaded.
	 * @param uri
	 *            The URI to resolve; i.e. the URI of the model resource to load.
	 * @param loadOnDemand
	 *            If <code>true</code>, creates and loads the resource if it does not already exist.
	 * @return The root of the loaded model either if loaded or <code>loadOnDemand</code> is <code>true</code>;
	 *         <code>null</code> if underlying resource has not been loaded and <code>loadOnDemand</code> is false.
	 * @deprecated Use {@link #loadModelRoot(ResourceSet, URI, Map)} for loading models or
	 *             {@link #getModelRoot(ResourceSet, URI)} for accessing already loaded models instead.
	 */
	@Deprecated
	public static EObject getModelRoot(ResourceSet resourceSet, URI uri, boolean loadOnDemand) {
		return loadModelRoot(resourceSet, uri, null, loadOnDemand);
	}

	/**
	 * Returns the root element of the model owned by the resource specified by the given URI. Asks the loading of the
	 * resource if it has not already been loaded in resource set.
	 *
	 * @param resourceSet
	 *            The resource set into which model resource must be loaded.
	 * @param uri
	 *            The URI to resolve; i.e. the URI of the model resource to load.
	 * @param options
	 *            The load options. If <code>null</code>, default load options are used.
	 * @return The root object contained by the loaded model resource or <code>null</code> if resource has not been
	 *         loaded yet or contains no or multiple root objects.
	 * @deprecated Use {@link #loadResource(ResourceSet, URI, Map)} or {@link #loadEObject(ResourceSet, URI)} instead.
	 */
	@Deprecated
	public static EObject loadModelRoot(ResourceSet resourceSet, URI uri, Map<?, ?> options) {
		return loadModelRoot(resourceSet, uri, options, true);
	}

	/**
	 * Loads a model from a {@link java.io.File File} in a given {@link ResourceSet}.
	 * <p>
	 * This will return the first root of the loaded model, other roots can be accessed via the resource's content.
	 * </p>
	 *
	 * @param resourceSet
	 *            The {@link ResourceSet} to load the model in.
	 * @param file
	 *            {@link java.io.File File} containing the model to be loaded.
	 * @param options
	 *            Optional custom load options to be used for loading the resource. May be set to <code>null</code> if
	 *            not such are needed.
	 * @return The root object contained by given file or <code>null</code> if the file has not been loaded yet or
	 *         contains no or multiple root objects.
	 * @deprecated Use {@link #loadResource(ResourceSet, File, Map)} or {@link #loadEObject(ResourceSet, URI)} instead.
	 */
	@Deprecated
	public static EObject loadModelRoot(ResourceSet resourceSet, File file, Map<?, ?> options) throws IOException {
		Assert.isNotNull(file);
		return loadModelRoot(resourceSet, URI.createFileURI(file.getPath()), options);
	}

	/**
	 * @deprecated Use {@link #getEObject(ResourceSet, URI)} instead.
	 */
	@Deprecated
	public static EObject getModelFragment(ResourceSet resourceSet, URI uri) {
		return getEObject(resourceSet, uri);
	}

	/**
	 * Returns the element of the model owned by the resource specified by the given URI and pointed by the given
	 * fragment.
	 *
	 * @param resourceSet
	 *            The resource set into which model resource must be loaded.
	 * @param uri
	 *            The URI to resolve; i.e. the URI of the model resource to load.
	 * @param loadOnDemand
	 *            If <code>true</code>, creates and loads the resource if it does not already exist.
	 * @return The element of the loaded model pointed by the fragment of the uri either if resource is loaded or
	 *         loadOnDemand is <code>true</code>; <code>null</code> if underlying resource has not been loaded and
	 *         <code>loadOnDemand</code> is <code>false</code>.
	 * @deprecated Use {@link #loadEObject(ResourceSet, URI)} for loading model fragments or
	 *             {@link #getEObject(ResourceSet, URI)} for accessing already loaded model fragments instead.
	 */
	@Deprecated
	public static EObject getModelFragment(ResourceSet resourceSet, URI uri, boolean loadOnDemand) {
		return loadEObject(resourceSet, uri, loadOnDemand);
	}

	/**
	 * @deprecated Use {@link #loadEObject(ResourceSet, URI)} instead.
	 */
	@Deprecated
	public static EObject loadModelFragment(ResourceSet resourceSet, URI uri) {
		return loadEObject(resourceSet, uri);
	}

	/**
	 * Retrieves the model {@link EObject object} referenced by provided {@link URI} from given {@link ResourceSet
	 * resource set}. Returns <code>null</code> if the {@link Resource resource} containing the model object referenced
	 * by the URI has not yet been loaded into the resource set.
	 *
	 * @param resourceSet
	 *            The resource set from which the model object is to be retrieved.
	 * @param uri
	 *            The URI that identifies the model object to be retrieved.
	 * @return The model object from given resource set referenced by provided URI or <code>null</code> if the
	 *         referenced model object does not exist in underlying resource or the latter has not yet been loaded into
	 *         the resource set.
	 */
	public static EObject getEObject(ResourceSet resourceSet, URI uri) {
		return loadEObject(resourceSet, uri, false);
	}

	/**
	 * Retrieves the model {@link EObject object} referenced by provided {@link URI} from given {@link ResourceSet
	 * resource set}. Loads the {@link Resource resource} containing the model object referenced by the URI into the
	 * resource set if this has not yet been done.
	 *
	 * @param resourceSet
	 *            The resource set from which the model object is to be retrieved.
	 * @param uri
	 *            The URI that identifies the model object to be retrieved.
	 * @return The model object from given resource set referenced by provided URI or <code>null</code> if referenced
	 *         model object does not exist in underlying resource.
	 */
	public static EObject loadEObject(ResourceSet resourceSet, URI uri) {
		return loadEObject(resourceSet, uri, true);
	}

	private static EObject loadEObject(ResourceSet resourceSet, URI uri, boolean loadOnDemand) {
		Assert.isNotNull(uri);

		if (uri.hasFragment()) {
			// Create new ResourceSet if none has been provided
			if (resourceSet == null) {
				resourceSet = new ResourceSetImpl();
			}

			// Try to convert given URI to platform:/resource URI if not yet so
			/*
			 * !! Important Note !! This is necessary in order to avoid that resources which are located inside the
			 * workspace get loaded multiple times just because they are referenced by URIs with different schemes. If
			 * given resource set were an instance of ResourceSetImpl this extra conversion wouldn't be necessary.
			 * org.eclipse.emf.ecore.resource.ResourceSet.getResource(URI, boolean) normalizes and compares given URI
			 * and to normalized copies of URIs of already present resources and thereby avoids multiple loading of same
			 * resources on its own. This is however not true when ExtendedResourceSetImpl or a subclass of it is used.
			 * Herein, URI normalization and comparison has been removed from
			 * org.eclipse.sphinx.emf.resource.ExtendedResourceSetImpl.getResource(URI, boolean) in order to increase
			 * runtime performance.
			 */
			if (!uri.isPlatform()) {
				uri = convertToPlatformResourceURI(uri);
			}

			return resourceSet.getEObject(uri, loadOnDemand);
		}
		return null;
	}

	/**
	 * Returns the {@linkplain Resource resource} corresponding to the specified {@linkplain Object object}.
	 * <p>
	 * The supported object types are:
	 * <ul>
	 * <li>{@linkplain org.eclipse.emf.ecore.resource.Resource}</li>
	 * <li>{@linkplain org.eclipse.emf.ecore.EObject}</li>
	 * <li>{@linkplain org.eclipse.emf.ecore.util.FeatureMap.Entry}</li>
	 * <li>{@linkplain org.eclipse.emf.edit.provider.IWrapperItemProvider}</li>
	 * </ul>
	 * <p>
	 * If the type of the specified object does not belongs to that list of supported types, <code>null</code> is
	 * returned.
	 *
	 * @param object
	 *            The object from which a resource must be returned.
	 * @return The underlying resource from the given object.
	 */
	public static Resource getResource(Object object) {
		if (object instanceof Resource) {
			return (Resource) object;
		} else if (object instanceof EObject) {
			return getResource((EObject) object);
		} else if (object instanceof IWrapperItemProvider) {
			return getResource((IWrapperItemProvider) object);
		} else if (object instanceof FeatureMap.Entry) {
			return getResource((FeatureMap.Entry) object);
		} else if (object instanceof TransientItemProvider) {
			return getResource((TransientItemProvider) object);
		}
		return null;
	}

	/**
	 * Retrieves the {@linkplain Resource resource} corresponding to the given {@link EObject object}.
	 *
	 * @param eObject
	 *            The {@linkplain EObject object} whose {@link Resource resource} is to be returned.
	 * @return The resource corresponding to the specified {@link EObject object}.
	 */
	public static Resource getResource(final EObject eObject) {
		if (eObject != null) {
			return eObject.eResource();
		}
		return null;
	}

	/**
	 * Retrieves the {@linkplain Resource resource} owning the given {@link IWrapperItemProvider provider}.
	 * <p>
	 * First retrieves the owner of the {@link IWrapperItemProvider provider}; then, if owner is an {@linkplain EObject}
	 * returns its resource, else delegates to {@linkplain #getResource(Object)}.
	 *
	 * @param provider
	 *            The {@linkplain IWrapperItemProvider} whose resource must be returned.
	 * @return The resource containing the specified {@link IWrapperItemProvider provider}; <code>null</code> if that
	 *         provider is <code>null</code>.
	 */
	public static Resource getResource(final IWrapperItemProvider provider) {
		if (provider != null) {
			Object owner = provider.getOwner();
			if (owner instanceof EObject) {
				return ((EObject) owner).eResource();
			} else {
				Object unwrapped = AdapterFactoryEditingDomain.unwrap(provider);
				return getResource(unwrapped);
			}
		}
		return null;
	}

	/**
	 * Retrieves the {@linkplain Resource resource} matching the given {@link FeatureMap.Entry entry}.
	 * <p>
	 * First unwraps the {@link FeatureMap.Entry entry}; then, delegates to {@linkplain #getResource(Object)}.
	 *
	 * @param entry
	 *            The {@linkplain FeatureMap.Entry} whose underlying resource must be returned.
	 * @return The resource under the specified {@link FeatureMap.Entry entry}.
	 */
	public static Resource getResource(FeatureMap.Entry entry) {
		Object unwrapped = AdapterFactoryEditingDomain.unwrap(entry);
		return getResource(unwrapped);
	}

	/**
	 * Retrieves the {@linkplain Resource resource} owning the given {@link TransientItemProvider provider}.
	 * <p>
	 * First retrieves the owner of the {@link TransientItemProvider provider}; then, if owner is an
	 * {@linkplain EObject} returns its resource, else delegates to {@linkplain #getResource(Object)}.
	 *
	 * @param provider
	 *            The {@linkplain TransientItemProvider} whose resource must be returned.
	 * @return The resource containing the specified {@link IWrapperItemProvider provider}; <code>null</code> if that
	 *         provider is <code>null</code>.
	 */
	public static Resource getResource(TransientItemProvider provider) {
		if (provider != null) {
			Notifier target = provider.getTarget();
			if (target instanceof EObject) {
				return ((EObject) target).eResource();
			}
		}
		return null;
	}

	/**
	 * Returns the contents of given Resource. If the provided Resource is
	 * <tt>null<tt> the method will return an empty list.
	 *
	 * &#64;param resource
	 * &#64;return The content of the given <code>resource</code> or an empty list if no Resource is provided.
	 */
	public static EList<EObject> getResourceContents(Resource resource) {
		if (resource != null) {
			return resource.getContents();
		}
		return new BasicEList<EObject>(0);
	}

	/**
	 * Loads the {@link Resource resource} referred to by given {@link URI}.
	 *
	 * @param resourceSet
	 *            The {@link ResourceSet resource set} that will contain the resource when it has been loaded.
	 * @param uri
	 *            The URI of the resource to be loaded.
	 * @param options
	 *            Optional custom load options to be used for loading the resource. May be set to <code>null</code> if
	 *            not such are needed.
	 * @return The resource referred to by given URI.
	 * @see #loadResource(ResourceSet, File, Map)
	 */
	public static Resource loadResource(ResourceSet resourceSet, URI uri, Map<?, ?> options) {
		Assert.isNotNull(uri);
		return loadResource(resourceSet, uri, options, true);
	}

	/**
	 * Loads the {@link Resource resource} referred to by given {@link java.io.File file}.
	 *
	 * @param resourceSet
	 *            The {@link ResourceSet resource set} that will contain the resource when it has been loaded.
	 * @param file
	 *            The file representing the resource to be loaded.
	 * @param options
	 *            Custom load options. If <code>null</code>, default load options are used.
	 * @return The resource referred to by given file.
	 * @see #loadResource(ResourceSet, URI, Map)
	 */
	public static Resource loadResource(ResourceSet resourceSet, File file, Map<?, ?> options) throws IOException {
		Assert.isNotNull(file);
		return loadResource(resourceSet, URI.createFileURI(file.getPath()), options, true);
	}

	/**
	 * Proves if the model with the specified {@link URI uri} is already loaded into the given {@link ResourceSet
	 * resourceSet}.
	 *
	 * @param resourceSet
	 *            The resource set to search resource in.
	 * @param uri
	 *            The URI of the concerned resource.
	 * @return
	 *         <ul>
	 *         <li><tt><b>true</b>&nbsp;&nbsp;</tt> if resource set contains the model with specified the URI;</li>
	 *         <li><tt><b>false</b>&nbsp;</tt> otherwise.</li>
	 *         </ul>
	 */
	public static boolean isResourceLoaded(ResourceSet resourceSet, URI uri) {
		if (resourceSet != null && uri != null) {
			Resource resource = resourceSet.getResource(uri, false);
			return resource != null && resource.isLoaded();
		}
		return false;
	}

	/**
	 * Returns the name of the model behind provided model object.
	 *
	 * @param notifier
	 *            Can either be an EObject or a Resource.
	 * @return The name of the model specified by the given <code>notifier</code>.
	 */
	public static String getModelName(Notifier notifier) {
		EObject modelContent = null;
		if (notifier instanceof EObject) {
			modelContent = (EObject) notifier;
		}
		if (notifier instanceof Resource) {
			modelContent = ((Resource) notifier).getContents().iterator().next();
		}
		if (modelContent != null) {
			String modelPackageName = modelContent.eClass().getEPackage().getName();
			return modelPackageName.substring(0, 1).toUpperCase() + modelPackageName.substring(1);
		}
		return ""; //$NON-NLS-1$
	}

	/**
	 * Create the new model given by the {@link EObject content} object parameter. The method will create a new Resource
	 * specified by a given URI and content type id. The new created resource will be added to a given ResourceSet.
	 *
	 * @param resourceSet
	 *            The ResourceSet to which the new Resource is added.
	 * @param uri
	 *            The URI specifying the location to which the Resource is to be saved to.
	 * @param contentTypeId
	 *            The id of the content type of which new created Resource shall be of.
	 * @param content
	 *            Can either be an EObject or a Resource.
	 * @since 0.7.0
	 */
	public static Resource addNewModelResource(ResourceSet resourceSet, URI uri, String contentTypeId, EObject content) {
		return addNewModelResource(resourceSet, uri, contentTypeId, Collections.singletonList(content));
	}

	/**
	 * Create the new model given by the list of {@link EObject content} objects parameter. The method will create a new
	 * Resource specified by a given URI and content type id. The new created resource will be added to a given
	 * ResourceSet.
	 *
	 * @param resourceSet
	 *            The ResourceSet to which the new Resource is added.
	 * @param uri
	 *            The URI specifying the location to which the Resource is to be saved to.
	 * @param contentTypeId
	 *            The id of the content type of which new created Resource shall be of.
	 * @param contents
	 *            The set of EObjects to be use as model root objects.
	 * @since 0.9.0
	 */
	public static Resource addNewModelResource(ResourceSet resourceSet, URI uri, String contentTypeId, List<EObject> contents) {
		if (uri != null && contents != null) {
			try {
				// Create new ResourceSet if none has been provided
				if (resourceSet == null) {
					resourceSet = new ResourceSetImpl();
				}

				// Unload and remove model resource if it is already loaded
				Resource resource = resourceSet.getResource(uri, false);
				if (resource != null) {
					try {
						unloadResource(resource);
					} catch (Exception ex) {
						PlatformLogUtil.logAsError(Activator.getPlugin(), ex);
					}
				}

				// Create and add new model resource to the resourceSet
				resource = resourceSet.createResource(uri, contentTypeId);
				if (resource != null) {
					resource.getContents().addAll(contents);
				}
				return resource;
			} catch (Exception ex) {
				throw new WrappedException(ex);
			}
		}
		return null;
	}

	/**
	 * The {@link Resource} provided as argument will be added to the given ResourceSet if it is not already inside.
	 *
	 * @param resourceSet
	 *            The resourceSet where to add resources
	 * @param resource
	 *            The resource to add
	 * @since 0.7.0
	 */
	public static void addModelResource(ResourceSet resourceSet, Resource resource) {
		if (resource != null) {
			// Create new ResourceSet if none has been provided
			if (resourceSet == null) {
				resourceSet = new ResourceSetImpl();
			}

			// Add resource to resourceSet if not already present
			if (resourceSet.getResource(resource.getURI(), false) == null) {
				resourceSet.getResources().add(resource);
			}
		}
	}

	/**
	 * Saves the new model given by the {@link EObject content} object parameter. The method will create a new Resource
	 * specified by a given URI and content type id. The new created resource will be added to a given ResourceSet and
	 * saved.
	 *
	 * @param resourceSet
	 *            The ResourceSet to which the new Resource is added.
	 * @param uri
	 *            The URI specifying the location to which the Resource is to be saved to.
	 * @param contentTypeId
	 *            The id of the content type of which new created Resource shall be of.
	 * @param content
	 *            Can either be an EObject or a Resource.
	 * @param options
	 *            The save options.
	 * @see #getDefaultSaveOptions()
	 */
	public static void saveNewModelResource(ResourceSet resourceSet, URI uri, String contentTypeId, EObject content, Map<?, ?> options) {
		saveNewModelResource(resourceSet, uri, contentTypeId, Collections.singletonList(content), options);
	}

	/**
	 * Saves the new model given by the list of {@link EObject content} objects parameter. The method will create a new
	 * Resource specified by a given URI and content type id. The new created resource will be added to a given
	 * ResourceSet and saved.
	 *
	 * @param resourceSet
	 *            The ResourceSet to which the new Resource is added.
	 * @param uri
	 *            The URI specifying the location to which the Resource is to be saved to.
	 * @param contentTypeId
	 *            The id of the content type of which new created Resource shall be of.
	 * @param contents
	 *            The set of EObjects to be use as model root objects.
	 * @param options
	 *            The save options.
	 * @see #getDefaultSaveOptions()
	 * @since 0.9.0
	 */
	public static void saveNewModelResource(ResourceSet resourceSet, URI uri, String contentTypeId, List<EObject> contents, Map<?, ?> options) {
		// Create new model resource and add it to the provided ResourceSet
		Resource resource = addNewModelResource(resourceSet, uri, contentTypeId, contents);

		// Save the newly created resource
		saveModelResource(resource, options);
	}

	/**
	 * Saves the specified <code>resource</code>.
	 *
	 * @param resource
	 *            The {@link Resource resource} to be saved.
	 * @param options
	 *            The save options.
	 * @see #getDefaultSaveOptions()
	 */
	public static void saveModelResource(Resource resource, Map<?, ?> options) {
		if (resource != null) {
			try {
				resource.save(options);
			} catch (Exception ex) {
				// Record exception as error on resource
				/*
				 * !! Important Note !! The main intention behind doing so is to enable the exception to be converted to
				 * a problem marker by the resource problem handler later on (see
				 * org.eclipse.sphinx.emf.internal.resource.ResourceProblemHandler#resourceChanged(IResourceChangeEvent)
				 * for details).
				 */
				Throwable cause = ex.getCause();
				Exception exception = cause instanceof Exception ? (Exception) cause : ex;
				URI uri = resource.getURI();
				resource.getErrors().add(new XMIException(NLS.bind(Messages.error_problemOccurredWhenSavingResource, uri.toString()), exception,
						uri.toString(), 1, 1));

				// Re-throw exception
				throw new WrappedException(ex);
			}
		}
	}

	/**
	 * Unloads given {@link Resource resource} and removes it from underlying {@link ResourceSet resourceSet}.
	 *
	 * @param resource
	 *            The resource to be unloaded.
	 */
	public static void unloadResource(Resource resource) {
		unloadResource(resource, false);
	}

	/**
	 * Unloads given {@link Resource resource} and removes it from underlying {@link ResourceSet resourceSet}.
	 *
	 * @param resource
	 *            The resource to be unloaded.
	 * @param memoryOptimized
	 *            Will activate the memory optimization option for unloading the resource. This is only available if the
	 *            resource is an XMLResource.
	 */
	public static void unloadResource(Resource resource, boolean memoryOptimized) {
		if (resource != null) {
			try {
				// Perform resource unload, either memory optimized or normally
				if (memoryOptimized) {
					ExtendedResource extendedResource = ExtendedResourceAdapterFactory.INSTANCE.adapt(resource);
					if (extendedResource != null) {
						Map<Object, Object> defaultLoadOptions = extendedResource.getDefaultLoadOptions();
						defaultLoadOptions.put(ExtendedResource.OPTION_UNLOAD_MEMORY_OPTIMIZED, Boolean.TRUE);
					}
				}
				resource.unload();
			} catch (Exception ex) {
				throw new WrappedException(ex);
			} finally {
				// Remove unloaded resource from ResourceSet
				ResourceSet resourceSet = resource.getResourceSet();
				if (resourceSet != null) {
					resourceSet.getResources().remove(resource);
				}

				// Remove all adapters from unloaded resource
				resource.eAdapters().clear();
			}
		}
	}

	/**
	 * Unloads the resource with the specified URI from the given resource set.
	 *
	 * @param resourceSet
	 *            A resource set from which the model's resource should be unloaded.
	 * @param uri
	 *            The URI of the resource to unload.
	 */
	public static void unloadResource(ResourceSet resourceSet, URI uri) {
		unloadResource(resourceSet, uri, false);
	}

	/**
	 * Unloads the resource with the specified URI from the given resource set.
	 * <p>
	 * It is recommended to call this method inside a write-transaction (see
	 * {@link EcorePlatformUtil#unloadFile(ResourceSet, IPath)}).
	 *
	 * @param resourceSet
	 *            A resource set from which the model's resource should be unloaded.
	 * @param uri
	 *            The URI of the resource to unload.
	 * @param memoryOptimized
	 *            Will activate the memory optimization option for unloading the resource. This is only available if the
	 *            resource is an XMLResource.
	 */
	public static void unloadResource(ResourceSet resourceSet, URI uri, boolean memoryOptimized) {
		if (resourceSet != null && uri != null) {
			// Get resource and unload it
			Resource resource = resourceSet.getResource(uri, false);
			unloadResource(resource, memoryOptimized);
		}
	}

	/**
	 * Parses {@link Resource resource} with given {@link URI uri} and validates it against XSD schema with specified
	 * {@link URL url}. Raises an exception if the {@link Resource resource}'s content is not compliant with respect to
	 * XSD schema.
	 *
	 * @param uri
	 *            The {@link URI uri} of the {@link Resource resource} to be validated.
	 * @param schemaURL
	 *            The {@link URL url} of the XSD schema to be used for validation.
	 */
	public static void validate(URI uri, URL schemaURL) throws SAXException, IOException {
		Assert.isNotNull(uri);

		// 1. Lookup a factory for the W3C XML Schema language
		SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

		// 2. Compile the schema
		Schema schema = factory.newSchema(schemaURL);

		// 3. Get a validator from the schema
		Validator validator = schema.newValidator();

		// 4. Load the resource and validate it
		InputStream stream = null;
		try {
			stream = URIConverter.INSTANCE.createInputStream(uri);
			Source source = new StreamSource(stream);
			validator.validate(source);
		} finally {
			ExtendedPlatform.safeClose(stream);
		}
	}

	/**
	 * Loads from resource set the resource specified by the given URI, or try to load the URI if not in resource set.
	 *
	 * @param resourceSet
	 *            The resource set into which model resource must be loaded.
	 * @param uri
	 *            The URI to resolve; <em>i.e.</em> the URI of the model resource to load.
	 * @param options
	 *            The loading options.
	 * @param loadOnDemand
	 *            If <code>true</code>, creates and loads the resource if it does not already exist.
	 * @return The resource referred to by given URI or <code>null</code> if the resource has not been loaded yet and
	 *         demand loading is not required.
	 */
	private static Resource loadResource(ResourceSet resourceSet, URI uri, Map<?, ?> options, boolean loadOnDemand) {
		Assert.isNotNull(uri);

		// Create new ResourceSet if none has been provided
		if (resourceSet == null) {
			resourceSet = new ResourceSetImpl();
		}

		// Try to convert given URI to platform:/resource URI if not yet so
		/*
		 * !! Important Note !! This is necessary in order to avoid that resources which are located inside the
		 * workspace get loaded multiple times just because they are referenced by URIs with different schemes. If given
		 * resource set were an instance of ResourceSetImpl this extra conversion wouldn't be necessary.
		 * org.eclipse.emf.ecore.resource.ResourceSet.getResource(URI, boolean) normalizes and compares given URI and to
		 * normalized copies of URIs of already present resources and thereby avoids multiple loading of same resources
		 * on its own. This is however not true when ExtendedResourceSetImpl or a subclass of it is used. Herein, URI
		 * normalization and comparison has been removed from
		 * org.eclipse.sphinx.emf.resource.ExtendedResourceSetImpl.getResource(URI, boolean) in order to increase
		 * runtime performance.
		 */
		if (!uri.isPlatform()) {
			uri = convertToPlatformResourceURI(uri);
		}

		// Just get model resource if it is already loaded
		Resource resource = resourceSet.getResource(uri, false);

		// Load it using specified options if not done so yet and a demand load has been requested
		if ((resource == null || !resource.isLoaded()) && loadOnDemand) {
			if (exists(uri)) {
				if (resource == null) {
					String contentType = getContentTypeId(uri);
					resource = resourceSet.createResource(uri, contentType);
				}
				if (resource != null) {
					try {
						// Capture errors and warnings encountered during resource creation
						/*
						 * !! Important note !! This is necessary because the resource's errors and warnings are
						 * automatically cleared when the loading begins. Therefore, if we don't retrieve them at this
						 * point all previously encountered errors and warnings would be lost (see
						 * org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(InputStream, Map<?, ?>) for details)
						 */
						List<Resource.Diagnostic> creationErrors = new ArrayList<Resource.Diagnostic>(resource.getErrors());
						List<Resource.Diagnostic> creationWarnings = new ArrayList<Resource.Diagnostic>(resource.getWarnings());

						// Load resource
						resource.load(options);

						// Make sure that no empty resources are kept in resource set
						if (resource.getContents().isEmpty()) {
							unloadResource(resource, true);
						}

						// Restore creation time errors and warnings
						resource.getErrors().addAll(creationErrors);
						resource.getWarnings().addAll(creationWarnings);
					} catch (Exception ex) {
						// Make sure that no empty resources are kept in resource set
						if (resource.getContents().isEmpty()) {
							// Capture errors and warnings encountered during resource load attempt
							/*
							 * !! Important note !! This is necessary because the resource's errors and warnings are
							 * automatically cleared when it gets unloaded. Therefore, if we didn't retrieve them at
							 * this point all errors and warnings encountered during loading would be lost (see
							 * org.eclipse.emf.ecore.resource.impl.ResourceImpl.doUnload() for details)
							 */
							List<Resource.Diagnostic> loadErrors = new ArrayList<Resource.Diagnostic>(resource.getErrors());
							List<Resource.Diagnostic> loadWarnings = new ArrayList<Resource.Diagnostic>(resource.getWarnings());

							// Make sure that resource gets unloaded and removed from resource set again
							try {
								unloadResource(resource, true);
							} catch (Exception e) {
								// Log unload problem in Error Log but don't let it go along as runtime exception. It is
								// most likely just a consequence of the load problems encountered before and therefore
								// should not prevent those from being restored as errors and warnings on resource.
								PlatformLogUtil.logAsError(Activator.getPlugin(), e);
							}

							// Restore load time errors and warnings on resource
							/*
							 * !! Important Note !! The main intention behind restoring recorded errors and warnings on
							 * the already unloaded resource is to enable these errors/warnings to be converted to
							 * problem markers by the resource problem handler later on (see
							 * org.eclipse.sphinx.emf.internal.resource.ResourceProblemHandler#resourceSetChanged(
							 * ResourceSetChangeEvent)) for details).
							 */
							resource.getErrors().addAll(loadErrors);
							resource.getWarnings().addAll(loadWarnings);
						}

						// Record exception as error on resource
						Throwable cause = ex.getCause();
						Exception exception = cause instanceof Exception ? (Exception) cause : ex;
						resource.getErrors().add(new XMIException(NLS.bind(Messages.error_problemOccurredWhenLoadingResource, uri.toString()),
								exception, uri.toString(), 1, 1));

						// Re-throw exception
						throw new WrappedException(ex);
					}
				}
			}
		}
		return resource;
	}

	/**
	 * Loads the model from the resource specified by the given URI and returns its root element.
	 *
	 * @param resourceSet
	 *            The resource set into which model resource must be loaded.
	 * @param uri
	 *            The URI to resolve; <em>i.e.</em> the URI of the model resource to load.
	 * @param options
	 *            The load options. If <code>null</code>, default load options are used.
	 * @param loadOnDemand
	 *            If <code>true</code>, creates and loads the resource if it does not already exist.
	 * @return The root object contained in resource referred to by given URI or <code>null</code> if the resource has
	 *         not been loaded yet and demand loading is not required or if resource contains no or multiple root
	 *         objects.
	 * @deprecated Use {@link #loadResource(ResourceSet, URI, Map, boolean)} or
	 *             {@link #loadEObject(ResourceSet, URI, boolean)} instead.
	 */
	@Deprecated
	private static EObject loadModelRoot(ResourceSet resourceSet, URI uri, Map<?, ?> options, boolean loadOnDemand) {
		// Use default load options when no specified
		if (options == null) {
			options = getDefaultLoadOptions();
		}

		// Load resource from resource set
		Resource resource = loadResource(resourceSet, uri, options, loadOnDemand);

		// Obtain and return resource content
		return getModelRoot(resource);
	}
}
