/*******************************************************************************
 * Copyright (c) 2017-2020 Dortmund University of Applied Sciences and Arts and others.
 *  
 *  This program and the accompanying materials are made
 *  available under the terms of the Eclipse Public License 2.0
 *  which is available at https://www.eclipse.org/legal/epl-2.0/
 *   
 *  SPDX-License-Identifier: EPL-2.0
 *  
 *  Contributors:
 *      Dortmund University of Applied Sciences and Arts - initial API and implementation
 *******************************************************************************/

package org.eclipse.app4mc.multicore.partitioning.utils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.app4mc.amalthea.model.AccessPrecedenceSpec;
import org.eclipse.app4mc.amalthea.model.Activation;
import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.Amalthea;
import org.eclipse.app4mc.amalthea.model.AmaltheaFactory;
import org.eclipse.app4mc.amalthea.model.ConstraintsModel;
import org.eclipse.app4mc.amalthea.model.ExecutionNeed;
import org.eclipse.app4mc.amalthea.model.IDiscreteValueDeviation;
import org.eclipse.app4mc.amalthea.model.Label;
import org.eclipse.app4mc.amalthea.model.LabelAccess;
import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
import org.eclipse.app4mc.amalthea.model.PeriodicActivation;
import org.eclipse.app4mc.amalthea.model.ProcessPrototype;
import org.eclipse.app4mc.amalthea.model.ProcessingUnitDefinition;
import org.eclipse.app4mc.amalthea.model.Runnable;
import org.eclipse.app4mc.amalthea.model.RunnableCall;
import org.eclipse.app4mc.amalthea.model.RunnableSequencingConstraint;
import org.eclipse.app4mc.amalthea.model.SWModel;
import org.eclipse.app4mc.amalthea.model.Task;
import org.eclipse.app4mc.amalthea.model.Ticks;
import org.eclipse.app4mc.amalthea.model.util.CustomPropertyUtil;
import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
import org.eclipse.app4mc.multicore.partitioning.algorithms.Path;
import org.eclipse.app4mc.multicore.sharelibs.UniversalHandler;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.jgrapht.DirectedGraph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides several calculations / generally needed methods
 */
public class Helper {

	private static final Logger LOGGER = LoggerFactory.getLogger(Helper.class);
	private static final String KEY = "slack";

	/**
	 * Calculation of a runnable's instructions (arithmetic average in case of deviations)
	 *
	 * @param r
	 *            Runnable
	 * @return long mean instructions
	 */
	public long getInstructions(final Runnable r) {
		if (null == r) {
			return 0l;
		}
		long instr = 0;
		if (null != SoftwareUtil.getExecutionNeeds(r, null)) {
			for (final ExecutionNeed en : SoftwareUtil.getExecutionNeeds(r, null)) {
				for (final Entry<String, IDiscreteValueDeviation> n : en.getNeeds()) {
					instr += n.getValue().getUpperBound();
				}
			}
		}
		if (null != SoftwareUtil.getTicks(r, null)) {
			for (final Ticks ticks : SoftwareUtil.getTicks(r, null)) {
				instr += getDefaultOrExtendedTicks(ticks);
			}
		}
		return instr == 0 ? 1 : instr;
	}

	public long getInstructions(final EList<Runnable> rs) {
		long instr = 0;
		for (final Runnable r : rs) {
			instr += getInstructions(r);
		}
		return instr;
	}

	List<Runnable> visited = new BasicEList<>();

	/**
	 * Get ProcessPrototype from a Runnable (the ProcessPrototype, that contains
	 * the given runnable)
	 *
	 * @param runnable
	 * @param swm
	 * @return ProcessPrototype, that contains the parameter runnable
	 */
	public ProcessPrototype getPPfromR(final Runnable runnable, final SWModel swm) {
		for (final ProcessPrototype pp : swm.getProcessPrototypes()) {
			for (final RunnableCall trc : pp.getRunnableCalls()) {
				if (trc.getRunnable().equals(runnable)) {
					return pp;
				}
			}
		}
		LOGGER.error("getPPFromR did not find PP for Runnable {}", runnable.getName());
		return null;
	}

	/**
	 * calculates the longest runtime of a runnable according to all succeeding (dependent) runnables recursively. Function is able to handle cyclic graphs.
	 *
	 * @param cm
	 *            constraints model represents dependencies
	 * @param r
	 *            the given runnable thats runtime shall be calculated
	 * @return runtime of succeeding runnables and the runnable's runtime
	 */
	public long getPreceedingRunTimeCycle(final ConstraintsModel cm, final Runnable r) {
		if (r == null) {
			return Long.MAX_VALUE;
		}
		long rt = 0;
		this.visited.add(r);
		for (final RunnableSequencingConstraint rsc : cm.getRunnableSequencingConstraints()) {
			if (rsc.getRunnableGroups().get(1).getRunnables().get(0).equals(r)
					&& !this.visited.contains(rsc.getRunnableGroups().get(0).getRunnables().get(0))) {
				final long temp = getPreceedingRunTimeCycle(cm, rsc.getRunnableGroups().get(0).getRunnables().get(0));
				if (temp > rt) {
					rt = temp;
				}
			}
		}
		return rt + getInstructions(r);
	}

	private final HashMap<Runnable, Set<Runnable>> cache = new HashMap<>();

	/**
	 *
	 * @param cm
	 *            constraints model represents dependencies
	 * @param r
	 *            runnable of which predecessors should be found
	 * @return predecessors of r
	 */
	public Set<Runnable> getPreceedingRunnables(final ConstraintsModel cm, final Runnable r,
			final DirectedGraph<Runnable, RunnableSequencingConstraint> directedGraph) {
		if (this.cache.containsKey(r)) {
			return this.cache.get(r);
		}
		final Set<Runnable> rs = new HashSet<>();
		/* it is more efficient if directedGraph is used */
		if (null == directedGraph) {
			for (final RunnableSequencingConstraint rsc : cm.getRunnableSequencingConstraints()) {
				if (rsc.getRunnableGroups().get(1).getRunnables().get(0).equals(r)) {
					rs.add(rsc.getRunnableGroups().get(0).getRunnables().get(0));
					rs.addAll(getPreceedingRunnables(cm, rsc.getRunnableGroups().get(0).getRunnables().get(0), directedGraph));
				}
			}
		}
		else {
			for (final RunnableSequencingConstraint rsc : directedGraph.incomingEdgesOf(r)) {
				rs.add(rsc.getRunnableGroups().get(0).getRunnables().get(0));
				rs.addAll(getPreceedingRunnables(cm, rsc.getRunnableGroups().get(0).getRunnables().get(0), directedGraph));
			}
		}
		this.cache.put(r, rs);
		return rs;
	}

	/**
	 * creates a ProcessPrototype with all runnables
	 *
	 * @param swm
	 */
	public void checkTRCsVsAllRunnables(final SWModel swm) {
		if (getAllTRCs(swm).size() < swm.getRunnables().size()) {
			final ProcessPrototype pp = AmaltheaFactory.eINSTANCE.createProcessPrototype();
			pp.setName("AllRunnables");
			final EList<RunnableCall> alltrcs = new BasicEList<>();
			for (final Runnable r : swm.getRunnables()) {
				final RunnableCall trc = AmaltheaFactory.eINSTANCE.createRunnableCall();
				trc.setRunnable(r);
				alltrcs.add(trc);
			}
			pp.getRunnableCalls().addAll(alltrcs);
			swm.getProcessPrototypes().add(pp);
			LOGGER.debug("Created AllRunnablesPP with {} TRCs", alltrcs.size());
		}
	}

	/**
	 * Checks if all runnables within the given software model reference an activation
	 *
	 * @param swm
	 *
	 * @return false if any runnable has no activation reference, true otherwise
	 */
	public boolean allRunnablesReferActivation(final SWModel swm) {
		for (final Runnable r : swm.getRunnables()) {
			if (null == r.getFirstActivation()) {
				return false;
			}
		}
		return true;
	}

	/**
	 *
	 * @return all runnablecalls across processprototypes
	 */
	public EList<RunnableCall> getAllTRCs(final SWModel swm) {
		final EList<RunnableCall> trcs = new BasicEList<>();
		for (final ProcessPrototype pp : swm.getProcessPrototypes()) {
			trcs.addAll(pp.getRunnableCalls());
		}
		return trcs;
	}

	/**
	 * calculates the longest runtime of a runnable according to all succeeding (dependent) runnables recursivly. Function is able to handle cyclic graphs
	 *
	 * @param cm
	 *            constraints model represents dependencies
	 * @param r
	 *            the given runnable thats runtime shall be calculated
	 * @return runtime of succeeding runnables and the runnable's runtime
	 */
	public long getSucceedingRunTimeCycle(final ConstraintsModel cm, final Runnable r) {
		if (r == null) {
			return Long.MAX_VALUE;
		}
		long rt = 0;
		this.visited.add(r);
		for (final RunnableSequencingConstraint rsc : cm.getRunnableSequencingConstraints()) {
			if (rsc.getRunnableGroups().get(0).getRunnables().get(0).equals(r)
					&& !this.visited.contains(rsc.getRunnableGroups().get(1).getRunnables().get(0))) {
				final long temp = getSucceedingRunTimeCycle(cm, rsc.getRunnableGroups().get(1).getRunnables().get(0));
				if (temp > rt) {
					rt = temp;
				}
			}
		}
		return rt + getInstructions(r);
	}

	/**
	 * determination of a common label that two runnables access
	 *
	 * @param runnable
	 * @param runnable2
	 * @return label common
	 */
	public Label getCommonLabel(final Runnable runnable, final Runnable runnable2) {
		for (final ActivityGraphItem ri1 : runnable.getRunnableItems()) {
			if (ri1 instanceof LabelAccess) {
				final LabelAccess la1 = (LabelAccess) ri1;
				for (final ActivityGraphItem ri2 : runnable2.getRunnableItems()) {
					if (ri2 instanceof LabelAccess) {
						return extracted(la1, ri2);
					}
				}
			}
		}
		return null;
	}

	private Label extracted(final LabelAccess la1, final ActivityGraphItem ri2) {
		final LabelAccess la2 = (LabelAccess) ri2;
		if (la1.getData().equals(la2.getData()) && ((la1.getAccess().equals(LabelAccessEnum.READ) && la2.getAccess().equals(LabelAccessEnum.WRITE))
				|| (la1.getAccess().equals(LabelAccessEnum.WRITE) && la2.getAccess().equals(LabelAccessEnum.READ)))) {
			return la1.getData();
		}
		return null;
	}

	/**
	 * calls UniversalHandler() and writes the @param models into the original file, thats filename is extended by @param name
	 *
	 * @param event
	 *            ExecutionEvent for File information
	 */
	public static void writeModelFile(final URI path, final Amalthea ama) {
		LOGGER.debug("Writing {}\n", path);
		UniversalHandler.getInstance().writeModel(path, ama);
	}

	/**
	 * Get all runnables from a ProcessPrototype in form of an EList
	 *
	 * @param pp
	 * @return Elist<Runnable> all runnables contained in pp
	 */
	public EList<Runnable> getRunnables(final ProcessPrototype pp) {
		final EList<Runnable> rl = new BasicEList<>();
		for (final RunnableCall trc : pp.getRunnableCalls()) {
			rl.add(trc.getRunnable());
		}
		return rl;
	}

	/**
	 * Set all model received from @param UniversalHandler to @return & @param Amalthea model
	 */
	public Amalthea setAllModels(final Amalthea amodels, final UniversalHandler uh) {
		amodels.setCommonElements(uh.getCommonElements());
		amodels.setConstraintsModel(uh.getConstraintsModel());
		amodels.setHwModel(uh.getHwModel());
		amodels.setMappingModel(uh.getMappingModel());
		amodels.setOsModel(uh.getOsModel());
		amodels.setPropertyConstraintsModel(uh.getPropertyConstraintsModel());
		amodels.setStimuliModel(uh.getStimuliModel());
		amodels.setSwModel(uh.getSwModel());
		amodels.setEventModel(uh.getEvModel());
		amodels.setComponentsModel(uh.getComModel());
		amodels.setConfigModel(uh.getConfModel());
		return amodels;
	}

	public void assignAPs(final Set<AccessPrecedenceSpec> aps) {
		for (final AccessPrecedenceSpec ap : aps) {
			final Runnable r = ap.getOrigin();
			final EList<RunnableCall> trcs = r.getRunnableCalls();
			for (final RunnableCall trc : trcs) {
				ProcessPrototype pp = AmaltheaFactory.eINSTANCE.createProcessPrototype();
				if (trc.eContainer() instanceof ProcessPrototype) {
					pp = (ProcessPrototype) trc.eContainer();
				}
				if (null != pp.getName() && !pp.getAccessPrecedenceSpec().contains(ap)) {
					pp.getAccessPrecedenceSpec().add(ap);
				}
			}
		}
	}

	/**
	 * Updates ProcessScope wrt ProcessPrototypes of all RSCs
	 *
	 * @param amodels
	 * @return
	 */
	public ConstraintsModel updateRSCs(final ConstraintsModel cm, final SWModel swm) {
		for (final RunnableSequencingConstraint rsc : cm.getRunnableSequencingConstraints()) {
			final Runnable source = rsc.getRunnableGroups().get(0).getRunnables().get(0);
			final Runnable target = rsc.getRunnableGroups().get(1).getRunnables().get(0);
			for (final ProcessPrototype pp : swm.getProcessPrototypes()) {
				for (final RunnableCall trc : pp.getRunnableCalls()) {
					if (trc.getRunnable().equals(source) || trc.getRunnable().equals(target)) {
						rsc.getProcessScope().clear();
						rsc.getProcessScope().add(pp);
					}
				}
			}
		}
		return cm;
	}

	/**
	 * Adds ProcessPrototypes' FirstRunnable, LastRunnable, and Activation properties
	 *
	 * @param swm
	 * @return
	 */
	public SWModel updatePPsFirstLastActParams(final SWModel swm) {
		for (final ProcessPrototype pp : swm.getProcessPrototypes()) {
			setFirstLastRunnable(pp);
			if (null == pp.getActivation() && !pp.getRunnableCalls().isEmpty() && pp.getRunnableCalls().get(0).getRunnable().getFirstActivation() != null) {
				pp.setActivation(pp.getRunnableCalls().get(0).getRunnable().getFirstActivation());
			}
			else if (!pp.getRunnableCalls().isEmpty() && pp.getRunnableCalls().get(0).getRunnable().getFirstActivation() == null) {
				LOGGER.debug("Runnable {} has no activation, this might be a problem for the mapping process.",
						pp.getRunnableCalls().get(0).getRunnable().getName());
			}
		}
		return swm;
	}

	private void setFirstLastRunnable(final ProcessPrototype pp) {
		if (!pp.getRunnableCalls().isEmpty()) {
			if (pp.getFirstRunnable() == null || pp.getFirstRunnable() != pp.getRunnableCalls().get(0).getRunnable()) {
				pp.setFirstRunnable(pp.getRunnableCalls().get(0).getRunnable());
			}
			if (pp.getLastRunnable() == null || pp.getLastRunnable() != pp.getRunnableCalls().get(pp.getRunnableCalls().size() - 1).getRunnable()) {
				pp.setLastRunnable(pp.getRunnableCalls().get(pp.getRunnableCalls().size() - 1).getRunnable());
			}
		}
	}


	private static final String LINE = "******************************************************\n";

	/**
	 *
	 * @param processPrototypes
	 * @return String with PP.name(sum(instructions)):Runnable1 Runnable2 ...
	 */
	public String writePPs(final EList<ProcessPrototype> processPrototypes) {
		final StringBuilder sb = new StringBuilder();
		short i = 0;
		sb.append(Helper.LINE);
		sb.append(String.format("%2S%22S%16S%6S", " #", "PP", "Instructionssum", "#TRCs") + " TRCs\n");
		sb.append(Helper.LINE);
		for (final ProcessPrototype pp : processPrototypes) {
			long ppt = 0;
			final int slack = null != CustomPropertyUtil.customGetInteger(pp, KEY) ? CustomPropertyUtil.customGetInteger(pp, KEY) : 0;
			sb.append(String.format("%2s%22.21s%16.15s%6s", i++, pp.getName(), getPPInstructions(pp), pp.getRunnableCalls().size()) + " ");
			for (final RunnableCall trc : pp.getRunnableCalls()) {
				final long inc = new Helper().getInstructions(trc.getRunnable());
				final int cslack = null != CustomPropertyUtil.customGetInteger(trc, KEY) ? CustomPropertyUtil.customGetInteger(trc, KEY) : 0;
				/*name (start, end, predsRT)*/
				sb.append(String.format("%43.43s",
						String.format("%20.20s", trc.getRunnable().getName()) + "(" + (ppt + cslack) + "," + (ppt + cslack + inc) + ")"));
				ppt += inc + cslack;

			}
			if (slack > 0) {
				sb.append(" !! slack cumulated: " + slack);
			}
			sb.append("\n");
		}
		sb.append(Helper.LINE);
		return sb.toString();
	}

	public String writeTasks(final EList<Task> tasks) {
		final StringBuilder sb = new StringBuilder();
		short i = 0;
		sb.append(Helper.LINE);
		sb.append(String.format("%2S%22S%16S%6S", " #", "PP", "Instructionssum", "#TRCs") + " TRCs\n");
		sb.append(Helper.LINE);
		for (final Task task : tasks) {
			long ppt = 0;
			final int slack = null != CustomPropertyUtil.customGetInteger(task, KEY) ? CustomPropertyUtil.customGetInteger(task, KEY) : 0;
			sb.append(String.format("%2s%22.21s%16.15s%6s", i++, task.getName(), getTaskInstructions(task), task.getActivityGraph().getItems().size()) + " ");
			final List<RunnableCall> rl = task.getActivityGraph().getItems().stream().filter(agi -> agi instanceof RunnableCall).map(agi -> (RunnableCall) agi)
					.collect(Collectors.toList());
			for (final RunnableCall trc : rl) {
				final long inc = new Helper().getInstructions(trc.getRunnable());
				final int cslack = null != CustomPropertyUtil.customGetInteger(trc, KEY) ? CustomPropertyUtil.customGetInteger(trc, KEY) : 0;
				/*name (start, end, predsRT)*/
				sb.append(String.format("%43.43s",
						String.format("%20.20s", trc.getRunnable().getName()) + "(" + (ppt + cslack) + "," + (ppt + cslack + inc) + ")"));
				ppt += inc + cslack;

			}
			if (slack > 0) {
				sb.append(" !! slack cumulated: " + slack);
			}
			sb.append("\n");
		}
		sb.append(Helper.LINE);
		return sb.toString();

	}

	private long getTaskInstructions(final Task task) {
		long instrSum = 0;
		for (final ActivityGraphItem agi : task.getActivityGraph().getItems()) {
			if (agi instanceof RunnableCall) {
				final RunnableCall rc = (RunnableCall) agi;
				instrSum += getInstructions(rc.getRunnable());
				final int slack = null != CustomPropertyUtil.customGetInteger(rc, KEY) ? CustomPropertyUtil.customGetInteger(rc, KEY) : 0;
				instrSum += slack > 0 ? slack : 0;
			}
		}
		return instrSum;
	}

	/**
	 *
	 * @param pp
	 * @return long the sum of the PP's Runnable Instructions
	 */
	public long getPPInstructions(final ProcessPrototype pp) {
		long instrSum = 0;
		for (final RunnableCall trc : pp.getRunnableCalls()) {
			instrSum += getInstructions(trc.getRunnable());
			final int slack = null != CustomPropertyUtil.customGetInteger(trc, KEY) ? CustomPropertyUtil.customGetInteger(trc, KEY) : 0;
			instrSum += slack > 0 ? slack : 0;
		}
		return instrSum;
	}

	/**
	 * @param pp
	 * @return double sum of all runnbles' instructions multiplied with PP's periodic activation in seconds
	 */
	public double getPPIntrSumActRel(final ProcessPrototype pp) {
		long instrSum = 0;
		for (final RunnableCall trc : pp.getRunnableCalls()) {
			instrSum += getInstructions(trc.getRunnable());
		}
		/* mpis = multiplier in seconds */
		double mpis = 1;
		if (pp.getActivation() instanceof PeriodicActivation) {
			final PeriodicActivation pact = (PeriodicActivation) pp.getActivation();
			/*e.g. 250ms => *4 (=(1/0.001)/250)*/
			mpis = (1 / getTimeUnit(pact)) / getMeanActivation(pact);
		}
		instrSum *= mpis;
		return instrSum;
	}

	private double getMeanActivation(final PeriodicActivation pact) {
		if (null != pact.getMax() && null != pact.getMin() && null != pact.getMax().getValue() && null != pact.getMin().getValue()
				&& null != pact.getMax().getUnit() && null != pact.getMin().getUnit()) {
			return (pact.getMax().getValue().add(pact.getMin().getValue())).divide(BigInteger.valueOf(2)).doubleValue();
		}
		LOGGER.error("{} min/max values set", pact.getName());
		return 1;
	}

	/**
	 * @param pact
	 * @return double fraction representing the time unit of the given period
	 */
	public double getTimeUnit(final Activation pact) {
		if (pact instanceof PeriodicActivation) {
			final PeriodicActivation periodic = (PeriodicActivation) pact;
			if (null != periodic.getMax() && null != periodic.getMax().getUnit()) {
				switch (periodic.getMax().getUnit()) {
					case MS:
						return 0.001;
					case US:
						return 0.000001;
					case NS:
						return 0.000000001;
					case PS:
						return 0.000000000001;
					case S:
						return 1;
					default:
						break;
				}
			}
			else {
				LOGGER.error("{} requres a max value and a timeunit to be set", periodic.getName());
			}
		}
		return 0;

	}

	/**
	 * @param rscl
	 * @return true if all RunnableSequencingConstraints have two groups and at least one runnable in each
	 */
	public boolean allRSCsHave2ValidEntries(final EList<RunnableSequencingConstraint> rscl) {
		for (final RunnableSequencingConstraint rsc : rscl) {
			if (null == rsc.getRunnableGroups().get(0) || null == rsc.getRunnableGroups().get(1) || rsc.getRunnableGroups().get(0).getRunnables().isEmpty()
					|| rsc.getRunnableGroups().get(1).getRunnables().isEmpty()) {
				return false;
			}
		}
		return true;
	}


	/**
	 * @param swm
	 * @return true if all Runnables are called once (single task runnable call)
	 */

	public boolean tRCsAreConsist(final SWModel swm) {
		for (final Runnable r : swm.getRunnables()) {
			if (r.getRunnableCalls().size() > 1) {
				return false;
			}
		}
		return true;
	}

	/**
	 * checks whether all periodic activations are harmonic
	 *
	 * @return true if periodic activations are harmonic
	 */
	public boolean activationsAreHarmonic(final EList<Activation> acts) {
		final ArrayList<Double> pacts = new ArrayList<>();
		for (final Activation act : acts) {
			if (act instanceof PeriodicActivation) {
				final PeriodicActivation pa = (PeriodicActivation) act;
				pacts.add(getMeanActivation(pa));
			}
			else {
				LOGGER.debug("{} is not a periodic activation and is ignored for harmonic activation analysis.", act.getName());
			}
		}
		Collections.sort(pacts, Collections.reverseOrder());
		if (pacts.size() > 1) {
			for (int i = 0; i < pacts.size(); i++) {
				final Double currentAct = pacts.get(i);
				for (int j = i; j < pacts.size(); j++) {
					if (currentAct % pacts.get(j) > 0) {
						return false;
					}
				}
			}
		}
		return true;
	}

	public boolean runnablesContainedinSamePP(final EList<Runnable> runnables, final EList<Runnable> runnables2) {
		for (final Runnable r : runnables) {
			for (final Runnable r2 : runnables2) {
				for (final RunnableCall rc : r.getRunnableCalls()) {
					for (final RunnableCall rc2 : r2.getRunnableCalls()) {
						if (rc.eContainer().equals(rc2.eContainer())) {
							return true;
						}
					}
				}
			}
		}
		return false;
	}

	public boolean runnablesContainedinSamePP(final Runnable r1, final Runnable r2) {
		for (final RunnableCall trc1 : r1.getRunnableCalls()) {
			for (final RunnableCall trc2 : r2.getRunnableCalls()) {
				if (trc1.eContainer().equals(trc2.eContainer())) {
					return true;
				}
			}
		}

		return false;
	}

	public long getDefaultOrExtendedTicks(final Ticks ticks) {
		long ret = 0l;
		if (null != ticks.getDefault() && ticks.getDefault().getUpperBound() > 0) {
			return ticks.getDefault().getUpperBound();
		}
		if (null != ticks.getExtended()) {
			long max = 0;
			for (final Entry<ProcessingUnitDefinition, IDiscreteValueDeviation> ticksl : ticks.getExtended()) {
				if (ticksl.getValue().getUpperBound() > max) {
					max = ticksl.getValue().getUpperBound();
				}
			}
			ret = max;
		}
		return ret;
	}

	public long getDefaultOrExtendedTicks(final List<Ticks> ticks) {
		long ret = 0;
		for (final Ticks ticksl : ticks) {
			ret += getDefaultOrExtendedTicks(ticksl);
		}
		return ret;
	}

	public ConstraintsModel ensureDepsNoCycles(final Amalthea ama) {
		/* If no dependencies (runnable sequencing constraints) exist,
		 * 		(i) 	analyze runnable label accesses and create RSCs
		 * 		(ii)	decompose cycles 								*/
		ConstraintsModel cm = ama.getConstraintsModel();
		if (null == cm || cm.getRunnableSequencingConstraints().isEmpty()) {
			final CheckLabels cl = new CheckLabels();
			cl.setSwm(ama.getSwModel());
			cl.setCMModel(cm);
			cl.run(new NullProgressMonitor());
			cm = cl.getCMModel();
		}
		final CycleElimination ce = new CycleElimination(ama.getSwModel(), cm);
		if (ce.containsCycles()) {
			ce.run(new NullProgressMonitor());
			cm = ce.getCm();
		}
		ama.setConstraintsModel(cm);
		return cm;
	}

	public long getRSLenth(final Path cpt) {
		long sum = 0;
		for (final Runnable r : cpt.getRunnables()) {
			sum += getInstructions(r);
		}
		return sum;
	}
}
