/**
 * This file was copied and re-packaged automatically by
 *     org.eclipse.ocl.examples.build.GenerateAutoCSModels.mwe2
 * from 
 *     ..\..\..\org.eclipse.qvtd\plugins\org.eclipse.qvtd.runtime\src\org\eclipse\qvtd\runtime\internal\evaluation\IncrementalObjectManager.java
 *
 * Do not edit this file. 
 */
/*******************************************************************************
 * Copyright (c) 2013, 2015 Willink Transformations 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:
 *   E.D.Willink - Initial API and implementation
 *******************************************************************************/
package org.eclipse.ocl.pivot.internal.evaluation.tx;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.oclstdlib.OCLstdlibPackage;
import org.eclipse.ocl.pivot.evaluation.tx.AbstractObjectManager;
import org.eclipse.ocl.pivot.evaluation.tx.AbstractSlotState;
import org.eclipse.ocl.pivot.evaluation.tx.AbstractTransformer;
import org.eclipse.ocl.pivot.evaluation.tx.Invocation;
import org.eclipse.ocl.pivot.evaluation.tx.InvocationFailedException;
import org.eclipse.ocl.pivot.evaluation.tx.ObjectManager;
import org.eclipse.ocl.pivot.evaluation.tx.SlotState;

/**
 * @since 1.1
 */
public class IncrementalObjectManager extends AbstractObjectManager
{
	/**
	 * Simple SlotState describing a DataType element or 1:1 Object navigation.
	 */
	public static abstract class BasicSlotState extends AbstractSlotState.Incremental
	{
		public enum SlotMode {
			ASSIGNABLE,		// No assignment has been performed, object reads are blocked (collections reads may be unblocked)
			ASSIGNED		// Last assignment has been performed, reads are unblocked
		}
		
		protected final @NonNull Object eObject; 
		protected final @NonNull EStructuralFeature eFeature; 
		private @Nullable Object value = null; 

		protected @NonNull SlotMode mode;
		private @Nullable Object blockedInvocations = null;
		
		public BasicSlotState(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
			mode = SlotMode.ASSIGNABLE;	
			this.eObject = eObject;
			this.eFeature = eFeature;
		}

		public BasicSlotState(@NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			mode = SlotMode.ASSIGNED;	
			this.eObject = eObject;
			this.eFeature = eFeature;
			this.value = ecoreValue;
		}

		public synchronized void assigned(@NonNull IncrementalObjectManager objectManager, @NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			switch (mode) {
				case ASSIGNABLE:
					mode = SlotMode.ASSIGNED;
					unblock(objectManager);
					break;
				case ASSIGNED:
					System.out.println("Re-assignment of " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + " with " + ecoreValue);
					break;
			}
			this.value = ecoreValue;
		}
		
		@Override
		public synchronized void block(@NonNull Invocation invocation) {
			final Object blockedInvocations2 = blockedInvocations;
			if (blockedInvocations2 == null) {
				blockedInvocations = invocation;
			}
			else if (blockedInvocations2 instanceof Invocation) {
				List<Invocation> blockedInvocationList = new ArrayList<Invocation>();
				blockedInvocationList.add((Invocation) blockedInvocations2);
				blockedInvocationList.add(invocation);
				blockedInvocations = blockedInvocationList;
			}
			else {
				@SuppressWarnings("unchecked")
				List<Invocation> blockedInvocationList = (List<Invocation>)blockedInvocations2;
				blockedInvocationList.add(invocation);
			}
		}

		@Override
		public @NonNull EStructuralFeature getEFeature() {
			return eFeature;
		}

		@Override
		public SlotState.@NonNull Incremental getPrimarySlotState() {
			return this;
		}

		@Override
		public @Nullable Object getValue() {
			return value;
		}

		@Override
		public synchronized void getting( @NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
			switch (mode) {
				case ASSIGNABLE:
					throw new InvocationFailedException(this);
				case ASSIGNED:
					break;
			}
		}

		protected boolean isAssigned() {
			return mode == SlotMode.ASSIGNED;
		}

		@Override
		public String toString() {
			return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + "[" + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + "]";
		}

		protected synchronized void unblock(@NonNull ObjectManager objectManager) {
			final Object blockedInvocations2 = blockedInvocations;
			if (blockedInvocations2 instanceof Invocation) {
				objectManager.unblock((Invocation) blockedInvocations2);
			}
			else if (blockedInvocations2 != null) {
				@SuppressWarnings("unchecked")
				List<Invocation> blockedInvocationList = (List<Invocation>)blockedInvocations2;
				for (@SuppressWarnings("null")@NonNull Invocation invocation : blockedInvocationList) {
					objectManager.unblock(invocation);
				}
			}
			blockedInvocations = null;
		}
	}
	
	/**
	 * SlotState describing the contained element side of a 1:N Object navigation.
	 * A single OneToManyContainedSlotState is shared by each of the possible containing features and also the
	 * generic OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER corresponding to eContainer().
	 * The eGet() must therefore check not only that the proprty is assigned but also that it is
	 * assigned to the containing feature of interest.
	 * <br>
	 * Lifecycle (read first, write later):
	 * Create due to
	 * - get of an aggregator => ASSIGNABLE, blocked
	 * Unblock
	 * - assign of possibly null aggregator for the element, ASSIGNABLE, blocked => ASSIGNED, not blocked
	 * - non-null aggregator is notified to unblock 
	 * Thereafter
	 * - get of aggregator ASSIGNED => ASSIGNED
	 * <br>
	 * Lifecycle (write first):
	 * Create due to
	 * - assign of a possibly null aggregator => ASSIGNED, unblocked
	 * - non-null aggregator is notified to unblock 
	 * Thereafter
	 * - get of aggregator ASSIGNED => ASSIGNED
	 *
	private static class ContainedSlotState extends SlotState
	{
		public static @NonNull SlotState create(@NonNull ObjectManager objectManager,
				@NonNull EObject eObject, @NonNull EReference eFeature, @Nullable EReference eOppositeFeature, @Nullable EObject eContainer) {
			if (eOppositeFeature == null) {
				eOppositeFeature = OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER;
				assert eOppositeFeature != null;
			}
			if (eContainer != null) {
				ContainerSlotState aggregatorSlotState = (ContainerSlotState) objectManager.getSlotState(eContainer, eOppositeFeature);
				aggregatorSlotState.assignedElement(objectManager, eContainer, eOppositeFeature, eObject);
			}
			return new ContainedSlotState(eObject, eFeature, eContainer);
		}
		
		public ContainedSlotState(@NonNull EObject eObject, @NonNull EReference eFeature) {
			super(eObject, eFeature);
			assert !eFeature.isMany();
			if (eFeature != OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {	// FIXME ensure oclContainer() composes
				assert eFeature.isContainment();
				assert eFeature.getEOpposite() != null;
			}
//			assert eFeature.getEOpposite().isMany();
		}
		
		private ContainedSlotState(@NonNull EObject eObject, @NonNull EReference eFeature, @Nullable EObject eContainer) {
			super(eObject, eFeature, eContainer);
			assert !eFeature.isMany();
			if (eFeature != OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {	// FIXME ensure oclContainer() composes
				assert eFeature.isContainment();
			}
//			assert eFeature.getEOpposite().isMany();
			assert eObject.eContainer() == eContainer;
		}

		@Override
		public synchronized void assigned(@NonNull ObjectManager objectManager, @NonNull EObject eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			if (!isAssigned() && (ecoreValue != null)) {
				EObject eOpposite = (EObject) ecoreValue;
				EReference eOppositeReference = ((EReference)eFeature).getEOpposite();
				assert eOppositeReference != null;
				ContainerSlotState aggregatorSlotState = (ContainerSlotState) objectManager.getSlotState(eOpposite, eOppositeReference);
				aggregatorSlotState.assignedElement(objectManager, eOpposite, eOppositeReference, eObject);
			}
			super.assigned(objectManager, eObject, eFeature, ecoreValue);
		}
		
		@Override
		@SuppressWarnings("unchecked")
		public synchronized @Nullable <G> G get(@NonNull ObjectManager objectManager, @NonNull EObject eObject, @NonNull EStructuralFeature eFeature) {
			switch (mode) {
				case ASSIGNABLE:
					throw new InvocationFailedException(this);
				case ASSIGNED:
					break;
			}
			if (eFeature != OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
				EStructuralFeature eContainingFeature = eObject.eContainingFeature();
				if (eContainingFeature != eFeature) {
					return null;
				}
			}
			return (G) eObject.eContainer();
		}
	} */
	
	/**
	 * SlotState describing the container side of a 1:N Object navigation.
	 * <br>
	 * Lifecycle:
	 * Create due to
	 * - get of all elements => ASSIGNABLE, blocked
	 * NO: - get of a container => ASSIGNABLE, blocked
	 * Create due to
	 * - assign of all elements => ASSIGNABLE => ASSIGNED, not blocked
	 * - assign of a first element to the container => ASSIGNABLE, not blocked
	 * Update due to
	 * - assign of a further element to the container => ASSIGNABLE => ASSIGNABLE
	 * Unblock due to
	 * - get of a container ASSIGNABLE => ASSIGNED
	 * - get of all elements ASSIGNABLE => ASSIGNED
	 * Thereafter
	 * - get of a container ASSIGNED => ASSIGNED
	 * - get of all elements ASSIGNED => ASSIGNED
	 * <br>
	 * Lifecycle 2: read first
	 * Create due to
	 * - get of elements => ASSIGNABLE, blocked
	 * Unblock due to
	 * - assign of an element to the container => ASSIGNABLE => ASSIGNED, not blocked
	 * Thereafter
	 * - get of either end ASSIGNED => ASSIGNED
	 * - (assign of either end is an ignored error)
	 *
	private static class ContainerSlotState extends SlotState
	{
		public static @NonNull SlotState create(@NonNull ObjectManager objectManager,
				@NonNull EObject eObject, @NonNull EReference eFeature, @NonNull EReference eOppositeFeature, @Nullable EObject eContent) {
			if (eContent != null) {
				ContainedSlotState containedSlotState = (ContainedSlotState) objectManager.getSlotState(eContent, eOppositeFeature);
				containedSlotState.assigned(objectManager, eContent, eOppositeFeature, eObject);
			}
			return new ContainerSlotState(eObject, eFeature, eContent);
		}
		
		public ContainerSlotState(@NonNull EObject eContainer, @NonNull EReference eFeature) {
			super(eContainer, eFeature);
			assert eFeature.isContainer();
//			assert eFeature.isMany();
//			assert eFeature.getEOpposite() != null;
//			assert eFeature.getEOpposite().isMany();
		}

		public ContainerSlotState(@NonNull EObject eContainer, @NonNull EReference eFeature, @Nullable Object elements) {
			super(eContainer, eFeature, elements);
			assert eFeature.isContainer();
//			assert eFeature.isMany();
//			assert eFeature.getEOpposite() != null;
//			assert eFeature.getEOpposite().isMany();
			assert eContainer.eGet(eFeature) == eContainer;
		}

		@Override
		public synchronized void assigned(@NonNull ObjectManager objectManager, @NonNull EObject eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			assert ecoreValue != null;
			@SuppressWarnings("unchecked")
			List<? extends EObject> ecoreValues = (List<? extends EObject>)ecoreValue;
			EReference eOppositeReference = ((EReference)eFeature).getEOpposite();
			for (EObject element : ecoreValues) {
				if (element != null) {
					Map<EStructuralFeature, SlotState> elementObjectState = objectManager.getObjectState(element);
					elementObjectState.put(eOppositeReference, this);
				}
			}
			super.assigned(objectManager, eObject, eFeature, ecoreValue);

		}
		
		public void assignedElement(@NonNull ObjectManager objectManager,
				@NonNull EObject eContainer, @NonNull EReference eReference, EObject eObject) {
			super.assigned(objectManager, eContainer, eReference, eObject);
		}
		
		@Override
		@SuppressWarnings("unchecked")
		public synchronized @Nullable <G> G get(@NonNull ObjectManager objectManager, @NonNull EObject eObject, @NonNull EStructuralFeature eFeature) {
			switch (mode) {
				case ASSIGNABLE:
					mode = PropertyMode.ASSIGNED;
					unblock(objectManager);
					break;
				case ASSIGNED:
					break;
			}
			return (G) eObject.eGet(eFeature);
		}
	} */
	
	/**
	 * SlotState describing an M:N Object navigation.
	 */
	class ManyToManySlotState extends BasicSlotState
	{	
		public ManyToManySlotState(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
			super(eObject, eFeature);
			throw new UnsupportedOperationException();
		}

		@Override
		public synchronized void assigned(@NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			throw new UnsupportedOperationException();
		}
	}
	
	/**
	 * SlotState describing the aggregator side of a 1:N Object navigation.
	 * <br>
	 * Lifecycle:
	 * Create due to
	 * - get of all elements => ASSIGNABLE, blocked
	 * NO: - get of an aggregator => ASSIGNABLE, blocked
	 * Create due to
	 * - assign of all elements => ASSIGNABLE => ASSIGNED, not blocked
	 * - assign of a first element to the aggregator => ASSIGNABLE, not blocked
	 * Update due to
	 * - assign of a further element to the aggregator => ASSIGNABLE => ASSIGNABLE
	 * Unblock due to
	 * - get of an aggregator ASSIGNABLE => ASSIGNED
	 * - get of all elements ASSIGNABLE => ASSIGNED
	 * Thereafter
	 * - get of an aggregator ASSIGNED => ASSIGNED
	 * - get of all elements ASSIGNED => ASSIGNED
	 * <br>
	 * Lifecycle 2: read first
	 * Create due to
	 * - get of elements => ASSIGNABLE, blocked
	 * Unblock due to
	 * - assign of an element to the aggregator => ASSIGNABLE => ASSIGNED, not blocked
	 * Thereafter
	 * - get of either end ASSIGNED => ASSIGNED
	 * - (assign of either end is an ignored error)
	 */
	class OneToManyAggregatorSlotState extends BasicSlotState
	{

//		public static @NonNull  SlotState create(@NonNull ObjectManager objectManager,
//				EObject eObject, @NonNull EReference eFeature, EReference eOppositeReference, Object ecoreValue) {
//			// TODO Auto-generated method stub
//			return null;
//		}
		
		public OneToManyAggregatorSlotState(@NonNull Object eContainer, @NonNull EStructuralFeature eFeature) {
			super(eContainer, eFeature);
			assert eFeature.isMany();
//			assert eFeature.getEOpposite() != null;
//			assert eFeature.getEOpposite().isMany();
		}

		private OneToManyAggregatorSlotState(@NonNull Object eContainer, @NonNull EStructuralFeature eFeature, @Nullable Object eContents) {
			super(eContainer, eFeature, eContents);
			assert eFeature.isMany();
//			assert eFeature.getEOpposite() != null;
//			assert eFeature.getEOpposite().isMany();
			assert ((EObject)eContainer).eGet(eFeature).equals(eContents);
		}

		@Override
		public synchronized void assigned(@NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			assert ecoreValue != null;
			@SuppressWarnings("unchecked")
			List<? extends EObject> ecoreValues = (List<? extends EObject>)ecoreValue;
			EReference eOppositeReference = ((EReference)eFeature).getEOpposite();
			for (EObject element : ecoreValues) {
				if (element != null) {
					Map<EStructuralFeature, BasicSlotState> elementObjectState = getObjectState(element);
					elementObjectState.put(eOppositeReference, this);
				}
			}
//			super.assigned(objectManager, eObject, eFeature, ecoreValue);
			assignedElement(eObject, (EReference)eFeature, (EObject)ecoreValue);
		}
		
		public void assignedElement(@NonNull Object eContainer, @NonNull EReference eReference, Object eObject) {
//			super.assigned(objectManager, eContainer, eReference, eObject);
			switch (mode) {
				case ASSIGNABLE:
					mode = SlotMode.ASSIGNED;
					unblock(IncrementalObjectManager.this);
					break;
				case ASSIGNED:
					break;
			}
		}
		
		@Override
		public synchronized void getting(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
			switch (mode) {
				case ASSIGNABLE:
					mode = SlotMode.ASSIGNED;
					unblock(IncrementalObjectManager.this);
					break;
				case ASSIGNED:
					break;
			}
		}
	}
	
	/**
	 * SlotState describing the element side of a 1:N Object navigation.
	 * <br>
	 * Lifecycle (read first, write later):
	 * Create due to
	 * - get of an aggregator => ASSIGNABLE, blocked
	 * Unblock
	 * - assign of possibly null aggregator for the element, ASSIGNABLE, blocked => ASSIGNED, not blocked
	 * - non-null aggregator is notified to unblock 
	 * Thereafter
	 * - get of aggregator ASSIGNED => ASSIGNED
	 * <br>
	 * Lifecycle (write first):
	 * Create due to
	 * - assign of a possibly null aggregator => ASSIGNED, unblocked
	 * - non-null aggregator is notified to unblock 
	 * Thereafter
	 * - get of aggregator ASSIGNED => ASSIGNED
	 */
	class OneToManyElementSlotState extends BasicSlotState
	{
		public OneToManyElementSlotState(@NonNull Object eObject, @NonNull EReference eFeature) {
			super(eObject, eFeature);
			assert !eFeature.isMany();
			if (eFeature == OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
				assert eFeature.getEOpposite() == null;
			}
			else {
				assert eFeature.getEOpposite() != null;
				assert eFeature.getEOpposite().isMany();
			}
		}
		
		public OneToManyElementSlotState(@NonNull Object eObject, @NonNull EReference eFeature, @NonNull Object eAggregator) {
			super(eObject, eFeature, eAggregator);
			assert !eFeature.isMany();
			assert eFeature.getEOpposite() != null;
			assert eFeature.getEOpposite().isMany();
			if (eFeature == OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
				assert ((EObject)eObject).eContainer() == eAggregator;
			}
			else {
				assert ((EObject)eObject).eGet(eFeature) == eAggregator;
			}
		}

		@Override
		public synchronized void assigned(@NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			if (!isAssigned() && (ecoreValue != null)) {
				EObject eOpposite = (EObject) ecoreValue;
				EReference eOppositeReference = ((EReference)eFeature).getEOpposite();
				if (eFeature == OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
					eOppositeReference = ((EObject)eObject).eContainmentFeature();
					assert eOppositeReference != null;
					SlotState aggregatorSlotState = getSlotState(eOpposite, eOppositeReference);
					aggregatorSlotState.assigned(eOpposite, eOppositeReference, eObject);
				}
				else {
					assert eOppositeReference != null;
					OneToManyAggregatorSlotState aggregatorSlotState = (OneToManyAggregatorSlotState) getSlotState(eOpposite, eOppositeReference);
					aggregatorSlotState.assignedElement(eOpposite, eOppositeReference, eObject);
				}
			}
			assigned(eObject, eFeature, ecoreValue);
		}

		@Override
		public SlotState.@NonNull Incremental getPrimarySlotState() {
			EObject eOpposite = (EObject) getValue();
			assert eOpposite != null;
			EReference eOppositeReference = ((EReference)eFeature).getEOpposite();
			if (eFeature == OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
				eOppositeReference = ((EObject)eObject).eContainmentFeature();
				assert eOppositeReference != null;
				return getSlotState(eOpposite, eOppositeReference);
			}
			else {
				assert eOppositeReference != null;
				return getSlotState(eOpposite, eOppositeReference);
			}
		}
	}
	
	/**
	 * SlotState describing a 1:1 Object navigation. Both ends are assigned exactly once. The remote assignment
	 * may be null.
	 * <br>
	 * Lifecycle 1: write first
	 * Create due to
	 * - assign of possibly null eOpposite => ASSIGNED
	 * Thereafter
	 * - get of either end ASSIGNED => ASSIGNED
	 * - (assign of either end is an ignored error)
	 * <br>
	 * Lifecycle 2: read first
	 * Create due to
	 * - get of other end => ASSIGNABLE_BLOCKED
	 * Unblock due to
	 * - assign of a further element to the aggregator => ASSIGNABLE_BLOCKED => ASSIGNED
	 * Thereafter
	 * - get of either end ASSIGNED => ASSIGNED
	 * - (assign of either end is an ignored error)
	 */
	class OneToOneSlotState extends BasicSlotState
	{
/*		public static @NonNull <G,S> SlotState createContainer(@NonNull ObjectManager objectManager,
				@NonNull EObject eObject, @NonNull EReference eFeature, @Nullable EReference eOppositeFeature, @Nullable EObject eOpposite) {
			Map<EStructuralFeature, SlotState> oppositeObjectState = null;
			if (eOpposite != null) {
				oppositeObjectState = objectManager.getObjectState(eObject);
				SlotState slotState = oppositeObjectState.get(eOppositeFeature);
				if (slotState != null) {
					return slotState;
				}		
			}
			SlotState slotState = new OneToOneSlotState(eObject, eFeature, eOpposite);
			if (oppositeObjectState != null) {
				oppositeObjectState.put(eOppositeFeature, slotState);
			}
			return slotState;
		} */
		
		public OneToOneSlotState(@NonNull Object eObject, @NonNull EReference eFeature) {
			super(eObject, eFeature);
			assert !eFeature.isMany();
			if (eFeature.isContainer()) {
//				assert eObject.eContainer() == eOpposite;
			}
			else if (eFeature.isContainment()) {
//				assert eOpposite != null;
//				assert eObject == eOpposite.eContainer();
			}
			else if (eFeature == OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
//				slotState = new OneToOneSlotState(eObject, eReference);
			}
			else {
				assert eFeature.getEOpposite() != null;
				assert !eFeature.getEOpposite().isMany();
			}
		}

		private OneToOneSlotState(@NonNull Object eObject, @NonNull EReference eFeature, @Nullable Object eOpposite) {
			super(eObject, eFeature, eOpposite);
			assert !eFeature.isMany();
			if (eFeature.isContainer()) {
				assert ((EObject)eObject).eContainer() == eOpposite;
			}
			else if (eFeature.isContainment()) {
				assert eOpposite != null;
				assert eObject == ((EObject)eOpposite).eContainer();
			}
			else {
				assert eFeature.getEOpposite() != null;
				assert !eFeature.getEOpposite().isMany();
				assert ((EObject)eObject).eGet(eFeature) == eOpposite;
			}
		}

		@Override
		public void assigned(@NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			assigned(IncrementalObjectManager.this, eObject, eFeature, ecoreValue);
		}
	}
	
	/**
	 * Simple SlotState describing a DataType element or 1:1 Object navigation.
	 */
	class SimpleSlotState extends BasicSlotState
	{
		public SimpleSlotState(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
			super(eObject, eFeature);
		}

		public SimpleSlotState(@NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			super(eObject, eFeature, ecoreValue);
		}

		@Override
		public void assigned(@NonNull Object eObject, @NonNull EStructuralFeature eFeature, @Nullable Object ecoreValue) {
			assigned(IncrementalObjectManager.this, eObject, eFeature, ecoreValue);
		}
	}

	protected final boolean debugTracing = AbstractTransformer.INVOCATIONS.isActive();
	
	/**
	 * This unpleasant Map of Maps is a pathfinder before embarking on slotted objects that merge user and overhead
	 * in a single object. The first map is then a null lookup and the nested map is an index within the object. 
	 */
	private Map<@NonNull Object, @NonNull Map<@NonNull EStructuralFeature, @NonNull BasicSlotState>> object2feature2slotState = new HashMap<@NonNull Object, @NonNull Map<@NonNull EStructuralFeature, @NonNull BasicSlotState>>();
	
	public IncrementalObjectManager(@NonNull IncrementalInvocationManager invocationManager) {
		super(invocationManager);
	}

	@Override
	public synchronized void assigned(@NonNull Object eObject, /*@NonNull*/ EStructuralFeature eFeature, @Nullable Object ecoreValue, @Nullable Object childKey) {
		assert eFeature != null;
		if (debugTracing) {
			AbstractTransformer.INVOCATIONS.println("assigned " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject + " = " + ecoreValue);
		}
		Map<EStructuralFeature, BasicSlotState> objectState = getObjectState(eObject);
		BasicSlotState slotState = objectState.get(eFeature);
		if (slotState != null) {
			slotState.assigned(eObject, eFeature, ecoreValue);		
		}
		else {
			if (eFeature instanceof EAttribute) {
				slotState = new SimpleSlotState(eObject, eFeature, ecoreValue);
			}
			else {
				EReference eReference = (EReference)eFeature;
				EReference eOppositeReference = eReference.getEOpposite();
				if (eOppositeReference != null) {
//					if (ecoreValue != null) {
//						Map<EStructuralFeature, SlotState> oppositeObjectState = getObjectState((EObject) ecoreValue);
//						SlotState oppositeSlotState = oppositeObjectState.get(eOppositeReference);
//					}
					if (eReference.isMany()) {
						assert ecoreValue != null;
						if (eOppositeReference.isMany()) {
							slotState = createManyToManySlotState(eObject, eReference, eOppositeReference);
						}
						else {
							slotState = createOneToManyAggregatorSlotState(eObject, eReference, eOppositeReference, ecoreValue);
						}
					}
					else if (ecoreValue != null) {
						if (eOppositeReference.isMany()) {
							slotState = createOneToManyElementSlotState(eObject, eReference, eOppositeReference, ecoreValue);
						}
//						else if (isIncremental) {
//							slotState = AbstractTransformerInternal.OneToOneSlotState.create(this, eObject, eReference, eOppositeReference, ecoreValue);
//						}
					}
				}
				else if (eReference.isContainment()) {
					assert ecoreValue != null;
					eOppositeReference = OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER;
					assert eOppositeReference != null;
					if (eReference.isMany()) {
						slotState = createOneToManyAggregatorSlotState(eObject, eReference, eOppositeReference, ecoreValue);
					}
					else {
						Map<EStructuralFeature, BasicSlotState> oppositeObjectState = getObjectState(ecoreValue);
						slotState = oppositeObjectState.get(eOppositeReference);
						if (slotState != null) {
							slotState.assigned(ecoreValue, eOppositeReference, eObject);		
						}
						else {
							slotState = createOneToOneSlotState(eObject, eReference, eOppositeReference, ecoreValue);
						}
					}
				}
//				else if (eReference == OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
//					slotState = OneToOneSlotState.create(this, eObject, eReference, eOppositeReference, ecoreValue);
//				}
				else {						// Unidirectional non-containment EReference
					slotState = new SimpleSlotState(eObject, eFeature, ecoreValue);
				}
			}
			objectState.put(eFeature, slotState);
		}
	}

	@Override
	public void assigned(Invocation.@NonNull Incremental invocation, @NonNull Object eObject, EStructuralFeature eFeature, @Nullable Object ecoreValue, @Nullable Object childKey) {
		assigned(eObject, eFeature, ecoreValue, childKey);
		assert eFeature != null;
		BasicSlotState slotState = getSlotState(eObject, eFeature);
		invocation.addWriteSlot(slotState);
	}

	@NonNull BasicSlotState createManyToManySlotState(
			@NonNull Object eObject, @NonNull EReference eFeature, @NonNull EReference eOppositeFeature) {
		throw new UnsupportedOperationException();
	}

	@NonNull BasicSlotState createOneToManyAggregatorSlotState(
			@NonNull Object eObject, @NonNull EReference eFeature, @NonNull EReference eOppositeFeature, @Nullable Object eContents) {
		if (eContents != null) {
//			SlotState containedSlotState = objectManager.getSlotState(eContent, eOppositeFeature);
//			containedSlotState.assigned(objectManager, eContent, eOppositeFeature, eObject);
		}
		return new OneToManyAggregatorSlotState(eObject, eFeature, eContents);
	}

	@NonNull BasicSlotState createOneToManyElementSlotState(
			@NonNull Object eObject, @NonNull EReference eFeature, @NonNull EReference eOppositeFeature, @NonNull Object eAggregator) {
		OneToManyAggregatorSlotState aggregatorSlotState = (OneToManyAggregatorSlotState) getSlotState(eAggregator, eOppositeFeature);
		aggregatorSlotState.assignedElement(eAggregator, eOppositeFeature, eObject);
		return new OneToManyElementSlotState(eObject, eFeature, eAggregator);
	}

	@NonNull <G,S> BasicSlotState createOneToOneSlotState(
			@NonNull Object eObject, @NonNull EReference eFeature, @NonNull EReference eOppositeFeature, @Nullable Object eOpposite) {
		Map<EStructuralFeature, BasicSlotState> oppositeObjectState = null;
		if (eOpposite != null) {
			oppositeObjectState = getObjectState(eOpposite);
			BasicSlotState slotState = oppositeObjectState.get(eOppositeFeature);
			if (slotState != null) {
				return slotState;
			}
		}
		BasicSlotState slotState = new OneToOneSlotState(eObject, eFeature, eOpposite);
		if (oppositeObjectState != null) {
			oppositeObjectState.put(eOppositeFeature, slotState);
		}
		return slotState;
	}

	@Override
	public void created(Invocation.@NonNull Incremental invocation, @NonNull Object eObject) {
		invocation.addCreatedObject(eObject);
	}

	public @NonNull Map<EStructuralFeature, BasicSlotState> getObjectState(@NonNull Object eObject) {
		Map<@NonNull EStructuralFeature, @NonNull BasicSlotState> feature2state = object2feature2slotState.get(eObject);
		if (feature2state == null) {
			feature2state = new HashMap<@NonNull EStructuralFeature, @NonNull BasicSlotState>();
			object2feature2slotState.put(eObject, feature2state);
		}
		return feature2state;
	}

	@Override
	public @NonNull Iterable<@NonNull ? extends Object> getObjects() {
		return object2feature2slotState.keySet();
	}

	public synchronized @NonNull BasicSlotState getSlotState(@NonNull Object eObject, @NonNull EStructuralFeature eFeature) {
		assert eFeature != null;
		Map<EStructuralFeature, BasicSlotState> objectState = getObjectState(eObject);
		BasicSlotState slotState = objectState.get(eFeature);
		if (slotState == null) {
			if (eFeature instanceof EAttribute) {
				slotState = new SimpleSlotState(eObject, eFeature);
			}
			else {
				EReference eReference = (EReference)eFeature;
				EReference eOppositeReference = eReference.getEOpposite();			// FIXME there is always a Pivot opposite
				if (eOppositeReference != null) {
					if (eReference.isMany()) {
						if (eOppositeReference.isMany()) {
							slotState = new ManyToManySlotState(eObject, eReference);
						}
						else {
							slotState = new OneToManyAggregatorSlotState(eObject, eReference);
						}
					}
					else {
						if (eOppositeReference.isMany()) {
							slotState = new OneToManyElementSlotState(eObject, eReference);
						}
						else {
							slotState = new OneToOneSlotState(eObject, eReference);
						}
					}
				}
				else if (eReference.isContainment()) {
					if (eReference.isMany()) {
						slotState = new OneToManyAggregatorSlotState(eObject, eReference);
					}
					else {
						slotState = new OneToOneSlotState(eObject, eReference);
					}
				}
				else if (eReference == OCLstdlibPackage.Literals.OCL_ELEMENT__OCL_CONTAINER) {
					slotState = new OneToManyElementSlotState(eObject, eReference); //FIXME may be many
				}
				else {						// Unidirectional non-containment EReference
					slotState = new SimpleSlotState(eObject, eFeature);
				}
			}
			objectState.put(eFeature, slotState);
		}
		return slotState;
	}

	@Override
	public @NonNull Iterable<@NonNull ? extends SlotState> getSlotStates(@NonNull Object object) {
		Map<@NonNull EStructuralFeature, @NonNull BasicSlotState> feature2slotState = object2feature2slotState.get(object);;
		return feature2slotState != null ? feature2slotState.values() : EMPTY_SLOT_STATE_LIST;
	}

	@Override
	public synchronized void getting(@NonNull Object eObject, /*@NonNull*/ EStructuralFeature eFeature, boolean isOpposite) {
		assert eFeature != null;
		if (debugTracing) {
			AbstractTransformer.INVOCATIONS.println("getting " + eFeature.getEContainingClass().getName() + "::" + eFeature.getName() + " for " + eObject);
		}
		SlotState slotState = getSlotState(eObject, eFeature);
		slotState.getting(eObject, eFeature);
	}

	@Override
	public void got(Invocation.@NonNull Incremental invocation, @NonNull Object eObject, /*@NonNull*/ EStructuralFeature eFeature, @Nullable Object ecoreValue) {
		assert eFeature != null;
		BasicSlotState slotState = getSlotState(eObject, eFeature);
		invocation.addReadSlot(slotState);
	}
}