post {
	// After all rules have executed, create constants for inputs and a scope to monitor output
	var topActivity = UML!Activity.all.selectOne(a|not a.eContainer().isTypeOf(UML!Activity));
	var topBlock = topActivity.equivalent();
	
	var outports = topActivity.ownedNode.select(n|n.isOut());
	var inports = topActivity.ownedNode.select(n|n.isIn());
	
	// Create constants for inputs
	for (i in Sequence{1..inports.size()}) {
		var constant : new Simulink!`simulink/Sources/Constant`;
		constant.link(topBlock, 1, i);
	}
	
	// Create a scope to monitor output 
	var scope : new Simulink!`simulink/Sinks/Scope`;
	scope.numInputPorts = outports.size();
	for (i in Sequence{1..outports.size()}) {
		topBlock.link(scope, i, i);
	}
}

rule Activity2Subsystem 
	transform s : UML!Activity
	to t : Simulink!`simulink/Ports & Subsystems/Subsystem` {
	
	guard : not s.isFunction()
	
	t.name = s.name;
	
	if (s.eContainer().isTypeOf(UML!Activity)) {
		t.parent ::= s.eContainer();
	}
	
}

rule Activity2Function 
	transform s : UML!Activity
	to t : Simulink!`simulink/User-Defined Functions/MATLAB Function` {
	
	guard : s.isFunction()
	
	t.name = s.name;
	t.parent ::= s.eContainer();
	t.script = s.getScript();
}

@abstract
rule ActivityParameter2Port
	transform s : UML!ActivityParameterNode
	to t : Any {
	
	guard : not s.eContainer().isFunction()
	
	t.parent ::= s.eContainer();
	t.name = s.parameter.name;
	
}

rule ActivityParameter2Inport 
	transform s : UML!ActivityParameterNode
	to t : Simulink!`simulink/Ports & Subsystems/In1` 
	extends ActivityParameter2Port {
	
	guard : s.isIn()
	
}

rule ActivityParameter2Outport 
	transform s : UML!ActivityParameterNode
	to t : Simulink!`simulink/Ports & Subsystems/Out1` 
	extends ActivityParameter2Port {
	
	guard : s.isOut()
	
}

rule ControlFlow2Link
	transform s : UML!ControlFlow
	to t : Sequence {
	
	deleteAutoPorts();
	
	var sourceBlock; var targetBlock;
	var sourcePort; var targetPort;
	
	// The connected activities are at the same level
	if (s.source.eContainer().eContainer() == s.target.eContainer().eContainer()) {
		sourceBlock = s.source.eContainer().equivalent();
		targetBlock = s.target.eContainer().equivalent();
		sourcePort = s.source.getSiblings().indexOf(s.source) + 1;
		targetPort = s.target.getSiblings().indexOf(s.target) + 1;
	} 
	// The target activity is the parent of the source activity
	else if (s.source.eContainer().eContainer() = s.target.eContainer()) { 
		sourceBlock = s.source.eContainer().equivalent();
		targetBlock = s.target.equivalent();
		sourcePort = s.source.getSiblings().indexOf(s.source) + 1;
		targetPort = 1;
	}
	// The source activity is the parent of the target activity
	else {
		sourceBlock = s.source.equivalent();
		targetBlock = s.target.eContainer().equivalent();
		sourcePort = 1;
		targetPort = s.target.getSiblings().indexOf(s.target) + 1;
	}
	sourceBlock.link(targetBlock, sourcePort, targetPort);
	//("Connecting " + sourceBlock.name + "[" + sourcePort + "] to " + targetBlock.name + "[" + targetPort + "]").println();
}

operation deleteAutoPorts() {
	// Delete all the auto-generated ports in subsystems
	delete Simulink!Inport.all.select(p|p.name = "In1").outports.flatten().lines.flatten();
	delete Simulink!Inport.all.select(p|p.name = "In1");
	delete Simulink!Outport.all.select(p|p.name = "Out1");
}

operation UML!ActivityParameterNode isOut() {
	return self.parameter.direction = UML!ParameterDirectionKind#out;
}

operation UML!ActivityParameterNode isIn() {
	return not self.isOut();
}

operation UML!ActivityParameterNode getSiblings(){ 
	return self.eContainer().ownedNode.select(n|n.parameter.direction = self.parameter.direction);
}

operation UML!Activity getScript() {
	var script = "function " + self.ownedNode.selectOne(n|n.isOut()).parameter.name + " = fcn(" + 
		self.ownedNode.select(n|n.isIn()).collect(n|n.name).concat(",") + ")\\n";
	script += self.stereotypeApplications.first.body.replaceAll("\\n","\\\\n");
	return script;
}

operation UML!Activity isFunction() {
	return self.appliedStereotypes.exists(s|s.name = "Function");
}
