text:
// Global variables
var graph;
var paper;
var stencil;
var mode;

// Mode specific variables
var graphObject = new graphObject();		// Stores all variables between modes

var linkInspector = new LinkInspector();
var elementInspector = new ElementInspector();
var currentHalo;
var currentAnalysis;

// Analysis variables
var historyObject = new historyObject();
var queryObject = new queryObject();

var loader;
var reader;

//Properties for both core and simulator.
// var satvalues = {satisfied: 2, partiallysatisfied: 1, partiallydenied: -1, denied: -2, unknown: 0, conflict: 3, none: 4};
var satValueDict = {
	"unknown": 5,
	"satisfied": 3,
	"partiallysatisfied": 2,
	"partiallydenied": 1,
	"denied": 0,
	"conflict": 4,
	"none": 6
};
var satValueDictInverse = {
	5: "unknown",
	3: "satisfied",
	2: "partiallysatisfied",
	1: "partiallydenied",
	0: "denied",
	4: "conflict",
	6: "none"
};
var weightedContDict = {
	"makes": 0,
	"helps": 1,
	"hurts": 2,
	"breaks": 3
};
const D = satValueDict['denied'];
const PD = satValueDict['partiallydenied'];
const PS = satValueDict['partiallysatisfied'];
const S = satValueDict['satisfied'];
const C = satValueDict['conflict'];
const U = satValueDict['unknown'];
const N = satValueDict['none'];

const weightedContributionFunction = [
	// makes, helps, hurts, breaks
	[ D, PD, PS, PS ], // D		// Last column PS for i* and S for GRL.
	[ PD, PD, PS, PS ], // PD
	[ PS, PS, PD, PD ], // PS
	[  S, PS, PD,  D ], // S
	[  U,  U,  U,  U ], // C
	[  U,  U,  U,  U ], // U
	[  N,  N,  N,  N ], // N
];
const combineContributionsFunction = [
	// D, PD, PS,  S,  C,  U,  N
	[  D,  D, PD,  C,  C,  U,  D ], // D
	[  D, PD,  U, PS,  C,  U, PD ], // PD		PD + PS -> U was originally N. Changed for controlled experiment.
	[ PD,  U, PS,  S,  C,  U, PS ], // PS
	[  C, PS,  S,  S,  C,  U,  S ], // S
	[  C,  C,  C,  C,  C,  C,  C ], // C
	[  U,  U,  U,  U,  C,  U,  U ], // U
	[  D, PD, PS,  S,  C,  U,  N ], // N
];
const combinePreconditionFunction = [ //row = previous-value col = min-precondition
	// D, PD, PS,  S,  C,  U,  N
	[  D,  D,  D,  D,  C,  U,  D ], // D
	[  D,  D,  D, PD,  C,  U, PD ], // PD
	[  D,  D,  D, PS,  C,  U, PS ], // PS
	[  D,  D,  S,  S,  C,  U,  S ], // S
	[  C,  C,  C,  C,  C,  C,  C ], // C
	[  D,  D,  D,  U,  C,  U,  U ], // U
	[  D,  D,  D,  S,  C,  U,  N ], // N
];

// ----------------------------------------------------------------- //
// Page setup

// Mode used specify layout and functionality of toolbars
mode = "Modelling";		// 'Analysis' or 'Modelling'
linkMode = "Relationships";	// 'Relationships' or 'Constraints'

graph = new joint.dia.Graph();

// Create a paper and wrap it in a PaperScroller.
paper = new joint.dia.Paper({
    width: 1000,
    height: 1000,
    gridSize: 10,
    perpendicularLinks: false,
    model: graph,
    defaultLink: new joint.dia.Link({
		'attrs': {
			'.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
			'.marker-source': {'d': 'M 0 0'},
			'.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 z'}
			},
		'labels': [{position: 0.5, attrs: {text: {text: "this is default link. You shouldnt be able to see it"}}}]
	})
});

var paperScroller = new joint.ui.PaperScroller({
	autoResizePaper: true,
	paper: paper
});

$('#paper').append(paperScroller.render().el);
paperScroller.center();

// Create and populate stencil.
stencil = new joint.ui.Stencil({
	graph: graph,
	paper: paper,
	width: 200,
	height: 600
});

$('#stencil').append(stencil.render().el);

var goal = new joint.shapes.basic.Goal({ position: {x: 50, y: 20} });
var task = new joint.shapes.basic.Task({ position: {x: 50, y: 100} });
var quality = new joint.shapes.basic.Quality({ position: {x: 50, y: 170} });
var res = new joint.shapes.basic.Resource({ position: {x: 50, y: 250} });
// This is actor without boundary
var act2 = new joint.shapes.basic.Actor2({ position: {x: 60, y: 330} });
var act = new joint.shapes.basic.Actor({ position: {x: 40, y: 430} });

stencil.load([goal, task, quality, res, act2, act]);

//Setup LinkInspector
$('.inspector').append(linkInspector.el);

//Interface set up for modelling mode on startup
$('#dropdown-model').css("display","none");
$('#history').css("display","none");

//If a cookie exists, process it as a previously created graph and load it.
if (document.cookie){
	var cookies = document.cookie.split(";");
	var prevgraph = "";

	//Loop through the cookies to find the one representing the graph, if it exists
	for (var i = 0; i < cookies.length; i++){
		if (cookies[i].indexOf("graph=") >= 0){
			prevgraph = cookies[i].substr(6);
		}
	}

	if (prevgraph){
		graph.fromJSON(JSON.parse(prevgraph));
	}

}

// ----------------------------------------------------------------- //
// Rappid setup

var element_counter = 0;
var max_font = 20;
var min_font = 6;
var current_font = 10;

//Whenever an element is added to the graph
graph.on("add", function(cell){
	if (cell instanceof joint.dia.Link){
		if (graph.getCell(cell.get("source").id) instanceof joint.shapes.basic.Actor){

			cell.attr({
				'.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
				'.marker-source': {'d': '0'},
				'.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 L 0 5 L 10 10 L 0 5 L 10 5 L 0 5'}
			});
			cell.prop("linktype", "actorlink");

			// Unable to model constraints for actors
			if(linkMode == "Relationships"){
				cell.label(0, {attrs: {text: {text: "is-a"}}});
			}
		}
	}	//Don't do anything for links

	//Give element a unique default
	cell.attr(".name/text", cell.attr(".name/text") + "_" + element_counter);
	element_counter++;

	//Add Functions and sat values to added types
	if (cell instanceof joint.shapes.basic.Intention){
		cell.attr('.funcvalue/text', ' ');
	}

	//Send actors to background so elements are placed on top
	if (cell instanceof joint.shapes.basic.Actor){
		cell.toBack();
	}

	paper.trigger("cell:pointerup", cell.findView(paper));
});

//Auto-save the cookie whenever the graph is changed.
graph.on("change", function(){
	saveCookie();
});
function saveCookie(){
	var graphtext = JSON.stringify(graph.toJSON());
	document.cookie = "graph=" + graphtext;
}

var selection = new Backbone.Collection();

var selectionView = new joint.ui.SelectionView({
	paper: paper,
	graph: graph,
	model: selection
});

// Initiate selecting when the user grabs the blank area of the paper while the Shift key is pressed.
// Otherwise, initiate paper pan.
paper.on('blank:pointerdown', function(evt, x, y) {
    if (_.contains(KeyboardJS.activeKeys(), 'shift')) {
    	if(mode == "Analysis")
			return

        selectionView.startSelecting(evt, x, y);
    } else {
        paperScroller.startPanning(evt, x, y);
    }
});

paper.on('cell:pointerdown', function(cellView, evt, x, y){
	if(mode == "Analysis"){
		queryObject.addCell(cellView);
		return
	}

	var cell = cellView.model;
	if (cell instanceof joint.dia.Link){
		cell.reparent();
	}

	//Unembed cell so you can move it out of actor
	if (cell.get('parent') && !(cell instanceof joint.dia.Link)) {
		graph.getCell(cell.get('parent')).unembed(cell);
	}
});

// Unhighlight everything when blank is being clicked
paper.on('blank:pointerclick', function(){
	var elements = graph.getElements();
	for (var i = 0; i < elements.length; i++){
		var cellView  = elements[i].findView(paper);
		var cell = cellView.model;
		cellView.unhighlight();
		cell.attr('.outer/stroke', 'black');
		cell.attr('.outer/stroke-width', '1');
		if (cell instanceof joint.shapes.basic.Actor){
			cell.attr('.outer/stroke-dasharray', '5 2');
		}

	}
	linkInspector.clear();
	elementInspector.clear();
});

// Disable context menu inside the paper.
paper.el.oncontextmenu = function(evt) { evt.preventDefault(); };

// A simple element editor.
// --------------------------------------
$('.inspector').append(elementInspector.el);

//Link equivalent of the element editor
paper.on("link:options", function(evt, cell){
	if(mode == "Analysis")
		return
	var link = cell.model;
	setLinkType(link);
	var linktype = link.attr(".link-type");
	linkInspector.clear();
	elementInspector.clear();
	if (linkMode == "Relationships"){
		linkInspector.render(cell, linktype);

	}
});
// Identify link-type: Refinement, Contribution, Qualification or NeededBy
// And store the linktype into the link
function setLinkType(link){
	if (!link.getTargetElement() || !link.getSourceElement()){
		link.attr(".link-type", "Error");
		return;
	}
	var sourceCell = link.getSourceElement().attributes.type;
	var targetCell = link.getTargetElement().attributes.type;
	var sourceCellInActor = link.getSourceElement().get('parent');
	var targetCellInActor = link.getTargetElement().get('parent');

	switch(true){
		// Links of actors must be paired with other actors
		case ((sourceCell == "basic.Actor" || sourceCell == "basic.Actor2") && (targetCell == "basic.Actor" || targetCell == "basic.Actor2")):
			link.attr(".link-type", "Actor");
			break;
		case ((sourceCell == "basic.Actor") && (!targetCellInActor)):
			link.attr(".link-type", "Error");
			break;
		case ((targetCell == "basic.Actor") && (!sourceCellInActor)):
			link.attr(".link-type", "Error");
			break;

		case ((sourceCell == "basic.Actor2") && (!targetCellInActor)):
			link.attr(".link-type", "Dependency");
			break;
		case ((targetCell == "basic.Actor2") && (!sourceCellInActor)):
			link.attr(".link-type", "Dependency");
			break;

		case ((!!sourceCellInActor) && (!targetCellInActor && (targetCell == "basic.Actor" || targetCell == "basic.Actor2"))):
			// link.attr(".link-type", "Dependency");
			link.attr(".link-type", "Error");
			break;
		case ((!!targetCellInActor) && (!sourceCellInActor && (sourceCell == "basic.Actor" || sourceCell == "basic.Actor2"))):
			// link.attr(".link-type", "Dependency");
			link.attr(".link-type", "Error");
			break;
		case ((!!sourceCellInActor) && (!targetCellInActor)):
			link.attr(".link-type", "Dependency");
			break;
		case ((!!targetCellInActor) && (!sourceCellInActor)):
			link.attr(".link-type", "Dependency");
			break;

		case ((sourceCell == "basic.Goal") && (targetCell == "basic.Goal")):
			link.attr(".link-type", "Refinement");
			break;
		case ((sourceCell == "basic.Goal") && (targetCell == "basic.Quality")):
			link.attr(".link-type", "Contribution");
			break;
		case ((sourceCell == "basic.Goal") && (targetCell == "basic.Task")):
			link.attr(".link-type", "Refinement");
			break;
		case ((sourceCell == "basic.Goal") && (targetCell == "basic.Resource")):
			link.attr(".link-type", "Error");
			break;
		case ((sourceCell == "basic.Quality") && (targetCell == "basic.Goal")):
			link.attr(".link-type", "Qualification");
			break;
		case ((sourceCell == "basic.Quality") && (targetCell == "basic.Quality")):
			link.attr(".link-type", "Contribution");
			break;
		case ((sourceCell == "basic.Quality") && (targetCell == "basic.Task")):
			link.attr(".link-type", "Qualification");
			break;
		case ((sourceCell == "basic.Quality") && (targetCell == "basic.Resource")):
			link.attr(".link-type", "Qualification");
			break;
		case ((sourceCell == "basic.Task") && (targetCell == "basic.Goal")):
			link.attr(".link-type", "Refinement");
			break;
		case ((sourceCell == "basic.Task") && (targetCell == "basic.Quality")):
			link.attr(".link-type", "Contribution");
			break;
		case ((sourceCell == "basic.Task") && (targetCell == "basic.Task")):
			link.attr(".link-type", "Refinement");
			break;
		case ((sourceCell == "basic.Task") && (targetCell == "basic.Resource")):
			link.attr(".link-type", "Error");
			break;
		case ((sourceCell == "basic.Resource") && (targetCell == "basic.Goal")):
			link.attr(".link-type", "Error");
			break;
		case ((sourceCell == "basic.Resource") && (targetCell == "basic.Quality")):
			link.attr(".link-type", "Contribution");
			break;
		case ((sourceCell == "basic.Resource") && (targetCell == "basic.Task")):
			link.attr(".link-type", "NeededBy");
			break;
		case ((sourceCell == "basic.Resource") && (targetCell == "basic.Resource")):
			link.attr(".link-type", "Error");
			break;

		default:
			console.log('Default');
	}
	return;
}
// Need to draw a link upon user creating link between 2 nodes
// Given a link and linktype, draw the deafult link
function drawDefaultLink(link, linktype){
	switch(linktype){
		case "Refinement":
			link.attr({
			  '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
			  '.marker-source': {'d': 'M 0 0'},
			  '.marker-target': {stroke: '#000000', 'stroke-width': 1, "d": 'M 10 0 L 10 10 M 10 5 L 0 5' }
			});
			link.label(0 ,{position: 0.5, attrs: {text: {text: 'and'}}});
			break;
		case "Qualification":
			link.attr({
			  '.connection': {stroke: '#000000', 'stroke-dasharray': '5 2'},
			  '.marker-source': {'d': 'M 0 0'},
			  '.marker-target': {'d': 'M 0 0'}
			});
			link.label(0 ,{position: 0.5, attrs: {text: {text: ""}}});
			break;
		case "Contribution":
			link.attr({
			  '.marker-target': {'d': 'M 12 -3 L 5 5 L 12 13 M 5 5 L 30 5', 'fill': 'transparent'}
			})
			link.label(0 ,{position: 0.5, attrs: {text: {text: "makes"}}});
			break;
		case "NeededBy":
			link.attr({
			  '.marker-target': {'d': 'M-4,0a4,4 0 1,0 8,0a4,4 0 1,0 -8,0'}
			})
			link.label(0 ,{position: 0.5, attrs: {text: {text: ""}}});
			break;
		case "Dependency":
			link.attr({
				'.marker-source': {'d': 'M 0 0'},
				//'.marker-target': {'d': 'M 100 0 C 85 -5, 85 20, 100 15 L 100 0 M -100 0' ,'fill': 'transparent'}, //Old
        '.marker-target': {'d': 'M 100 0 C 85 -5, 85 20, 100 15 L 100 0','fill': 'transparent'},
			})
      link.label(0 ,{position: 0.5, attrs: {text: {text: "depends"}}});
			break;
		case "Actor":
			link.label(0 ,{position: 0.5, attrs: {text: {text: 'is-a'}}});
			break;
		case "Error":
			link.label(0 ,{position: 0.5, attrs: {text: {text: "Error"}}});
			break;
		default:
			break;
	}
}

//When a cell is clicked, create the Halo
function isLinkInvalid(link){
	return (!link.prop('source/id') || !link.prop('target/id'));
}

//Single click on cell
paper.on('cell:pointerup', function(cellView, evt) {
	if(mode == "Analysis")
		return

	// Link
	if (cellView.model instanceof joint.dia.Link){
		var link = cellView.model;
		// var sourceCell = link.getSourceElement().attributes.type;
		setLinkType(link);
		var linktype = link.attr(".link-type");
		drawDefaultLink(link, linktype);

		// Check if link is valid or not
		if (link.getTargetElement()){
			var targetCell = link.getTargetElement().attributes.type;

		}
		return

	// element is selected
	}else{
		selection.reset();
		selection.add(cellView.model);
		var cell = cellView.model;
		// Unhighlight everything
		var elements = graph.getElements();
		for (var i = 0; i < elements.length; i++){
			var cellview  = elements[i].findView(paper);
			cellview.unhighlight();
			cellview.model.attr('.outer/stroke', 'black');
			cellview.model.attr('.outer/stroke-width', '1');
			if (cellview.model instanceof joint.shapes.basic.Actor){
				cellview.model.attr('.outer/stroke-dasharray', '5 2');
			}
		}
		// Highlight when cell is clicked
		cellView.highlight();
		searchRoot(cell, null, null);
		searchLeaf(cell, null, null);

		currentHalo = new joint.ui.Halo({
			graph: graph,
			paper: paper,
			cellView: cellView,
			type: 'toolbar'
		});

		currentHalo.removeHandle('unlink');
		currentHalo.removeHandle('clone');
		currentHalo.removeHandle('fork');
		currentHalo.removeHandle('rotate');
		currentHalo.render();

		//Embed an element into an actor boundary, if necessary
		if (!(cellView.model instanceof joint.shapes.basic.Actor) && !(cellView.model instanceof joint.shapes.basic.Actor2)){
			var ActorsBelow = paper.findViewsFromPoint(cell.getBBox().center());

			if (ActorsBelow.length){
				for (var a = 0; a < ActorsBelow.length; a++){
					if (ActorsBelow[a].model instanceof joint.shapes.basic.Actor){

						ActorsBelow[a].model.embed(cell);
					}
				}
			}
		}

		linkInspector.clear();
		elementInspector.render(cellView);
	}
});

// ===================Search for root and leaf =====================

// Given a cell, search and highlight its root
// It ultilizes recursion
// When first time calling it, originalCell is null
// After that it is set to the cell that is being clicked on
// This is to prevent searching in an cyclic graph
function searchRoot(cell, originalCell, path){
	// If cellView = originalCell, we have a cycle
	if (cell == originalCell){
		return;
	}
	// If first time calling it, set originalCell to cell
	if (originalCell == null){
		originalCell = cell;
	}
	// if path is null, then create an empty array
	if (path == null) {
		var path = [];
	}
	// Highlight it when it is a root
	if (isRoot(cell)){
		cell.attr('.outer/stroke', '#996633');
		cell.attr('.outer/stroke-width', '5');
		cell.attr('.outer/stroke-dasharray', '');

		return;
	}
	// A list of nodes to find next
	var queue = enQueue1(cell);
	// If no more node to search for, we are done
	if (queue.length == 0){
		return;
	}
	// append all elements in queue to the path
	path.push(cell)
	// check all elements in the path to see whether the cycle exist
	for (var i = path.length - 1; i >= 0; i--) {
		for (var p = i - 1; p >= 0; p--) {
			if (path[i] == path[p]) {
				return;
			}
		}
	}
	// Call searchRoot for all nodes in queue
	for (var i = queue.length - 1; i >= 0; i--) {
		searchRoot(queue[i], originalCell, path);
	}

	return;
}
// Definition of root:
// No outgoing refinement, contribution, neededby link
// No incoming dependency , Actor link
// No error link at all
function isRoot(cell){
	var outboundLinks = graph.getConnectedLinks(cell, {outbound: true});
	var inboundLinks = graph.getConnectedLinks(cell, {inbound: true});
	var inboundQualificationCount = 0;
	var outboundQualificationCount = 0;

	for (var i = inboundLinks.length - 1; i >= 0; i--) {
		var linkType = inboundLinks[i].attr('.link-type')
		if (linkType == 'Error' || linkType == 'Dependency' || linkType == 'Actor' ){
			return false;
		}
		if (linkType == 'Qualification'){
			inboundQualificationCount = inboundQualificationCount + 1;
		}
	}

	for (var i = outboundLinks.length - 1; i >= 0; i--) {
		var linkType = outboundLinks[i].attr('.link-type')
		if (linkType == 'Error' || (linkType != 'Dependency' && linkType != 'Actor' && linkType != 'Qualification')){
			return false;
		}

		if (linkType == 'Qualification'){
			outboundQualificationCount = outboundQualificationCount + 1;
		}
	}

	// If no outbound and inbound link, do not highlight anything
	// If all outbound links are qualification, and all inbound links are qualification, do not highlight anything
	if (outboundLinks.length == outboundQualificationCount && inboundLinks.length == inboundQualificationCount){
		return false;
	}

	return true;
}
// This is for searchRoot function
// Given a cell, find a list of all "parent" cells for searchRoot to search next
// We define a parent P as:
// A dependency/actor link going from P to current node
// Or
// A refinement, contribution, neededby link from current node to P
function enQueue1(cell){
	var queue = [];
	var outboundLinks = graph.getConnectedLinks(cell, {outbound: true});
	var inboundLinks = graph.getConnectedLinks(cell, {inbound: true});
	for (var i = inboundLinks.length - 1; i >= 0; i--) {
		var linkType = inboundLinks[i].attr('.link-type')
		if (linkType == 'Dependency' || linkType == 'Actor'){
			var sourceCell = inboundLinks[i].getSourceElement();
			queue.push(sourceCell);
		}
	}

	for (var i = outboundLinks.length - 1; i >= 0; i--) {
		var linkType = outboundLinks[i].attr('.link-type')
		if (linkType != 'Error' && linkType != 'Dependency' && linkType != 'Actor' && linkType != 'Qualification'){
			var targetCell = outboundLinks[i].getTargetElement();
			queue.push(targetCell);
		}
	}
	return queue;

}

// Given a cell, search and highlight its leaf
// This is a modified BFS alg ultilizing recursion
// When first time calling it, originalCell is null
// After that it is set to the cell that is being clicked on
// This is to prevent searching in an cyclic graph
function searchLeaf(cell, originalCell, path){
	// If cellView = originalCell, we have a cycle
	if (cell == originalCell){
		return;
	}
	// If first time calling it, set originalCell to cell
	if (originalCell == null){
		originalCell = cell;
	}
	// if path is null, then create an empty array
	if (path == null) {
		var path = [];
	}
	// Highlight it when it is a leaf
	if (isLeaf(cell)){
		cell.attr('.outer/stroke', '#339933');
		cell.attr('.outer/stroke-width', '5');
		cell.attr('.outer/stroke-dasharray', '');

		return;
	}
	// A list of nodes to find next
	var queue = enQueue2(cell);
	// If no more node to search for, we are done
	if (queue.length == 0){
		return;
	}
	// append all elements in queue to the path
	path.push(cell)
	// check all elements in the path to see whether the cycle exist
	for (var i = path.length - 1; i >= 0; i--) {
		for (var p = i - 1; p >= 0; p--) {
			if (path[i] == path[p]) {
				return;
			}
		}
	}
	// Call searchLeaf for all nodes in queue
	for (var i = queue.length - 1; i >= 0; i--) {
		searchLeaf(queue[i], originalCell, path);
	}

	return;
}
// Definition of leaf:
// No incoming refinement, contribution, neededby link
// No outgoing dependency , Actor link
// No error link at all
function isLeaf(cell){
	var outboundLinks = graph.getConnectedLinks(cell, {outbound: true});
	var inboundLinks = graph.getConnectedLinks(cell, {inbound: true});
	var inboundQualificationCount = 0;
	var outboundQualificationCount = 0;

	for (var i = outboundLinks.length - 1; i >= 0; i--) {
		var linkType = outboundLinks[i].attr('.link-type')
		if (linkType == 'Error' || linkType == 'Dependency' || linkType == 'Actor' ){
			return false;
		}
		if (linkType == 'Qualification'){
			outboundQualificationCount = outboundQualificationCount + 1;
		}
	}

	for (var i = inboundLinks.length - 1; i >= 0; i--) {
		var linkType = inboundLinks[i].attr('.link-type')
		if (linkType == 'Error' || (linkType != 'Dependency' && linkType != 'Actor' && linkType != 'Qualification')){
			return false;
		}
		if (linkType == 'Qualification'){
			inboundQualificationCount = inboundQualificationCount + 1;
		}
	}

	// If no outbound and inbound link, do not highlight anything
	// If all outbound links are qualification, and all inbound links are qualification, do not highlight anything
	if (outboundLinks.length == outboundQualificationCount && inboundLinks.length == inboundQualificationCount){
		return false;
	}

	return true;
}
// This is for searchLeaf function
// Given a cell, find a list of all "parent" cells for searchLeaf to search next
// We define a children C as:
// A dependency/actor link going from current node to C
// Or
// A refinement, contribution, qualification, neededby link from C to current node
function enQueue2(cell){
	var queue = [];
	var outboundLinks = graph.getConnectedLinks(cell, {outbound: true});
	var inboundLinks = graph.getConnectedLinks(cell, {inbound: true});
	for (var i = outboundLinks.length - 1; i >= 0; i--) {
		var linkType = outboundLinks[i].attr('.link-type')
		if (linkType == 'Dependency' || linkType == 'Actor'){
			var targetCell = outboundLinks[i].getTargetElement();
			queue.push(targetCell);
		}
	}

	for (var i = inboundLinks.length - 1; i >= 0; i--) {
		var linkType = inboundLinks[i].attr('.link-type')
		if (linkType != 'Error' && linkType != 'Dependency' && linkType != 'Actor' && linkType != 'Qualification'){
			var sourceCell = inboundLinks[i].getSourceElement();
			queue.push(sourceCell);
		}
	}
	return queue;

}

// ====================================================================
graph.on('change:size', function(cell, size){
	cell.attr(".label/cx", 0.25 * size.width);

	//Calculate point on actor boundary for label (to always remain on boundary)
	var b = size.height;
	var c = -(size.height/2 + (size.height/2) * (size.height/2) * (1 - (-0.75 * size.width/2) * (-0.75 * size.width/2)  / ((size.width/2) * (size.width/2)) ));
	var y_cord = (-b + Math.sqrt(b*b - 4*c)) / 2;

	cell.attr(".label/cy", y_cord);
});

// ----------------------------------------------------------------- //
// Keyboard shortcuts

var clipboard = new joint.ui.Clipboard();
KeyboardJS.on('ctrl + c', function() {
	// Copy all selected elements and their associatedf links.
	clipboard.copyElements(selection, graph, { translate: { dx: 20, dy: 20 }, useLocalStorage: true });
});
KeyboardJS.on('ctrl + v', function() {
	clipboard.pasteCells(graph);

	selectionView.cancelSelection();

	clipboard.pasteCells(graph, { link: { z: -1 }, useLocalStorage: true });

	// Make sure pasted elements get selected immediately. This makes the UX better as
	// the user can immediately manipulate the pasted elements.
	clipboard.each(function(cell) {
		if (cell.get('type') === 'link') return;

		// Push to the selection not to the model from the clipboard but put the model into the graph.
		// Note that they are different models. There is no views associated with the models
		// in clipboard.
		selection.add(graph.get('cells').get(cell.id));
	});

	selection.each(function(cell) {
	selectionView.createSelectionBox(paper.findViewByModel(cell));
	});
});

//Delete selected nodes when the delete key is pressed.

KeyboardJS.on('del', function(){
// 	while (selection.length > 0){
// 		selection.pop();
// //		console.log(paper.findViewByModel(current));
// //		selectionView.destroySelectionBox(paper.findViewByModel(current));
// //		current.remove();
// 	}
});
// Override browser's default action when backspace is pressed
KeyboardJS.on('backspace', function(){

});
// ----------------------------------------------------------------- //
// Toolbar

var commandManager = new joint.dia.CommandManager({ graph: graph });

$('#btn-undo').on('click', _.bind(commandManager.undo, commandManager));
$('#btn-redo').on('click', _.bind(commandManager.redo, commandManager));
$('#btn-clear-all').on('click', function(){
	graph.clear();
	//Delete cookie by setting expiry to past date
	document.cookie='graph={}; expires=Thu, 18 Dec 2013 12:00:00 UTC;';
});

$('#btn-clear-elabel').on('click', function(){
	var elements = graph.getElements();
	for (var i = 0; i < elements.length; i++){
		elements[i].removeAttr(".satvalue/d");
		elements[i].attr(".constraints/lastval", "none");
		elements[i].attr(".funcvalue/text", " ");
		var cellView  = elements[i].findView(paper);
		elementInspector.render(cellView);
		elementInspector.$('#init-sat-value').val("none");
		elementInspector.updateHTML(null);
	}

});

$('#btn-svg').on('click', function() {
	paper.openAsSVG();
});

$('#btn-png').on('click', function() {
	paper.openAsPNG();
});

$('#btn-zoom-in').on('click', function() {
	paperScroller.zoom(0.2, { max: 3 });
});
$('#btn-zoom-out').on('click', function() {
	paperScroller.zoom(-0.2, { min: 0.2 });
});

$('#btn-save').on('click', function() {
	// Always initalize files on modelling links for code simplicity
	if (linkMode == "Constraints")
		$('#symbolic-btn').trigger( "click" );

	var name = window.prompt("Please enter a name for your file. \nIt will be saved in your Downloads folder. \n.json will be added as the file extension.", "<file name>");
	if (name){
		var fileName = name + ".json";
		download(fileName, JSON.stringify(graph.toJSON()));
	}
});

//Workaround for load, activates a hidden input element
$('#btn-load').on('click', function(){
	if (linkMode == "Constraints")
		$('#symbolic-btn').trigger( "click" );
	$('#loader').click();
});

//Universally increase or decrease font size
$('#btn-fnt-up').on('click', function(){
	var elements = graph.getElements();
	for (var i = 0; i < elements.length; i++){
		if (elements[i].attr(".name/font-size") < max_font){
			elements[i].attr(".name/font-size", elements[i].attr(".name/font-size") + 1);
		}
	}
});

$('#btn-fnt-down').on('click', function(){
	var elements = graph.getElements();
	for (var i = 0; i < elements.length; i++){
		if (elements[i].attr(".name/font-size") > min_font){
			elements[i].attr(".name/font-size", elements[i].attr(".name/font-size") - 1);
		}
	}
});

//Default font size
$('#btn-fnt').on('click', function(){
	var elements = graph.getElements();
	for (var i = 0; i < elements.length; i++){
		elements[i].attr(".name/font-size", 10);
	}
});

//Save in .leaf format
$('#btn-save-leaf').on('click', saveLeaf);

//Simulator
loader = document.getElementById("loader");
reader = new FileReader();

//Whenever the input is changed, read the file.
loader.onchange = function(){
	reader.readAsText(loader.files.item(0));
};

//When read is performed, if successful, load that file.
reader.onload = function(){
	if (reader.result){
		if (mode == "Modelling"){
			graph.fromJSON(JSON.parse(reader.result));

			// Load different links and intension constraints
			var allLinks = graph.getLinks();
			graphObject.links = [];
			graphObject.intensionConstraints = [];
			allLinks.forEach(function(link){
				if(link.attr('./display') == "none"){
					graphObject.intensionConstraints.push(link);
				}else{
					graphObject.links.push(link);
				}
			});
		}else{
			analysisResults = reader.result.split("\n");
			loadAnalysis(analysisResults, null, -1);
		}
	}
};

//Save in a .leaf format
function saveLeaf(){
	var datastring = generateLeafFile();
	var name = window.prompt("Please enter a name for your file. \nIt will be saved in your Downloads folder. \n.leaf will be added as the file extension.", "<file name>");
	if (name){
		var fileName = name + ".leaf";
		download(fileName, datastring);
	}
}

//Helper function to download saved graph in JSON format
function download(filename, text) {
	var dl = document.createElement('a');
	dl.setAttribute('href', 'data:application/force-download;charset=utf-8,' + encodeURIComponent(text));
	dl.setAttribute('download', filename);

	dl.style.display = 'none';
	document.body.appendChild(dl);

	dl.click();
	document.body.removeChild(dl);
}

// ----------------------------------------------------------------- //
// forward analysis
$('#frd-analysis-btn').on('click', function(){
	// propogation
	// analysis
	// Question: how do you update the drawing and also the elementInspector value together
	// TODO: Check to make sure there are not nodes that have more than one type of Decomposition (AND/OR/XOR) connected to them.
	// TODO: This doesn't work in the growingleaf tool
	var all_elements = graph.getElements();
	var eLabelsBefore = [];
	// store the evaluation values
	for (var i = 0; i < all_elements.length; i++){
		eLabelsBefore.push(all_elements[i].attr(".satvalue/value"));
	}
	// Filter out Actors
	var elements = [];
	for (var e1 = 0; e1 < all_elements.length; e1++){
		if (!(all_elements[e1] instanceof joint.shapes.basic.Actor)){
			elements.push(all_elements[e1]);
		}
	}

	// loop through all elements and build a dictionary of {id:LinkCalc}
	// with LinkCalc represents the number of imcoming links to the element
	var LinkCalc = {};
	// step 1: get a list of all elements and put leaves to the elementsReady, other elements to elementsWaiting
	var elementsReady = [];
	var elementsWaiting = [];
	for (var e = 0; e < elements.length; e++){
		// initialize all nodes with 0
		LinkCalc[elements[e].id] = 0;
		// set up elementID
		var elementID = e.toString();
		while (elementID.length < 4){ elementID = "0" + elementID;}
		elements[e].prop("elementid", elementID);
		// check if it is leaf node or not, assign to elementsReady if yes; assign to elementsWaiting if no
		if (isLeaf(elements[e])){
			elementsReady.push(elements[e]);
		}
		else {
			elementsWaiting.push(elements[e]);
		}
	}

	// update all links
	var savedLinks = [];
	if (linkMode == "Relationships"){
		var links = graph.getLinks();
	    links.forEach(function(link){
	        if(!isLinkInvalid(link)){
				if ((link.attributes.attrs[".link-type"] != "none") && (link.attributes.attrs[".link-type"] != "Qualification")){
					savedLinks.push(link);
					// add 1 to the node for each incoming link
					LinkCalc[link.get("target").id] ++;
				}
	        }
	        else{link.remove();}
		});
	}

	// evaluate model
	// when the list is not empty
	while (elementsReady.length > 0){
		// Get and remove the first element in the elementsReady to evaluate
		var element = elementsReady.shift();
		// Calculate New Evaluation by calling calculateEvaluation function
		var satisfactionValue = calculateEvaluation(elements, savedLinks, element);
		// console.log(element.attr(".name/text"), element.attr(".satvalue/value"), satisfactionValue);
		// update the satisfactionValue of the element and udpate the graph
		if (satisfactionValue >= 0){
			updateValues(element, satValueDictInverse[satisfactionValue]);
		}
		// bookkeeping:
		// loop through all links in the graph and find the one with the element
		// find the eleDest aka target of the element
		for (var l = 0; l < savedLinks.length; l++){
			var current = savedLinks[l]; // current is each link
			if (current.get("source").id && current.get("source").id == element.id && current.get("target").id && inElementsWaiting(elementsWaiting, current.get("target"))){
				var targetID = savedLinks[l].get("target").id;
				// check whether the children of the source have all been examed
				// if we examined a node, we decrement the LinkCalc of its parent by 1
				LinkCalc[targetID] --;
				// when the target becomes a new "leaf", add it to the elementsReady and remove it from elementsWaiting
				if (LinkCalc[targetID] == 0){
					// udpate elementsWaiting
					var newLeaf = null;
					for (var p = 0; p < elementsWaiting.length; p++){
						if (elementsWaiting[p].id == targetID){
							newLeaf = elementsWaiting[p];
							var temp_i = elementsWaiting.indexOf(elementsWaiting[p]);
							elementsWaiting.splice(temp_i, 1);
						}
					}
					// udpate elementsReady
					elementsReady.push(newLeaf);
				}
			}
		}
	}

	// after updating all the elements
	// we check whether the before graph is the same as the after graph, if yes, pop up the error message
	var elements_after = graph.getElements();
	var allSame = true;
	for (var i = 0; i < elements_after.length; i++){
		if (elements_after[i].attr(".satvalue/value") != eLabelsBefore[i]){
			allSame = false;
		}
	}
	// show the error message if the evaluation labels for all elements doesn't change
	if (allSame) {
		noChangePopUp();
	}
});

// calculate evaluation
// return an int representing the new evaluation
// elements is a list of all elements in the graph
// element is the one that we are currently exploring
function calculateEvaluation(elements, savedLinks, element) {

	// setup variables for bookkeeping
	var hasDecomposition = false;
	var decomSums = [];
	for (var i = 0; i < 7; i++) {
		decomSums[i] = 0;
	}

	var numContributions = 0;
	var sums = [];
	for (var i = 0; i < 7; i++) {
		sums[i] = 0;
	}

	var hasDependencies = false;
	var dependSums = [];
	for (var i = 0; i < 7; i++) {
		dependSums[i] = 0;
	}

	//Go through all links that the current node is the *target* of
	var linksWanted = [];
	for (var l = 0; l < savedLinks.length; l++){
		var current = savedLinks[l]; // current is each link
		if (current.get("target").id && current.get("target").id == element.id && current.get("source").id){
			linksWanted.push(current);
		} else if (current.label(0).attrs.text.text == "depends" && current.get("source").id == element.id){
			// with exception of dependency where source is the dependerElmt, target is the dependum/dependeeElmt
			linksWanted.push(current);
		}
	}
	// get the current evaluation value of the source and target along with the link label
	for (var l = 0; l < linksWanted.length; l++){
		var eachLink = linksWanted[l];
		var sourceNode = getSource(elements, eachLink.get("source").id);
		var sVal = satValueDict[sourceNode.attr(".satvalue/value")]; // satisfaction value of the target node
		// var tVal = satValueDict[element.attr(".satvalue/value")]; // satisfaction value of the source node
		// four cases that we are consiedering here
		// decomposition (and, or)
		if (eachLink.label(0).attrs.text.text == "and" || eachLink.label(0).attrs.text.text == "or" || eachLink.attributes.attrs[".link-type"] == "NeededBy"){
			hasDecomposition = true;
			decomSums[sVal]++;
		} else if (eachLink.label(0).attrs.text.text == "helps" || eachLink.label(0).attrs.text.text == "hurts" || eachLink.label(0).attrs.text.text == "makes" || eachLink.label(0).attrs.text.text == "breaks") {
			// contributions
			var contValue = weightedContDict[eachLink.label(0).attrs.text.text];
			var ci = weightedContributionFunction[sVal][contValue];
			sums[ci] ++;
			numContributions ++;
		} else if (eachLink.label(0).attrs.text.text == "depends"){// TODO
			// dependency
			hasDependencies = true;
			dependSums[sVal] ++;
		}
	}

	var result = satValueDict[element.attr(".satvalue/value")]; // use the initia value of the element to be the initial value
	if (hasDecomposition){
		result = getDecomposition(decomSums, eachLink);
	}

	if (numContributions > 0) {
		if (hasDecomposition)
			sums[result]++;
		result = getQualitativeContribution(sums, numContributions);
	}

	if (hasDependencies){
		if (hasDecomposition || numContributions > 0) // Since result will be none we shouldn't need this condition, just the next statement.
			dependSums[result]++;		// Add previous result to the dependSum.
		result = getDecomposition(dependSums, "and");
	}

	return result;
}

function getDecomposition(decomSums, eachLink){
	/**
	 * return the satisfaction value of the node which has decomposition links
	 * its arguments are:
	 * `decomSums`: A array with a list of integers with each integer representing the numeber
	 * of occurance of each satisfaction value associated with the ndoe
	 * `type`: indicates types of decomposition. Either AND or OR
	 */
	// rules
	type_ = eachLink.label(0).attrs.text.text
	if (type_ == "Refinement") {
		type = eachLink.label(0).attrs.text.text
	}
	else{
		type = "NeededBy"
	}
	var result = N;
	var dns = decomSums[S];
	var dnws = decomSums[PS];
	var dnn = decomSums[N];
	var dnwd = decomSums[PD];
	var dnd = decomSums[D];
	var dnc = decomSums[C];
	var dnu = decomSums[U];
	// console.log(dns,dnws,dnn,dnwd,dnd,dnc,dnu);
	if (type == "and" || type == "NeededBy") {
		if (dnd > 0) {
			result = D;
		} else if ((dnc > 0) || (dnu > 0)) {
			result = U;
		} else if (dnwd > 0) {
			result = PD;
		} else if (dnn > 0) {
			result = N;
		} else if (dnws > 0) {
			result = PS;
		} else if (dns > 0) {
			result = S;
		} else {
			result = N;
		}
	} else if (type == "or") {
		if (dns > 0) {
			result = S;
		} else if (dnws > 0) {		// CHANGED over AMYOT ET. Al. was after U conditions.
			result = PS;
		} else if ((dnc > 0) || (dnu > 0)) {
			result = U;
		} else if (dnn > 0) {
			result = N;
		} else if (dnwd > 0) {
			result = PD;
		} else if (dnd > 0) {
			result = D;
		}
	}
	return result;
}

function getQualitativeContribution(sums, numRead) {
	if (numRead == 1)
		for (var i = 0; i < sums.length; i++) {
			if (sums[i] > 0){
				return i;
			}
		}
	else {
		var ns = sums[S];
		var nws = sums[PS];
		//int nn = sums[N];	//Unused Variable
		var nwd = sums[PD];
		var nd = sums[D];
		var nc = sums[C];
		var nu = sums[U];

		if (nc > 0 || nu > 0)
			return U;
		return combineContributionsFunction[comparePS_PD(nws, nwd)][compareS_D(ns, nd)];
	}
	return -1;	//This line should never be reached.
}

function comparePS_PD(nws, nwd) {
	// w1 = ws, if nws > nwd = wd, if nwd > nws = n, otherwise
	if (nws > nwd)
		return PS;
	if (nwd > nws)
		return PD;
	if ((nws > 0) && (nwd == nws))		//November 2016: Added to prevent none variables.
		return U;
	return N;
}

function compareS_D(ns, nd) {
	//w2 = c, if ns >0 && nd >0 = s, if ns >0 && nd=0 = d, if nd >0 && ns=0 = n, if ns =0 && nd=0
	if (ns > 0 && nd > 0)
		return C;
	if (ns > 0 && nd == 0)
		return S;
	if (nd > 0 && ns == 0)
		return D;
	return N;
}

// check whether the element is in the elementsWaiting
function inElementsWaiting(elementsWaiting, target) {
	for (var l = 0; l < elementsWaiting.length; l++){
		if (elementsWaiting[l].id == target.id ){
			return true
		}
	}
	return false

}

function getSource(elements, sourceID){
	for (var l = 0; l < elements.length; l++){
		if (elements[l].id == sourceID){
			return elements[l];
		}
	}
}

//Update the satisfaction value of a particular node in the graph
function updateValues(cell, value){
	var value;
	//Update images for properties
	if (value == "satisfied"){
		cell.attr({ '.satvalue': {'d': 'M 0 10 L 5 20 L 20 0 L 5 20 L 0 10', 'stroke': '#00FF00', 'stroke-width':4, 'value':value}});
	}else if(value == "partiallysatisfied") {
		cell.attr({ '.satvalue': {'d': 'M 0 8 L 5 18 L 20 0 L 5 18 L 0 8 M 17 30 L 17 15 C 17 15 30 17 18 23', 'stroke': '#00FF00', 'stroke-width':4, 'fill':'transparent', 'value':value}});
	}else if (value == "denied"){
		cell.attr({ '.satvalue': {'d': 'M 0 20 L 20 0 M 10 10 L 0 0 L 20 20', 'stroke': '#FF0000', 'stroke-width': 4, 'value':value}});
	}else if (value == "partiallydenied") {
		cell.attr({ '.satvalue': {'d': 'M 0 15 L 15 0 M 15 15 L 0 0 M 17 30 L 17 15 C 17 15 30 17 18 23', 'stroke': '#FF0000', 'stroke-width': 4, 'fill': 'transparent', 'value':value}});
	}else if (value == "conflict") {
		cell.attr({ '.satvalue': {'d': 'M 0 0 L 20 8 M 20 7 L 5 15 M 5 14 L 25 23', 'stroke': '#222222', 'stroke-width': 4, 'value':value}});
	}else if (value == "unknown") {
		cell.attr({ '.satvalue': {'d': 'M15.255,0c5.424,0,10.764,2.498,10.764,8.473c0,5.51-6.314,7.629-7.67,9.62c-1.018,1.481-0.678,3.562-3.475,3.562\
		    c-1.822,0-2.712-1.482-2.712-2.838c0-5.046,7.414-6.188,7.414-10.343c0-2.287-1.522-3.643-4.066-3.643\
		    c-5.424,0-3.306,5.592-7.414,5.592c-1.483,0-2.756-0.89-2.756-2.584C5.339,3.683,10.084,0,15.255,0z M15.044,24.406\
		    c1.904,0,3.475,1.566,3.475,3.476c0,1.91-1.568,3.476-3.475,3.476c-1.907,0-3.476-1.564-3.476-3.476\
		    C11.568,25.973,13.137,24.406,15.044,24.406z', 'stroke': '#222222', 'stroke-width': 10, 'value':value}});
	}else {
		// case when the cell should be None
		cell.removeAttr(".satvalue/d");
		cell.attr(".constraints/lastval", "none");
		cell.attr(".funcvalue/text", " ");
		var cellView  = cell.findView(paper);
		elementInspector.render(cellView);
		elementInspector.$('#init-sat-value').val("none");
		elementInspector.updateHTML(null);
	}
}

// pop up error message when the before and after graph are the same after evaluation
function noChangePopUp() {
    alert("Warning: Uh-oh, something could go wrong. No change in the graph. Please check your evaluation labels.");
}


text:
#pragma once

#include "envoy/api/api.h"
#include "envoy/common/time.h"
#include "envoy/event/deferred_deletable.h"
#include "envoy/network/connection.h"
#include "envoy/network/connection_handler.h"
#include "envoy/network/filter.h"
#include "envoy/network/listener.h"
#include "envoy/network/listen_socket.h"

#include "common/common/linked_object.h"
#include "common/common/non_copyable.h"
#include "common/network/listen_socket_impl.h"

// clang-format off
#define ALL_LISTENER_STATS(COUNTER, GAUGE, TIMER)                                                  \
  COUNTER(downstream_cx_total)                                                                     \
  COUNTER(downstream_cx_destroy)                                                                   \
  GAUGE  (downstream_cx_active)                                                                    \
  TIMER  (downstream_cx_length_ms)
// clang-format on

namespace Server {

/**
 * Wrapper struct for listener stats. @see stats_macros.h
 */
struct ListenerStats {
  ALL_LISTENER_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT, GENERATE_TIMER_STRUCT)
};

/**
 * Server side connection handler. This is used both by workers as well as the
 * main thread for non-threaded listeners.
 */
class ConnectionHandlerImpl : public Network::ConnectionHandler, NonCopyable {
public:
  ConnectionHandlerImpl(spdlog::logger& logger, Api::ApiPtr&& api);
  ~ConnectionHandlerImpl();

  Api::Api& api() { return *api_; }
  Event::Dispatcher& dispatcher() { return *dispatcher_; }

  /**
   * Close and destroy all connections.
   */
  void closeConnections();

  // Network::ConnectionHandler
  uint64_t numConnections() override { return num_connections_; }

  void addListener(Network::FilterChainFactory& factory, Network::ListenSocket& socket,
                   Stats::Scope& scope, const Network::ListenerOptions& listener_options) override;

  void addSslListener(Network::FilterChainFactory& factory, Ssl::ServerContext& ssl_ctx,
                      Network::ListenSocket& socket, Stats::Scope& scope,
                      const Network::ListenerOptions& listener_options) override;

  Network::Listener* findListenerByAddress(const Network::Address::Instance& address) override;

  void closeListeners() override;

private:
  /**
   * Wrapper for an active listener owned by this worker.
   */
  struct ActiveListener : public Network::ListenerCallbacks {
    ActiveListener(ConnectionHandlerImpl& parent, Network::ListenSocket& socket,
                   Network::FilterChainFactory& factory, Stats::Scope& scope,
                   const Network::ListenerOptions& listener_options);

    ActiveListener(ConnectionHandlerImpl& parent, Network::ListenerPtr&& listener,
                   Network::FilterChainFactory& factory, Stats::Scope& scope);

    /**
     * Fires when a new connection is received from the listener.
     * @param new_connection supplies the connection to take control of.
     */
    void onNewConnection(Network::ConnectionPtr&& new_connection) override;

    ConnectionHandlerImpl& parent_;
    Network::FilterChainFactory& factory_;
    Network::ListenerPtr listener_;
    ListenerStats stats_;
  };

  struct SslActiveListener : public ActiveListener {
    SslActiveListener(ConnectionHandlerImpl& parent, Ssl::ServerContext& ssl_ctx,
                      Network::ListenSocket& socket, Network::FilterChainFactory& factory,
                      Stats::Scope& scope, const Network::ListenerOptions& listener_options);
  };

  typedef std::unique_ptr<ActiveListener> ActiveListenerPtr;

  /**
   * Wrapper for an active connection owned by this worker.
   */
  struct ActiveConnection : LinkedObject<ActiveConnection>,
                            public Event::DeferredDeletable,
                            public Network::ConnectionCallbacks {
    ActiveConnection(ConnectionHandlerImpl& parent, Network::ConnectionPtr&& new_connection,
                     ListenerStats& stats);
    ~ActiveConnection();

    // Network::ConnectionCallbacks
    void onEvent(uint32_t event) override {
      // Any event leads to destruction of the connection.
      if (event == Network::ConnectionEvent::LocalClose ||
          event == Network::ConnectionEvent::RemoteClose) {
        parent_.removeConnection(*this);
      }
    }

    ConnectionHandlerImpl& parent_;
    Network::ConnectionPtr connection_;
    ListenerStats& stats_;
    Stats::TimespanPtr conn_length_;
  };

  typedef std::unique_ptr<ActiveConnection> ActiveConnectionPtr;

  /**
   * Remove and destroy an active connection.
   * @param connection supplies the connection to remove.
   */
  void removeConnection(ActiveConnection& connection);

  static ListenerStats generateStats(Stats::Scope& scope);

  spdlog::logger& logger_;
  Api::ApiPtr api_;
  Event::DispatcherPtr dispatcher_;
  std::list<std::pair<Network::Address::InstanceConstSharedPtr, ActiveListenerPtr>> listeners_;
  std::list<ActiveConnectionPtr> connections_;
  std::atomic<uint64_t> num_connections_{};
};

typedef std::unique_ptr<ConnectionHandlerImpl> ConnectionHandlerImplPtr;

} // Server

redpajama_set_name: RedPajamaGithub


text:
using System;

namespace Iodine.Runtime
{
    [BuiltinDocString (
        "Provides miscellaneous mathematical functions."
    )]
    [IodineBuiltinModule ("math")]
    public class MathModule : IodineModule
    {
        public MathModule ()
            : base ("math")
        {
            SetAttribute ("PI", new IodineFloat (Math.PI));
            SetAttribute ("E", new IodineFloat (Math.E));
            SetAttribute ("pow", new BuiltinMethodCallback (Pow, this));
            SetAttribute ("sin", new BuiltinMethodCallback (Sin, this));
            SetAttribute ("cos", new BuiltinMethodCallback (Cos, this));
            SetAttribute ("tan", new BuiltinMethodCallback (Tan, this));
            SetAttribute ("asin", new BuiltinMethodCallback (ASin, this));
            SetAttribute ("acos", new BuiltinMethodCallback (ACos, this));
            SetAttribute ("atan", new BuiltinMethodCallback (ATan, this));
            SetAttribute ("abs", new BuiltinMethodCallback (Abs, this));
            SetAttribute ("sqrt", new BuiltinMethodCallback (Sqrt, this));
            SetAttribute ("floor", new BuiltinMethodCallback (Floor, this));
            SetAttribute ("ceiling", new BuiltinMethodCallback (Ceiling, this));
            SetAttribute ("log", new BuiltinMethodCallback (Log, this));
        }

        [BuiltinDocString (
            "Returns the specified number raised to the specified power.",
            "@param number The number.",
            "@param power The power."
        )]
        IodineObject Pow (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 1) {
                vm.RaiseException (new IodineArgumentException (2));
                return null;
            }

            double a1 = 0;
            double a2 = 0;

            if (!ConvertToDouble (args [0], out a1)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            if (!ConvertToDouble (args [1], out a2)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Pow (a1, a2));
        }

        [BuiltinDocString (
            "Returns the sine of the specified number.",
            "@param number The number."
        )]
        IodineObject Sin (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Sin (input));
        }

        [BuiltinDocString (
            "Returns the cosine of the specified number.",
            "@param number The number."
        )]
        IodineObject Cos (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }
            return new IodineFloat (Math.Cos (input));
        }

        [BuiltinDocString (
            "Returns the tangent of the specified number.",
            "@param number The number."
        )]
        IodineObject Tan (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Tan (input));
        }

        [BuiltinDocString (
            "Returns the arc sine of the specified number.",
            "@param number The number."
        )]
        IodineObject ASin (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Asin (input));
        }

        [BuiltinDocString (
            "Returns the arc cosine of the specified number.",
            "@param number The number."
        )]
        IodineObject ACos (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Acos (input));
        }

        [BuiltinDocString (
            "Returns the arc tangent of the specified number.",
            "@param number The number."
        )]
        IodineObject ATan (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Atan (input));
        }

        [BuiltinDocString (
            "Returns the absolute value of the specified number.",
            "@param number The number."
        )]
        IodineObject Abs (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Abs (input));
        }

        [BuiltinDocString (
            "Returns the square root of the specified number.",
            "@param number The number."
        )]
        IodineObject Sqrt (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Sqrt (input));
        }

        [BuiltinDocString (
            "Returns the specified number, rounded down to the closest integer.",
            "@param number The number."
        )]
        IodineObject Floor (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Floor (input));
        }

        [BuiltinDocString (
            "Returns the specified numner, rounded up to the closest integer."
        )]
        IodineObject Ceiling (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double input = 0;

            if (!ConvertToDouble (args [0], out input)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Ceiling (input));
        }

        [BuiltinDocString (
            "Returns the base 10 logarithm of the specified number.",
            "@param number The number."
        )]
        IodineObject Log (VirtualMachine vm, IodineObject self, IodineObject [] args)
        {
            if (args.Length <= 0) {
                vm.RaiseException (new IodineArgumentException (1));
                return null;
            }

            double value = 0;
            double numericBase = 10;

            if (!ConvertToDouble (args [0], out value)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            if (args.Length > 1 && !ConvertToDouble (args [1], out numericBase)) {
                vm.RaiseException (new IodineTypeException ("Float"));
                return null;
            }

            return new IodineFloat (Math.Log (value, numericBase));
        }

        static bool ConvertToDouble (IodineObject obj, out double value)
        {
            if (obj is IodineInteger) {
                value = (double)((IodineInteger)obj).Value;
                return true;
            } else if (obj is IodineFloat) {
                value = ((IodineFloat)obj).Value;
                return true;
            }
            value = 0;
            return false;
        }
    }
}


text:
package org.traccar.protocol;

import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import org.traccar.BaseProtocol;
import org.traccar.PipelineBuilder;
import org.traccar.TrackerServer;

public class FlexApiProtocol extends BaseProtocol {

    public FlexApiProtocol() {
        addServer(new TrackerServer(false, getName()) {
            @Override
            protected void addProtocolHandlers(PipelineBuilder pipeline) {
                pipeline.addLast(new LineBasedFrameDecoder(5120));
                pipeline.addLast(new StringDecoder());
                pipeline.addLast(new FlexApiProtocolDecoder(FlexApiProtocol.this));
            }
        });
    }

}


text:
namespace MvcApp.Data.Models
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public class Director
    {
        private ICollection<Movie> movies;

        public Director()
        {
            this.movies = new HashSet<Movie>();
        }

        [Key]
        public int DirectorId { get; set; }

        [Required]
        [StringLength(30, ErrorMessage = "First name must be between 2 and 30 characters long", MinimumLength = 2)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(30, ErrorMessage = "Last name be between 2 and 30 characters long", MinimumLength = 2)]
        public string LastName { get; set; }

        [Required]
        public Gender Gender { get; set; }

        public DateTime? BirthDate { get; set; }

        public virtual ICollection<Movie> Movies
        {
            get
            {
                return this.movies;
            }
            set
            {
                this.movies = value;
            }
        }
    }
}


text:
Ext.define('websure.backup.model.ClusterDeviceModel', {
    extend: 'Ext.data.Model',
    fields: [
	    {name : 'deviceId',type: 'int'},
	    {name : 'deviceShowName',type: 'string'},
	    {name : 'masterCount',type: 'int'},
	    {name : 'standbyModel',type: 'int'}
    ]
});


text:
<?php

namespace Elixir\Config\Loader;

/**
 * @author Cédric Tanghe <ced.tanghe@gmail.com>
 */
class LoaderFactory
{
    /**
     * @param LoaderFactory $factory
     */
    public static function addProvider(self $factory)
    {
        $factory->add('array', function ($config, $options) {
            if (is_array($config) || strstr($config, '.php')) {
                $options['environment'] = isset($options['environment']) ? $options['environment'] : null;
                $options['strict'] = isset($options['strict']) ? $options['strict'] : false;

                return new ArrayLoader($options['environment'], $options['strict']);
            }

            return null;
        });

        $factory->add('JSON', function ($config, $options) {
            if (strstr($config, '.json')) {
                $options['environment'] = isset($options['environment']) ? $options['environment'] : null;
                $options['strict'] = isset($options['strict']) ? $options['strict'] : false;

                return new JSONLoader($options['environment'], $options['strict']);
            }

            return null;
        });

        $factory->add('YAML', function ($config, $options) {
            if (strstr($config, '.yml')) {
                $options['environment'] = isset($options['environment']) ? $options['environment'] : null;
                $options['strict'] = isset($options['strict']) ? $options['strict'] : false;

                return new YAMLLoader($options['environment'], $options['strict']);
            }

            return null;
        });

        $factory->add('serialized', function ($config, $options) {
            if (strstr($config, '.cache')) {
                $options['environment'] = isset($options['environment']) ? $options['environment'] : null;
                $options['strict'] = isset($options['strict']) ? $options['strict'] : false;

                return new SerializedLoader($options['environment'], $options['strict']);
            }

            return null;
        });
    }

    /**
     * @var array
     */
    protected $factories = [];

    /**
     * @param string $key
     *
     * @return bool
     */
    public function has($key)
    {
        return isset($this->factories[$key]);
    }

    /**
     * @param string   $key
     * @param callable $resolver
     */
    public function add($key, callable $resolver)
    {
        $this->factories[$key] = $resolver;
    }

    /**
     * @param mixed $config
     * @param array $options
     *
     * @return LoaderInterface
     *
     * @throws \InvalidArgumentException
     */
    public function create($config, array $options = [])
    {
        foreach ($this->factories as $loader) {
            $result = $loader($config, $options);

            if (null !== $result) {
                return $result;
            }
        }

        throw new \InvalidArgumentException('No loader has been implemented for this type of resource.');
    }
}


text:
//Copyright (c) 2014 Sang Ki Kwon (Cranberrygame)
//Email: cranberrygame@yahoo.com
//Homepage: http://cranberrygame.github.io
//License: MIT (http://opensource.org/licenses/MIT)
#import "AdMobOverlap.h"
#import <AdSupport/ASIdentifierManager.h>
#import <CommonCrypto/CommonDigest.h> //md5

@implementation AdMobOverlap

@synthesize plugin;
//
@synthesize bannerAdUnit;
@synthesize interstitialAdUnit;
@synthesize isOverlap;
@synthesize isTest;
//
@synthesize bannerPreviousPosition;
@synthesize bannerPreviousSize;
@synthesize lastOrientation;
//
@synthesize bannerAdPreload;
@synthesize interstitialAdPreload;
@synthesize rewardedVideoAdPreload;
//admob
@synthesize bannerView;
@synthesize interstitial;
@synthesize rewardedVideo;

/*
- (CDVPlugin *) initWithWebView:(UIWebView *)theWebView {
    self = (Admob *)[super initWithWebView:theWebView];
    if (self) {
        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector:@selector(deviceOrientationChangeAdMob:)
         name:UIDeviceOrientationDidChangeNotification
         object:nil];
    }
    return self;
}
*/

- (void) deviceOrientationChangeAdMob:(NSNotification *)notification {
    if (bannerView != nil) {
/*
        CGRect bannerFrame = bannerView.frame;
        if (bannerFrame.origin.y != 0)
        {
            bannerFrame.origin.y = self.webView.frame.size.width - bannerView.frame.size.height;
        }
        bannerFrame.origin.x = self.webView.frame.size.height * 0.5f - bannerView.frame.size.width * 0.5f;
        bannerView.frame = bannerFrame;
*/
    }
}

- (bool) _isLandscape {
    bool landscape = NO;

    UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
    if (UIInterfaceOrientationIsLandscape(currentOrientation)) {
        landscape = YES;
    }
    return landscape;
}

- (id) initWithPlugin:(id<Plugin>)plugin_{
    self = [super init];
    if (self) {
		self.plugin = plugin_;
    }
    return self;
}

- (void) _setLicenseKey:(NSString *)email aLicenseKey:(NSString *)licenseKey {
}

- (void) _setUp:(NSString *)bannerAdUnit anInterstitialAdUnit:(NSString *)interstitialAdUnit aRewardedVideoAdUnit:(NSString *)rewardedVideoAdUnit anIsOverlap:(BOOL)isOverlap anIsTest:(BOOL)isTest {
	self.bannerAdUnit = bannerAdUnit;
    self.interstitialAdUnit = interstitialAdUnit;
    self.rewardedVideoAdUnit = rewardedVideoAdUnit;
	self.isOverlap = isOverlap;
	self.isTest = isTest;
}

- (void) _preloadBannerAd {
	self.bannerAdPreload = YES;

	[self _hideBannerAd];

    [self loadBannerAd];
}

- (void) loadBannerAd {
	//
    if (bannerView == nil) {
		if(self.bannerPreviousSize == nil) {
			self.bannerPreviousSize = @"SMART_BANNER";
		}
		GADAdSize adSize = kGADAdSizeBanner;
		//https://developers.google.com/mobile-ads-sdk/docs/admob/android/banner
		if ([self.bannerPreviousSize isEqualToString:@"BANNER"]) {
			adSize = kGADAdSizeBanner;//Banner (320x50, Phones and Tablets)
		}
		else if ([self.bannerPreviousSize isEqualToString:@"LARGE_BANNER"]) {
			adSize = kGADAdSizeLargeBanner;//Large banner (320x100, Phones and Tablets)
		}
		else if ([self.bannerPreviousSize isEqualToString:@"MEDIUM_RECTANGLE"]) {
			adSize = kGADAdSizeMediumRectangle;//Medium rectangle (300x250, Phones and Tablets)
		}
		else if ([self.bannerPreviousSize isEqualToString:@"FULL_BANNER"]) {
			adSize = kGADAdSizeFullBanner;//Full banner (468x60, Tablets)
		}
		else if ([self.bannerPreviousSize isEqualToString:@"LEADERBOARD"]) {
			adSize = kGADAdSizeLeaderboard;//Leaderboard (728x90, Tablets)
		}
		else if ([self.bannerPreviousSize isEqualToString:@"SKYSCRAPER"]) {
			adSize = kGADAdSizeSkyscraper;//Skyscraper (120x600, Tablets)
		}
		else if ([self.bannerPreviousSize isEqualToString:@"SMART_BANNER"]) {
			if([self _isLandscape]) {
				adSize = kGADAdSizeSmartBannerLandscape;//Smart banner (Auto size, Phones and Tablets) //https://developers.google.com/mobile-ads-sdk/docs/admob/android/banner#smart
			}
			else {
				adSize = kGADAdSizeSmartBannerPortrait;
			}
		}
		else {
			if([self _isLandscape]) {
				adSize = kGADAdSizeSmartBannerLandscape;
			}
			else {
				adSize = kGADAdSizeSmartBannerPortrait;
			}
		}

		bannerView = [[GADBannerView alloc] initWithAdSize:adSize];
        //
		bannerView.adUnitID = self.bannerAdUnit;
		bannerView.delegate = self;
		bannerView.rootViewController = [self.plugin getViewController];//
	}

	GADRequest *request = [GADRequest request];
    //Note: Starting in SDK version 7.0.0, simulators will automatically show test ads.
    //https://developers.google.com/admob/ios/targeting
    if (self.isTest) {
		NSUUID* adid = [[ASIdentifierManager sharedManager] advertisingIdentifier];
        request.testDevices =
        [NSArray arrayWithObjects:
        // TODO: Add your device/simulator test identifiers here. They are printed to the console when the app is launched.
        [self md5:adid.UUIDString],
        nil];
    }
	[self.bannerView loadRequest:request];
}

- (NSString*) md5:(NSString*) input {
	const char *cStr = [input UTF8String];
	unsigned char digest[16];
	CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call

	NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];

	for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
	[output appendFormat:@"%02x", digest[i]];

	return  output;
}

- (void) _showBannerAd:(NSString *)position aSize:(NSString *)size {

	if ([self bannerIsShowingOverlap] && [position isEqualToString:self.bannerPreviousPosition] && [size isEqualToString:self.bannerPreviousSize]) {
		return;
	}

	self.bannerPreviousPosition = position;
	self.bannerPreviousSize = size;

	if(bannerAdPreload) {
		bannerAdPreload = NO;
	}
	else{
		[self _hideBannerAd];

		[self loadBannerAd];
	}

	[self addBannerViewOverlap:position aSize:size];

	CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onBannerAdShown"];
	[pr setKeepCallbackAsBool:YES];
	[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
	//CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
	//[pr setKeepCallbackAsBool:YES];
	//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
}

- (BOOL) bannerIsShowingOverlap {
	//
	BOOL bannerIsShowing = NO;
	if (bannerView != nil) {
		//if banner is showing
		//if ([bannerView isDescendantOfView:webView]) {
		UIView* webView = [bannerView superview];
		if (webView != nil) {
			bannerIsShowing = YES;
		}
	}

	return bannerIsShowing;
}

- (void) addBannerViewOverlap:(NSString*)position aSize:(NSString*)size {
/*
	//http://tigerwoods.tistory.com/11
	//http://developer.android.com/reference/android/widget/RelativeLayout.html
	//http://stackoverflow.com/questions/24900725/admob-banner-poitioning-in-android-on-bottom-of-the-screen-using-no-xml-relative
	RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(AdView.LayoutParams.WRAP_CONTENT, AdView.LayoutParams.WRAP_CONTENT);
	if (position.equals("top-left")) {
		Log.d("Admob", "top-left");
		params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
	}
	else if (position.equals("top-center")) {
		params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		params.addRule(RelativeLayout.CENTER_HORIZONTAL);
	}
	else if (position.equals("top-right")) {
		params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
	}
	else if (position.equals("left")) {
		params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		params.addRule(RelativeLayout.CENTER_VERTICAL);
	}
	else if (position.equals("center")) {
		params.addRule(RelativeLayout.CENTER_HORIZONTAL);
		params.addRule(RelativeLayout.CENTER_VERTICAL);
	}
	else if (position.equals("right")) {
		params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		params.addRule(RelativeLayout.CENTER_VERTICAL);
	}
	else if (position.equals("bottom-left")) {
		params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
	}
	else if (position.equals("bottom-center")) {

		params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		params.addRule(RelativeLayout.CENTER_HORIZONTAL);
	}
	else if (position.equals("bottom-right")) {
		params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
	}
	else {
		params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		params.addRule(RelativeLayout.CENTER_HORIZONTAL);
	}

	//bannerViewLayout.addView(bannerView, params);
	bannerView.setLayoutParams(params);
	bannerViewLayout.addView(bannerView);
*/
///*
	CGRect bannerFrame = bannerView.frame;
	if ([position isEqualToString:@"top-center"]) {
		bannerFrame.origin.y = 0;
	}
	else {
		bannerFrame.origin.y = [self.plugin getWebView].frame.size.height - bannerView.frame.size.height;
	}
	bannerFrame.origin.x = [self.plugin getWebView].frame.size.width * 0.5f - bannerView.frame.size.width * 0.5f;
	bannerView.frame = bannerFrame;
	//https://developer.apple.com/library/ios/documentation/uikit/reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/cl/UIView
	[[self.plugin getWebView] addSubview:bannerView];
//*/
/*
     CGFloat width = [self.plugin getWebView].bounds.size.width;
     CGFloat height = [self.plugin getWebView].bounds.size.height;
     if ([position isEqualToString:@"top-center"]) {
        bannerView.frame = CGRectMake(0, 0, width, 50);
     }
     else {
        bannerView.frame = CGRectMake(0, height - 50, width, 50);
     }
     //bannerView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
     [[self.plugin getWebView] addSubview:bannerView];
*/
}

- (void) _reloadBannerAd {
    [self loadBannerAd];
}

- (void) _hideBannerAd {
	[self _removeBannerViewOverlap];

	CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onBannerAdHidden"];
	[pr setKeepCallbackAsBool:YES];
	[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
	//CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
	//[pr setKeepCallbackAsBool:YES];
	//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
}

- (void)_removeBannerViewOverlap {
    if (bannerView == nil)
		return;

	//[self.bannerView removeFromSuperview];
	//if banner is showing
	UIView* webView = [bannerView superview];
	if (webView != nil) {
		//https://developer.apple.com/library/ios/documentation/uikit/reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/cl/UIView
		[self.bannerView removeFromSuperview];
		bannerView = nil;
	}
}

- (void) _preloadInterstitialAd {
	self.interstitialAdPreload = YES;

	[self loadinterstitialAd];
}

- (void) loadinterstitialAd {
    if (interstitial == nil || self.interstitial.hasBeenUsed){//ios only //An interstitial object can only be used once for ios
        self.interstitial = [[GADInterstitial alloc] initWithAdUnitID: interstitialAdUnit];
        //
        self.interstitial.delegate = self;
    }

	GADRequest *request = [GADRequest request];
    if (self.isTest) {
        NSUUID* adid = [[ASIdentifierManager sharedManager] advertisingIdentifier];
        request.testDevices =
        [NSArray arrayWithObjects:
        // TODO: Add your device/simulator test identifiers here. They are printed to the console when the app is launched.
        [self md5:adid.UUIDString],
        nil];
    }
	[self.interstitial loadRequest:request];
}

- (void) _showInterstitialAd {
	if(interstitialAdPreload) {
		interstitialAdPreload = NO;

		[self.interstitial presentFromRootViewController:[self.plugin getViewController]];
	}
	else{
		[self loadinterstitialAd];
	}
}

- (void) _preloadRewardedVideoAd {
    rewardedVideoAdPreload = YES;

    [self loadRewardedVideoAd];
}

- (void) loadRewardedVideoAd {
    if (rewardedVideo == nil){
        self.rewardedVideo = [GADRewardBasedVideoAd sharedInstance];
        //
        self.rewardedVideo.delegate = self;
    }

	GADRequest *request = [GADRequest request];
    if (self.isTest) {
        NSUUID* adid = [[ASIdentifierManager sharedManager] advertisingIdentifier];
        request.testDevices =
        [NSArray arrayWithObjects:
        // TODO: Add your device/simulator test identifiers here. They are printed to the console when the app is launched.
        [self md5:adid.UUIDString],
        nil];
    }
	[self.rewardedVideo loadRequest:request withAdUnitID:self.rewardedVideoAdUnit];
}

- (void) _showRewardedVideoAd {
    if(rewardedVideoAdPreload) {
        rewardedVideoAdPreload = NO;

        [rewardedVideo presentFromRootViewController:[plugin getViewController]];
    }
    else {
        [self loadRewardedVideoAd];
    }
}

#pragma mark GADBannerViewDelegate

- (void) adViewDidReceiveAd:(GADBannerView *)view {
	NSLog(@"adViewDidReceiveAd");

	if(bannerAdPreload) {
		CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onBannerAdPreloaded"];
		[pr setKeepCallbackAsBool:YES];
		[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
		//CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
		//[pr setKeepCallbackAsBool:YES];
		//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
	}

	CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onBannerAdLoaded"];
	[pr setKeepCallbackAsBool:YES];
	[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
	//CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
	//[pr setKeepCallbackAsBool:YES];
	//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];

	bannerView.hidden = NO;
}

- (void) adView:(GADBannerView *)view didFailToReceiveAdWithError:(GADRequestError *)error {
	NSLog(@"adView: %@",error.description);
	bannerView.hidden = YES;
}

- (void) adViewWillLeaveApplication:(GADBannerView *)adView {
	NSLog(@"adViewWillLeaveApplication");
}

- (void) adViewWillPresentScreen:(GADBannerView *)adView {
	NSLog(@"adViewWillPresentScreen");//click and ad opened //onBannerAdShown x
}

- (void) adViewWillDismissScreen:(GADBannerView *)adView {
	NSLog(@"adViewWillDismissScreen");
}

- (void)adViewDidDismissScreen:(GADBannerView *)adView {
	NSLog(@"adViewDidDismissScreen");//onBannerAdHidden x
}

#pragma mark GADInterstitialDelegate

- (void) interstitialDidReceiveAd:(GADInterstitial *)ad {
	NSLog(@"interstitialDidReceiveAd");

	if(interstitialAdPreload) {
		CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onInterstitialAdPreloaded"];
		[pr setKeepCallbackAsBool:YES];
		[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
		//CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
		//[pr setKeepCallbackAsBool:YES];
		//[self.commandDelegate sendPluginResult:pr callbackId:self.callbackIdKeepCallback];
	}

	CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onInterstitialAdLoaded"];
	[pr setKeepCallbackAsBool:YES];
	[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
	//CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
	//[pr setKeepCallbackAsBool:YES];
	//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];

	if(!interstitialAdPreload) {
		[self.interstitial presentFromRootViewController:[self.plugin getViewController]];
	}
}

- (void) interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADRequestError *)error {
	NSLog(@"interstitial: %@",error.description);
}

- (void) interstitialWillLeaveApplication:(GADInterstitial *)ad {
	NSLog(@"interstitialWillLeaveApplication");
}

- (void) interstitialWillPresentScreen:(GADInterstitial *)ad {
	NSLog(@"interstitialWillPresentScreen");

    CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onInterstitialAdShown"];
	[pr setKeepCallbackAsBool:YES];
	[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
    //CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
	//[pr setKeepCallbackAsBool:YES];
	//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
}

- (void) interstitialWillDismissScreen:(GADInterstitial *)ad {
	NSLog(@"interstitialWillDismissScreen");
}

- (void) interstitialDidDismissScreen:(GADInterstitial *)ad {
	NSLog(@"interstitialDidDismissScreen");

    CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onInterstitialAdHidden"];
	[pr setKeepCallbackAsBool:YES];
	[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
    //CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
	//[pr setKeepCallbackAsBool:YES];
	//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
}

#pragma mark GADRewardBasedVideoAdDelegate

- (void)rewardBasedVideoAdDidReceiveAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
	NSLog(@"rewardBasedVideoAdDidReceiveAd");

	if(rewardedVideoAdPreload) {
		CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onRewardedVideoAdPreloaded"];
		[pr setKeepCallbackAsBool:YES];
		[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
		//CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
		//[pr setKeepCallbackAsBool:YES];
		//[self.commandDelegate sendPluginResult:pr callbackId:self.callbackIdKeepCallback];
	}

	CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onRewardedVideoAdLoaded"];
	[pr setKeepCallbackAsBool:YES];
	[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
	//CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
	//[pr setKeepCallbackAsBool:YES];
	//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];

	if(!rewardedVideoAdPreload) {
		[rewardedVideo presentFromRootViewController:[plugin getViewController]];
	}
}

- (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd didFailToLoadWithError:(NSError *)error {
	NSLog(@"rewardBasedVideoAd");
}

- (void)rewardBasedVideoAdWillLeaveApplication:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
	NSLog(@"rewardBasedVideoAdWillLeaveApplication");
}

- (void)rewardBasedVideoAdDidOpen:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
	NSLog(@"rewardBasedVideoAdDidOpen");

    CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onRewardedVideoAdShown"];
    [pr setKeepCallbackAsBool:YES];
    [[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
    //CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    //[pr setKeepCallbackAsBool:YES];
    //[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
}

- (void)rewardBasedVideoAdDidStartPlaying:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
	NSLog(@"rewardBasedVideoAdDidStartPlaying");
}

- (void)rewardBasedVideoAdDidClose:(GADRewardBasedVideoAd *)rewardBasedVideoAd {
	NSLog(@"rewardBasedVideoAdDidClose");

    CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onRewardedVideoAdHidden"];
	[pr setKeepCallbackAsBool:YES];
	[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
    //CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
	//[pr setKeepCallbackAsBool:YES];
	//[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
}

- (void)rewardBasedVideoAd:(GADRewardBasedVideoAd *)rewardBasedVideoAd didRewardUserWithReward:(GADAdReward *)reward {
   NSLog(@"rewardBasedVideoAd");

/*
    NSString* obj = [self __getProductShortName];
    NSString* json = [NSString stringWithFormat:@"{'adNetwork':'%@','adType':'%@','adEvent':'%@','rewardType':'%@','rewardAmount':%lf}",
                      obj, ADTYPE_REWARDVIDEO, EVENT_AD_PRESENT, reward.type, [reward.amount doubleValue]];
    [self fireEvent:obj event:EVENT_AD_PRESENT withData:json];
*/

    CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"onRewardedVideoAdCompleted"];
    [pr setKeepCallbackAsBool:YES];
    [[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
    //CDVPluginResult* pr = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    //[pr setKeepCallbackAsBool:YES];
    //[[self.plugin getCommandDelegate] sendPluginResult:pr callbackId:[self.plugin getCallbackIdKeepCallback]];
}

//

- (void) dealloc {
	[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
	[[NSNotificationCenter defaultCenter]
     removeObserver:self
     name:UIDeviceOrientationDidChangeNotification
     object:nil];
}

@end


text:
package cucumber.demo.bank.steps;

import static org.junit.Assert.assertEquals;

import java.util.List;
import java.util.Map;

import cucumber.demo.bank.Account;
import cucumber.demo.bank.AccountManager;
import cucumber.demo.bank.AccountTransferService;
import cucumber.demo.bank.Person;
import io.cucumber.datatable.DataTable;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
public class BankSteps {

	private boolean lastTransferResult;

	@Given("^Create an account '(\\w+)'")
	public void create_an_account(String accountId) throws Throwable {
		AccountManager.instance().create(accountId);
	}

	@Given("^Save (\\d+) to account '(\\w+)'$")
	public void save_to_account(int amount, String accountId) throws Throwable {
		Account account = AccountManager.instance().getAccount(accountId);
		account.increase(amount);
	}

	@Given("^Transfer (\\d+) from account '(\\w+)' to '(\\w+)'$")
	public void transfer_from_account_to(int amount, String accountOrigin, String accountDestination) throws Throwable {
		Account accountFrom = AccountManager.instance().getAccount(accountOrigin);
		Account accountTo = AccountManager.instance().getAccount(accountDestination);
		AccountTransferService service = new AccountTransferService();
		lastTransferResult = service.transfer(accountFrom, accountTo, amount);
	}

	@Then("^The account '(\\w+)' should have (\\d+)$")
	public void account_should_have(String accountId, int amount) throws Throwable {
		Account account = AccountManager.instance().getAccount(accountId);
		assertEquals(amount,account.getBalance());
	}

	@Then("^The transfer result should be '(.*)'$")
	public void the_transfer_result_should_be_fail(String result) throws Throwable {
		boolean expectedResult = Boolean.parseBoolean(result);
		assertEquals(expectedResult,lastTransferResult);
	}

	@Given("^The following accounts:$")
	public void createAccount(List<Account> accounts){
		for (Account account:accounts){
			AccountManager.instance().addAccount(account);
		}
	}

	/*
	 * | name | value |
          | OrderNumber | 1 |
          | Name | Zhang San|
          | Age | 20|
          | Height| 180|
	 */
	@Given("^Create a complex data structure with:$")
	public void create_a_complex_data_structure_with(DataTable data) throws Throwable {
		Map<String, String> map = data.asMap(String.class, String.class);
		Person p = new Person();
		p.orderNumber = map.get("OrderNumber");
		p.name =  map.get("Name");
		p.age = Integer.parseInt(map.get("Age"));
		p.height = Integer.parseInt(map.get("Height"));
	}
}


text:
package net.nemerosa.ontrack.repository;

import net.nemerosa.ontrack.model.structure.*;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import static net.nemerosa.ontrack.test.TestUtils.uid;
import static org.junit.Assert.*;

public class StructureJdbcRepositoryIT extends AbstractRepositoryTestSupport {

    @Test(expected = IllegalArgumentException.class)
    public void create_branch_project_not_defined() {
        structureRepository.newBranch(Branch.of(
                Project.of(nameDescription()),
                nameDescription()
        ));
    }

    @Test
    public void create_branch() {
        // Creates a project
        Project project = do_create_project();
        // Creates a branch for this project
        Branch branch = structureRepository.newBranch(Branch.of(project, nameDescription()));
        // Checks
        assertNotNull("Branch is defined", branch);
        assertTrue("Branch ID is defined", ID.isDefined(branch.getId()));
    }

    @Test
    public void create_build_with_long_name() {
        // Creates a ranch
        Branch branch = do_create_branch();
        // Creates a build for this branch, with a very long name
        String buildName = StringUtils.repeat("b", 150);
        Build build = structureRepository.newBuild(Build.of(
                branch,
                NameDescription.nd(buildName, ""),
                Signature.of("test")
        ));
        // Checks
        assertNotNull("Build is defined", build);
        assertTrue("Build ID is defined", ID.isDefined(build.getId()));
    }

    @Test
    public void create_branch_with_null_description() {
        // Creates a project
        Project project = do_create_project();
        // Creates a branch for this project
        Branch branch = structureRepository.newBranch(Branch.of(project, NameDescription.nd("B", null)));
        // Checks
        assertNotNull("Branch is defined", branch);
        assertNull(branch.getDescription());
        assertTrue("Branch ID is defined", ID.isDefined(branch.getId()));
    }

    @Test
    public void save_branch_disabled() {
        // Creates a project
        Project project = do_create_project();
        // Creates a branch for this project
        Branch branch = structureRepository.newBranch(Branch.of(project, nameDescription()));
        // Disables it
        branch = branch.withDisabled(true);
        // Saves it
        structureRepository.saveBranch(branch);
        // Retrieves it
        branch = structureRepository.getBranch(branch.getId());
        // Checks it is disabled
        assertTrue("Branch must be disabled", branch.isDisabled());
    }

    @Test
    public void create_project() {
        Project p = do_create_project();
        assertNotNull("Project is defined", p);
        assertTrue("Project ID is defined", ID.isDefined(p.getId()));
    }

    @Test
    public void create_project_with_null_description() {
        Project p = structureRepository.newProject(Project.of(NameDescription.nd(uid("P"), null)));
        assertNotNull("Project is defined", p);
        assertNull(p.getDescription());
        assertTrue("Project ID is defined", ID.isDefined(p.getId()));
    }

    @Test
    public void save_project_disabled() {
        Project p = do_create_project();
        p = p.withDisabled(true);
        structureRepository.saveProject(p);
        p = structureRepository.getProject(p.getId());
        assertTrue("Project must be disabled", p.isDisabled());
    }

}


text:
{% extends "wedding_base.html" %}
{%  load static %}

{% block wedding-content %}

We're getting married!

Welcome to our wedding web site!  We can't wait to share our special day with you all. Information about our wedding will be available for you here.

Please check back often as we will be making frequent updates to the website as the plans progress.

        {% if is_married %}
          We're Married!
        {% elif days_left <= 7 %}
          Only {{ days_left }} day{{days_left|pluralize}}, {{ hours_left }} hour{{hours_left|pluralize}} and {{ mins_left }} min{{mins_left|pluralize}} until the wedding!
        {% else %}
          Only {{ days_left }} day{{days_left|pluralize}} until the wedding!
        {% endif %}

{% endblock %}


text:
package im.actor.model.api;
/*
 *  Generated by the Actor API Scheme generator.  DO NOT EDIT!
 */

import im.actor.model.droidkit.bser.BserObject;
import im.actor.model.droidkit.bser.BserValues;
import im.actor.model.droidkit.bser.BserWriter;

import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

public class Config extends BserObject {

    private int maxGroupSize;

    public Config(int maxGroupSize) {
        this.maxGroupSize = maxGroupSize;
    }

    public Config() {

    }

    public int getMaxGroupSize() {
        return this.maxGroupSize;
    }

    @Override
    public void parse(BserValues values) throws IOException {
        this.maxGroupSize = values.getInt(1);
    }

    @Override
    public void serialize(BserWriter writer) throws IOException {
        writer.writeInt(1, this.maxGroupSize);
    }

    @Override
    public String toString() {
        String res = "struct Config{";
        res += "maxGroupSize=" + this.maxGroupSize;
        res += "}";
        return res;
    }

}


text:
@implementation SWGUserTokenRequestInnerUserField

+ (JSONKeyMapper *)keyMapper
{
  return [[JSONKeyMapper alloc] initWithDictionary:@{ @"_id": @"_id" }];
}

@end


text:
This library defines methods for resolving addresses of CHIP Nodes/Peers.

While dnssd is used for discovery, that method generally can yield several IP
addresses due to:

-   multiple IP addresses per interface (e.g. LL, GUA, ULA or even IPv4)
-   multiple interfaces per device

The purpose of address resolution is to find a _single_ ip address to use for
the given lookup. It employs a set of heuristics to determine what the best IP
(the most likely to route correctly) is and allows custom implementations from
applications by not including the default implementation.


text:
Slider::Slider(Int2 topLeft,Int2 bottomRight,double slideLength) :
        Button(topLeft,bottomRight,""),
        slideLength(slideLength)
    {

    Serial.println("Created slider. YAY!");
}

void Slider::Draw(){
}
bool Slider::Pressing(){
    return false;
}
bool Slider::Dragging(){
    return false;
}


text:
try {
   var autobahn = require('autobahn');
} catch (e) {
   // when running in browser, AutobahnJS will
   // be included without a module system
}

var connection = new autobahn.Connection({
   url: 'ws://127.0.0.1:9000/',
   realm: 'realm1'}
);

connection.onopen = function (session) {

   session.call('com.myapp.longop', [3], {}, {receive_progress: true}).then(
      function (res) {
         console.log("Final:", res);
         connection.close();
      },
      function (err) {
      },
      function (progress) {
         console.log("Progress:", progress);
      }
   );
};

connection.open();