/*****************************************************************************
 * Copyright (c) 2017 CEA LIST 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:
 *  Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
 *  
 *****************************************************************************/

package org.eclipse.papyrus.interoperability.sysml14.sysml.transformations;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.gmf.runtime.emf.core.resources.GMFResource;
import org.eclipse.m2m.internal.qvt.oml.library.Context;
import org.eclipse.m2m.qvt.oml.BasicModelExtent;
import org.eclipse.m2m.qvt.oml.ExecutionContextImpl;
import org.eclipse.m2m.qvt.oml.ModelExtent;
import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
import org.eclipse.papyrus.infra.tools.util.ListHelper;
import org.eclipse.papyrus.interoperability.sysml14.sysml.Activator;
import org.eclipse.papyrus.interoperability.sysml14.sysml.xmi.helper.PreserveXMIIDHelper;
import org.eclipse.papyrus.uml.m2m.qvto.common.MigrationParameters.ThreadConfig;
import org.eclipse.papyrus.uml.m2m.qvto.common.concurrent.ResourceAccessHelper;
import org.eclipse.papyrus.uml.m2m.qvto.common.transformation.AbstractImportTransformation;
import org.eclipse.papyrus.uml.m2m.qvto.common.transformation.IDependencyAnalysisHelper;
import org.eclipse.papyrus.uml.m2m.qvto.common.transformation.MigrationResourceSetImpl;
import org.eclipse.uml2.uml.resource.UMLResource;
import org.eclipse.uml2.uml.util.UMLUtil;

/**
 * This call defines the SysML transformation from 1.1 to 1.4.
 */
@SuppressWarnings("restriction")
public class SysMLImportTransformation extends AbstractImportTransformation {

	/**
	 * The notation file extension.
	 */
	private static final String NOTATION_FILE_EXTENSION = "notation";

	/**
	 * The model extent for the primitives types.
	 */
	protected ModelExtent umlPrimitivesTypes;

	/**
	 * The model extent for the SysML 1.4 profile.
	 */
	protected ModelExtent sysML14Profile;

	/**
	 * The model extent for the Block Definition viewpoint.
	 */
	protected ModelExtent blockDefinitionViewpoint;

	/**
	 * The model extent for the Internal Block viewpoint.
	 */
	protected ModelExtent internalBlockViewpoint;

	/**
	 * The model extent for the Parametric viewpoint.
	 */
	protected ModelExtent parametricViewpoint;

	/**
	 * The model extent for the Requirement viewpoint.
	 */
	protected ModelExtent requirementViewpoint;

	/**
	 * The model extent for the Requirement NatTable configuration for SysML 1.1.
	 */
	protected ModelExtent requirementNatTable11;

	/**
	 * The model extent for the Allocation NatTable configuration for SysML 1.1.
	 */
	protected ModelExtent allocationNatTable11;

	/**
	 * The model extent for the Requirement NatTable configuration for SysML 1.4.
	 */
	protected ModelExtent requirementNatTable14;

	/**
	 * The model extent for the Allocation NatTable configuration for SysML 1.4.
	 */
	protected ModelExtent allocationNatTable14;

	/**
	 * The model extent for the Requirement Table viewpoint.
	 */
	protected ModelExtent requirementTableViewpoint;

	/**
	 * The model extent for the Allocation Table viewpoint.
	 */
	protected ModelExtent allocationTableViewpoint;

	/**
	 * Constructor.
	 *
	 * @param sourceURI
	 *            The source URI.
	 * @param config
	 *            The thread config.
	 * @param analysisHelper
	 *            The analyses helper.
	 */
	public SysMLImportTransformation(final URI sourceURI, final ThreadConfig config, final IDependencyAnalysisHelper analysisHelper) {
		super(sourceURI, config, analysisHelper);
		DEBUG = true;
	}

	/**
	 * Constructor.
	 *
	 * @param sourceURI
	 *            The source URI.
	 */
	public SysMLImportTransformation(final URI sourceURI) {
		super(sourceURI);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#initTransformationProperties(org.eclipse.m2m.qvt.oml.ExecutionContextImpl)
	 */
	@Override
	protected void initTransformationProperties(final ExecutionContextImpl context) {
		// Nothing to do for the transformations initialization
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#loadInPapyrusProfiles()
	 */
	@Override
	protected Diagnostic loadInPapyrusProfiles() {
		resourceSet.getResource(sourceURI.trimFileExtension().appendFileExtension(UMLResource.FILE_EXTENSION), true);
		resourceSet.getResource(sourceURI.trimFileExtension().appendFileExtension(NOTATION_FILE_EXTENSION), true);
		return null;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#countSupportedElements()
	 */
	@Override
	protected int countSupportedElements() {
		return -1;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#run(org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	protected IStatus run(final IProgressMonitor monitor) {
		//
		// INITIALIZATION / LOADING
		//

		monitor.subTask("Loading source model " + getModelName());

		long startLoad = System.nanoTime();
		initResourceSet(monitor);

		int numberOfElements = countSupportedElements();

		monitor.beginTask("Importing " + getModelName(), numberOfElements);
		monitor.subTask("Loading transformations (This may take a few seconds for the first import)...");

		loadTransformations(monitor);

		List<ModelExtent> extents = getModelExtents();

		String statusMessage = String.format("Import %s", getModelName());
		MultiStatus generationStatus = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, statusMessage, null);

		context = createExecutionContext(monitor, generationStatus);

		try {
			getInPapyrusProfiles(); // Preload profiles

			long endLoad = System.nanoTime();
			loadingTime = endLoad - startLoad;

			//
			// TRANSFORMATIONS
			//

			IStatus result; // Result of an individual transformation (Will be aggregated to the complete GenerationStatus)

			prepareExtensions();

			long startExtensions = System.nanoTime();
			result = importExtensions(context, monitor, ExtensionFunction::executeBefore);
			long endExtensions = System.nanoTime();

			this.importExtensionsTime = endExtensions - startExtensions;
			generationStatus.add(result);

			// calculate the existing identifier for the UML resource
			final Map<EObject, String> oldUMLIds = new HashMap<EObject, String>();
			final Resource oldUMLResource = resourceSet.getResource(sourceURI.trimFileExtension().appendFileExtension(UMLResource.FILE_EXTENSION), true);
			final Iterator<EObject> UMLContents = oldUMLResource.getAllContents();
			while (UMLContents.hasNext()) {
				final EObject eObject = UMLContents.next();
				oldUMLIds.put(eObject, ((XMIResource) oldUMLResource).getID(eObject));
			}

			monitor.subTask("Importing semantic model...");
			URI semanticTransformationURI = getSemanticTransformationURI();
			if (null != semanticTransformationURI) {
				result = runTransformation(semanticTransformationURI, extents, monitor);
				generationStatus.add(result);
			}

			if (generationStatus.getSeverity() <= Diagnostic.WARNING) {
				targetURI = convertToPapyrus(sourceURI, UMLResource.FILE_EXTENSION);
				umlResource = createUMLResource(resourceSet, sourceURI, targetURI);
				configureResource((XMIResource) umlResource);

				// This list contains all the objects from the initial ModelExtent, plus all the ones
				// which were created during the QVTo transformations.
				List<EObject> outUMLObjects = getInOutUMLModel().getContents();
				umlResource.getContents().addAll(outUMLObjects);

				// Manage the Ids
				new PreserveXMIIDHelper(new Context(context)).keepIdForUMLResource((XMIResource) this.umlResource, oldUMLIds);
				oldUMLIds.clear();

				// Calculate the existing identifier for the notation resource
				final Map<EObject, String> oldNotationIds = new HashMap<EObject, String>();
				Resource oldNotationResource = resourceSet.getResource(sourceURI.trimFileExtension().appendFileExtension(NOTATION_FILE_EXTENSION), true);
				final Iterator<EObject> notationContents = oldNotationResource.getAllContents();
				while (notationContents.hasNext()) {
					final EObject eObject = notationContents.next();
					oldNotationIds.put(eObject, ((XMIResource) oldNotationResource).getID(eObject));
				}

				// Diagrams
				extents = getDiagramsModelExtents();
				final Collection<URI> transformations = getDiagramTransformationURIs();
				monitor.subTask("Importing diagrams and tables...");
				for (URI transformationURI : transformations) {
					result = runTransformation(transformationURI, extents, monitor);
					generationStatus.add(result);
				}

				if (generationStatus.getSeverity() <= Diagnostic.WARNING) {

					// Manage the notation resource
					final URI notationModelURI = convertToPapyrus(sourceURI, NOTATION_FILE_EXTENSION);
					final GMFResource notationResource = new GMFResource(notationModelURI); // GMF Resource content type?
					resourceSet.getResources().add(notationResource);
					final List<EObject> outNotationObjects = getInoutNotationModel().getContents();
					notationResource.getContents().addAll(outNotationObjects);
					configureResource(notationResource);

					// Manage the Ids
					new PreserveXMIIDHelper(new Context(context)).keepIdForNotationResource((XMIResource) notationResource, oldNotationIds);
					oldNotationIds.clear();

					monitor.subTask("Cleaning-up target model...");

					// Manage the DI resource
					final URI sashModelURI = convertToPapyrus(sourceURI, DiModel.DI_FILE_EXTENSION);
					final XMIResource sashResource = new XMIResourceImpl(sashModelURI);
					configureResource(sashResource);

					// Profile mappings are also library mappings
					uriMappings.put(sourceURI, targetURI);

					monitor.subTask("Handling fragments...");

					final Collection<Resource> resourcesToSave = handleFragments(umlResource, notationResource, sashResource);

					monitor.subTask("Analyzing dangling references...");

					long startDangling = System.nanoTime();
					handleDanglingURIs(resourcesToSave);
					long endDangling = System.nanoTime();
					this.danglingRefTime = endDangling - startDangling;

					monitor.subTask("Saving models...");

					for (final Resource resource : resourcesToSave) {
						try {
							cleanMetadataAnnotations(resource);
							ResourceAccessHelper.INSTANCE.saveResource(resource, null);
						} catch (Exception ex) {
							Activator.log.error(ex);
							generationStatus.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "An exception occurred during save", ex));
						}
					}
				}
			}

			long startExtensionsAfter = System.nanoTime();
			result = importExtensions(context, monitor, ExtensionFunction::executeAfter);
			long endExtensionsAfter = System.nanoTime();
			this.importExtensionsTime += endExtensionsAfter - startExtensionsAfter;

		} finally {
			// Do nothing
		}

		// Set the context of the QvTo to null
		context = null;

		monitor.subTask("Releasing memory...");
		unloadResourceSet(this.resourceSet);
		dispose();

		monitor.done();
		return generationStatus;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#getDiagramTransformationURIs()
	 */
	@Override
	protected Collection<URI> getDiagramTransformationURIs() {
		return ListHelper.asList(new URI[] { getTransformationURI("SysMLNotation", Activator.PLUGIN_ID) });
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#getSemanticTransformationURI()
	 */
	@Override
	protected URI getSemanticTransformationURI() {
		return getTransformationURI("SysMLSemantic", Activator.PLUGIN_ID);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#getProfilesTransformationURI()
	 */
	@Override
	protected Collection<URI> getProfilesTransformationURI() {
		return Collections.emptyList();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#getAllTransformationURIs()
	 */
	@Override
	protected Collection<URI> getAllTransformationURIs() {
		final Collection<URI> allTransformations = new ArrayList<URI>();
		final URI semanticTransformationURI = getSemanticTransformationURI();
		if (null != semanticTransformationURI) {
			allTransformations.add(semanticTransformationURI);
		}
		final Collection<URI> diagramTransformationURI = getDiagramTransformationURIs();
		if (null != diagramTransformationURI) {
			allTransformations.addAll(diagramTransformationURI);
		}
		final Collection<URI> profilesTransformationURI = getProfilesTransformationURI();
		if (null != profilesTransformationURI) {
			allTransformations.addAll(profilesTransformationURI);
		}
		final Collection<URI> additionalTransformationURIs = getAdditionalTransformationURIs();
		if (null != additionalTransformationURIs) {
			allTransformations.addAll(additionalTransformationURIs);
		}
		return allTransformations;

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#getModelExtents()
	 */
	@Override
	protected List<ModelExtent> getModelExtents() {
		final List<ModelExtent> allExtents = new LinkedList<ModelExtent>();
		allExtents.add(getInSysML1_4Profile());
		allExtents.add(getInUMLPrimitivesTypes());
		allExtents.add(getInSysMLStandardLibrary());
		allExtents.add(getInUMLProfileStandard());
		allExtents.add(getInOutUMLModel());
		return allExtents;
	}

	/**
	 * Get the list of model extents needed for the diagrams transformations.
	 * 
	 * @return The list of model extents.
	 */
	protected List<ModelExtent> getDiagramsModelExtents() {
		final List<ModelExtent> allExtents = new LinkedList<ModelExtent>();
		allExtents.add(getOutUMLModelForDiagrams());
		allExtents.add(getInSysML1_4Profile());
		allExtents.add(getInRequirementNatTableSysML11());
		allExtents.add(getInAllocationNatTableSysML11());
		allExtents.add(getInRequirementNatTableSysML14());
		allExtents.add(getInAllocationNatTableSysML14());
		allExtents.add(getInoutNotationModel());
		return allExtents;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#getInOutUMLModel()
	 */
	@Override
	public ModelExtent getInOutUMLModel() {
		Resource oldUMLResource = resourceSet.getResource(sourceURI.trimFileExtension().appendFileExtension(UMLResource.FILE_EXTENSION), true);
		if (null != oldUMLResource) {
			outUML = new BasicModelExtent(oldUMLResource.getContents());
		} else {
			outUML = new BasicModelExtent();
		}
		return outUML;
	}

	/**
	 * Get the UML model extend for the diagrams transformation.
	 * 
	 * @return The Model Extent for UML.
	 */
	public ModelExtent getOutUMLModelForDiagrams() {
		if (null != umlResource) {
			outUML = new BasicModelExtent(umlResource.getContents());
		} else {
			outUML = new BasicModelExtent();
		}
		return outUML;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#getInoutNotationModel()
	 */
	@Override
	public ModelExtent getInoutNotationModel() {
		Resource oldNotationResource = resourceSet.getResource(sourceURI.trimFileExtension().appendFileExtension(NOTATION_FILE_EXTENSION), true);
		if (null != oldNotationResource) {
			outNotation = new BasicModelExtent(oldNotationResource.getContents());
		} else {
			outNotation = new BasicModelExtent();
		}
		return outNotation;
	}

	/**
	 * Get the model extent for the SysML1.4 profile.
	 * 
	 * @return The model extentfor the SysML1.4 profile.
	 */
	protected ModelExtent getInSysML1_4Profile() {
		final URI sysMLProfile = URI.createURI("pathmap://SysML14_PROFILES/SysML.profile.uml");
		final Resource fCMProfile = resourceSet.getResource(sysMLProfile, true);
		sysML14Profile = new BasicModelExtent(fCMProfile.getContents());
		return sysML14Profile;
	}

	/**
	 * Get the model extent for the SysML1.4 profile.
	 * 
	 * @return The model extent for the SysML1.4 profile.
	 */
	protected ModelExtent getInUMLPrimitivesTypes() {
		final URI umlPrimitivesTypesURI = URI.createURI("pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml");
		final Resource umlPrimitivesTypesResource = resourceSet.getResource(umlPrimitivesTypesURI, true);
		umlPrimitivesTypes = new BasicModelExtent(umlPrimitivesTypesResource.getContents());
		return umlPrimitivesTypes;
	}

	/**
	 * Get the model extent with the SysML standard library.
	 * 
	 * @return The model extent with the SysML standard library.
	 */
	protected ModelExtent getInSysMLStandardLibrary() {
		final URI sysMLProfile = URI.createURI("pathmap://SysML14_LIBRARIES/SysML-Standard-Library.uml");
		final Resource fCMProfile = resourceSet.getResource(sysMLProfile, true);
		sysML14Profile = new BasicModelExtent(fCMProfile.getContents());
		return sysML14Profile;
	}

	/**
	 * Get the model extent with the UML standard profile.
	 * 
	 * @return The model extent with the UML standard profile.
	 */
	protected ModelExtent getInUMLProfileStandard() {
		final URI sysMLProfile = URI.createURI("pathmap://UML_PROFILES/Standard.profile.uml");
		final Resource fCMProfile = resourceSet.getResource(sysMLProfile, true);
		sysML14Profile = new BasicModelExtent(fCMProfile.getContents());
		return sysML14Profile;
	}

	/**
	 * Get the model extent with the Requirement NatTable configuration in SysML 1.1.
	 * 
	 * @return The model extent with the Requirement NatTable configuration in SysML 1.1.
	 */
	protected ModelExtent getInRequirementNatTableSysML11() {
		final URI sysMLProfile = URI.createURI("platform:/plugin/org.eclipse.papyrus.sysml.nattable.requirement.config/configs/requirement.nattableconfiguration");
		final Resource fCMProfile = resourceSet.getResource(sysMLProfile, true);
		requirementNatTable11 = new BasicModelExtent(fCMProfile.getContents());
		return requirementNatTable11;
	}

	/**
	 * Get the model extent with the Allocation NatTable configuration in SysML 1.1.
	 * 
	 * @return The model extent with the Allocation NatTable configuration in SysML 1.1.
	 */
	protected ModelExtent getInAllocationNatTableSysML11() {
		final URI sysMLProfile = URI.createURI("platform:/plugin/org.eclipse.papyrus.sysml.nattable.allocation.config/resources/allocation.nattableconfiguration");
		final Resource fCMProfile = resourceSet.getResource(sysMLProfile, true);
		allocationNatTable11 = new BasicModelExtent(fCMProfile.getContents());
		return allocationNatTable11;
	}

	/**
	 * Get the model extent with the Requirement NatTable configuration in SysML 1.4.
	 * 
	 * @return The model extent with the Requirement NatTable configuration in SysML 1.4.
	 */
	protected ModelExtent getInRequirementNatTableSysML14() {
		final URI sysMLProfile = URI.createURI("platform:/plugin/org.eclipse.papyrus.sysml14.nattable.requirement/resources/requirement.nattableconfiguration");
		final Resource fCMProfile = resourceSet.getResource(sysMLProfile, true);
		requirementNatTable14 = new BasicModelExtent(fCMProfile.getContents());
		return requirementNatTable14;
	}

	/**
	 * Get the model extent with the Allocation NatTable configuration in SysML 1.4.
	 * 
	 * @return The model extent with the Allocation NatTable configuration in SysML 1.4.
	 */
	protected ModelExtent getInAllocationNatTableSysML14() {
		final URI sysMLProfile = URI.createURI("platform:/plugin/org.eclipse.papyrus.sysml14.nattable.allocation/resources/allocation.nattableconfiguration");
		final Resource fCMProfile = resourceSet.getResource(sysMLProfile, true);
		allocationNatTable14 = new BasicModelExtent(fCMProfile.getContents());
		return allocationNatTable14;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#convertToPapyrus(org.eclipse.emf.common.util.URI, java.lang.String)
	 */
	@Override
	protected URI convertToPapyrus(final URI initialModelURI, final String extension) {
		// TODO: define if the final file need to be the same or specify the name
		URI uriWithoutExtension = initialModelURI.trimFileExtension();
		String lastSegment = uriWithoutExtension.lastSegment();
		lastSegment += "_converted";
		uriWithoutExtension = uriWithoutExtension.trimSegments(1);
		uriWithoutExtension = uriWithoutExtension.appendSegment(lastSegment);
		return uriWithoutExtension.appendFileExtension(extension);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.papyrus.migration.common.transformation.AbstractImportTransformation#createUMLResource(org.eclipse.emf.ecore.resource.ResourceSet, org.eclipse.emf.common.util.URI, org.eclipse.emf.common.util.URI)
	 */
	@Override
	protected Resource createUMLResource(final ResourceSet resourceSet, final URI sourceResourceURI, final URI targetResourceURI) {
		return resourceSet.createResource(targetResourceURI, UMLResource.UML_5_0_0_CONTENT_TYPE_IDENTIFIER);
	}

	/**
	 * Initializes the resource set, and resolve all dependencies
	 */
	protected void initResourceSet(IProgressMonitor monitor) {
		resourceSet = new MigrationResourceSetImpl();
		synchronized (UMLUtil.class) {
			UMLUtil.init(resourceSet);
		}
		resourceSet.getLoadOptions().put(XMLResource.OPTION_DEFER_ATTACHMENT, true);
		resourceSet.getLoadOptions().put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);
		resourceSet.getLoadOptions().put(XMLResource.OPTION_LAX_FEATURE_PROCESSING, Boolean.TRUE);
		resourceSet.getLoadOptions().put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
		resourceSet.getLoadOptions().put(XMLResource.OPTION_USE_PACKAGE_NS_URI_AS_LOCATION, Boolean.FALSE);

		monitor.subTask("Loading source model " + getModelName());

		try {
			resourceSet.getResource(sourceURI, true);
			loadInPapyrusProfiles();
		} catch (Exception ex) {
			Activator.log.error("An error occurred while loading " + getModelName(), ex);
		}
	}

	/**
	 * This allows to dispose the needed variables.
	 */
	protected void dispose() {
		umlPrimitivesTypes = null;
		sysML11Profile = null;
		sysML14Profile = null;
		blockDefinitionViewpoint = null;
		internalBlockViewpoint = null;
		parametricViewpoint = null;
		requirementViewpoint = null;
		requirementNatTable11 = null;
		allocationNatTable11 = null;
		requirementNatTable14 = null;
		allocationNatTable14 = null;
		requirementTableViewpoint = null;
		allocationTableViewpoint = null;
		umlResource = null;
		outUML = null;
		outNotation = null;
		inPapyrusProfiles = null;
		inParameters = null;
		outSashModel = null;
		resourceSet = null;
		// Set the context of the QvTo to null
		context = null;
	}
}
