/*******************************************************************************
 * Copyright (c) 2011, 2019 Willink Transformations and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   E.D.Willink - Initial API and implementation
 *******************************************************************************/

package org.eclipse.ocl.examples.pivot.tests;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
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.ResourceSetImpl;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.EcoreUtil.UnresolvedProxyCrossReferencer;
import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.ecore.xml.namespace.XMLNamespacePackage;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.common.OCLConstants;
import org.eclipse.ocl.examples.xtext.tests.TestUtil;
import org.eclipse.ocl.pivot.evaluation.EvaluationException;
import org.eclipse.ocl.pivot.internal.delegate.ValidationDelegate;
import org.eclipse.ocl.pivot.internal.resource.ASResourceImpl;
import org.eclipse.ocl.pivot.internal.resource.EnvironmentFactoryAdapter;
import org.eclipse.ocl.pivot.internal.resource.StandaloneProjectMap;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
import org.eclipse.ocl.pivot.internal.utilities.GlobalEnvironmentFactory;
import org.eclipse.ocl.pivot.internal.utilities.PivotDiagnostician;
import org.eclipse.ocl.pivot.internal.utilities.PivotObjectImpl;
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.model.OCLstdlib;
import org.eclipse.ocl.pivot.resource.ASResource;
import org.eclipse.ocl.pivot.resource.CSResource;
import org.eclipse.ocl.pivot.resource.ProjectManager;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.EnvironmentFactory;
import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.pivot.utilities.PivotConstants;
import org.eclipse.ocl.pivot.utilities.PivotStandaloneSetup;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.utilities.StringUtil;
import org.eclipse.ocl.pivot.utilities.TracingOption;
import org.eclipse.ocl.pivot.utilities.XMIUtil;
import org.eclipse.ocl.pivot.values.Bag;
import org.eclipse.ocl.pivot.values.Value;
import org.eclipse.ocl.xtext.base.BaseStandaloneSetup;
import org.eclipse.ocl.xtext.completeocl.CompleteOCLStandaloneSetup;
import org.eclipse.ocl.xtext.essentialocl.EssentialOCLStandaloneSetup;
import org.eclipse.ocl.xtext.essentialocl.utilities.EssentialOCLCSResource;
import org.eclipse.ocl.xtext.markup.MarkupStandaloneSetup;
import org.eclipse.ocl.xtext.oclinecore.OCLinEcoreStandaloneSetup;
import org.eclipse.ocl.xtext.oclinecorecs.OCLinEcoreCSPackage;
import org.eclipse.ocl.xtext.oclstdlib.OCLstdlibStandaloneSetup;
import org.eclipse.xtext.XtextPackage;
import org.eclipse.xtext.resource.IResourceServiceProvider;
import org.eclipse.xtext.resource.XtextResource;
import org.junit.Rule;
import org.junit.rules.TestName;

import junit.framework.TestCase;

/**
 * Tests for OclAny operations.
 */
public class PivotTestCase extends TestCase
{
	public static final @NonNull String @NonNull [] NO_MESSAGES = new @NonNull String[] {};
	public static final @NonNull String @NonNull [] SUPPRESS_VALIDATION = new @NonNull String[] {"FIXME"};	// FIXME should not be needed
	public static final @NonNull String PLUGIN_ID = "org.eclipse.ocl.examples.xtext.tests";
	public static final @NonNull TracingOption TEST_START = new TracingOption(PLUGIN_ID, "test/start");
	//	private static StandaloneProjectMap projectMap = null;
	private static Writer testLog = null;

	/*
	 * The following may be tweaked to assist debugging.
	 */
	public static boolean DEBUG_GC = false;			// True performs an enthusuastic resource release and GC at the end of each test
	public static boolean DEBUG_ID = false;			// True prints the start and end of each test.
	{
		//		PivotUtilInternal.noDebug = false;
		//		DEBUG_GC = true;
		//		DEBUG_ID = true;
		//		PivotMetamodelManager.liveMetamodelManagers = new WeakHashMap<PivotMetamodelManager,Object>();	// Prints the create/finalize of each MetamodelManager
		//		StandaloneProjectMap.liveStandaloneProjectMaps = new WeakHashMap<StandaloneProjectMap,Object>();	// Prints the create/finalize of each StandaloneProjectMap
		//		ResourceSetImpl.liveResourceSets = new WeakHashMap<ResourceSet,Object>();				// Requires edw-debug private EMF branch
	}

	public static void appendLog(String name, Object context, String testExpression, String parseVerdict, String evaluationVerdict, String evaluationTolerance) {
		if (testLog != null) {
			try {
				testLog.append("\"" + name.replace("\"", "\"\"") + "\"");
				testLog.append(";");
				try {
					if (context instanceof EObject) {
						URI contextURI = EcoreUtil.getURI((EObject)context);
						testLog.append("\"" + contextURI.toString().replace("\"", "\"\"") + "\"");
					}
				} catch(Throwable e) {
					testLog.append("\"null\"");
				}
				testLog.append(";");
				if (testExpression != null) {
					testLog.append("\"" + StringUtil.convertToOCLString(testExpression) + "\"");
				}
				testLog.append(";");
				if (parseVerdict != null) {
					testLog.append("\"" + StringUtil.convertToOCLString(parseVerdict) + "\"");
				}
				testLog.append(";");
				if (evaluationVerdict != null) {
					testLog.append("\"" + StringUtil.convertToOCLString(evaluationVerdict) + "\"");
				}
				testLog.append(";");
				if (evaluationTolerance != null) {
					testLog.append("\"" + evaluationTolerance.replace("\"", "\"\"") + "\"");
				}
				testLog.append("\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static @NonNull XtextResource as2cs(@NonNull OCL ocl, @NonNull ResourceSet resourceSet, @NonNull ASResource asResource, @NonNull URI outputURI) throws IOException {
		XtextResource xtextResource = ClassUtil.nonNullState((XtextResource) resourceSet.createResource(outputURI, OCLinEcoreCSPackage.eCONTENT_TYPE));
		//		ResourceSet csResourceSet = resourceSet; //new ResourceSetImpl();
		//		csResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("cs", new EcoreResourceFactoryImpl());
		//		csResourceSet.getPackageRegistry().put(PivotPackage.eNS_URI, PivotPackage.eINSTANCE);
		//		Resource csResource = csResourceSet.createResource(uri);
		//		URI oclinecoreURI = ecoreResource.getURI().appendFileExtension("oclinecore");
		ocl.as2cs(asResource, (CSResource) xtextResource);
		assertNoResourceErrors("Conversion failed", xtextResource);
		//		csResource.save(null);
		//
		//	CS save and reload
		//
		URI savedURI = ClassUtil.nonNullState(asResource.getURI());
		//		asResource.setURI(PivotUtil.getNonPivotURI(savedURI).appendFileExtension(PivotConstants.OCL_AS_FILE_EXTENSION));
		asResource.setURI(outputURI.trimFileExtension().trimFileExtension().appendFileExtension(PivotConstants.OCL_AS_FILE_EXTENSION));
		asResource.save(XMIUtil.createSaveOptions());
		asResource.setURI(savedURI);

		assertNoDiagnosticErrors("Concrete Syntax validation failed", xtextResource);
		try {
			xtextResource.save(null);
		}
		catch (Exception e) {
			e.printStackTrace();
			URI xmiURI = outputURI.appendFileExtension(".xmi");
			Resource xmiResource = resourceSet.createResource(xmiURI);
			xmiResource.getContents().addAll(xtextResource.getContents());
			xmiResource.save(null);
			fail(e.toString());
		}
		return xtextResource;
	}

	public static @NonNull Resource as2ecore(@NonNull OCL ocl, @NonNull Resource asResource, @NonNull URI ecoreURI, @NonNull String @NonNull [] asValidationMessages) throws IOException {
		Resource ecoreResource = ocl.as2ecore(asResource, ecoreURI);
		ecoreResource.save(XMIUtil.createSaveOptions());
		if (asValidationMessages != SUPPRESS_VALIDATION) {
			//			assertNoValidationErrors("AS2Ecore invalid", ecoreResource);
			assertValidationDiagnostics("AS2Ecore invalid", ecoreResource, asValidationMessages);
		}
		return ecoreResource;
	}

	@Deprecated /* @deprecated provide resource argument */
	public static @NonNull List<Diagnostic> assertDiagnostics(@NonNull String prefix, @NonNull List<Diagnostic> diagnostics, @NonNull String... messages) {
		return assertDiagnostics(prefix, null, diagnostics, messages);
	}

	public static @NonNull List<Diagnostic> assertDiagnostics(@NonNull String prefix, @Nullable Resource resource, @NonNull List<Diagnostic> diagnostics, @NonNull String... messages) {
		Map<String, Integer> expected = new HashMap<String, Integer>();
		for (@NonNull String message : messages) {
			Integer count = expected.get(message);
			count = count == null ? 1 : count + 1;
			expected.put(message, count);
		}
		StringBuilder s1 = null;
		for (Diagnostic diagnostic : diagnostics) {
			String actual = diagnostic.getMessage();
			Integer expectedCount = expected.get(actual);
			if ((expectedCount == null) || (expectedCount <= 0)) {
				if (s1 == null) {
					s1 = new StringBuilder();
					s1.append("\nUnexpected errors");
					if (resource != null) {
						s1.append(" in '");
						s1.append(resource.getURI());
						s1.append("'");
					}
				}
				s1.append("\n");
				s1.append(actual);
			}
			else {
				expected.put(actual, expectedCount-1);
			}
		}
		StringBuilder s2 = null;
		for (String key : expected.keySet()) {
			Integer count = expected.get(key);
			assert count != null;
			while (count-- > 0) {
				if (s2 == null) {
					s2 = new StringBuilder();
					s2.append("\nMissing errors");
					if (resource != null) {
						s2.append(" in '");
						s2.append(resource.getURI());
						s2.append("'");
					}
				}
				s2.append("\n");
				s2.append(key);
			}
		}
		if (s1 == null) {
			if (s2 != null) {
				fail(s2.toString());
			}
		}
		else {
			if (s2 == null) {
				fail(s1.toString());
			}
			else {
				fail(s1.toString() + s2.toString());
			}
		}
		return diagnostics;
	}

	public static void assertNoDiagnosticErrors(@NonNull String message, @NonNull XtextResource xtextResource) {
		List<Diagnostic> diagnostics = xtextResource.validateConcreteSyntax();
		if (diagnostics.size() > 0) {
			StringBuilder s = new StringBuilder();
			s.append(message);
			for (Diagnostic diagnostic : diagnostics) {
				s.append("\n");
				s.append(diagnostic.toString());
			}
			fail(s.toString());
		}
	}

	public static void assertNoResourceErrors(@NonNull String prefix, @NonNull Resource resource) {
		String message = PivotUtil.formatResourceDiagnostics(ClassUtil.nonNullEMF(resource.getErrors()), prefix, "\n\t");
		if (message != null)
			fail(message);
	}

	public static void assertNoResourceErrorsOrWarnings(@NonNull String prefix, @NonNull Resource resource) {
		String message = PivotUtil.formatResourceDiagnostics(ClassUtil.nonNullEMF(resource.getErrors()), prefix, "\n\t");
		if (message != null)
			fail(message);
		message = PivotUtil.formatResourceDiagnostics(ClassUtil.nonNullEMF(resource.getWarnings()), prefix, "\n\t");
		if (message != null)
			fail(message);
	}

	public static void assertNoUnresolvedProxies(@NonNull String message, @NonNull Resource resource) {
		Map<EObject, Collection<Setting>> unresolvedProxies = UnresolvedProxyCrossReferencer.find(resource);
		if (unresolvedProxies.size() > 0) {
			StringBuilder s = new StringBuilder();
			s.append(unresolvedProxies.size());
			s.append(" unresolved proxies in ");
			s.append(message);
			for (Map.Entry<EObject, Collection<Setting>> unresolvedProxy : unresolvedProxies.entrySet()) {
				s.append("\n");
				BasicEObjectImpl key = (BasicEObjectImpl) unresolvedProxy.getKey();
				s.append(key.eProxyURI());
				for (Setting setting : unresolvedProxy.getValue()) {
					s.append("\n\t");
					EObject eObject = setting.getEObject();
					s.append(eObject.toString());
				}
			}
			fail(s.toString());
		}
	}

	public static void assertNoValidationErrors(@NonNull String string, @NonNull Resource resource) {
		for (EObject eObject : resource.getContents()) {
			assertNoValidationErrors(string, ClassUtil.nonNullEMF(eObject));
		}
	}

	public static void assertNoValidationErrors(@NonNull String string, @NonNull EObject eObject) {
		Map<Object, Object> validationContext = LabelUtil.createDefaultContext(Diagnostician.INSTANCE);
		//		Resource eResource = ClassUtil.nonNullState(eObject.eResource());
		//		PivotUtilInternal.getMetamodelManager(eResource);	// FIXME oclIsKindOf fails because ExecutableStandardLibrary.getMetaclass is bad
		//		Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject, validationContext);
		BasicDiagnostic diagnostics = PivotDiagnostician.BasicDiagnosticWithRemove.validate(eObject, validationContext);
		List<Diagnostic> children = diagnostics.getChildren();
		if (children.size() <= 0) {
			return;
		}
		StringBuilder s = new StringBuilder();
		s.append(children.size() + " validation errors");
		appendChildren(s, children, 0);
		fail(s.toString());
	}

	protected static void appendChildren(StringBuilder s, List<Diagnostic> children, int depth) {
		for (Diagnostic child : children){
			s.append("\n");
			for (int i = 0; i < depth; i++) {
				s.append("    ");
			}
			s.append(child.getMessage());
			appendChildren(s, child.getChildren(), depth+1);
		}
	}

	public static void assertResourceErrors(@NonNull String prefix, @NonNull Resource resource, String... messages) {
		assertResourceDiagnostics(prefix, ClassUtil.nonNullEMF(resource.getErrors()), messages);
	}

	public static void assertResourceDiagnostics(@NonNull String prefix, @NonNull List<Resource.Diagnostic> resourceDiagnostics, String... messages) {
		Map<String, Integer> expected = new HashMap<String, Integer>();
		if (messages != null) {
			for (String message : messages) {
				Integer count = expected.get(message);
				count = count == null ? 1 : count + 1;
				expected.put(message, count);
			}
		}
		StringBuilder s1 = null;
		for (Resource.Diagnostic error : resourceDiagnostics) {
			String actual = error.getMessage();
			Integer expectedCount = expected.get(actual);
			if ((expectedCount == null) || (expectedCount <= 0)) {
				if (s1 == null) {
					s1 = new StringBuilder();
					s1.append("\nUnexpected errors");
				}
				s1.append("\n");
				s1.append(actual);
			}
			else {
				expected.put(actual, expectedCount-1);
			}
		}
		StringBuilder s2 = null;
		for (String key : expected.keySet()) {
			Integer count = expected.get(key);
			assert count != null;
			while (count-- > 0) {
				if (s2 == null) {
					s2 = new StringBuilder();
					s2.append("\nMissing errors");
				}
				s2.append("\n");
				s2.append(key);
			}
		}
		if (s1 == null) {
			if (s2 == null) {
				return;
			}
			else {
				fail(s2.toString());
			}
		}
		else {
			if (s2 == null) {
				fail(s1.toString());
			}
			else {
				fail(s1.toString() + s2.toString());
			}
		}
	}

	public static @NonNull List<Diagnostic> assertValidationDiagnostics(@NonNull String prefix, @NonNull Resource resource, @NonNull String @NonNull [] messages) {
		Map<Object, Object> validationContext = LabelUtil.createDefaultContext(Diagnostician.INSTANCE);
		return assertValidationDiagnostics(prefix, resource, validationContext, messages);
	}

	public static @NonNull List<Diagnostic> assertValidationDiagnostics(@NonNull String prefix, @NonNull Resource resource, Map<Object, Object> validationContext, @NonNull String @Nullable [] messages) {
		List<Diagnostic> diagnostics = new ArrayList<Diagnostic>();
		for (EObject eObject : resource.getContents()) {
			//			Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject, validationContext);
			Diagnostic diagnostic = PivotDiagnostician.BasicDiagnosticWithRemove.validate(eObject, validationContext);
			diagnostics.addAll(diagnostic.getChildren());
		}
		return messages != null ? assertDiagnostics(prefix, resource, diagnostics, messages) : Collections.emptyList();
	}

	public static @Nullable StandaloneProjectMap basicGetProjectMap() {
		EnvironmentFactory globalEnvironmentFactory = GlobalEnvironmentFactory.basicGetInstance();
		return globalEnvironmentFactory != null ? (StandaloneProjectMap)globalEnvironmentFactory.getProjectManager() : null; //projectMap;
	}

	public static void closeTestLog() {
		if (testLog != null) {
			try {
				testLog.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Install a platform:/resource/project... mapping for all folders in
	 * $WORKSPACE_LOC/* if defined, or $user.dir/../* otherwise.
	 */
	public static void configurePlatformResources() {
		if (!eclipseIsRunning()) {
			String urlString = System.getProperty("WORKSPACE_LOC");
			File workspaceLoc;
			if (urlString != null) {
				workspaceLoc = new File(urlString);
			}
			else {
				workspaceLoc = new File(System.getProperty("user.dir")).getParentFile();
			}
			File[] files = workspaceLoc.listFiles();
			for (File file : files) {
				if (file.isDirectory()) {
					String name = file.getName();
					EcorePlugin.getPlatformResourceMap().put(name, URI.createFileURI(file.toString() + "/"));
				}
			}
		}
	}

	public static void createTestLog(File file) {
		try {
			testLog = file != null ? new FileWriter(file) : null;
			if (testLog != null) {
				try {
					testLog.append("Test Group");
					testLog.append(";");
					testLog.append("Context Object");
					testLog.append(";");
					testLog.append("Test Expression");
					testLog.append(";");
					testLog.append("Parser Result");
					testLog.append(";");
					testLog.append("Evaluation Result");
					testLog.append(";");
					testLog.append("Result Tolerance");
					testLog.append("\n");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static @NonNull Resource cs2ecore(@NonNull OCL ocl, @NonNull String testDocument, @NonNull URI ecoreURI) throws IOException {
		InputStream inputStream = new URIConverter.ReadableInputStream(testDocument, "UTF-8");
		URI xtextURI = URI.createURI("test.oclinecore");
		ResourceSet resourceSet = new ResourceSetImpl();
		EssentialOCLCSResource xtextResource = ClassUtil.nonNullState((EssentialOCLCSResource) resourceSet.createResource(xtextURI, null));
		ocl.getEnvironmentFactory().adapt(xtextResource);
		xtextResource.load(inputStream, null);
		assertNoResourceErrors("Loading Xtext", xtextResource);
		Resource asResource = cs2as(ocl, xtextResource, null);
		Resource ecoreResource = as2ecore(ocl, asResource, ecoreURI, NO_MESSAGES);
		return ecoreResource;
	}

	public static @NonNull Resource cs2as(@NonNull OCL ocl, @NonNull String testDocument) throws IOException {
		InputStream inputStream = new URIConverter.ReadableInputStream(testDocument, "UTF-8");
		URI xtextURI = URI.createURI("test.oclinecore");
		ResourceSet resourceSet = new ResourceSetImpl();
		EssentialOCLCSResource xtextResource = ClassUtil.nonNullState((EssentialOCLCSResource) resourceSet.createResource(xtextURI, null));
		ocl.getEnvironmentFactory().adapt(xtextResource);
		xtextResource.load(inputStream, null);
		assertNoResourceErrors("Loading Xtext", xtextResource);
		Resource asResource = cs2as(ocl, xtextResource, null);
		return asResource;
	}

	public static @NonNull Resource cs2as(@NonNull OCL ocl, @NonNull CSResource xtextResource, @Nullable URI pivotURI) throws IOException {
		ASResource asResource = ocl.cs2as(xtextResource);
		assertNoUnresolvedProxies("Unresolved proxies", asResource);
		if (pivotURI != null) {
			asResource.setURI(pivotURI);
			asResource.save(XMIUtil.createSaveOptions());
		}
		return asResource;
	}

	public static void disposeResourceSet(@NonNull ResourceSet resourceSet) {
		for (Resource next : resourceSet.getResources()) {
			next.unload();
			next.eAdapters().clear();
		}
		resourceSet.getResources().clear();
		resourceSet.eAdapters().clear();
	}

	/**
	 * Perform the appropriate initialization to support Complete OCL parsing and editing using Xtext.
	 * NB. This must be called before setUp() creates a GlobalStateMemento if the aggressive DEBUG_GC
	 * garbage collection is enabled.
	 * @deprecated Use TestUtil
	 */
	@Deprecated
	public static void doCompleteOCLSetup() {
		TestUtil.doCompleteOCLSetup();
	}

	/**
	 * Perform the appropriate initialization to support Essential OCL parsing and editing using Xtext.
	 * NB. This must be called before setUp() creates a GlobalStateMemento if the aggressive DEBUG_GC
	 * garbage collection is enabled.
	 * @deprecated Use TestUtil
	 */
	@Deprecated
	public static void doEssentialOCLSetup() {
		TestUtil.doEssentialOCLSetup();
	}

	/**
	 * Perform the appropriate initialization to support OCLinEcore parsing and editing using Xtext.
	 * NB. This must be called before setUp() creates a GlobalStateMemento if the aggressive DEBUG_GC
	 * garbage collection is enabled.
	 * @deprecated Use TestUtil
	 */
	@Deprecated
	public static void doOCLinEcoreSetup() {
		TestUtil.doOCLinEcoreSetup();
	}

	/**
	 * Perform the appropriate initialization to support OCLstdlib parsing and editing using Xtext.
	 * NB. This must be called before setUp() creates a GlobalStateMemento if the aggressive DEBUG_GC
	 * garbage collection is enabled.
	 * @deprecated Use TestUtil
	 */
	@Deprecated
	public static void doOCLstdlibSetup() {
		TestUtil.doOCLstdlibSetup();
	}

	public static boolean eclipseIsRunning() {
		try {
			Class<?> platformClass = Class.forName("org.eclipse.core.runtime.Platform");
			Method isRunningMethod = platformClass.getDeclaredMethod("isRunning");
			return Boolean.TRUE.equals(isRunningMethod.invoke(null));
		} catch (Exception e) {
		}
		return false;
	}

	protected static Value failOn(@NonNull String expression, @Nullable Throwable e) {
		if (e instanceof EvaluationException) {
			Throwable eCause = e.getCause();
			if (eCause != null) {
				return failOn(expression, eCause);
			}
			throw new Error(StringUtil.bind("Failed to evaluate ''{0}'' : {1}", expression, e.getMessage()), e);
		}
		else if (e instanceof EvaluationException) {
			throw new Error("Failed to parse or evaluate \"" + expression + "\"", e);
		}
		else {
			throw new Error("Failure for \"" + expression + "\"", e);
		}
	}

	/**
	 * Return the difference between expectedMessages and actualMessages, or null if no differences.
	 *
	 * The return is formatted one message per line with a leading new-line followed by
	 * an expected/actual count in parentheses followed by the messages
	 */
	public static String formatMessageDifferences(Bag<String> expectedMessages, @NonNull Bag<String> actualMessages) {
		Set<String> allMessages = new HashSet<String>(expectedMessages);
		allMessages.addAll(actualMessages);
		StringBuilder s = null;
		for (String message : allMessages) {
			int actualCount = actualMessages.count(message);
			int expectedCount = expectedMessages.count(message);
			if (actualCount != expectedCount) {
				if (s == null) {
					s = new StringBuilder();
				}
				s.append("\n  (" + expectedCount + "/" + actualCount + ") " + message);
			}
		}
		return s != null ? s.toString() : null;
	}

	public static @NonNull String @NonNull [] getMessages(String... messages) {
		@NonNull String[] messageArray = new @NonNull String[messages.length];
		for (int i = 0; i < messages.length; i++) {
			String message = messages[i];
			assert message != null;
			messageArray[i] = message;
		}
		return messageArray;
	}

	public static @NonNull StandaloneProjectMap getProjectMap() {
		return (StandaloneProjectMap)ProjectManager.CLASS_PATH;
		//		StandaloneProjectMap projectMap2 = projectMap;
		//		if (projectMap2 == null) {
		//			projectMap = projectMap2 = EcorePlugin.IS_ECLIPSE_RUNNING ? new ProjectMap() : new StandaloneProjectMap();
		//		}
		//		return projectMap2;
	}

	public static boolean isWindows() {
		String os = System.getProperty("os.name");
		return (os != null) && os.startsWith("Windows");
	}

	public static void unloadResourceSet(@NonNull ResourceSet resourceSet) {
		StandaloneProjectMap projectMap = StandaloneProjectMap.findAdapter(resourceSet);
		if (projectMap != null) {
			projectMap.unload(resourceSet);
		}
		EnvironmentFactoryAdapter environmentFactoryAdapter = EnvironmentFactoryAdapter.find(resourceSet);
		if (environmentFactoryAdapter != null) {
			EnvironmentFactoryInternal environmentFactory = environmentFactoryAdapter.getMetamodelManager().getEnvironmentFactory();
			ProjectManager projectManager = environmentFactory.getProjectManager();
			projectManager.unload(resourceSet);
		}
		for (Resource resource : resourceSet.getResources()) {
			resource.unload();
		}
		resourceSet.eAdapters().clear();
	}

	@Deprecated /* @deprecated not used */
	protected @NonNull File getProjectFile() {
		String projectName = getProjectName();
		URL projectURL = getTestResource(projectName);
		assertNotNull(projectURL);
		return new File(projectURL.getFile());
	}

	@Deprecated /* @deprecated use getTestModelURI to facilitate legacy inherited testing */
	protected @NonNull URI getProjectFileURI(@NonNull String referenceName) {
		throw new UnsupportedOperationException();
		//		File projectFile = getProjectFile();
		//		return ClassUtil.nonNullState(URI.createFileURI(projectFile.toString() + "/" + referenceName));
	}

	protected @NonNull String getProjectName() {
		return getClass().getPackage().getName().replace('.', '/') + "/models";
	}

	@Rule public TestName testName = new TestName();

	@Override
	public @NonNull String getName() {
		return TestUtil.getName(getTestName());
	}

	public @NonNull String getTestName() {
		String name = super.getName();
		if (name != null) {
			return name;
		}
		String methodName = testName.getMethodName();
		return methodName != null ? methodName : "<unnamed>";
	}

	public static @NonNull URI getTestModelURI(@NonNull String localFileName) {
		String testPlugInPrefix = PLUGIN_ID + "/";
		URI testPlugURI = EcorePlugin.IS_ECLIPSE_RUNNING ? URI.createPlatformPluginURI(testPlugInPrefix, true) : URI.createPlatformResourceURI(testPlugInPrefix, true);
		URI localURI = URI.createURI(localFileName.startsWith("/") ? localFileName.substring(1) : localFileName);
		return localURI.resolve(testPlugURI);
	}

	@Deprecated /* @deprecated not used */
	protected @NonNull URL getTestResource(@NonNull String resourceName) {
		URL projectURL = getClass().getClassLoader().getResource(resourceName);
		try {
			if ((projectURL != null) && Platform.isRunning()) {
				try {
					projectURL = FileLocator.resolve(projectURL);
				} catch (IOException e) {
					TestCase.fail(e.getMessage());
					assert false;;
				}
			}
		}
		catch (Throwable e) {}
		return ClassUtil.nonNullState(projectURL);
	}

	private GlobalStateMemento makeCopyOfGlobalState = null;

	public void resetRegistries() {
		final Object object = ValidationDelegate.Factory.Registry.INSTANCE.get(OCLConstants.OCL_DELEGATE_URI);
		if (object instanceof org.eclipse.ocl.common.internal.delegate.OCLValidationDelegateMapping) {
			((org.eclipse.ocl.common.internal.delegate.OCLValidationDelegateMapping)object).reset();
		}
	}

	@Override
	protected void setUp() throws Exception {
		PivotUtilInternal.debugReset();
		GlobalEnvironmentFactory.resetSafeNavigationValidations();
		//		EssentialOCLLinkingService.DEBUG_RETRY = true;
		ASResourceImpl.CHECK_IMMUTABILITY.setState(true);
		if (DEBUG_GC) {
			XMLNamespacePackage.eINSTANCE.getClass();
			makeCopyOfGlobalState = new GlobalStateMemento();
		}
		super.setUp();
		if (DEBUG_ID) {
			PivotUtilInternal.debugPrintln("-----Starting " + getClass().getSimpleName() + "." + getName() + "-----");
		}
		TEST_START.println("-----Starting " + getClass().getSimpleName() + "." + getName() + "-----");
		EcorePackage.eINSTANCE.getClass();						// Workaround Bug 425841
		//		EPackage.Registry.INSTANCE.put(UML302UMLResource.STANDARD_PROFILE_NS_URI, L2Package.eINSTANCE);
	}

	@Override
	protected void tearDown() throws Exception {
		//		if (DEBUG_ID) {
		//			PivotUtilInternal.debugPrintln("==> Done " + getName());
		//		}
		if (DEBUG_GC) {
			uninstall();
			makeCopyOfGlobalState.restoreGlobalState();
			makeCopyOfGlobalState = null;
			System.gc();
			System.runFinalization();
			//			MetamodelManagerResourceAdapter.INSTANCES.show();
		}
		if (DEBUG_ID) {
			PivotUtilInternal.debugPrintln("==> Finish " + getClass().getSimpleName() + "." + getName());
		}
		/**
		 * Reset any PivotEObject.target that may have reverted to proxies when a ProjectMap unloaded,
		 * and which might be resolved using the wrong strategy in another test.
		 */
		OCLstdlib oclstdlib = OCLstdlib.basicGetDefault();
		if (oclstdlib != null) {
			for (TreeIterator<EObject> tit = oclstdlib.getAllContents(); tit.hasNext(); ) {
				EObject eObject = tit.next();
				if (eObject instanceof PivotObjectImpl) {
					PivotObjectImpl asObject = (PivotObjectImpl)eObject;
					EObject eTarget = asObject.getESObject();
					if ((eTarget != null) && eTarget.eIsProxy()) {
						asObject.setESObject(null);
					}
				}
			}
		}
		super.tearDown();
	}

	protected void uninstall() {
		PivotStandaloneSetup.doTearDown();
		BaseStandaloneSetup.doTearDown();
		CompleteOCLStandaloneSetup.doTearDown();
		EssentialOCLStandaloneSetup.doTearDown();
		MarkupStandaloneSetup.doTearDown();
		OCLinEcoreStandaloneSetup.doTearDown();
		OCLstdlibStandaloneSetup.doTearDown();
		GlobalEnvironmentFactory.disposeInstance();
		GeneratorAdapterFactory.Descriptor.Registry.INSTANCE.removeDescriptors(GenModelPackage.eNS_URI);
		//		OCLstdlib.uninstall(); // should be able to persist
		//		if (projectMap != null) {
		//			projectMap.dispose();
		//			projectMap = null;
		//		}
	}

	public static class GlobalStateMemento
	{
		private @NonNull HashMap<EPackage, Object> validatorReg;
		private @NonNull HashMap<String, Object> epackageReg;
		private @NonNull HashMap<String, Object> protocolToFactoryMap;
		private @NonNull HashMap<String, Object> extensionToFactoryMap;
		private @NonNull HashMap<String, Object> contentTypeIdentifierToFactoryMap;
		private @NonNull HashMap<String, Object> protocolToServiceProviderMap;
		private @NonNull HashMap<String, Object> extensionToServiceProviderMap;
		private @NonNull HashMap<String, Object> contentTypeIdentifierToServiceProviderMap;

		public GlobalStateMemento() {
			validatorReg = new HashMap<EPackage, Object>(EValidator.Registry.INSTANCE);
			epackageReg = new HashMap<String, Object>(EPackage.Registry.INSTANCE);
			protocolToFactoryMap = new HashMap<String, Object>(Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap());
			extensionToFactoryMap = new HashMap<String, Object>(Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap());
			contentTypeIdentifierToFactoryMap = new HashMap<String, Object>(Resource.Factory.Registry.INSTANCE.getContentTypeToFactoryMap());

			protocolToServiceProviderMap = new HashMap<String, Object>(IResourceServiceProvider.Registry.INSTANCE.getProtocolToFactoryMap());
			extensionToServiceProviderMap = new HashMap<String, Object>(IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap());
			contentTypeIdentifierToServiceProviderMap = new HashMap<String, Object>(IResourceServiceProvider.Registry.INSTANCE.getContentTypeToFactoryMap());
		}

		public void restoreGlobalState() {
			clearGlobalRegistries();
			EValidator.Registry.INSTANCE.putAll(validatorReg);
			EPackage.Registry.INSTANCE.putAll(epackageReg);

			Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap().putAll(protocolToFactoryMap);
			Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().putAll(extensionToFactoryMap);
			Resource.Factory.Registry.INSTANCE.getContentTypeToFactoryMap().putAll(contentTypeIdentifierToFactoryMap);

			IResourceServiceProvider.Registry.INSTANCE.getProtocolToFactoryMap().putAll(protocolToServiceProviderMap);
			IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap().putAll(extensionToServiceProviderMap);
			IResourceServiceProvider.Registry.INSTANCE.getContentTypeToFactoryMap().putAll(contentTypeIdentifierToServiceProviderMap);
		}

		public static void clearGlobalRegistries() {
			//			Registry eValidatorRegistry = EValidator.Registry.INSTANCE;
			//			for (EPackage key : eValidatorRegistry.keySet()) {
			//				Object object = eValidatorRegistry.get(key);
			//				System.out.println("key : " + key.getNsURI() + " => " + object.getClass().getName());
			//			}
			EValidator.Registry.INSTANCE.clear();
			EPackage.Registry.INSTANCE.clear();
			Resource.Factory.Registry.INSTANCE.getProtocolToFactoryMap().clear();
			Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().clear();
			Resource.Factory.Registry.INSTANCE.getContentTypeToFactoryMap().clear();

			IResourceServiceProvider.Registry.INSTANCE.getProtocolToFactoryMap().clear();
			IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap().clear();
			IResourceServiceProvider.Registry.INSTANCE.getContentTypeToFactoryMap().clear();
			initializeDefaults();
		}

		public static void initializeDefaults() {
			//EMF Standalone setup
			if (!Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("ecore"))
				Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
					"ecore", new EcoreResourceFactoryImpl());
			if (!Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().containsKey("xmi"))
				Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
					"xmi", new XMIResourceFactoryImpl());
			if (!EPackage.Registry.INSTANCE.containsKey(EcorePackage.eNS_URI))
				EPackage.Registry.INSTANCE.put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
			if (!EPackage.Registry.INSTANCE.containsKey(XtextPackage.eNS_URI))
				EPackage.Registry.INSTANCE.put(XtextPackage.eNS_URI, XtextPackage.eINSTANCE);
		}
	}
}
