/*******************************************************************************
 * Copyright (c) 2010, 2013 E.D.Willink 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.xtext.base.as2cs;

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

import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.CompletePackage;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.Package;
import org.eclipse.ocl.pivot.PivotConstants;
import org.eclipse.ocl.pivot.PivotPackage;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.TemplateSignature;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.UMLReflection;
import org.eclipse.ocl.pivot.VoidType;
import org.eclipse.ocl.pivot.manager.MetaModelManager;
import org.eclipse.ocl.pivot.util.Visitable;
import org.eclipse.ocl.pivot.utilities.AbstractConversion;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.pivot.values.Unlimited;
import org.eclipse.ocl.xtext.base.as2cs.AS2CS.Factory;
import org.eclipse.ocl.xtext.base.utilities.BaseCSResource;
import org.eclipse.ocl.xtext.basecs.AnnotationCS;
import org.eclipse.ocl.xtext.basecs.BaseCSFactory;
import org.eclipse.ocl.xtext.basecs.BaseCSPackage;
import org.eclipse.ocl.xtext.basecs.ClassCS;
import org.eclipse.ocl.xtext.basecs.ConstraintCS;
import org.eclipse.ocl.xtext.basecs.DetailCS;
import org.eclipse.ocl.xtext.basecs.ElementCS;
import org.eclipse.ocl.xtext.basecs.ImportCS;
import org.eclipse.ocl.xtext.basecs.ModelElementCS;
import org.eclipse.ocl.xtext.basecs.MultiplicityBoundsCS;
import org.eclipse.ocl.xtext.basecs.MultiplicityStringCS;
import org.eclipse.ocl.xtext.basecs.NamedElementCS;
import org.eclipse.ocl.xtext.basecs.PackageCS;
import org.eclipse.ocl.xtext.basecs.PathElementCS;
import org.eclipse.ocl.xtext.basecs.PathElementWithURICS;
import org.eclipse.ocl.xtext.basecs.PathNameCS;
import org.eclipse.ocl.xtext.basecs.RootCS;
import org.eclipse.ocl.xtext.basecs.StructuralFeatureCS;
import org.eclipse.ocl.xtext.basecs.TemplateBindingCS;
import org.eclipse.ocl.xtext.basecs.TemplateSignatureCS;
import org.eclipse.ocl.xtext.basecs.TypedElementCS;
import org.eclipse.ocl.xtext.basecs.TypedRefCS;
import org.eclipse.ocl.xtext.basecs.TypedTypeRefCS;

public class AS2CSConversion extends AbstractConversion implements PivotConstants
{	
	private static final Logger logger = Logger.getLogger(AS2CSConversion.class);

	protected final @NonNull AS2CS converter;
	protected final @NonNull BaseDeclarationVisitor defaultDeclarationVisitor;
	protected final @NonNull BaseReferenceVisitor defaultReferenceVisitor;
	
	private org.eclipse.ocl.pivot.Class scope = null;

	private final @NonNull Map<EClass, BaseDeclarationVisitor> declarationVisitorMap = new HashMap<EClass, BaseDeclarationVisitor>();
	private final @NonNull Map<EClass, BaseReferenceVisitor> referenceVisitorMap = new HashMap<EClass, BaseReferenceVisitor>();
	private Map<Namespace, List<String>> importedNamespaces = null;

	/**
	 * The CS Resource currently being converted.
	 */
	private @Nullable BaseCSResource csResource = null;;
	
	public AS2CSConversion(@NonNull AS2CS converter) {
		super(converter.getMetaModelManager());
		this.converter = converter;
		this.defaultDeclarationVisitor = converter.createDefaultDeclarationVisitor(this);
		this.defaultReferenceVisitor = converter.createDefaultReferenceVisitor(this);
	}

	protected void addBooleanQualifier(@NonNull List<String> qualifiers, @NonNull DetailCS csDetail, @NonNull String csString) {
		EList<String> values = csDetail.getValues();
		if ((values.size() == 1) && Boolean.valueOf(values.get(0))) {
			qualifiers.add(csString);
		}
		else {
			qualifiers.add("!" + csString);
		}
	}

	public void createImports(@NonNull RootCS documentCS, @NonNull Map<Namespace, List<String>> importedNamespaces) {
		BaseCSResource csResource = (BaseCSResource) ClassUtil.nonNullState(documentCS.eResource());
		AliasAnalysis.dispose(csResource);			// Force reanalysis
		MetaModelManager metaModelManager = PivotUtil.findMetaModelManager(csResource);
		if (metaModelManager == null) {
			throw new IllegalStateException("No MetaModelManager");
		}
		AliasAnalysis aliasAnalysis = null;
		URI csURI = csResource.getURI();
		List<ImportCS> imports = new ArrayList<ImportCS>();
		for (Namespace importedNamespace : importedNamespaces.keySet()) {
			if (importedNamespace != null) {
				if (importedNamespace instanceof org.eclipse.ocl.pivot.Package){
					Package pivotPackage = metaModelManager.getCompletePackage((org.eclipse.ocl.pivot.Package)importedNamespace).getPivotPackage();
		//			ModelElementCS csElement = createMap.get(importedPackage);
		//			if ((csElement != null) && (csElement.eResource() == xtextResource)) {
		//				continue;		// Don't import defined packages
		//			}
					if (metaModelManager.getLibraries().contains(pivotPackage)) {
						continue;
					}
				}
				List<String> aliases = importedNamespaces.get(importedNamespace);
				if ((aliases == null) || aliases.isEmpty()) {
					if (aliasAnalysis == null) {
						aliasAnalysis = AliasAnalysis.getAdapter(csResource, metaModelManager);
					}
					String alias = aliasAnalysis.getAlias(importedNamespace, null);
					aliases = Collections.singletonList(alias);
				}
				EObject eObject = importedNamespace.getETarget();
				String importURI = null;
				if (eObject instanceof EPackage) {
					EPackage ePackage = (EPackage)eObject;
					Resource resource = ePackage.eResource();
					if (ClassUtil.isRegistered(resource)) {
						importURI = ePackage.getNsURI();
					}
				}
				if (importURI == null) {
					URI fullURI = EcoreUtil.getURI(eObject != null ? eObject : importedNamespace);
					URI deresolvedURI = fullURI.deresolve(csURI, true, true, false);
					importURI = deresolvedURI.toString();
				}
				for (String alias : aliases) {
					ImportCS importCS = BaseCSFactory.eINSTANCE.createImportCS();
					importCS.setName(alias);
					@SuppressWarnings("null") @NonNull PathNameCS csPathName = BaseCSFactory.eINSTANCE.createPathNameCS();
					importCS.setOwnedPathName(csPathName);
					List<PathElementCS> csPath = csPathName.getOwnedPathElements();
					PathElementWithURICS csSimpleRef = BaseCSFactory.eINSTANCE.createPathElementWithURICS();
					csPath.add(csSimpleRef);
					csSimpleRef.setReferredElement(importedNamespace);
					csSimpleRef.setUri(importURI);
					importCS.setPivot(importedNamespace);
					imports.add(importCS);
				}
			}
		}
		if (aliasAnalysis != null) {
			aliasAnalysis.dispose();
		}
		aliasAnalysis = AliasAnalysis.getAdapter(csResource, metaModelManager);
		for (ImportCS csImport : imports) {
			Namespace namespace = csImport.getReferredNamespace();
			String alias = csImport.getName();
			if ((namespace != null) && (alias == null)) {
				alias = aliasAnalysis.getAlias(namespace, null);
				if (alias == null) {
					String hint = null;
					if (namespace instanceof org.eclipse.ocl.pivot.Package) {
						hint = ((org.eclipse.ocl.pivot.Package)namespace).getNsPrefix();
					}
					if (hint == null) {
						String name = namespace.getName();
						if (name.length() > 0) {
							hint = name.substring(0, 1).toLowerCase() + name.substring(1);
						}
					}
					if (hint != null) {
						alias = aliasAnalysis.getAlias(namespace, hint);
					}
				}
				if (alias != null) {
					csImport.setName(alias);
				}
			}
		}
		Collections.sort(imports, new Comparator<ImportCS>()
		{
			@Override
			public int compare(ImportCS o1, ImportCS o2) {
				Namespace ns1 = o1.getReferredNamespace();
				Namespace ns2 = o2.getReferredNamespace();
				int d1 = PivotUtil.getContainmentDepth(ns1);
				int d2 = PivotUtil.getContainmentDepth(ns2);
				if (d1 != d2) {
					return d1 - d2;
				}
				String n1 = o1.getName();
				String n2 = o2.getName();
				return n1.compareTo(n2);
			}
		});
		documentCS.getOwnedImports().addAll(imports);
	}

	public @Nullable BaseCSResource getCSResource() {
		return csResource;
	}

	public @NonNull AS2CS getConverter() {
		return converter;
	}

	public @Nullable BaseDeclarationVisitor getDeclarationVisitor(@NonNull EClass eClass) {
		BaseDeclarationVisitor declarationVisitor = declarationVisitorMap.get(eClass);
		if ((declarationVisitor == null) && !declarationVisitorMap.containsKey(eClass)) {
			Factory factory = converter.getFactory(eClass);
			if (factory != null) {
				declarationVisitor = factory.createDeclarationVisitor(this);
			}
			else {
				declarationVisitor = defaultDeclarationVisitor;
			}
			declarationVisitorMap.put(eClass, declarationVisitor);
		}
		return declarationVisitor;
	}

	public @Nullable BaseReferenceVisitor getReferenceVisitor(@NonNull EClass eClass, @Nullable Namespace scope) {
		if (scope == null) {
			BaseReferenceVisitor referenceVisitor = referenceVisitorMap.get(eClass);
			if ((referenceVisitor == null) && !referenceVisitorMap.containsKey(eClass)) {
				Factory factory = converter.getFactory(eClass);
				if (factory != null) {
					referenceVisitor = factory.createReferenceVisitor(this, null);
				}
				else {
					referenceVisitor = defaultReferenceVisitor;
				}
				referenceVisitorMap.put(eClass, referenceVisitor);
			}
			return referenceVisitor;
		}
		else {
			Factory factory = converter.getFactory(eClass);
			if (factory != null) {
				return factory.createReferenceVisitor(this, scope);
			}
			else {
				return defaultReferenceVisitor;
			}
			
		}
	}

	public org.eclipse.ocl.pivot.Class getScope() {
		return scope;
	}

	protected List<TemplateBindingCS> getTemplateBindings(ElementCS csElement) {
		List<TemplateBindingCS> csTemplateBindings;
//		EObject container = csElement.eContainer();
//		if (container instanceof ElementCS) {			
//			csTemplateBindings = getTemplateBindings((ElementCS) container);
//		}
//		else {
			csTemplateBindings = new ArrayList<TemplateBindingCS>();
//		}
		if (csElement instanceof TypedTypeRefCS) {
			TypedTypeRefCS csTemplateableElement = (TypedTypeRefCS)csElement;
			TemplateBindingCS csTemplateBinding = csTemplateableElement.getOwnedBinding();
			if (csTemplateBinding != null) {
				csTemplateBindings.add(csTemplateBinding);
			}
		}
		return csTemplateBindings;
	}

	public void importNamespace(@NonNull Namespace importNamespace, @Nullable String alias) {
		Namespace primaryNamespace = metaModelManager.getPrimaryElement(importNamespace);
		List<String> aliases = importedNamespaces.get(primaryNamespace);
		if (aliases == null) {
			aliases = new ArrayList<String>();
			importedNamespaces.put(primaryNamespace, aliases);
		}
		if ((alias != null) && !aliases.contains(alias)) {
			aliases.add(alias);
		}
	}

	protected <T extends ClassCS> T refreshClassifier(@NonNull Class<T> csClass, /*@NonNull*/ EClass csEClass, @NonNull org.eclipse.ocl.pivot.Class object) {
		T csElement = refreshNamedElement(csClass, csEClass, object);
		List<ConstraintCS> csInvariants = visitDeclarations(ConstraintCS.class, object.getOwnedInvariants(), null);
		for (ConstraintCS csInvariant : csInvariants) {
			csInvariant.setStereotype(UMLReflection.INVARIANT);
		}
		refreshList(csElement.getOwnedConstraints(), csInvariants);
		TemplateSignature ownedTemplateSignature = object.getOwnedSignature();
		if (ownedTemplateSignature != null) {
			csElement.setOwnedSignature(visitDeclaration(TemplateSignatureCS.class, ownedTemplateSignature));
		}
		if (object.eIsSet(PivotPackage.Literals.CLASS__INSTANCE_CLASS_NAME)) {
			csElement.setInstanceClassName(object.getInstanceClassName());
		}
		else {
			csElement.eUnset(BaseCSPackage.Literals.CLASS_CS__INSTANCE_CLASS_NAME);
		}
		return csElement;
	}

	public <T extends ModelElementCS> T refreshElement(@NonNull Class<T> csClass, /*@NonNull*/ EClass csEClass, @NonNull Element object) {
		assert csClass == csEClass.getInstanceClass();
		EFactory eFactoryInstance = csEClass.getEPackage().getEFactoryInstance();
		ModelElementCS csElement = (ModelElementCS) eFactoryInstance.create(csEClass);
		if (!csClass.isAssignableFrom(csElement.getClass())) {
			throw new ClassCastException();
		}
		csElement.setPivot(object);
		@SuppressWarnings("unchecked")
		T castElement = (T) csElement;
		return castElement;
	}

	public <T extends NamedElementCS> T refreshNamedElement(@NonNull Class<T> csClass, /*@NonNull */EClass csEClass, @NonNull NamedElement object) {
		T csElement = refreshElement(csClass, csEClass, object);
		String name = object.getName();
		csElement.setName(name);
		refreshList(csElement.getOwnedAnnotations(), visitDeclarations(AnnotationCS.class, object.getOwnedAnnotations(), null));
		return csElement;
	}

	/**
	 * Assign a sequence of one or more path elements to csPathName that identify element with respect
	 * to scope.
	 * <br>
	 * For example A::B::C::D::E with respect to A::B::C::X::Y is D::E.
	 * <br>
	 * Validation is performed to check that the shortened name resolves to the same
	 * element.
	 * <br>
	 * For example if there is also an A::B::C::X::D::E, the scope is shortened to A::B so
	 * that the result is C::D::E.
	 */
	public void refreshPathName(@NonNull PathNameCS csPathName, @NonNull Element element, @Nullable Namespace scope) {//, @Nullable Resource csResource) {
		Namespace safeScope = scope;
		Element primaryElement = metaModelManager.getPrimaryElement(element);
		if ((safeScope != null) && (primaryElement instanceof Type)) {
			String name = ((Type)primaryElement).getName();
			for (EObject eObject = safeScope; eObject != null; eObject = eObject.eContainer()) {
				if (eObject instanceof Namespace) {
					safeScope = (Namespace) eObject;
				}
				if (eObject instanceof org.eclipse.ocl.pivot.Package) {
					CompletePackage completePackage = metaModelManager.getCompletePackage((org.eclipse.ocl.pivot.Package)eObject);
					org.eclipse.ocl.pivot.Class memberType = completePackage.getMemberType(name);
					if (memberType == primaryElement) {
						if ((eObject != scope) && (eObject != PivotUtil.getContainingPackage(scope))) {
							eObject = eObject.eContainer(); // If eObject is needed in path, optional scope is its container
						}
						if (eObject instanceof Namespace) {
							safeScope = (Namespace) eObject;
						}
						break;
					}
				}
			}
		}
		List<PathElementCS> csPath = csPathName.getOwnedPathElements();
		csPath.clear();		// FIXME re-use
		PathElementCS csSimpleRef = BaseCSFactory.eINSTANCE.createPathElementCS();
		csPath.add(csSimpleRef);
		csSimpleRef.setReferredElement(primaryElement);
		BaseCSResource csResource2 = this.csResource;
		if ((csResource2 == null) || (csResource2.isPathable(primaryElement) == null)) {
			return;
		}
		for (EObject eContainer = primaryElement.eContainer(); eContainer instanceof Element; eContainer = eContainer.eContainer()) {
			if (eContainer instanceof Model) {
				return;				// Skip root package
			}
			for (EObject aScope = safeScope; aScope != null; aScope = aScope.eContainer()) {
				if (metaModelManager.getPrimaryElement(aScope) == metaModelManager.getPrimaryElement(eContainer)) { 		// If element ancestor is scope or an ancestor
					return;							// no need for further qualification
				}
			}
			csSimpleRef = BaseCSFactory.eINSTANCE.createPathElementCS();
			csPath.add(0, csSimpleRef);
			csSimpleRef.setReferredElement((Element) eContainer);
		}
	}

	public void refreshQualifiers(List<String> qualifiers, String string, boolean polarity) {
		for (String qualifier : qualifiers) {
			if (qualifier.equals(string)) {
				if (!polarity) {
					qualifiers.remove(qualifier);
				}
				return;		
			}
		}
		if (polarity) {
			qualifiers.add(string);
		}
	}

	public <T extends StructuralFeatureCS> T refreshStructuralFeature(@NonNull Class<T> csClass, /*@NonNull */EClass csEClass, @NonNull Property object) {
		T csElement = refreshTypedElement(csClass, csEClass, object);
		csElement.setIsDerived(object.isDerived());
		csElement.setIsReadonly(object.isReadOnly());
		csElement.setIsStatic(object.isStatic());
		csElement.setIsTransient(object.isTransient());
		csElement.setIsUnsettable(object.isUnsettable());
		csElement.setIsVolatile(object.isVolatile());
		csElement.setDefault(object.getDefaultValueString());
		return csElement;
	}
	
	public <T extends TypedElementCS> T refreshTypedElement(@NonNull Class<T> csClass, /*@NonNull */EClass csEClass, @NonNull TypedElement object) {
		T csElement = refreshNamedElement(csClass, csEClass, object);
		final Type type = object.getType();
		final Type elementType;
		if ((type instanceof CollectionType) && (((CollectionType)type).getUnspecializedElement() != standardLibrary.getCollectionType())) {
			PivotUtil.debugWellContainedness(type);
			elementType = ((CollectionType)type).getElementType();
		}
		else if (type instanceof VoidType) {
			elementType = null;
		}
		else {
			elementType = type;
		}
		if (elementType != null) {
			PivotUtil.debugWellContainedness(elementType);
			TypedRefCS typeRef = visitReference(TypedRefCS.class, elementType, null);
			csElement.setOwnedType(typeRef);
		}
		else {
			csElement.setOwnedType(null);
		}
		TypedRefCS csTypeRef = csElement.getOwnedType();
		if (csTypeRef != null) {
			int lower;
			int upper;
			if ((type instanceof CollectionType) && (((CollectionType)type).getUnspecializedElement() != standardLibrary.getCollectionType())) {
				CollectionType collectionType = (CollectionType)type;
				lower = collectionType.getLower().intValue();
				Number upper2 = collectionType.getUpper();
				upper = upper2 instanceof Unlimited ? -1 : upper2.intValue();
				csElement.setIsOrdered(collectionType.isOrdered());
				csElement.setIsNotUnique(!collectionType.isUnique());
			}
			else {
				lower = object.isRequired() ? 1 : 0;
				upper = 1;
			}
			if ((lower == 1) && (upper == 1)) {
				csTypeRef.setOwnedMultiplicity(null);
			}
			else {
				String stringValue = null;
				if (lower == 0) {
					if (upper == 1) {
						stringValue = "?";
					}
					else if (upper == -1) {
						stringValue = "*";				
					}
		//			else if (upper == -2) {
		//				stringValue = "0..?";				
		//			}
				}
				else if (lower == 1) {
					if (upper == -1) {
						stringValue = "+";				
					}
				}
				if (stringValue != null) {
					MultiplicityStringCS csMultiplicity = BaseCSFactory.eINSTANCE.createMultiplicityStringCS();
					csMultiplicity.setStringBounds(stringValue);
					csTypeRef.setOwnedMultiplicity(csMultiplicity);
				}
				else {
					MultiplicityBoundsCS csMultiplicity = BaseCSFactory.eINSTANCE.createMultiplicityBoundsCS();
					if (lower != 1) {
						csMultiplicity.setLowerBound(lower);
					}
					if (upper != 1) {
						csMultiplicity.setUpperBound(upper);
					}
					csTypeRef.setOwnedMultiplicity(csMultiplicity);
				}
			}
		}
		return csElement;
	}

	public org.eclipse.ocl.pivot.Class setScope(org.eclipse.ocl.pivot.Class object) {
		org.eclipse.ocl.pivot.Class savedScope = scope;
		this.scope = object;
		return savedScope;
	}

	/**
	 * Sequence the update passes to make the pivot match the CS.
	 * @param csResources 
	 */
	public void update(@NonNull BaseCSResource csResource) {
		this.csResource = csResource;
//		Map<Resource, Map<Namespace, List<String>>> imports = new HashMap<Resource, Map<Namespace, List<String>>>();
		//
		//	Perform the pre-order traversal to create the CS for each declaration. A
		//	separate reference pass is not needed since references are to the pivot model.
		//
		importedNamespaces = new HashMap<Namespace, List<String>>();
		Resource asResource = converter.getPivotResource(csResource);
		if (asResource != null) {
			List<PackageCS> list = visitDeclarations(PackageCS.class, asResource.getContents(), null);
			refreshList(csResource.getContents(), list);
			if (importedNamespaces != null) {
				defaultDeclarationVisitor.postProcess(csResource, importedNamespaces);
			}
//			imports.put(csResource, importedNamespaces);
		}
	}

	public @Nullable <T extends ElementCS> T visitDeclaration(@NonNull Class<T> csClass, @Nullable EObject eObject) {
		if (eObject == null) {
			return null;
		}
		@SuppressWarnings("null") @NonNull EClass eClass = eObject.eClass();
		BaseDeclarationVisitor declarationVisitor = getDeclarationVisitor(eClass);
		if ((declarationVisitor == null) || !(eObject instanceof Visitable)) {
			logger.warn("Unsupported declaration " + eClass.getName());
			return null;
		}
		ElementCS csElement = ((Visitable)eObject).accept(declarationVisitor);
		@SuppressWarnings("unchecked")
		T castElement = (T) csElement;
		return castElement;
	}

	public @Nullable <T extends ElementCS, V extends EObject> List<T> visitDeclarationAsList(@NonNull Class<T> csClass, @Nullable V eObject) {
		if (eObject == null) {
			return null;
		}
		T csElement = visitDeclaration(csClass, eObject);
		if (csElement == null) {
			return null;
		}
		return Collections.singletonList(csElement);
	}

	public @NonNull <T extends ElementCS, V extends EObject> List<T> visitDeclarations(@NonNull Class<T> csClass, /*@NonNull*/ List<V> eObjects, @Nullable AS2CS.Predicate<V> predicate) {
		assert eObjects != null;
		List<T> csElements = new ArrayList<T>();
		for (V eObject : eObjects) {
			if ((eObject != null) && ((predicate == null) || predicate.filter(eObject))) {
				T csElement = visitDeclaration(csClass, eObject);
				if (csElement != null) {
					csElements.add(csElement);
				}
			}
		}
		return csElements;
	}

	public @Nullable <T extends ElementCS> T visitReference(@NonNull Class<T> csClass, @NonNull EObject eObject, @Nullable Namespace scope) {
		@SuppressWarnings("null") @NonNull EClass eClass = eObject.eClass();
		BaseReferenceVisitor referenceVisitor = getReferenceVisitor(eClass, scope);
		if ((referenceVisitor == null) || !(eObject instanceof Visitable)) {
			logger.warn("Unsupported reference " + eObject.eClass().getName());
			return null;
		}
		ElementCS csElement = ((Visitable)eObject).accept(referenceVisitor);
		if (csElement == null) {
			return null;
		}
		if (!csClass.isAssignableFrom(csElement.getClass())) {
			logger.error("CS " + csElement.getClass().getName() + "' element is not a '" + csClass.getName() + "'"); //$NON-NLS-1$
			return null;
		}
		@SuppressWarnings("unchecked")
		T castElement = (T) csElement;
		return castElement;
	}

	public @NonNull <T extends ElementCS, V extends EObject> List<T> visitReferences(@NonNull Class<T> csClass, /*@NonNull*/ List<? extends V> eObjects, @Nullable AS2CS.Predicate<V> predicate) {
		assert eObjects != null;
		List<T> csElements = new ArrayList<T>();
		for (V eObject : eObjects) {
			if ((eObject != null) && ((predicate == null) || predicate.filter(eObject))) {
				T csElement = visitReference(csClass, eObject, null);
				if (csElement != null) {
					csElements.add(csElement);
				}
			}
		}
		return csElements;
	}
}
