@cached
operation getNodes() {
	return ECore!EClass.all.select(c|c.isNode());	
}

@cached
operation getPhantomNodes() {
	return ECore!EClass.all.select(c|c.isPhantom());
}

@cached
operation getLinks() {
	return ECore!EClass.all.select(c|c.isLink());
}

@cached
operation getLabelledAttributesFor(class : ECore!EClass) {
	return class.eAllAttributes.select(a|a.isLabelled());	
}

@cached
operation getReferenceLinks() {
	var diagramClass := getDiagramClass();
	if (diagramClass.getAnnotationValue('gmf.diagram', 'refsarelinks') = 'true') {
		return ECore!EReference.all.select(r|r.containment = false);
	}
	else {
		return ECore!EReference.all.select(r|r.isLink());
	}
}

@cached
operation ECore!EClass getAllConcreteSubTypes() { 
	return ECore!EClass.all.select(c|not c.abstract and c.eAllSuperTypes.includes(self));
}

operation getDiagramClass() : ECore!EClass {
	return ECore!EClass.all.selectOne(c|c.isAnnotatedAs('gmf.diagram'));
}

operation getDiagramContainmentReference(class : ECore!EClass) {
	for (ref in getDiagramClass().getContainmentReferences()){
		if (class.eAllSuperTypes.includes(ref.eType) or class = ref.eType) return ref;
	}
}

operation getOneSuitableContainmentReference(class : ECore!EClass) {
	for (ref in ECore!EReference.all.select(sf|sf.containment)){
		if (class.eAllSuperTypes.includes(ref.eType) or class = ref.eType) return ref;
	}
}

@cached
operation getAllSuitableContainmentReferences(class : ECore!EClass) {
	var suitableReferences : Sequence;
	for (ref in ECore!EReference.all.select(sf|sf.containment)){
		if (class.eAllSuperTypes.includes(ref.eType) or class = ref.eType) 
			suitableReferences.add(ref);
	}
	return suitableReferences;
}

@cached
operation ECore!EClass getContainmentReferences() {
	return self.eAllStructuralFeatures.select(sf : ECore!EReference | sf.containment);
}

@cached
operation ECore!EClass getCompartmentReferences() {
	return self.getContainmentReferences().select(r|r.isAnnotatedAs('gmf.compartment'));
}

@cached
operation ECore!EClass getAffixedReferences() {
	return self.getContainmentReferences().select(r|r.isAnnotatedAs('gmf.affixed'));
}

@cached
operation ECore!EReference isListLayout() : Boolean {
	var label := self.getAnnotationValue('gmf.compartment', 'layout');
	if (label = 'list') return true;
	else return false;
}

@cached
operation ECore!EReference isCollapsible() : Boolean {
	var label := self.getAnnotationValue('gmf.compartment', 'collapsible');
	if (label = 'false') return false;
	else return true;
}

@cached
operation ECore!EReference getLinkLabel() : String {
	var customText := self.getAnnotationValue('gmf.link', 'label.text');
	if (customText.isDefined()) {
		return customText;
	}

	return self.getAnnotationValue('gmf.link', 'label');
}

@cached
operation ECore!EReference getLongName() : String {
	return self.eContainingClass.name + self.name.firstToUpperCase();
}

@cached
operation ECore!EReference getLinkIncoming() : Boolean {
	return self.getAnnotationValue('gmf.link', 'incoming') = 'true';
}

@cached
operation ECore!EClass getConcreteSubtypes() {
	return ECore!EClass.all.select(e|(not e.abstract) and (e.eAllSuperTypes.includes(self) or e = self));
}

@cached
operation ECore!EClass getNodeSize() {
	var size := self.getAnnotationValue('gmf.node', 'size');
	if (not size.isDefined()) return size;
	else {
		var d : new GmfGraph!Dimension;
		d.dx := size.split(',').at(0).asInteger();
		d.dy := size.split(',').at(1).asInteger();
		return d;
	}
	
}

@cached
operation ECore!EClass getNodeSize() {
	var size := self.getAnnotationValue('gmf.node', 'size');
	if (not size.isDefined()) return size;
	else {
		var d : new GmfGraph!Dimension;
		d.dx := size.split(',').at(0).asInteger();
		d.dy := size.split(',').at(1).asInteger();
		return d;
	}
	
}
operation ECore!EClass getLinkEndFeature(name : String) {
	var featureName := self.getAnnotationValue('gmf.link', name);
	return self.eAllStructuralFeatures.selectOne(sf|sf.name = featureName);
}

@cached
operation ECore!EClass getLinkIncoming() : Boolean {
	return self.getAnnotationValue('gmf.link', 'incoming') = 'true';
}

@cached
operation ECore!EClass getLinkSourceFeature() {
	return self.getLinkEndFeature('source');
}

@cached
operation ECore!EClass getLinkTargetFeature() {
	return self.getLinkEndFeature('target');
}

@cached
operation ECore!EClass getSourceConstraint() {
	return self.getAnnotationValue('gmf.link', 'source.constraint');
}

@cached
operation ECore!EClass getTargetConstraint() {
	return self.getAnnotationValue('gmf.link', 'target.constraint');
}

@cached
operation ECore!EReference isLink() : Boolean {
	return self.isAnnotatedAs('gmf.link');
}

@cached
operation ECore!EClass isLink() : Boolean {
	
	if (self.abstract) return false;
	 
	var isLink := self.isAnnotatedAs('gmf.link');
	var isNoLink := self.isAnnotatedAs('gmf.nolink');
	
	if (isNoLink) return false;
	else if (isLink) return true;
	else return self.eSuperTypes.exists(s|s.isLink());
	
	return isLink;
}

@cached
operation ECore!EClass isNode() : Boolean {
	
	if (self.isLink()) return false;
	if (self.abstract) return false;
	
	var isNode := self.isAnnotatedAs('gmf.node');
	var isNoNode := self.isAnnotatedAs('gmf.nonode');
	
	if (isNoNode) return false;
	else if (isNode) return true;
	else return self.eSuperTypes.exists(s|s.isNode());
	
	return isNode;
}

@cached
operation ECore!EClass getLabelName() : String {
	return self.name + 'Label';
}

@cached
operation ECore!EClass getLabelPlacement() : String {
	var labelPosition := self.getAnnotationValue('gmf.node', 'label.placement');
	if (labelPosition.isUndefined()) {
		return 'internal';
	} else {
		return labelPosition;
	}
}

@cached
operation ECore!EClass labelHasIcon(defaultValue : Boolean) : Boolean {

	var ann : String;
	if (self.isNode()) ann := 'gmf.node';
	else ann := 'gmf.link';
	
	var hasIcon := self.getAnnotationValue(ann, 'label.icon');
	
	if (hasIcon.isUndefined()) return defaultValue;
	else if (hasIcon = 'true') return true;
	else return false;
	
}

@cached
operation ECore!EClass getLabelViewPattern() {
	var ann : String;
	if (self.isNode()) ann := 'gmf.node';
	else ann := 'gmf.link';
	return self.getLabelViewPattern(ann);
}

@cached
operation ECore!EClass getLabelEditPattern() {
	var ann : String;
	if (self.isNode()) ann := 'gmf.node';
	else ann := 'gmf.link';
	return self.getLabelEditPattern(ann);
}

@cached
operation ECore!EClass getLabelParser() {
	var ann : String;
	if (self.isNode()) ann := 'gmf.node';
	else ann := 'gmf.link';
	return self.getLabelParser(ann);
}

@cached
operation ECore!EClass getLabelText() {
	var ann : String;
	if (self.isNode()) ann := 'gmf.node';
	else ann := 'gmf.link';

	var customText := self.getAnnotationValue(ann, 'label.text');
	if (customText.isDefined()) {
		return customText;
	}
	else {
		return self.name;
	}
}

@cached
operation ECore!EClass isPhantom() {
	if (self.isNode()) {
		return self.getAnnotationValue('gmf.node', 'phantom') = 'true';
	}
	else {
		return false;
	}
}

operation ECore!EClass getLabelClass() {
	var ann : String;
	if (self.isNode()) ann := 'gmf.node';
	else ann := 'gmf.link';
	
	return self.getAnnotationValue(ann, 'label.impl');
}

operation ECore!EClass getLabelAttributes() {
	var ann : String;
	if (self.isNode()) ann := 'gmf.node';
	else ann := 'gmf.link';

	return self.getLabelAttributes(ann);
}

@cached
operation ECore!EClass getLabelReadOnly() : Boolean {
	var ann : String;
	if (self.isNode()) ann := 'gmf.node';
	else ann := 'gmf.link';
	
	return self.getAnnotationValue(ann, 'label.readOnly') = 'true';
}

@cached
operation ECore!EAttribute isLabelled() : Boolean {
	return self.isAnnotatedAs('gmf.label');
}

@cached
operation ECore!EAttribute getLabelName() : String {
	return self.eContainingClass.name + self.name.firstToUpperCase() + 'Label';
}

@cached
operation ECore!EAttribute getReadOnly() : Boolean {
	return self.getAnnotationValue('gmf.label', 'readOnly') = 'true';
}

@cached
operation ECore!EAttribute getLabelViewPattern() {
	return self.getLabelViewPattern('gmf.label');
}

@cached
operation ECore!EAttribute getLabelEditPattern() {
	return self.getLabelEditPattern('gmf.label');
}

@cached
operation ECore!EAttribute getLabelParser() {
	return self.getLabelParser('gmf.label');
}

@cached
operation ECore!EAttribute getLabelAttributes() {
	return self.getLabelAttributes('gmf.label');
}

@cached
operation ECore!EAnnotation getDetail(key : String) : String {
	var detail := self.details.selectOne(d|d.key = key);
	if (detail.isDefined()) {return detail.value;}
	else {return null;}
}

operation ECore!EModelElement getLabelParser(ann: String) {
	return self.getAnnotationValue(ann, 'label.parser');
}

operation ECore!EModelElement getLabelEditPattern(ann: String) {
	return self.getLabelPattern(ann, 'label.edit.pattern', 'label.pattern');
}

operation ECore!EModelElement getLabelViewPattern(ann: String) {
	return self.getLabelPattern(ann, 'label.view.pattern', 'label.pattern');
}

operation ECore!EModelElement getLabelPattern(ann: String, subtype: String, fallback: String) {
	var pattern = self.getAnnotationValue(ann, subtype);
	if (pattern.isDefined()) {
		return pattern;
	} else {
		return self.getAnnotationValue(ann, fallback);
	}
}

operation ECore!EModelElement getLabelAttributes(ann: String) {
	var labelAnnotationValue := self.getAnnotationValue(ann, 'label');
	
	if (labelAnnotationValue.isDefined()) {
		var labels := labelAnnotationValue.split(',').collect(s|s.trim());
		return self.eAllStructuralFeatures.select(f|labels.exists(s|s = f.name));
	}
	else {
		return Sequence {};
	}
}

operation ECore!EModelElement getAnnotationValue(name : String, detail : String) : Any {
	var ann := self.eAnnotations.selectOne(a|a.source = name);
	var det;

	if (ann.isDefined()) {
		det := ann.details.selectOne(d|d.key = detail);
	}

	if (det.isDefined()) {
		return det.value;
	}
	else if (self.isTypeOf(ECore!EClass)) {
		for (s in self.eSuperTypes) {
			var sann := s.getAnnotationValue(name, detail);
			if (sann.isDefined()) {
				return sann;
			}
		}
	}
	return det;	
}

@cached
operation ECore!EModelElement getAnnotation(name : String) : ECore!EAnnotation {
	var ann := self.eAnnotations.selectOne(a|a.source = name);
	
	if (self.isTypeOf(ECore!EClass) and ann.isUndefined()) {
		for (s in self.eSuperTypes) {
			var sann := s.getAnnotation(name);
			if (sann.isDefined()) return sann;
		}
	}
	
	return ann;
	
}

@cached
operation ECore!EModelElement isAnnotatedAs(name : String) : Boolean {
	return self.getAnnotation(name).isDefined();
}

@cached
operation ECore!EReference isLabelled() : Boolean {
	return false;
}