package org.eclipse.emf.henshin.variability.mergein.refactoring.logic;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.henshin.model.And;
import org.eclipse.emf.henshin.model.Annotation;
import org.eclipse.emf.henshin.model.Attribute;
import org.eclipse.emf.henshin.model.Edge;
import org.eclipse.emf.henshin.model.Formula;
import org.eclipse.emf.henshin.model.Graph;
import org.eclipse.emf.henshin.model.GraphElement;
import org.eclipse.emf.henshin.model.HenshinFactory;
import org.eclipse.emf.henshin.model.Mapping;
import org.eclipse.emf.henshin.model.MappingList;
import org.eclipse.emf.henshin.model.Module;
import org.eclipse.emf.henshin.model.NestedCondition;
import org.eclipse.emf.henshin.model.Node;
import org.eclipse.emf.henshin.model.Not;
import org.eclipse.emf.henshin.model.Parameter;
//import org.eclipse.emf.henshin.model.Module;
import org.eclipse.emf.henshin.model.Rule;
import org.eclipse.emf.henshin.model.resource.HenshinResourceSet;
import org.eclipse.emf.henshin.variability.wrapper.VariabilityFactory;
import org.eclipse.emf.henshin.variability.wrapper.VariabilityRule;

import mergeSuggestion.MergeNAC;
import mergeSuggestion.MergePAC;
import mergeSuggestion.MergeRule;
import mergeSuggestion.MergeRuleElement;
import mergeSuggestion.MergeSuggestionFactory;

public class NewMerger {

	private static final String VAR = "Var";
	private static final String COMMA = ",";
	private static final String BRACKET_LEFT = "(";
	private static final String XOR = "xor";
	private static final String AC = "AC";
	private static final String BRACKET_RIGHT = ")";
	private static final String OR = " or ";

	private MergeRule mergeRule;
	private Rule masterRule;
	private List<Rule> furtherRules;
	private int numberOfRules;
	private Module henshinModule;
	private HashMap<Node, Node> nodesMap;
	private HashMap<Rule, String> rule2ConditionMap;
	private EList<MergeRuleElement> elementsLhs, elementsRhs, elementsConditions, elementsNestedRules;
	private EList<ParameterRulesMapping> parameterRulesMappings;
	private EList<MergeRuleElementRulesMapping> mergeRuleElementRulesMappings;
	private boolean unifyParameters;

	public NewMerger(MergeRule m) throws MergeInException {
		this(m, false);
	}

	public NewMerger(MergeRule m, boolean unifyParams) throws MergeInException {
		mergeRule = m;
		unifyParameters = unifyParams;
		masterRule = mergeRule.getMasterRule();
		furtherRules = new ArrayList<Rule>();
		furtherRules.addAll(mergeRule.getRules());
		furtherRules.remove(masterRule);
		numberOfRules = furtherRules.size() + 1;
		setModule();
		nodesMap = new HashMap<Node, Node>();
		rule2ConditionMap = new LinkedHashMap<Rule, String>();
		elementsLhs = new BasicEList<MergeRuleElement>();
		elementsRhs = new BasicEList<MergeRuleElement>();
		elementsConditions = new BasicEList<MergeRuleElement>();
		elementsNestedRules = new BasicEList<MergeRuleElement>();
		parameterRulesMappings = new BasicEList<ParameterRulesMapping>();
		mergeRuleElementRulesMappings = new BasicEList<MergeRuleElementRulesMapping>();
	}

	public void saveModule(String path) throws MergeInException {
		File file = new File(path);
		HenshinResourceSet resourceSet = new HenshinResourceSet(file.getParent());
		Resource resource = resourceSet.createResource(path);
		resource.getContents().add(henshinModule);
		try {
			resource.save(null);
		} catch (IOException e) {
			throw new MergeInException(MergeInException.SAVING_IMPOSSIBLE);
		}
	}

	public void merge() throws MergeInException {
		prepareMerging();
		mergeParameters();
		mergeLhsRhsGraphs();
		mergeConditions();
		// mergeNestedRules();
		completeMerging();
	}

	private void prepareMerging() {
		sortMergeRuleElements();
		setPresenceConditions();
		fillNodesMap();
		partitionMergeRuleElements();
	}

	private void mergeParameters() {
		if (unifyParameters) {
			unifyParameterNames();
		}
		mergeParametersIntoMasterRule();
	}

	private void mergeLhsRhsGraphs() {
		mergeLhsGraph();
		mergeRhsGraph();
		addLhsRhsMapping();
	}

	private void mergeConditions() {
		c: for (MergeNAC mergeNAC : mergeRule.getMergeNacs()) {
			for (Graph refNAC : mergeNAC.getReferenceNACs())
				for (NestedCondition masterNac : masterRule.getLhs().getNACs())
					if (masterNac.getConclusion() == refNAC)
						continue c; // mergeNAC already merged -> skip
			Graph nonMasterNac = mergeNAC.getReferenceNACs().get(0);
			addNestedCondition2Graph((NestedCondition) nonMasterNac.eContainer(), true);
		}

		d: for (MergePAC mergePAC : mergeRule.getMergePacs()) {
			for (Graph refPAC : mergePAC.getReferencePACs())
				for (NestedCondition masterPac : masterRule.getLhs().getPACs())
					if (masterPac.getConclusion() == refPAC)
						continue d;// mergePAC already merged -> skip
			Graph nonMasterPac = mergePAC.getReferencePACs().get(0);
			addNestedCondition2Graph((NestedCondition) nonMasterPac.eContainer(), false);
		}

		int number = 1;
		for (NestedCondition nac : masterRule.getLhs().getNACs()) {
			nac.getConclusion().setName("" + number);
			number++;
		}
		for (NestedCondition pac : masterRule.getLhs().getPACs()) {
			pac.getConclusion().setName("" + number);
			number++;
		}
	}

	private void completeMerging() throws MergeInException {
		setInjectiveMatching();
		setFeatureModel();
		setFeatures();
		setAnnotation();
		if (furtherRules.isEmpty()) {
			masterRule.setName(masterRule.getName() + "-var");
		} else {
			for (Rule rule : furtherRules) {
				masterRule.setName(masterRule.getName() + "," + rule.getName());
			}
		}
		removeNonMasterRules();
	}
	
	private void setAnnotation() {
		Annotation anno = HenshinFactory.eINSTANCE.createAnnotation();
		StringBuilder sb = new StringBuilder();
		for ( Entry<Rule, String> entry : rule2ConditionMap.entrySet()) {
			sb.append(entry.getValue());
			sb.append('=');
			sb.append(entry.getKey());
			sb.append(", ");
		}
		String value = sb.toString();
		value = value.substring(0, value.length()-2);
		anno.setKey("originalRules");
		anno.setValue(value);
		masterRule.getAnnotations().add(anno);
	}


	private void removeNonMasterRules() throws MergeInException {
		for (Rule rule : furtherRules) {
			if (rule.getModule() == null) {
				throw new MergeInException(MergeInException.NO_MODULE_2);
			}
		}
		henshinModule.getUnits().removeAll(furtherRules);
	}

	private void setFeatureModel() {
		String featureModel = XOR;
		VariabilityRule masterVarRule = VariabilityFactory.createVariabilityRule(masterRule);
		masterVarRule.addFeature(masterVarRule.getName());
		featureModel += BRACKET_LEFT;
		featureModel += getCondition(masterRule);
		for (Rule rule : furtherRules) {
			featureModel += COMMA;
			featureModel += getCondition(rule);
			masterVarRule.addFeature(rule.getName());
		}
		featureModel += BRACKET_RIGHT;
		VariabilityFactory.createVariabilityRule(masterRule).setFeatureModel(featureModel);
	}
	
	private void setFeatures() {
		StringBuilder sb = new StringBuilder();
		for ( Entry<Rule, String> entry : rule2ConditionMap.entrySet()) {
			sb.append(getCondition(entry.getKey()));
			sb.append(",");
		}
		String value = sb.toString();
		value = value.substring(0, value.length()-1);
		VariabilityFactory.createVariabilityRule(masterRule).setFeatures(value);
	}

	private void addNestedCondition2Graph(NestedCondition condition, boolean nac) {
		Formula formula = condition;
		if (nac) {
			formula = HenshinFactory.eINSTANCE.createNot();
			((Not) formula).setChild(condition);
		}

		if (masterRule.getLhs().getFormula() == null) {
			masterRule.getLhs().setFormula(formula);
		} else {
			And and = HenshinFactory.eINSTANCE.createAnd();
			and.setLeft(masterRule.getLhs().getFormula());
			and.setRight(formula);
			masterRule.getLhs().setFormula(and);
		}
		adjustMappings(formula);
	}

	private void adjustMappings(Formula formula) {
		if (formula instanceof NestedCondition) {
			NestedCondition nestedCondition = (NestedCondition) formula;
			Iterator<Mapping> iter = nestedCondition.getMappings().iterator();
			while (iter.hasNext()) {
				Mapping mapping = iter.next();
				Node oldOrigin = mapping.getOrigin();
				mapping.setOrigin(nodesMap.get(oldOrigin));
			}
		}
		if (formula instanceof Not) {
			Not not = (Not) formula;
			adjustMappings(not.getChild());
		}
	}

	private EList<Rule> getRulesWithCondition() {
		EList<Rule> rulesWithCondition = new BasicEList<Rule>();
		for (MergeRuleElementRulesMapping mapping : mergeRuleElementRulesMappings) {
			Rule rule = mapping.getRules().get(0);
			if (rule != masterRule) {
				rulesWithCondition.add(rule);
			}
		}
		return rulesWithCondition;
	}

	private void prepareRuleSets() {
		for (MergeRuleElement mre : elementsConditions) {
			MergeRuleElementRulesMapping mapping = new MergeRuleElementRulesMapping(this, mre);
			for (GraphElement elem : mre.getReferenceElements()) {
				mapping.addRule(elem.getGraph().getRule());
			}
			if (!mappingContainsRuleList(mapping)) {
				mergeRuleElementRulesMappings.add(mapping);
			}
			setConditionName(mre);
		}
	}

	private void setConditionName(MergeRuleElement mre) {
		for (GraphElement elem : mre.getReferenceElements()) {
			if (elem.getGraph().isNestedCondition()) {
				EList<Rule> affectedRules = getRulesFromMergeRuleElement(mre);
				String str = "";
				for (Rule rule : affectedRules) {
					str += rule.getName();
				}
				elem.getGraph().setName(AC + str);
			}
		}
	}

	private boolean mappingContainsRuleList(MergeRuleElementRulesMapping mapping) {
		for (MergeRuleElementRulesMapping m : mergeRuleElementRulesMappings) {
			if (m.hasSameRuleList(mapping)) {
				return true;
			}
		}
		return false;
	}

	private void addLhsRhsMapping() {
		for (Rule rule : furtherRules) {
			MappingList mappingList = rule.getMappings();
			addMappings2Rule(masterRule, mappingList);
		}
	}

	private void addMappings2Rule(Rule rule, MappingList mappingList) {
		Iterator<Mapping> iter = mappingList.iterator();
		while (iter.hasNext()) {
			Mapping mapping = iter.next();
			Node origin = nodesMap.get(mapping.getOrigin());
			Node image = nodesMap.get(mapping.getImage());
			if (rule.getMappings().get(origin, image) == null) {
				rule.getMappings().add(HenshinFactory.eINSTANCE.createMapping(origin, image));
			}
		}
	}

	private void mergeRhsGraph() {
		List<Node> nodesRhs = new ArrayList<Node>();
		List<Edge> edgesRhs = new ArrayList<Edge>();
		List<Attribute> attributesRhs = new ArrayList<Attribute>();
		fillLists(nodesRhs, edgesRhs, attributesRhs, elementsRhs);
		addNodes2GraphOfMasterRule(masterRule.getRhs(), nodesRhs);
		addAttributes2Nodes(attributesRhs);
		addEdges2Graph(masterRule.getRhs(), edgesRhs);
	}

	private void mergeLhsGraph() {
		List<Node> nodesLhs = new ArrayList<Node>();
		List<Edge> edgesLhs = new ArrayList<Edge>();
		List<Attribute> attributesLhs = new ArrayList<Attribute>();
		fillLists(nodesLhs, edgesLhs, attributesLhs, elementsLhs);
		addNodes2GraphOfMasterRule(masterRule.getLhs(), nodesLhs);
		addAttributes2Nodes(attributesLhs);
		addEdges2Graph(masterRule.getLhs(), edgesLhs);
	}

	private void addEdges2Graph(Graph graph, List<Edge> edges) {
		for (Edge edge : edges) {
			Node sourceNew = nodesMap.get(edge.getSource());
			Node targetNew = nodesMap.get(edge.getTarget());
			Edge e = sourceNew.getOutgoing(edge.getType(), targetNew);
			if (e == null) {
				edge.setSource(sourceNew);
				edge.setTarget(targetNew);
				graph.getEdges().add(edge);
			} else {
				if (e == edge && !graph.getEdges().contains(edge)) {
					graph.getEdges().add(edge);
				}
			}
		}
	}

	private void addAttributes2Nodes(List<Attribute> attributes) {
		for (Attribute attribute : attributes) {
			Node newOwningNode = nodesMap.get(attribute.getNode());
			// if (newOwningNode.getAttribute(attribute.getType()) == null) {
			newOwningNode.getAttributes().add(attribute);
			// }
		}
	}

	private void addNodes2GraphOfMasterRule(Graph graph, List<Node> nodes) {
		for (Node node : nodes) {
			if (nodesMap.get(node) == node && !(node.getGraph().getRule() == masterRule)) {
				graph.getNodes().add(node);
			}
		}
	}

	private void fillLists(List<Node> nodes, List<Edge> edges, List<Attribute> attributes,
			EList<MergeRuleElement> elements) {
		for (MergeRuleElement mre : elements) {
			for (GraphElement elem : mre.getReferenceElements()) {
				if (elem instanceof Node) {
					nodes.add((Node) elem);
				}
				if (elem instanceof Edge) {
					edges.add((Edge) elem);
				}
				if (elem instanceof Attribute) {
					attributes.add((Attribute) elem);
				}
			}
		}
	}

	private void mergeParametersIntoMasterRule() {
		for (Rule rule : furtherRules) {
			for (Parameter param : rule.getParameters()) {
				if (!masterRuleContainsParameter(param)) {
					Parameter paramCopy = HenshinFactory.eINSTANCE.createParameter();
					paramCopy.setName(param.getName());
					if (param.getType() != null) {
						paramCopy.setType(param.getType());
					}
					masterRule.getParameters().add(paramCopy);
				}
			}
		}
	}

	private boolean masterRuleContainsParameter(Parameter param) {
		for (Parameter p : masterRule.getParameters()) {
			if (p.getName().equals(param.getName())) {
				if (p.getType() == null && param.getType() == null) {
					return true;
				}
				if (p.getType() != null && param.getType() != null && p.getType() == param.getType()) {
					return true;
				}
			}
		}
		return false;
	}

	private void unifyParameterNames() {
		for (Parameter param : masterRule.getParameters()) {
			ParameterRulesMapping parameterRulesMapping = new ParameterRulesMapping(param, this);
			assignRules2Parameter(parameterRulesMapping);
			parameterRulesMappings.add(parameterRulesMapping);
		}
		for (Rule rule : furtherRules) {
			for (Parameter param : rule.getParameters()) {
				ParameterRulesMapping parameterRulesMapping = new ParameterRulesMapping(param, this);
				assignRules2Parameter(parameterRulesMapping);
				parameterRulesMappings.add(parameterRulesMapping);
			}
		}
		for (ParameterRulesMapping mapping : parameterRulesMappings) {
			Parameter param = mapping.getParameter();
			String oldName = param.getName();
			String newName = "";
			for (Rule rule : mapping.getRules()) {
				if (rule.getName() != null && !rule.getName().isEmpty()) {
					newName += firstToUpper(rule.getName().toLowerCase());
				}
			}
			newName += firstToUpper(oldName);
			param.setName(newName);
			updateReferences2Parameter(((Rule) param.getUnit()), oldName, newName);
		}
	}

	private void updateReferences2Parameter(Rule rule, String oldName, String newName) {
		for (MergeRuleElement mre : mergeRule.getElements()) {
			for (GraphElement ge : mre.getReferenceElements()) {
				if (ge instanceof Node && ((Node) ge).getName() != null && ((Node) ge).getName().equals(oldName)) {
					if (ge.getGraph().getRule().getKernelRule() != null) {
						if (ge.getGraph().getRule().getKernelRule() == rule) {
							((Node) ge).setName(newName);
						}
					} else {
						if (ge.getGraph().getRule() == rule) {
							((Node) ge).setName(newName);
						}
					}
				}
				if (ge instanceof Attribute && ((Attribute) ge).getValue().equals(oldName)) {
					if (ge.getGraph().getRule().getKernelRule() != null) {
						if (ge.getGraph().getRule().getKernelRule() == rule) {
							((Attribute) ge).setValue(newName);
						}
					} else {
						if (ge.getGraph().getRule() == rule) {
							((Attribute) ge).setValue(newName);
						}
					}
				}
			}
		}
	}

	private String firstToUpper(String str) {
		return str.substring(0, 1).toUpperCase() + str.substring(1);
	}

	private void assignRules2Parameter(ParameterRulesMapping mapping) {
		Parameter param = mapping.getParameter();
		for (MergeRuleElement mre : mergeRule.getElements()) {
			if (getRulesFromMergeRuleElement(mre).contains((Rule) param.getUnit())) {
				for (GraphElement ge : mre.getReferenceElements()) {
					if (ge instanceof Node && ((Node) ge).getName() != null && ((Node) ge).getName().equals(param.getName())) {
						if (ge.getGraph().getRule().getKernelRule() != null) {
							mapping.addRule(ge.getGraph().getRule().getKernelRule());
						} else {
							mapping.addRule(ge.getGraph().getRule());
						}
					}
					if (ge instanceof Attribute && ((Attribute) ge).getValue().equals(param.getName())) {
						if (ge.getGraph().getRule().getKernelRule() != null) {
							mapping.addRule(ge.getGraph().getRule().getKernelRule());
						} else {
							mapping.addRule(ge.getGraph().getRule());
						}
					}
				}
			}
		}
	}

	private EList<Rule> getRulesFromMergeRuleElement(MergeRuleElement mre) {
		EList<Rule> rules = new BasicEList<Rule>();
		for (GraphElement ge : mre.getReferenceElements()) {
			if (ge.getGraph().getRule().getKernelRule() != null) {
				rules.add(ge.getGraph().getRule().getKernelRule());
			} else {
				rules.add(ge.getGraph().getRule());
			}
		}
		return rules;
	}

	private void partitionMergeRuleElements() {
		for (MergeRuleElement mre : mergeRule.getElements()) {
			GraphElement elem = mre.getReferenceElements().get(0);
			if (elem.getGraph().getRule().getKernelRule() != null) {
				elementsNestedRules.add(mre);
				continue;
			}
			if (elem.getGraph().isLhs()) {
				elementsLhs.add(mre);
				continue;
			}
			if (elem.getGraph().isRhs()) {
				elementsRhs.add(mre);
				continue;
			}
			if (elem.getGraph().isNestedCondition()) {
				elementsConditions.add(mre);
				setPresenceCondition(mre);
				continue;
			}
		}
	}

	private void setPresenceCondition(MergeRuleElement mre) {
		for (GraphElement elem : mre.getReferenceElements()) {
			String presenceCondition = VariabilityFactory.createVariabilityGraphElement(elem).getPresenceCondition();
			if (elem.getGraph().isNestedCondition()) {
				NestedCondition condition = (NestedCondition) elem.getGraph().eContainer();
				VariabilityFactory.createVariabilityNestedCondition(condition).setPresenceCondition(presenceCondition);
			}
		}
	}

	private void fillNodesMap() {
		for (MergeRuleElement mre : mergeRule.getElements()) {
			if (mre.getReferenceElements().get(0) instanceof Node) {
				Node baseNode = (Node) mre.getReferenceElements().get(0);
				for (GraphElement elem : mre.getReferenceElements()) {
					Node node = (Node) elem;
					nodesMap.put(node, baseNode);
				}
			}
		}
	}

	private void setPresenceConditions() {
		int i = 0;
		for (Rule rule : mergeRule.getRules()) {
			rule2ConditionMap.put(rule, str(i));
			i++;
		}
		
		for (MergeRuleElement mre : mergeRule.getElements()) {
			if (mre.getReferenceElements().size() != numberOfRules) {
				for (GraphElement elem : mre.getReferenceElements()) {
					String condition = getCondition(mre);
					VariabilityFactory.createVariabilityGraphElement(elem).setPresenceCondition(condition);
				}
			}
		}

		for (MergeNAC nac : mergeRule.getMergeNacs()) {
			if (nac.getReferenceNACs().size() != numberOfRules) {
				for (Graph g : nac.getReferenceNACs()) {
					setPresenceCondition(nac, g);
				}
			}
		}
	}
	
	static String str(int i) {
	    return i < 0 ? "" : str((i / 26) - 1) + (char)(65 + i % 26);
	}

	private void setPresenceCondition(MergeNAC nac, Graph g) {
		String condition = getCondition(nac);
		VariabilityFactory.createVariabilityNestedCondition(((NestedCondition) g.eContainer())).setPresenceCondition(condition);
		for (Node node : g.getNodes()) {
			if (node.getActionNode() == node)
				VariabilityFactory.createVariabilityNode(node).setPresenceCondition(condition);

			for (Attribute attribute : node.getAttributes()) {
				if (attribute.getActionAttribute() == attribute)
					VariabilityFactory.createVariabilityAttribute(attribute).setPresenceCondition(condition);
			}
		}
		for (Edge edge : g.getEdges()) {
			if (edge.getActionEdge() == edge)
				VariabilityFactory.createVariabilityEdge(edge).setPresenceCondition(condition);
		}
	}

	private String getCondition(MergeNAC nac) {
		List<Rule> affectedRules = new ArrayList<Rule>();
		for (Graph el : nac.getReferenceNACs()) {
			affectedRules.add(el.getRule());
		}
		return getCondition(affectedRules);
	}

	private String getCondition(MergeRuleElement mre) {
		List<Rule> affectedRules = new ArrayList<Rule>();
		for (GraphElement elem : mre.getReferenceElements()) {
			affectedRules.add(elem.getGraph().getRule());
		}
		return getCondition(affectedRules);
	}

	private String getCondition(List<Rule> affectedRules) {
		String condition = "";
		if (!affectedRules.isEmpty()) {
			condition = getCondition(affectedRules.get(0));
		}
		for (int i = 1; i < affectedRules.size(); i++) {
			condition += OR + getCondition(affectedRules.get(i));
		}
		return condition;
	}

	private String getCondition(Rule rule) {
		String ruleName = rule.getName();
		ruleName = ruleName.replaceAll("\\W", "");
		ruleName = ruleName.replaceAll("_", "");
		return "def("+ruleName.toLowerCase()+")";
//		return "def("+rule2ConditionMap.get(rule)+")";
	}

	private void sortMergeRuleElements() {
		EList<MergeRuleElement> elements = new BasicEList<MergeRuleElement>();
		for (MergeRuleElement mre : mergeRule.getElements()) {
			elements.add(getSortedElement(mre));
		}
		mergeRule.getElements().clear();
		mergeRule.getElements().addAll(elements);
	}

	private MergeRuleElement getSortedElement(MergeRuleElement mre) {
		int oldSize = mre.getReferenceElements().size();
		MergeRuleElement elem = MergeSuggestionFactory.eINSTANCE.createMergeRuleElement();
		for (GraphElement ge : mre.getReferenceElements()) {
			if (ge.getGraph().getRule() == masterRule) {
				elem.getReferenceElements().add(ge);
				break;
			}
		}
		for (int i = 0; i < furtherRules.size(); i++) {
			Rule rule = furtherRules.get(i);
			for (GraphElement ge : mre.getReferenceElements()) {
				if (ge.getGraph().getRule() == rule) {
					elem.getReferenceElements().add(ge);
					break;
				}
			}
		}
		if (elem.getReferenceElements().size() != oldSize)
			throw new RuntimeException("Error during sorting!");
		return elem;
	}

	private void setModule() throws MergeInException {
		if (mergeRule != null) {
			if (masterRule != null) {
				if (masterRule.getModule() != null) {
					henshinModule = masterRule.getModule();
				} else {
					throw new MergeInException(MergeInException.NO_MODULE);
				}
			} else {
				throw new MergeInException(MergeInException.NO_MASTERRULE);
			}
		} else {
			throw new MergeInException(MergeInException.NO_MERGERULE);
		}
	}

	private void setInjectiveMatching() {
		List<Rule> injective = new ArrayList<Rule>();
		for (Rule rule : mergeRule.getRules()) {
			if (rule.isInjectiveMatching())
				injective.add(rule);
		}
		if (injective.isEmpty()) {
			VariabilityFactory.createVariabilityRule(masterRule).setInjectiveMatchingPresenceCondition("false");
		} else if (injective.size() == mergeRule.getRules().size()) {
			// NOOP, is default.
		} else {
			String condition = getCondition(injective.get(0));
			for (int i = 1; i < injective.size(); i++) {
				condition += OR + getCondition(injective.get(i));
			}
			VariabilityFactory.createVariabilityRule(masterRule).setInjectiveMatchingPresenceCondition(condition);
		}
	}

	MergeRule getMergeRule() {
		return mergeRule;
	}

	HashMap<Node, Node> getNodesMap() {
		return nodesMap;
	}

	EList<MergeRuleElement> getElementsLhs() {
		return elementsLhs;
	}

	EList<MergeRuleElement> getElementsRhs() {
		return elementsRhs;
	}

	EList<MergeRuleElement> getElementsConditions() {
		return elementsConditions;
	}

	EList<MergeRuleElement> getElementsNestedRules() {
		return elementsNestedRules;
	}

	Rule getMasterRule() {
		return masterRule;
	}

	List<Rule> getFurtherRules() {
		return furtherRules;
	}

	EList<MergeRuleElementRulesMapping> getMergeRuleElementRulesMappings() {
		return mergeRuleElementRulesMappings;
	}

	Module getModule() {
		return henshinModule;
	}
}
