[571721] Ensure Console uses part-specific EnvironmentFactory
diff --git a/examples/org.eclipse.ocl.examples.xtext.console/src/org/eclipse/ocl/examples/xtext/console/OCLConsolePage.java b/examples/org.eclipse.ocl.examples.xtext.console/src/org/eclipse/ocl/examples/xtext/console/OCLConsolePage.java
index 68724d4..58357ed 100644
--- a/examples/org.eclipse.ocl.examples.xtext.console/src/org/eclipse/ocl/examples/xtext/console/OCLConsolePage.java
+++ b/examples/org.eclipse.ocl.examples.xtext.console/src/org/eclipse/ocl/examples/xtext/console/OCLConsolePage.java
@@ -18,6 +18,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -114,7 +115,9 @@
 import org.eclipse.ui.ISelectionListener;
 import org.eclipse.ui.ISelectionService;
 import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.console.IConsole;
 import org.eclipse.ui.console.IConsoleConstants;
@@ -350,39 +353,6 @@
 	private @Nullable Iterable<org.eclipse.ocl.pivot.@NonNull Class> contextModelClasses = null;
 	private ParserContext parserContext;
 
-	/*	public IItemLabelProvider tupleTypeLabelProvider = new IItemLabelProvider() {
-
-		public Object getImage(Object object) {
-			return null;
-		}
-
-		public String getText(Object object) {
-		    @SuppressWarnings("unchecked")
-            TupleValue tuple = (TupleValue) object;
-			TupleType tupleType = tuple.getTupleType();
-
-			StringBuilder result = new StringBuilder();
-			result.append("Tuple{");//$NON-NLS-1$
-
-			for (Iterator<?> iter = tupleType.oclProperties().iterator();
-					iter.hasNext();) {
-
-				Object next = iter.next();
-
-				result.append(oclFactory.getName(next));
-				result.append(" = "); //$NON-NLS-1$
-				result.append(OCLConsolePage.this.toString(tuple.getValue(next)));
-
-				if (iter.hasNext()) {
-					result.append(", "); //$NON-NLS-1$
-				}
-			}
-
-			result.append('}');
-
-			return result.toString();
-		}}; */
-
 	/**
 	 * Initializes me.
 	 * @param console
@@ -569,7 +539,8 @@
 		Composite client = s1; //new Composite(s1, SWT.NULL);
 		Injector injector = XtextConsolePlugin.getInstance().getInjector(EssentialOCLPlugin.LANGUAGE_ID);
 		Composite editorComposite = client; //new Composite(client, SWT.NULL);
-		editor = new EmbeddedXtextEditor(editorComposite, injector, /*SWT.BORDER |*/ SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
+		EnvironmentFactoryInternal currentEnvironmentFactory = ThreadLocalExecutor.basicGetEnvironmentFactory();
+		editor = new EmbeddedXtextEditor(editorComposite, injector, /*SWT.BORDER |*/ SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL, currentEnvironmentFactory);
 		//		MetamodelManagerResourceSetAdapter.getAdapter(editor.getResourceSet(), metamodelManager);
 
 		/*		editor.getViewer().getTextWidget().addModifyListener(new ModifyListener() {
@@ -840,7 +811,7 @@
 						((BaseCSResource)resource).dispose();
 					}
 
-					EnvironmentFactory environmentFactory = getEnvironmentFactory(contextObject);
+					EnvironmentFactory environmentFactory = ClassUtil.nonNullState(ThreadLocalExecutor.basicGetEnvironmentFactory()); //getEnvironmentFactory(contextObject);
 					IdResolver.IdResolverExtension idResolver = (IdResolver.IdResolverExtension)environmentFactory.getIdResolver();
 					//				DomainType staticType = idResolver.getStaticTypeOfValue(null, selectedObject);
 					org.eclipse.ocl.pivot.Class staticType = idResolver.getStaticTypeOfValue(null, contextObject);
@@ -856,11 +827,6 @@
 						instanceContext = ((EnvironmentFactoryInternalExtension)environmentFactory).getASOf(Element.class, instanceContext);
 					}
 					parserContext = new ClassContext(environmentFactory, null, contextType, (instanceContext instanceof Type) && !(instanceContext instanceof ElementExtension) ? (Type)instanceContext : null);
-					//				}
-					//				else {
-					//					parserContext = new ModelContext(metamodelManager, null);
-					//				}
-					//		        parserContext = new EObjectContext(metamodelManager, null, contextObject);
 					EssentialOCLCSResource csResource = (EssentialOCLCSResource) resource;
 					if (csResource != null) {
 						if (contextObject != null) {
diff --git a/examples/org.eclipse.ocl.examples.xtext.console/src/org/eclipse/ocl/examples/xtext/console/xtfo/EmbeddedXtextEditor.java b/examples/org.eclipse.ocl.examples.xtext.console/src/org/eclipse/ocl/examples/xtext/console/xtfo/EmbeddedXtextEditor.java
index b61326f..14b5c99 100644
--- a/examples/org.eclipse.ocl.examples.xtext.console/src/org/eclipse/ocl/examples/xtext/console/xtfo/EmbeddedXtextEditor.java
+++ b/examples/org.eclipse.ocl.examples.xtext.console/src/org/eclipse/ocl/examples/xtext/console/xtfo/EmbeddedXtextEditor.java
@@ -58,6 +58,7 @@
 import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
 import org.eclipse.ocl.pivot.internal.resource.EnvironmentFactoryAdapter;
+import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
 import org.eclipse.ocl.pivot.internal.utilities.OCLInternal;
 import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
 import org.eclipse.ocl.pivot.resource.ProjectManager;
@@ -199,18 +200,7 @@
 	 * @param style the SWT style of the {@link SourceViewer} of this editor.
 	 */
 	public EmbeddedXtextEditor(Composite control, Injector injector, int style) {
-		fControl = control;
-		fStyle = style;
-		fAnnotationPreferences = new MarkerAnnotationPreferences();
-
-		injector.injectMembers(this);
-		ThreadLocalExecutor.reset();
-		ocl = OCLInternal.newInstance(PivotUtilInternal.getEnvironmentFactory(null));
-		ResourceSet xtextResourceSet = getResourceSet();
-		if (xtextResourceSet != null) {
-			ocl.getEnvironmentFactory().adapt(xtextResourceSet);
-		}
-		createEditor(fControl);
+		this(control, injector, style, null);
 	}
 
 	/**
@@ -222,7 +212,24 @@
 	 * @param injector the Guice injector to get Xtext configuration elements
 	 */
 	public EmbeddedXtextEditor(Composite control, Injector injector) {
-		this(control, injector, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+		this(control, injector, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, null);
+	}
+
+	public EmbeddedXtextEditor(Composite control, Injector injector, int style, EnvironmentFactoryInternal currentEnvironmentFactory) {
+		fControl = control;
+		fStyle = style;
+		fAnnotationPreferences = new MarkerAnnotationPreferences();
+
+		injector.injectMembers(this);
+		if (currentEnvironmentFactory == null) {
+			currentEnvironmentFactory = PivotUtilInternal.getEnvironmentFactory(null);
+		}
+		ocl = OCLInternal.newInstance(currentEnvironmentFactory);
+		ResourceSet xtextResourceSet = getResourceSet();
+		if (xtextResourceSet != null) {
+			currentEnvironmentFactory.adapt(xtextResourceSet);
+		}
+		createEditor(fControl);
 	}
 
 	public Composite getControl() {
diff --git a/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/model/BaseDocument.java b/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/model/BaseDocument.java
index 49e9375..c6b40de 100644
--- a/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/model/BaseDocument.java
+++ b/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/model/BaseDocument.java
@@ -69,17 +69,21 @@
 		public <T> T modify(IUnitOfWork<T, XtextResource> work) {
 		//	System.out.println("[" + Thread.currentThread().getName() + "] modify " + NameUtil.debugSimpleName(this));
 			EnvironmentFactoryInternal oldEnvironmentFactory = ThreadLocalExecutor.basicGetEnvironmentFactory();
-			if ((environmentFactory != null) && (oldEnvironmentFactory != environmentFactory)) {
+			EnvironmentFactoryInternal newEnvironmentFactory = environmentFactory;
+			if ((newEnvironmentFactory != null) && (oldEnvironmentFactory != newEnvironmentFactory)) {
 			//	assert environmentFactory != null;
-				ThreadLocalExecutor.attachEnvironmentFactory(environmentFactory);
+				if (oldEnvironmentFactory != null) {
+					ThreadLocalExecutor.detachEnvironmentFactory(oldEnvironmentFactory);
+				}
+				ThreadLocalExecutor.attachEnvironmentFactory(newEnvironmentFactory);
 			}
 			try {
 				return super.modify(work);
 			}
 			finally {
-				if ((environmentFactory != null) && (oldEnvironmentFactory != environmentFactory)) {
+				if ((newEnvironmentFactory != null) && (oldEnvironmentFactory != newEnvironmentFactory)) {
 				//	assert environmentFactory != null;
-					ThreadLocalExecutor.detachEnvironmentFactory(environmentFactory);
+					ThreadLocalExecutor.detachEnvironmentFactory(newEnvironmentFactory);
 				}
 			}
 		}
@@ -88,17 +92,21 @@
 		public <T> T readOnly(IUnitOfWork<T, XtextResource> work) {
 		//	System.out.println("[" + Thread.currentThread().getName() + "] readOnly " + NameUtil.debugSimpleName(this));
 			EnvironmentFactoryInternal oldEnvironmentFactory = ThreadLocalExecutor.basicGetEnvironmentFactory();
-			if (oldEnvironmentFactory != environmentFactory) {
-				assert environmentFactory != null;
-				ThreadLocalExecutor.attachEnvironmentFactory(environmentFactory);
+			EnvironmentFactoryInternal newEnvironmentFactory = environmentFactory;
+			if ((newEnvironmentFactory != null) && (oldEnvironmentFactory != newEnvironmentFactory)) {
+			//	assert environmentFactory != null;
+				if (oldEnvironmentFactory != null) {
+					ThreadLocalExecutor.detachEnvironmentFactory(oldEnvironmentFactory);
+				}
+				ThreadLocalExecutor.attachEnvironmentFactory(newEnvironmentFactory);
 			}
 			try {
 				return super.readOnly(work);
 			}
 			finally {
-				if (oldEnvironmentFactory != environmentFactory) {
-					assert environmentFactory != null;
-					ThreadLocalExecutor.detachEnvironmentFactory(environmentFactory);
+				if (oldEnvironmentFactory != newEnvironmentFactory) {
+					assert newEnvironmentFactory != null;
+					ThreadLocalExecutor.detachEnvironmentFactory(newEnvironmentFactory);
 				}
 			}
 		}
diff --git a/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/model/BaseDocumentProvider.java b/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/model/BaseDocumentProvider.java
index 7506af1..9903bf9 100644
--- a/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/model/BaseDocumentProvider.java
+++ b/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/model/BaseDocumentProvider.java
@@ -72,6 +72,7 @@
 	}
 
 	public void initOCL(@NonNull BaseEditor baseEditor) {
+		ThreadLocalExecutorUI.initPart(baseEditor, null);
 		OCLInternal ocl = getOCL();
 		ThreadLocalExecutorUI.initPart(baseEditor, ocl.getEnvironmentFactory());
 	}
diff --git a/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/utilities/ThreadLocalExecutorUI.java b/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/utilities/ThreadLocalExecutorUI.java
index 228087f..b09cf78 100644
--- a/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/utilities/ThreadLocalExecutorUI.java
+++ b/plugins/org.eclipse.ocl.xtext.base.ui/src/org/eclipse/ocl/xtext/base/ui/utilities/ThreadLocalExecutorUI.java
@@ -41,8 +41,11 @@
 	 *
 	 * If initActivePart is null the prevailing activePart is used to provide support for OCL-blind applications
 	 * such as the Sample Ecore Editor.
+	 *
+	 * If initEnvironmentfactory is null a new activePart will be defining a new initEnvironmentfactory later.
 	 */
-	public static void initPart(@Nullable IWorkbenchPart initActivePart, @NonNull EnvironmentFactoryInternal initEnvironmentfactory) {
+	public static void initPart(@Nullable IWorkbenchPart initActivePart, @Nullable EnvironmentFactoryInternal initEnvironmentfactory) {
+		assert (initActivePart != null) || (initEnvironmentfactory != null);
 		ThreadLocalExecutor threadLocalExecutor = get();
 		if (threadLocalExecutor instanceof ThreadLocalExecutorUI) {
 			((ThreadLocalExecutorUI)threadLocalExecutor).localInitPart(initActivePart, initEnvironmentfactory);
@@ -81,7 +84,7 @@
 		return "[" + Thread.currentThread().getName() + ":" + NameUtil.debugSimpleName(activePart) + "]";
 	}
 
-	protected void localInitPart(@Nullable IWorkbenchPart initActivePart, @NonNull EnvironmentFactoryInternal initEnvironmentfactory) {
+	protected void localInitPart(@Nullable IWorkbenchPart initActivePart, @Nullable EnvironmentFactoryInternal initEnvironmentfactory) {
 		if (initEnvironmentfactory != basicGetEnvironmentFactory()) {			// == if a late not-active init
 			setEnvironmentFactory(null);
 		}
@@ -89,10 +92,12 @@
 			initActivePart = this.activePart;
 			assert initActivePart != null;
 		}
-		EnvironmentFactoryInternal oldEnvironmentFactory = part2environmentFactory.put(initActivePart, initEnvironmentfactory);
-		assert oldEnvironmentFactory == null;
-		if (THREAD_LOCAL_ENVIRONMENT_FACTORY.isActive()) {
-			THREAD_LOCAL_ENVIRONMENT_FACTORY.println(getThreadName() + " Init [" + Thread.currentThread().getName() + ":" + NameUtil.debugSimpleName(initActivePart) + "] " + toString());
+		if (initEnvironmentfactory != null) {
+			EnvironmentFactoryInternal oldEnvironmentFactory = part2environmentFactory.put(initActivePart, initEnvironmentfactory);
+			assert oldEnvironmentFactory == null;
+			if (THREAD_LOCAL_ENVIRONMENT_FACTORY.isActive()) {
+				THREAD_LOCAL_ENVIRONMENT_FACTORY.println(getThreadName() + " Init [" + Thread.currentThread().getName() + ":" + NameUtil.debugSimpleName(initActivePart) + "] " + toString());
+			}
 		}
 	}
 
@@ -144,18 +149,16 @@
 		if (THREAD_LOCAL_ENVIRONMENT_FACTORY.isActive()) {
 			THREAD_LOCAL_ENVIRONMENT_FACTORY.println(getThreadName() + " partDeactivated [" + Thread.currentThread().getName() + ":" + NameUtil.debugSimpleName(oldActivePart) + "] " + toString());
 		}
-		if (oldActivePart != null) {
-			EnvironmentFactoryInternal environmentFactory = localBasicGetEnvironmentFactory();
-			if (environmentFactory != null) {
-				EnvironmentFactory partEnvironmentFactory = oldActivePart.getAdapter(EnvironmentFactory.class);
-				part2environmentFactory.put(oldActivePart, environmentFactory);    // part2environmentFactory persists for an activate
-				if (partEnvironmentFactory == null) {		// OCL-blind editor
-					environmentFactory.attach(this);
-				}
+		EnvironmentFactoryInternal environmentFactory = localBasicGetEnvironmentFactory();
+		if (environmentFactory != null) {
+			EnvironmentFactory partEnvironmentFactory = oldActivePart.getAdapter(EnvironmentFactory.class);
+			part2environmentFactory.put(oldActivePart, environmentFactory);    // part2environmentFactory persists for an activate
+			if (partEnvironmentFactory == null) {		// OCL-blind editor
+				environmentFactory.attach(this);
 			}
-			else {
-				part2environmentFactory.remove(oldActivePart);
-			}
+		}
+		else {
+			part2environmentFactory.remove(oldActivePart);
 		}
 		activePart = null;
 		setEnvironmentFactory(null);
diff --git a/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/AbstractConsoleTests.java b/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/AbstractConsoleTests.java
index 310bb55..888f990 100644
--- a/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/AbstractConsoleTests.java
+++ b/tests/org.eclipse.ocl.examples.xtext.tests/src/org/eclipse/ocl/examples/test/xtext/AbstractConsoleTests.java
@@ -10,12 +10,16 @@
  *******************************************************************************/
 package org.eclipse.ocl.examples.test.xtext;
 
+import java.util.Collections;
+import java.util.List;
+
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.debug.core.ILaunch;
 import org.eclipse.emf.common.EMFPlugin;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.ocl.examples.pivot.tests.PivotTestCaseWithAutoTearDown;
@@ -23,9 +27,18 @@
 import org.eclipse.ocl.examples.xtext.console.OCLConsole;
 import org.eclipse.ocl.examples.xtext.console.OCLConsolePage;
 import org.eclipse.ocl.examples.xtext.tests.TestUIUtil;
+import org.eclipse.ocl.pivot.evaluation.ModelManager;
+import org.eclipse.ocl.pivot.internal.library.executor.LazyEcoreModelManager;
+import org.eclipse.ocl.pivot.internal.resource.EnvironmentFactoryAdapter;
+import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
+import org.eclipse.ocl.pivot.internal.utilities.PivotEnvironmentFactory;
 import org.eclipse.ocl.pivot.model.OCLstdlib;
+import org.eclipse.ocl.pivot.utilities.AbstractEnvironmentFactory;
+import org.eclipse.ocl.pivot.utilities.ThreadLocalExecutor;
+import org.eclipse.ocl.pivot.values.ObjectValue;
 import org.eclipse.ocl.xtext.base.ui.model.BaseDocument;
 import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.console.ConsolePlugin;
 import org.eclipse.ui.console.IConsole;
 import org.eclipse.ui.console.IConsoleManager;
@@ -105,6 +118,13 @@
 		}
 
 		@Override
+		protected @Nullable EnvironmentFactoryAdapter createEditor(Composite s1) {
+			EnvironmentFactoryInternal testEnvironmentFactory = new TestEnvironmentFactory();
+			ThreadLocalExecutor.attachEnvironmentFactory(testEnvironmentFactory);
+			return super.createEditor(s1);
+		}
+
+		@Override
 		public boolean evaluate(String expression) {
 			return super.evaluate(expression);
 		}
@@ -142,6 +162,31 @@
 		}
 	}
 
+	/**
+	 * See Bug 570894. Overridden to override LazyEcoreModelManager coonstruction to avoid
+	 * all the sibling ResourceSet roots being found in the extent.
+	 */
+	protected static class TestEnvironmentFactory extends PivotEnvironmentFactory
+	{
+		protected TestEnvironmentFactory() {
+			super(getProjectMap(), null, null);
+		}
+
+		@Override
+		public @NonNull ModelManager createModelManager(@Nullable Object object) {
+			if (object instanceof ObjectValue) {
+				object = ((ObjectValue) object).getObject();
+			}
+			if (object instanceof EObject) {
+				EObject rootContainer = EcoreUtil.getRootContainer((EObject)object);
+				assert rootContainer != null;
+				List<@NonNull EObject> rootList = Collections.singletonList(rootContainer);
+				return new LazyEcoreModelManager(rootList, null, null);
+			}
+			return ModelManager.NULL;
+		}
+	}
+
 	public static void assertConsoleResult(TestConsolePage consolePage, EObject contextObject, String testExpression, String expectedResult) {
 		consolePage.resetDocument();
 		TestUIUtil.flushEvents();