/*******************************************************************************
 * Copyright (c) 2015, 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.qvtd.pivot.qvtimperative.evaluation;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.util.URI;
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.utilities.ClassUtil;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphMLStringBuilder;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphEdge;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphElement;
import org.eclipse.qvtd.pivot.qvtbase.graphs.GraphStringBuilder.GraphNode;
import org.eclipse.qvtd.pivot.qvtbase.graphs.ToGraphHelper;
import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.AssociationStatus;
import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.AttributeStatus;
import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.ClassStatus;
import org.eclipse.qvtd.pivot.qvtimperative.evaluationstatus.PropertyStatus;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleConstants;
import org.eclipse.qvtd.pivot.qvtschedule.utilities.QVTscheduleUtil;
import org.eclipse.qvtd.runtime.evaluation.AbstractExecutionVisitor;
import org.eclipse.qvtd.runtime.evaluation.AbstractObjectManager;
import org.eclipse.qvtd.runtime.evaluation.Computation;
import org.eclipse.qvtd.runtime.evaluation.Connection;
import org.eclipse.qvtd.runtime.evaluation.Execution;
import org.eclipse.qvtd.runtime.evaluation.Interval;
import org.eclipse.qvtd.runtime.evaluation.Invocation;
import org.eclipse.qvtd.runtime.evaluation.InvocationConstructor;
import org.eclipse.qvtd.runtime.evaluation.InvocationManager;
import org.eclipse.qvtd.runtime.evaluation.ObjectManager;
import org.eclipse.qvtd.runtime.evaluation.SlotState;
import org.eclipse.qvtd.runtime.evaluation.Transformer;

import com.google.common.collect.Iterables;

public class Execution2GraphVisitor extends AbstractExecutionVisitor<@Nullable Object> implements ToGraphHelper
{
	protected static final class ExecutionEdge implements GraphEdge
	{
		private final @NonNull GraphNode sourceNode;
		private final @NonNull GraphNode targetNode;
		private final @NonNull String color;
		private final @Nullable String style;

		protected ExecutionEdge(@NonNull GraphNode sourceNode, @NonNull GraphNode targetNode, @NonNull String color, @Nullable String style) {
			this.sourceNode = sourceNode;
			this.targetNode = targetNode;
			this.color = color;
			this.style = style;
		}

		@Override
		public void appendEdgeAttributes(@NonNull ToGraphHelper toGraphHelper, @NonNull String sourceName, @NonNull String targetName) {
			GraphStringBuilder s = toGraphHelper.getGraphStringBuilder();
			toGraphHelper.setColor(this);
			if (style != null) {
				s.setStyle(style);
			}
			s.appendAttributedEdge(sourceName, this, targetName);
		}

		@Override
		public @NonNull String getColor() {
			return color;
		}

		@Override
		public @NonNull GraphNode getEdgeSource() {
			return sourceNode;
		}

		@Override
		public @NonNull GraphNode getEdgeTarget() {
			return targetNode;
		}
	}

	protected static final class ExecutionNode implements GraphNode
	{
		private final @NonNull String label;
		private final @NonNull String color;
		private final @NonNull String shape;
		private final @Nullable String style;

		protected ExecutionNode(@NonNull String label, @NonNull String color, @NonNull String shape, @Nullable String style) {
			this.label = label;
			this.color = color;
			this.shape = shape;
			this.style = style;
		}

		@Override
		public void appendNode(@NonNull ToGraphHelper toGraphHelper, @NonNull String nodeName) {
			GraphStringBuilder s = toGraphHelper.getGraphStringBuilder();
			s.setLabel(label);
			s.setShape(shape);
			if (style != null) {
				s.setStyle(style);
			}
			toGraphHelper.setColor(this);
			s.appendAttributedNode(nodeName);
		}

		@Override
		public @NonNull String getColor() {
			return color;
		}
	};

	protected static @NonNull String NULL_PLACEHOLDER = "\"<null>\""; //$NON-NLS-1$

	public static void writeGraphMLfile(Transformer tx, @NonNull URI graphmlURI) {
		try {
			OutputStream outputStream = tx.getExecutor().getEnvironmentFactory().getResourceSet().getURIConverter().createOutputStream(graphmlURI);
			GraphMLStringBuilder s = new GraphMLStringBuilder();
			Execution2GraphVisitor execution2GraphVisitor = new Execution2GraphVisitor(s);
			tx.accept(execution2GraphVisitor);
			outputStream.write(s.toString().getBytes());
			outputStream.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	protected final @NonNull GraphStringBuilder context;

	private Map<@NonNull AssociationStatus, @NonNull String> associationId = new HashMap<>();
	private Map<@NonNull ClassStatus, @NonNull String> classId = new HashMap<>();
	private Map<@NonNull Computation, @NonNull GraphNode> computation2node = new HashMap<>();
	private Map<@NonNull Connection, @NonNull GraphNode> connection2node = new HashMap<>();
	private Map<@NonNull Interval, @NonNull GraphNode> interval2node = new HashMap<>();
	private Map<@NonNull Invocation, @NonNull GraphNode> invocation2node = new HashMap<>();
	private Map<@NonNull InvocationConstructor, @NonNull GraphNode> invocationConstructor2node = new HashMap<>();
	private Map<@NonNull Object, @NonNull GraphNode> object2node = new HashMap<>();
	private Map<@NonNull SlotState, @NonNull GraphNode> slot2node = new HashMap<>();
	//	private Map<@NonNull String, @NonNull String> propertyId2associationId = new HashMap<>();
	//	private Map<@NonNull String, @NonNull PropertyStatus> associationId2propertyStatus = new HashMap<>();

	public Execution2GraphVisitor(@NonNull GraphStringBuilder s) {
		this.context = s;
	}

	protected void appendEdge(@NonNull GraphNode sourceNode, @NonNull GraphNode targetNode, @NonNull String color, @Nullable String style) {
		context.appendEdge(this, sourceNode, new ExecutionEdge(sourceNode, targetNode, color, style), targetNode);
	}

	protected @NonNull String appendNode(@NonNull GraphNode node) {
		return context.appendNode(this, node);
	}

	protected @NonNull String getAssociationColor(@NonNull AssociationStatus associationStatus) {
		if (associationStatus.isIsInput()) {
			return associationStatus.isIsOutput() ? "#ccffff" : "#ccff00";
		}
		else {
			return associationStatus.isIsOutput() ? "#cc80ff" : "#cc0000";
		}
	}

	protected @NonNull String getAssociationId(@NonNull AssociationStatus object) {
		String id = associationId.get(object);
		if (id == null) {
			id = "a" + associationId.size()+1;
			associationId.put(object, id);
		}
		return id;
	}

	protected String getAssociationLabel(@NonNull AssociationStatus associationStatus) {
		EReference forwardReference = associationStatus.getForwardEReference();
		EReference oppositeReference = forwardReference.getEOpposite();
		String firstName = forwardReference.getName();
		String secondName = oppositeReference.getName();
		boolean swap = false;
		if (forwardReference.isMany() != oppositeReference.isMany()) {
			swap = forwardReference.isMany();
		}
		else {
			swap = firstName.compareTo(secondName) > 0;
		}
		return swap ? secondName + " / " + firstName : firstName + " / " + secondName;
	}

	protected @NonNull String getAttributeId(@NonNull AttributeStatus attributeStatus) {
		ClassStatus classStatus = attributeStatus.getOwningClassStatus();
		assert classStatus != null;
		return getClassId(classStatus) + "-" + attributeStatus.getEFeature().getName();
	}

	protected @NonNull String getClassColor(@NonNull ClassStatus classStatus) {
		if (classStatus.isIsInput()) {
			return classStatus.isIsOutput() ? "#ccffff" : "#ccff00";
		}
		else {
			return classStatus.isIsOutput() ? "#cc80ff" : "#cc0000";
		}
	}

	protected @NonNull String getClassId(@NonNull ClassStatus object) {
		String id = classId.get(object);
		if (id == null) {
			id = object.getType().getName() + "-" + (classId.size() + 1);
			classId.put(object, id);
		}
		return id;
	}

	protected @NonNull GraphNode getComputationNode(@NonNull Computation object) {
		GraphNode node = computation2node.get(object);
		if (node == null) {
			//			id = object.getReferredMappingCall().getReferredMapping().getName() + "-" + (mappingId.size() + 1);
			final String label = object.getName();
			//			final String label;
			//			if (object instanceof EObject) {
			//				label = ((EObject)object).eClass().getName() + "-" + (invocation2node.size() + 1);
			//			}
			//			else {
			//				label = object.toString().replace("@",  "\n@");
			//				label = object.getClass().getSimpleName() + "-" + (invocation2node.size() + 1);
			//			}
			node = new ExecutionNode(label, "brown", "hexagon", null);
			computation2node.put(object, node);
			appendNode(node);
		}
		return node;
	}

	protected @NonNull GraphNode getConnectionNode(@NonNull Connection object) {
		GraphNode node = connection2node.get(object);
		if (node == null) {
			String label = QVTscheduleUtil.getName(object);
			node = new ExecutionNode(label, "blue", "ellipse", null);
			connection2node.put(object, node);
			appendNode(node);
		}
		return node;
	}

	protected @NonNull GraphNode getExecutionNode(@NonNull Execution object) {
		if (object instanceof Computation) {
			return  getComputationNode((@NonNull Computation) object);
		}
		else if (object instanceof Invocation) {
			return  getInvocationNode((@NonNull Invocation) object);
		}
		else {
			throw new UnsupportedOperationException();
		}
	}

	@Override
	public @NonNull GraphStringBuilder getGraphStringBuilder() {
		return context;
	}

	protected @NonNull GraphNode getIntervalNode(@NonNull Interval object) {
		GraphNode node = interval2node.get(object);
		if (node == null) {
			final String label = "          " + object.getName() + "          ";
			node = new ExecutionNode(label, "black", "octagon", null);
			interval2node.put(object, node);
			appendNode(node);
		}
		return node;
	}

	protected @NonNull GraphNode getInvocationConstructorNode(@NonNull InvocationConstructor object) {
		GraphNode node = invocationConstructor2node.get(object);
		if (node == null) {
			final String label = object.getName();
			node = new ExecutionNode(label, "brown", "hexagon", null);
			invocationConstructor2node.put(object, node);
			appendNode(node);
		}
		return node;
	}

	protected @NonNull GraphNode getInvocationNode(@NonNull Invocation object) {
		GraphNode node = invocation2node.get(object);
		if (node == null) {
			//			id = object.getReferredMappingCall().getReferredMapping().getName() + "-" + (mappingId.size() + 1);
			final String label = object.getName();
			//			final String label;
			//			if (object instanceof EObject) {
			//				label = ((EObject)object).eClass().getName() + "-" + (invocation2node.size() + 1);
			//			}
			//			else {
			//				label = object.toString().replace("@",  "\n@");
			//				label = object.getClass().getSimpleName() + "-" + (invocation2node.size() + 1);
			//			}
			node = new ExecutionNode(label, "orange", "hexagon", null);
			invocation2node.put(object, node);
			appendNode(node);
		}
		return node;
	}

	protected @NonNull GraphNode getObjectNode(@NonNull Object object) {
		GraphNode node = object2node.get(object);
		if (node == null) {
			//			id = object.getReferredMappingCall().getReferredMapping().getName() + "-" + (mappingId.size() + 1);
			final String label;
			if (object instanceof EObject) {
				label = ((EObject)object).eClass().getName() + "-" + (object2node.size() + 1);
			}
			else {
				label = object.toString().replace("@",  "\n@");
				//				label = object.getClass().getSimpleName() + "-" + (invocation2node.size() + 1);
			}
			node = new ExecutionNode(label, "blue", "rectangle", null);
			object2node.put(object, node);
			appendNode(node);
		}
		return node;
	}

	protected @NonNull String getPropertyId(@NonNull PropertyStatus object) {
		if (object instanceof AssociationStatus) {
			return getAssociationId((AssociationStatus) object);
		}
		else if (object instanceof AttributeStatus) {
			return getAttributeId((AttributeStatus)object);
		}
		else {
			throw new UnsupportedOperationException();
		}
	}

	protected @NonNull GraphNode getSlotNode(SlotState.@NonNull Incremental object) {
		if (object.getValue() != AbstractObjectManager.NOT_A_VALUE) {
			object = object.getPrimarySlotState();
		}
		GraphNode node = slot2node.get(object);
		if (node == null) {
			final EStructuralFeature eFeature = object.getEFeature();
			String label = ClassUtil.nonNullState(eFeature.getName());
			if (eFeature instanceof EReference) {
				EReference eOpposite = ((EReference)eFeature).getEOpposite();
				if (eOpposite != null) {
					label += " / " + eOpposite.getName();
				}
			}
			else if (eFeature instanceof EAttribute) {
				Object value = object.getValue();	// FIXME may be null for inputs, and some slots seem crooked
				String stringValue = value != null ? value.toString() : "???";
				if (stringValue.length() > 20) {
					stringValue = stringValue.substring(0, 17) + "...";
				}
				label += "  \n  " + stringValue;
			}
			node = new ExecutionNode(label, "blue", "rectangle", "rounded");
			slot2node.put(object, node);
			appendNode(node);
		}
		return node;
	}

	@Override
	public void setColor(@NonNull GraphElement element) {
		context.setColor(element.getColor());
	}

	@Override
	public void setHead(@NonNull GraphNode graphNode) {
		boolean isHead = false;
		if (graphNode instanceof Node) {
			Node node = (Node) graphNode;
			isHead = node.isHead();
		}
		if (isHead) {
			context.setHead();
		}
	}

	@Override
	public void setLabel(@NonNull GraphNode graphNode) {
		if (graphNode instanceof Node) {
			Node node = (Node) graphNode;
			context.setLabel(node.getLabel());
		}
	}

	@Override
	public void setPenwidth(@NonNull GraphNode graphNode) {
		boolean isHead = false;
		boolean isExpression = false;
		if (graphNode instanceof Node) {
			Node node = (Node) graphNode;
			isHead = node.isHead();
			isExpression = node.isExpression();
		}
		context.setPenwidth(isHead ? QVTscheduleConstants.HEAD_WIDTH : !isExpression ? 2*QVTscheduleConstants.LINE_WIDTH : QVTscheduleConstants.LINE_WIDTH);
	}

	@Override
	public void setShapeAndStyle(@NonNull GraphNode graphNode) {
		String shape = null;
		String style = null;
		if (graphNode instanceof Node) {
			Node node = (Node)graphNode;
			shape = node.getShape();
			style = node.getStyle();
		}
		if (shape != null) {
			context.setShape(shape);
		}
		if (style != null) {
			context.setStyle(style);
		}
	}

	@Override
	public @Nullable String visitComputation(@NonNull Computation object) {
		@SuppressWarnings("unused")
		GraphNode computationNode = getComputationNode(object);
		return null;
	}

	@Override
	public @Nullable Object visitConnection(@NonNull Connection object) {
		GraphNode connectionNode = getConnectionNode(object);
		if (object instanceof Connection.Incremental) {
			for (@NonNull InvocationConstructor producer : ((Connection.Incremental)object).getAppenders()) {
				GraphNode producerNode = getInvocationConstructorNode(producer);
				appendEdge(producerNode, connectionNode, "brown", null);
			}
		}
		for (@NonNull InvocationConstructor consumer : object.getConsumers()) {
			GraphNode consumerNode = getInvocationConstructorNode(consumer);
			appendEdge(connectionNode, consumerNode, "brown", null);
		}
		int iMax = object.getValues();
		for (int i = 0; i < iMax; i++) {
			Object value = object.getValue(i);
			if (value != null) {
				GraphNode objectNode = getObjectNode(value);
				appendEdge(connectionNode, objectNode, "blue", "dotted");
				//			for (@NonNull Invocation invocation : object.getConsumers(i)) {
				//				GraphNode consumerNode = getInvocationNode(invocation);
				//			}
			}
		}
		return null;
	}

	/*	@Override
	public String visiting(@NonNull EvaluationElement visitable) {
//		append(visitable.getClass().getName());
		return null;
	} */

	/*	@Override
	public @Nullable String visitAssociationStatus(@NonNull AssociationStatus object) {
		String associationId = getAssociationId(object);
		String fillColor = object.isIsError() ? "#ff0000" : getAssociationColor(object);
		String label = getAssociationLabel(object);
		appendNode(associationId, "rectangle", fillColor, 30, 100, label);
		for (ClassStatus classStatus : object.getFromClassStatuses()) {
			if (classStatus != null) {
				String classId = getClassId(classStatus);
				context.appendEdge(classId, associationId, "#339966", "line","diamond", "none");
			}
		}
		for (ClassStatus classStatus : object.getToClassStatuses()) {
			if (classStatus != null) {
				String classId = getClassId(classStatus);
				context.appendEdge(classId, associationId, "#339966", "line","diamond", "none");
			}
		}
		return null;
	} */

	/*	@Override
	public @Nullable String visitAttributeStatus(@NonNull AttributeStatus object) {
		ClassStatus classStatus = object.getOwningClassStatus();
		assert classStatus != null;
		String classId = getClassId(classStatus);
		String attributeId = getAttributeId(object);
		String fillColor = object.isIsError() ? "#ff0000" : getClassColor(classStatus);
		EStructuralFeature eFeature = object.getEFeature();
		String label = eFeature.getName();
		EClassifier type = eFeature.getEType();
//		if (type instanceof DataType) {
//			Type behavioralType = ((DataType)type).getBehavioralClass();
//			if (behavioralType != null) {
//				type = behavioralType;
//			}
//		}
		if (type instanceof EDataType) {
			label = label + "\n" + String.valueOf(object.getObject());
		}
		appendNode(attributeId, "rectangle", fillColor, 30, 50, label);
		context.appendEdge(classId, attributeId, "#339966", "line","diamond", "none");
		return null;
	} */

	/*	@Override
	public @Nullable String visitClassStatus(@NonNull ClassStatus object) {
		String classId = getClassId(object);
		appendNode(classId, "rectangle", getClassColor(object), 30, 120, classId.replace("-",  "\n"));
		for (AttributeStatus attributeStatus : object.getOwnedAttributeStatuses()) {
			attributeStatus.accept(this);
		}
		return null;
	} */

	@Override
	public @Nullable Object visitInterval(@NonNull Interval object) {
		GraphNode intervalNode = getIntervalNode(object);
		for (@NonNull Connection connection : object.getConnections()) {
			connection.accept(this);
			GraphNode connectionNode = getConnectionNode(connection);
			appendEdge(connectionNode, intervalNode, "black", "dashed");
		}
		return null;
	}

	@Override
	public @Nullable String visitInvocation(@NonNull Invocation object) {
		GraphNode invocationNode = getInvocationNode(object);
		if (object instanceof Invocation.Incremental) {
			Invocation.Incremental invocation = (Invocation.Incremental)object;
			int iMax = invocation.getBoundValues();
			for (int i = 0; i < iMax; i++) {
				Object boundObject = invocation.getBoundValue(i);
				if (boundObject instanceof Connection) {
					GraphNode connectionNode = getConnectionNode((Connection) boundObject);
					appendEdge(invocationNode, connectionNode, "green", "dotted");
				}
				else {
					GraphNode objectNode = getObjectNode(boundObject);
					appendEdge(objectNode, invocationNode, "cyan", null);
				}
			}
		}
		/*		appendNode(mappingId, "hexagon", "#ffcc00", 30, 150, mappingId.replace("-",  "\n"));
			for (ElementStatus inputStatus : object.getInputs()) {
				if (inputStatus instanceof ClassStatus) {
					ClassStatus classStatus = (ClassStatus)inputStatus;
					String classId = getClassId(classStatus);
					context.appendEdge(classId, mappingId, "#000000", "line","none", "standard");
				}
				else if (inputStatus instanceof PropertyStatus) {
					PropertyStatus propertyStatus = (PropertyStatus)inputStatus;
					String propertyId = getPropertyId(propertyStatus);
					context.appendEdge(propertyId, mappingId, "#000000", "dashed","none", "standard");
				}
			}
			for (ElementStatus outputStatus : object.getOutputs()) {
				if (outputStatus instanceof ClassStatus) {
					ClassStatus classStatus = (ClassStatus)outputStatus;
					String classId = getClassId(classStatus);
					context.appendEdge(mappingId, classId, "#000000", "line","none", "standard");
				}
				else if (outputStatus instanceof PropertyStatus) {
					PropertyStatus propertyStatus = (PropertyStatus)outputStatus;
					String propertyId = getPropertyId(propertyStatus);
					context.appendEdge(mappingId, propertyId, "#000000", "dashed","none", "standard");
				}
			} */
		return null;
	}

	@Override
	public @Nullable Object visitInvocationConstructor(@NonNull InvocationConstructor object) {
		GraphNode invokerNode = getInvocationConstructorNode(object);
		GraphNode intervalNode = getIntervalNode(object.getInterval());
		appendEdge(invokerNode, intervalNode, "black", "dashed");
		for (@NonNull Invocation invocation : object.debugGetInvocations()) {
			GraphNode invocationNode = getInvocationNode(invocation);
			appendEdge(invokerNode, invocationNode, "orange", "dotted");
		}
		return null;
	}

	@Override
	public @Nullable String visitInvocationManager(@NonNull InvocationManager object) {
		GraphNode previousNode = null;
		for (@NonNull InvocationConstructor invoker : object.getInvokers()) {
			invoker.accept(this);
		}
		for (@NonNull Interval interval : object.getIntervals()) {
			interval.accept(this);
			GraphNode nextNode = getIntervalNode(interval);
			if (previousNode != null) {
				appendEdge(previousNode, nextNode, "black", null);
			}
			previousNode = nextNode;
		}
		return null;
	}

	@Override
	public @Nullable String visitObjectManager(@NonNull ObjectManager objectManager) {
		Set<Execution.@NonNull Incremental> allExecutions = new HashSet<>();
		Set<SlotState.@NonNull Incremental> allSlots = new HashSet<>();
		Map<@NonNull Object, @NonNull List<SlotState.@NonNull Incremental>> object2slots = new HashMap<>();
		for (@NonNull Object object : objectManager.getObjects()) {
			List<SlotState.@NonNull Incremental> objectSlots = new ArrayList<>();
			for (@NonNull SlotState slotState : objectManager.getSlotStates(object)) {
				if (slotState instanceof SlotState.Incremental) {
					allSlots.add((SlotState.Incremental)slotState);
					objectSlots.add((SlotState.Incremental)slotState);
				}
			}
			object2slots.put(object, objectSlots);
		}
		for (SlotState.@NonNull Incremental slotState : allSlots) {
			Iterables.addAll(allExecutions, slotState.getSources());
			Iterables.addAll(allExecutions, slotState.getTargets());
			slotState.accept(this);
		}
		for (Execution.@NonNull Incremental execution : allExecutions) {
			execution.accept(this);
			GraphNode invocationNode = getExecutionNode(execution);
			for (@NonNull Object createdObject : execution.getCreatedObjects()) {
				GraphNode objectNode = getObjectNode(createdObject);
				appendEdge(invocationNode, objectNode, "green", null);
			}
		}
		for (SlotState.@NonNull Incremental slotState : allSlots) {
			GraphNode slotNode = getSlotNode(slotState);
			slotState.accept(this);
			for (@NonNull Invocation invocation : slotState.getSources()) {
				appendEdge(getInvocationNode(invocation), slotNode, "green", "dashed");
			}
			for (@NonNull Execution invocation : slotState.getTargets()) {
				appendEdge(slotNode, getExecutionNode(invocation), "cyan", "dashed");
			}
			Iterables.addAll(allExecutions, slotState.getTargets());
		}
		for (@NonNull Object object : objectManager.getObjects()) {
			GraphNode objectNode = getObjectNode(object);
			List<SlotState.@NonNull Incremental> slots = object2slots.get(object);
			if (slots != null) {
				for (SlotState.@NonNull Incremental slotState : slots) {
					GraphNode slotNode = getSlotNode(slotState);
					slotState.accept(this);
					appendEdge(objectNode, slotNode, "blue", "dashed");
				}
			}
		}
		return null;
	}

	@Override
	public @Nullable String visitSlotState(@NonNull SlotState object) {
		//		GraphNode slotNode = getSlotNode((SlotState.@NonNull Incremental) object, "orange");
		return null;
	}

	@Override
	public @Nullable String visitTransformer(@NonNull Transformer transformer) {
		transformer.getInvocationManager().accept(this);
		transformer.getObjectManager().accept(this);
		return null;
	}

	/*	@Override
	public @Nullable String visitTransformationStatus(@NonNull TransformationStatus object) {
		context.open();
			for (ClassStatus classStatus : object.getOwnedClassStatuses()) {
				classStatus.accept(this);
			}
			for (MappingStatus mappingStatus : object.getOwnedMappingStatuses()) {
				mappingStatus.accept(this);
			}
			for (AssociationStatus associationStatus : object.getOwnedAssociationStatuses()) {
				associationStatus.accept(this);
			}
		context.close();
		return null;
	} */
}
