text:
/**
 * @fileoverview
 * Error checkers and related classes for the editor widget.
 * @author Partridge Jiang
 */

/*
 * requires /lan/classes.js
 * requires /core/kekule.common.js
 * requires /core/kekule.structures.js
 * requires /chemDoc/errorCheckers/kekule.errorCheckers.js
 * requires /widgets/editor/kekule.chemEditor.baseEditors.js
 * requires /widgets/editor/kekule.chemEditor.operations.js
 *
 * requires /localization/kekule.localize.general.js
 */

(function(){

"use strict";

Kekule.IssueCheck.IssueCode = Object.extend(Kekule.IssueCheck.IssueCode, {
	WARNING_NODE_TOO_CLOSE: 2101
});
var EC = Kekule.IssueCheck.IssueCode;

Kekule.IssueCheck.CheckerIds = Object.extend(Kekule.IssueCheck.CheckerIds, {
	NODE_DISTANCE_2D: 'nodeDistance2D'
});
var CIDs = Kekule.IssueCheck.CheckerIds;
var ICM = Kekule.IssueCheck.CheckerManager;

var CU = Kekule.CoordUtils;

/**
 * A specified issue check executor for checking objects inside a chem editor.
 * @class
 * @augments Kekule.IssueCheck.Executor
 *
 * @param {Kekule.Editor.BaseEditor} editor
 *
 * @property {Kekule.Editor.BaseEditor} editor
 */
Kekule.IssueCheck.ExecutorForEditor = Class.create(Kekule.IssueCheck.Executor,
/** @lends Kekule.IssueCheck.ExecutorForEditor# */
{
	/** @private */
	CLASS_NAME: 'Kekule.IssueCheck.ExecutorForEditor',
	/** @constructs */
	initialize: function(editor)
	{
		this.setPropStoreFieldValue('editor', editor);
		this.tryApplySuper('initialize');
		// debug
		//this.getCheckers().push(new Kekule.IssueCheck.Node2DDistanceChecker());
	},
	/** @private */
	initProperties: function()
	{
		this.defineProp('editor', {'dataType': 'Kekule.Editor.BaseEditor', 'serializable': false});
	},
	/** @ignore */
	doPrepareOptions: function(inputOptions)
	{
		var result = inputOptions? Object.create(inputOptions): {};
		var editor = this.getEditor();
		if (editor)
			result.editor = editor;
		return result;
	}
});

/**
 * A base class to generate operations to fix certain kind of issue.
 * @class
 * @augments ObjectEx
 */
Kekule.IssueCheck.IssueResolver = Class.create(ObjectEx,
/** @lends Kekule.IssueCheck.IssueResolver# */
{
	/** @private */
	CLASS_NAME: 'Kekule.IssueCheck.IssueResolver',
	/** @constructs */
	initialize: function()
	{
		this.tryApplySuper('initialize');
	},
	/**
	 * Find the solutions to resolve issue.
	 * @param {Kekule.IssueCheck.CheckResult} issueResult
	 * @param {Object} caller The caller object, usually the editor widget.
	 * @returns {Array}
	 */
	createSolutions: function(issueResult, caller)
	{
		return this.doCreateSolutions(issueResult, caller);
	},
	/**
	 * Do actual work of {@link Kekule.IssueCheck.IssueResolver.createSolutions}.
	 * Descendants may should override this method.
	 * @param {Kekule.IssueCheck.CheckResult} issueResult
	 * @param {Object} caller The caller object, usually the editor widget.
	 * @returns {Array}
	 * @private
	 */
	doCreateSolutions: function(issueResult, caller)
	{
		return [];
	},
	/** @private */
	_createSolutionInstance: function(title, description, operation, issueResult, solutionClass)
	{
		if (!solutionClass)
			solutionClass = Kekule.IssueCheck.IssueSolution;
		return new solutionClass(title, description, operation, issueResult);
	},
	/** @private */
	_getEditorWidget: function(caller)
	{
		return (caller && (caller instanceof Kekule.Editor.BaseEditor))? caller: null;
	}
});

/**
 * The base issue solution class.
 * @class
 * @augments ObjectEx
 *
 * @param {String} title
 * @param {String} description
 * @param {Kekule.Operation} operation Execute this operation can solve the issue.
 *
 * @property {String} title
 * @property {String} description
 * @property {Kekule.Operation} operation Execute this operation can solve the issue.
 */
Kekule.IssueCheck.IssueSolution = Class.create(ObjectEx,
/** @lends Kekule.IssueCheck.IssueSolution# */
{
	/** @private */
	CLASS_NAME: 'Kekule.IssueCheck.IssueSolution',
	/** @constructs */
	initialize: function(title, description, operation, issueResult)
	{
		this.setPropStoreFieldValue('issueResult', issueResult);
		this.setPropStoreFieldValue('title', title);
		this.setPropStoreFieldValue('description', description);
		this.setPropStoreFieldValue('operation', operation);
		this.tryApplySuper('initialize');
	},
	/** @private */
	initProperties: function()
	{
		this.defineProp('issueResult', {'dataType': 'Kekule.IssueCheck.CheckResult', 'serializable': false});
		this.defineProp('title', {'dataType': DataType.STRING});
		this.defineProp('description', {'dataType': DataType.STRING});
		this.defineProp('operation', {'dataType': 'Kekule.Operation', 'serializable': false});
	},
	/** @ignore */
	doFinalize: function()
	{
		var op = this.getOperation();
		if (op)
			op.finalize();
		this.tryApplySuper('doFinalize');
	}
});

/**
 * The util class to register and store issue resolver class info.
 * @class
 */
Kekule.IssueCheck.ResolverManager = {
	/** @private */
	_resolverMap: new Kekule.MapEx(),
	/** @private */
	_resolverInstanceMap: new Kekule.MapEx(),
	/**
	 * Register to manager.
	 * @param {Class} issueResultClass
	 * @param {Class} resolverClass
	 */
	register: function(issueResultClass, resolverClass)
	{
		var rclasses = IRM._resolverMap.get(issueResultClass);
		if (!rclasses)
		{
			rclasses = [];
			IRM._resolverMap.set(issueResultClass, rclasses);
		}
		if (rclasses.indexOf(resolverClass) < 0)
			rclasses.push(resolverClass);
	},
	/**
	 * Unregister from class.
	 * @param {Class} issueResultClass
	 * @param {Class} resolverClass
	 */
	unregister: function(issueResultClass, resolverClass)
	{
		var rclasses = IRM._resolverMap.get(issueResultClass);
		var index = rclasses.indexOf(resolverClass);
		if (index >= 0)
			rclasses.splice(index, 1);
	},
	/**
	 * Returns the registered resolver class.
	 * @param {Class} issueResultClass
	 * @returns {Array} Resolver classes found.
	 */
	getResolverClasses: function(issueResultClass)
	{
		return IRM._resolverMap.get(issueResultClass) || [];
	},
	/**
	 * Returns the instance of registered resolver class.
	 * Note the instance will be cached. So multiple calls of this function only returns one single instance.
	 * @param {Class} issueResultClass
	 * @returns {Array} Instances of {@link Kekule.IssueCheck.IssueResolver}.
	 */
	getResolverInstances: function(issueResultClass)
	{
		var result = [];
		var classes = IRM.getResolverClasses(issueResultClass);
		for (var i = 0, l = classes.length; i < l; ++i)
		{
			var rclass = classes[i];
			var instance = IRM._resolverInstanceMap.get(rclass);
			if (!instance)
			{
				instance = new rclass();
				IRM._resolverInstanceMap.set(rclass, instance);
			}
			result.push(instance);
		}
		return result;
	}
};
var IRM = Kekule.IssueCheck.ResolverManager;

// expand Kekule.IssueCheck.CheckResult, enable it can retreive solutions from Kekule.IssueCheck.ResolverManager
ClassEx.extend(Kekule.IssueCheck.CheckResult, {
	/**
	 * Returns resolver instances for this issue result.
	 * @returns {Array}
	 */
	getResolvers: function()
	{
		return IRM.getResolverInstances(this.getClass());
	},
	/**
	 * Create solution objects for this issue result.
	 * @param {Object} caller
	 * @returns {Array}
	 */
	fetchSolutions: function(caller)
	{
		var resolvers = this.getResolvers();
		var result = [];
		for (var i = 0, l = resolvers.length; i < l; ++i)
		{
			var r = resolvers[i];
			var solutions = r.createSolutions(this, caller);
			if (solutions && solutions.length)
				result = result.concat(solutions);
		}
		return result;
	}
});
/*
ClassEx.defineProp(Kekule.IssueCheck.CheckResult, 'solutions', {
	'dataType': DataType.ARRAY,
	'serializable': false,
	'setter': null
});
*/

/**
 * The resolver class for {@link Kekule.IssueCheck.BondOrderChecker.Result}.
 * @class
 * @augments Kekule.IssueCheck.IssueResolver
 */
Kekule.IssueCheck.BondOrderChecker.Resolver = Class.create(Kekule.IssueCheck.IssueResolver,
/** @lends Kekule.IssueCheck.BondOrderChecker.Resolver# */
{
	/** @private */
	CLASS_NAME: 'Kekule.IssueCheck.BondOrderChecker.Resolver',
	/** @ignore */
	doCreateSolutions: function(issueResult, caller)
	{
		var bond = issueResult.getTargets()[0];
		var currOrder = bond.getBondOrder();
		var maxOrder = issueResult.getData().maxOrder;
		var editor = this._getEditorWidget(caller);

		if (bond && maxOrder && editor)
		{
			// create operation to change current bond order to maxOrder
			var op = new Kekule.ChemObjOperation.Modify(bond, {'bondOrder': maxOrder}, editor);
			var title = Kekule.$L('ErrorCheckMsg.TITLE_CHANGE_BOND_ORDER_TO').format(maxOrder);
			var description = Kekule.$L('ErrorCheckMsg.DESCRIPTION_CHANGE_BOND_ORDER_TO').format(currOrder, maxOrder);
			return [
				this._createSolutionInstance(title, description, op, issueResult)
			];
		}
		else
			return [];
	}
});
IRM.register(Kekule.IssueCheck.BondOrderChecker.Result, Kekule.IssueCheck.BondOrderChecker.Resolver);

/**
 * The checker to check if two nodes are too close to be merged together.
 * Note this class check only the 2D issues.
 * @class
 * @augments Kekule.IssueCheck.BaseChecker
 */
Kekule.IssueCheck.Node2DDistanceChecker = Class.create(Kekule.IssueCheck.BaseChecker,
/** @lends Kekule.IssueCheck.Node2DDistanceChecker# */
{
	/** @private */
	CLASS_NAME: 'Kekule.IssueCheck.Node2DDistanceChecker',
	/** @ignore */
	doApplicable: function(target, rootObj, options)
	{
		// only check exposed nodes in a chem space
		return (rootObj instanceof Kekule.ChemSpace)
			&& (target instanceof Kekule.ChemStructureNode)
			&& (!(target instanceof Kekule.Molecule) || !(target.isExpanded && target.isExpanded))
			&& (!target.isExposed || target.isExposed());
	},
	/* @ignore */
	/*
	doCheck: function(targets, rootObj, options)
	{
		var result = [];
		for (var i = 0, l = targets.length; i < l; ++i)
		{
			var node1 = targets[i];
			for (var j = i + 1; j < l; ++j)
			{
				var node2 = targets[j];
				var repItem = this.doCheckDistance(node1, node2, rootObj, options);
				if (repItem)
					result.push(repItem);
			}
		}
		return result;
	},
	*/
	/** @ignore */
	doCheckOnTarget: function(target, targetIndex, targets, rootObj, options)
	{
		var result = [];
		var node1 = target;
		for (var i = targetIndex + 1, l = targets.length; i < l; ++i)
		{
			var node2 = targets[i];
			if (node2)
			{
				var repItem = this.doCheckDistance(node1, node2, rootObj, options);
				if (repItem)
					result.push(repItem);
			}
		}
		return result;
	},
	/** @private */
	doCheckDistance: function(node1, node2, rootObj, options)
	{
		var threshold = this._getDistanceRefLength(rootObj) / 5;
		var editor = options.editor;
		var allowCoordBorrow = editor? editor.getAllowCoordBorrow(): false;
		if (this._isNodesDistanceTooClose(node1, node2, threshold, allowCoordBorrow, editor))
		{
			// (errorLevel, errorCode, data, targets, reporter)
			var repItem = new Kekule.IssueCheck.Node2DDistanceChecker.Result(Kekule.ErrorLevel.WARNING,
				EC.WARNING_NODE_TOO_CLOSE, null, [node1, node2], this);
			return repItem;
		}
		else
			return null;
	},
	/** @private */
	_getDistanceRefLength: function(rootObj)
	{
		// in doApplicable method, we are sure that the rootObj is an instanceof ChemSpace
		return rootObj.getDefAutoScaleRefLength();
	},
	/** @private */
	_getEditor: function(checkOptions)
	{
		return checkOptions.editor;
	},
	/** @private */
	_isNodesDistanceTooClose: function(node1, node2, objDistanceThreshold, allowCoordBorrow, editor)
	{
		if (editor)
		{
			// get threshold in screen sys, for checking with screen bound shape more quickly
			var screenDistanceThreshold = editor.translateDistance(objDistanceThreshold, Kekule.Render.CoordSystem.CHEM, Kekule.Render.CoordSystem.SCREEN);
			// check bound of two nodes
			return this._isNodesDistanceTooCloseByBound(node1, node2, objDistanceThreshold, screenDistanceThreshold, editor);
		}
		else
		{
			var distance = this._getNodesDistanceByCoord(node1, node2, allowCoordBorrow);
			return distance < distanceThreshold;
		}
	},
	/** @private */
	_getNodesDistanceByCoord: function(node1, node2, allowCoordBorrow)
	{
		var coord1 = node1.getAbsCoord2D(allowCoordBorrow);
		var coord2 = node2.getAbsCoord2D(allowCoordBorrow);
		return CU.getDistance(coord1, coord2);
	},
	/** @private */
	_isNodesDistanceTooCloseByBound: function(node1, node2, objDistanceThreshold, screenDistanceThreshold, editor)
	{
		var ST = Kekule.Render.BoundShapeType;
		var MU = Kekule.Render.MetaShapeUtils;
		var shape1 = editor.getChemObjBounds(node1)[0];  // node usually has only one bound (point or atom label rectange)
		var shape2 = editor.getChemObjBounds(node2)[0];
		if (!shape1 || !shape2)
			return false;

		if (this._isPointOrCircleShape(shape1) && this._isPointOrCircleShape(shape2))  // calc distance of two points
		{
			var screenDistance = CU.getDistance(shape1.coords[0], shape2.coords[0]) - (shape1.radius || 0) - (shape1.radius || 0);
			//console.log(node1.getId(), node2.getId(), screenDistance, editor.getDefBondScreenLength());
			//console.log(node1.getId(), node2.getId(), shape1, shape2, distance, distanceThreshold);
			return screenDistance < screenDistanceThreshold;
		}
		else if (this._isPointOrCircleShape(shape1) || this._isPointOrCircleShape(shape2))  // one of the shape is point, the other should be rect, ensure they does not overlap
		{
			var isShape1Point = this._isPointOrCircleShape(shape1);
			var pointCoord = isShape1Point? shape1.coords[0]: shape2.coords[0];
			var radius = isShape1Point? (shape1.radius || 0): (shape2.radius || 0);
			var complexShape = isShape1Point? shape2: shape1;
			var checkShape = MU.inflateShape(complexShape, screenDistanceThreshold);
			var screenDistance = MU.getDistance(pointCoord, checkShape) - radius;
			return screenDistance < 0;
		}
		else // both shapes are rect, atom with label, check if they intersects
		{
			for (var i = 0, l = shape1.coords.length; i < l; ++i)
			{
				var c = shape1.coords[i];
				if (MU.isCoordInside(c, shape2))
					return true;
			}
			for (var i = 0, l = shape2.coords.length; i < l; ++i)
			{
				var c = shape2.coords[i];
				if (MU.isCoordInside(c, shape1))
					return true;
			}
			return false;
		}
	},
	/** @private */
	_isPointOrCircleShape: function(shape)
	{
		var ST = Kekule.Render.BoundShapeType;
		return shape.shapeType === ST.POINT || shape.shapeType === ST.CIRCLE;
	}
});
// register
ICM.register(CIDs.NODE_DISTANCE_2D, Kekule.IssueCheck.Node2DDistanceChecker);

/**
 * Represent the checking result of {@link Kekule.IssueCheck.AtomValenceChecker}.
 * @class
 * @augments Kekule.IssueCheck.CheckResult
 */
Kekule.IssueCheck.Node2DDistanceChecker.Result = Class.create(Kekule.IssueCheck.CheckResult,
/** @lends Kekule.IssueCheck.NodeDistanceChecker.Result# */
{
	/** @private */
	CLASS_NAME: 'Kekule.IssueCheck.NodeDistanceChecker.Result',
	/** @private */
	DEF_ERROR_CODE: EC.WARNING_NODE_TOO_CLOSE,
	/** @ignore */
	getMessage: function()
	{
		var node1 = this.getTargets()[0];
		var node2 = this.getTargets()[1];
		//var id1 = node1 && node1.getId && node1.getId();
		//var id2 = node2 && node2.getId && node2.getId();
		//var msg =(id1 && id2)? Kekule.$L('ErrorCheckMsg.NODE_DISTANCE_TOO_CLOSE_WITH_ID').format(id1 + '/' + id2): Kekule.$L('ErrorCheckMsg.NODE_DISTANCE_TOO_CLOSE');
		var label1 = (node1.getLabel && node1.getLabel()) || (node1.getId && node1.getId());
		var label2 = (node2.getLabel && node2.getLabel()) || (node2.getId && node2.getId());
		var msg = (label1 && label1)? Kekule.$L('ErrorCheckMsg.NODE_DISTANCE_TOO_CLOSE_WITH_LABEL').format(label1 + '/' + label2): Kekule.$L('ErrorCheckMsg.NODE_DISTANCE_TOO_CLOSE');
		return msg;
	}
});

/**
 * The resolver class for {@link Kekule.IssueCheck.Node2DDistanceChecker.Result}.
 * @class
 * @augments Kekule.IssueCheck.IssueResolver
 */
Kekule.IssueCheck.Node2DDistanceChecker.Resolver = Class.create(Kekule.IssueCheck.IssueResolver,
/** @lends Kekule.IssueCheck.Node2DDistanceChecker.Resolver# */
{
	/** @private */
	CLASS_NAME: 'Kekule.IssueCheck.Node2DDistanceChecker.Resolver',
	/** @ignore */
	doCreateSolutions: function(issueResult, caller)
	{
		var node1 = issueResult.getTargets()[0];
		var node2 = issueResult.getTargets()[1];
		var label1 = (node1.getLabel && node1.getLabel()); // || (node1.getId && node1.getId());
		var label2 = (node2.getLabel && node2.getLabel()); // || (node2.getId && node2.getId());
		var sameLabel = label1 === label2;
		if (!label1 || sameLabel)
		{
			var id1 = node1.getId && node1.getId();
			if (id1)
				label1 = label1? label1 + '(' + id1 + ')': id1;
		}
		if (!label1 || sameLabel)
		{
			var id2 = node2.getId && node2.getId();
			if (id2)
				label2 = label2? label2 + '(' + id2 + ')': id2;
		}

		var editor = this._getEditorWidget(caller);

		var result = [];
		if (node1 && node2 && editor)
		{
			var canMergeStructFragment = editor.getEditorConfigs().getInteractionConfigs().getEnableStructFragmentMerge();
			var canMergeNeighborNodes = editor.getEditorConfigs().getInteractionConfigs().getEnableNeighborNodeMerge();
			if (Kekule.ChemStructOperation.MergeNodes.canMerge(node1, node2, canMergeStructFragment, canMergeNeighborNodes))  // can merge node1 to node2
			{
				var op = new Kekule.ChemStructOperation.MergeNodes(node1, node2, canMergeStructFragment, editor);
				result.push(this._createSolutionInstance(
					Kekule.$L('ErrorCheckMsg.TITLE_MERGE_TO').format(label1, label2),
					Kekule.$L('ErrorCheckMsg.DESCRIPTION_MERGE_TO').format(label1, label2),
					op,
					issueResult
				));
			}
			if (Kekule.ChemStructOperation.MergeNodes.canMerge(node2, node1, canMergeStructFragment, canMergeNeighborNodes))  // can merge node2 to node1
			{
				var op = new Kekule.ChemStructOperation.MergeNodes(node2, node1, canMergeStructFragment, editor);
				result.push(this._createSolutionInstance(
					Kekule.$L('ErrorCheckMsg.TITLE_MERGE_TO').format(label2, label1),
					Kekule.$L('ErrorCheckMsg.DESCRIPTION_MERGE_TO').format(label2, label1),
					op,
					issueResult
				));
			}
		}

		return result;
	}
});
IRM.register(Kekule.IssueCheck.Node2DDistanceChecker.Result, Kekule.IssueCheck.Node2DDistanceChecker.Resolver);

})();


text:
<?php

/**
 * @author Donald Ball
 */
class Doctrine_Ticket_941_TestCase extends Doctrine_UnitTestCase
{

  public function prepareTables()
  {
    $this->tables = array('Site', 'Variable', 'SiteVarvalue');
    parent::prepareTables();
  }

  public function prepareData()
  {
      $site = new Site();
      $site->site_id      = 1;
      $site->site_domain  = 'site1';
      $site->save();

      $site = new Site();
      $site->site_id      = 2;
      $site->site_domain  = 'site2';
      $site->save();

      $var  = new Variable();
      $var->variable_id   = 1;
      $var->variable_name = 'var1';
      $var->save();

      $var  = new Variable();
      $var->variable_id   = 2;
      $var->variable_name = 'var2';
      $var->save();

      $varval = new SiteVarvalue();
      $varval->site_id        = 1;
      $varval->variable_id    = 1;
      $varval->varvalue_value = 'val1 dom1 var1';
      $varval->save();

      $varval = new SiteVarvalue();
      $varval->site_id        = 1;
      $varval->variable_id    = 2;
      $varval->varvalue_value = 'val2 dom1 var2';
      $varval->save();

      $varval = new SiteVarvalue();
      $varval->site_id        = 2;
      $varval->variable_id    = 1;
      $varval->varvalue_value = 'val3 dom2 var1';
      $varval->save();

      $varval = new SiteVarvalue();
      $varval->site_id        = 2;
      $varval->variable_id    = 2;
      $varval->varvalue_value = 'val4 dom2 var2';
      $varval->save();
  }

  public function testTicket()
  {
      $query = new Doctrine_Query();
      $query = $query->from('Site s LEFT JOIN s.Variables v LEFT JOIN v.Values vv WITH vv.site_id = s.site_id');

      $sites = $query->execute();

      $this->assertEqual('site1', $sites[0]->site_domain);
      $this->assertEqual(2, count($sites));

      // this is important for the understanding of the behavior
      $this->assertIdentical($sites[0]->Variables[0], $sites[1]->Variables[0]);
      $this->assertIdentical($sites[0]->Variables[1], $sites[1]->Variables[1]);
      $this->assertEqual(2, count($sites[0]->Variables[0]->Values));
      $this->assertEqual(2, count($sites[1]->Variables[0]->Values));
      $this->assertEqual(2, count($sites[0]->Variables[1]->Values));
      $this->assertEqual(2, count($sites[1]->Variables[1]->Values));
      // Here we see that there can be only one Values on each Variable object. Hence
      // they end up with 2 objects each.
      $this->assertEqual('val1 dom1 var1', $sites[0]->Variables[0]->Values[0]->varvalue_value);
      $this->assertEqual('val3 dom2 var1', $sites[0]->Variables[0]->Values[1]->varvalue_value);
      $this->assertEqual('val2 dom1 var2', $sites[0]->Variables[1]->Values[0]->varvalue_value);
      $this->assertEqual('val4 dom2 var2', $sites[0]->Variables[1]->Values[1]->varvalue_value);

      $this->assertEqual('var1', $sites[0]->Variables[0]->variable_name);
      $this->assertEqual('var1', $sites[1]->Variables[0]->variable_name);

      $this->assertEqual('var2', $sites[0]->Variables[1]->variable_name);
      $this->assertEqual('var2', $sites[1]->Variables[1]->variable_name);

      // now array hydration

      $sites = $query->fetchArray();

      $this->assertEqual('site1', $sites[0]['site_domain']);
      $this->assertEqual('site2', $sites[1]['site_domain']);
      $this->assertEqual(2, count($sites));

      // this is important for the understanding of the behavior
      $this->assertEqual(1, count($sites[0]['Variables'][0]['Values']));
      $this->assertEqual(1, count($sites[1]['Variables'][0]['Values']));
      $this->assertEqual(1, count($sites[0]['Variables'][1]['Values']));
      $this->assertEqual(1, count($sites[1]['Variables'][1]['Values']));
      // Here we see that the Values collection of the *same* Variable object can have
      // different contents when hydrating arrays
      $this->assertEqual('val1 dom1 var1', $sites[0]['Variables'][0]['Values'][0]['varvalue_value']);
      $this->assertEqual('val3 dom2 var1', $sites[1]['Variables'][0]['Values'][0]['varvalue_value']);
      // Here we see that the Values collection of the *same* Variable object can have
      // different contents when hydrating arrays
      $this->assertEqual('val2 dom1 var2', $sites[0]['Variables'][1]['Values'][0]['varvalue_value']);
      $this->assertEqual('val4 dom2 var2', $sites[1]['Variables'][1]['Values'][0]['varvalue_value']);

      $this->assertEqual('var1', $sites[0]['Variables'][0]['variable_name']);
      $this->assertEqual('var1', $sites[1]['Variables'][0]['variable_name']);

      $this->assertEqual('var2', $sites[0]['Variables'][1]['variable_name']);
      $this->assertEqual('var2', $sites[1]['Variables'][1]['variable_name']);

  }

}

abstract class BaseSite extends Doctrine_Record
{

  public function setTableDefinition()
  {
    $this->setTableName('_site');
    $this->hasColumn('site_id', 'integer', 4, array('notnull' => true, 'primary' => true, 'autoincrement' => true));
    $this->hasColumn('site_domain', 'string', 255, array('notnull' => true));
  }

  public function setUp()
  {
    parent::setUp();
    $this->hasMany('Variable as Variables', array('refClass' => 'SiteVarvalue',
                                                  'local' => 'site_id',
                                                  'foreign' => 'variable_id'));
  }

}
abstract class BaseVariable extends Doctrine_Record
{

  public function setTableDefinition()
  {
    $this->setTableName('_variable');
    $this->hasColumn('variable_id', 'integer', 4, array('notnull' => true, 'primary' => true, 'autoincrement' => true));
    $this->hasColumn('variable_name', 'string', 100, array('notnull' => true));
  }

  public function setUp()
  {
    parent::setUp();
    $this->hasMany('Site as Sites', array('refClass' => 'SiteVarvalue',
                                          'local' => 'variable_id',
                                          'foreign' => 'site_id'));

    $this->hasMany('SiteVarvalue as Values', array('local' => 'variable_id',
                                                    'foreign' => 'variable_id'));
  }

}
abstract class BaseSiteVarvalue extends Doctrine_Record
{

  public function setTableDefinition()
  {
    $this->setTableName('_site_varvalue');
    $this->hasColumn('varvalue_id', 'integer', 4, array('notnull' => true, 'primary' => true, 'autoincrement' => true));
    $this->hasColumn('site_id', 'integer', 4, array('notnull' => true));
    $this->hasColumn('variable_id', 'integer', 4, array('notnull' => true));
    $this->hasColumn('varvalue_value', 'string', null, array('notnull' => true));
  }

  public function setUp()
  {
    parent::setUp();
    $this->hasOne('Variable as Variables', array('local' => 'variable_id',
                                                 'foreign' => 'variable_id'));
  }

}
class Site extends BaseSite
{
}
class Variable extends BaseVariable
{
}
class SiteVarvalue extends BaseSiteVarvalue
{
}

redpajama_set_name: RedPajamaGithub


text:
Index Basics
============

GeoMesa will create various indices for a given ``SimpleFeatureType`` schema (see :ref:`index_overview`). This
allows us to answer a variety of queries in a optimized manner. GeoMesa will make a best effort to determine
the attributes used for indexing. The attributes to use can also be specified as part of the ``SimpleFeatureType``.

Spatial Index (Z2/XZ2)
----------------------

If the ``SimpleFeatureType`` has a ``Geometry``-type attribute (``Point``, ``LineString``, ``Polygon``, etc),
GeoMesa will create a spatial index on that attribute. If there is more than one ``Geometry``-type attribute,
the default one will be used. The default geometry is generally specified with a ``*`` prefix in the
``SimpleFeatureType`` string, and is the one returned by ``SimpleFeatureType.getGeometryDescriptor``.

Spatio-temporal Index (Z3/XZ3)
------------------------------

If the ``SimpleFeatureType`` has both a ``Geometry``-type attribute and a ``Date`` attribute, GeoMesa will
create a spatio-temporal index on those attributes. The ``Geometry``-type attribute used is the same as
for the spatial index, above. The ``Date`` attribute selected will be the first one declared, or can be
set explicitly. See :ref:`set_date_attribute` for details on setting the indexed date.

ID Index
--------

GeoMesa will always create an ID index on ``SimpleFeature.getID()``.

.. _attribute_indices:

Attribute Index
---------------

Some queries are slow to answer using the default indices. For example, with twitter data you
might want to return all tweets for a given user. To speed up this type of query, any
attribute in your simple feature type may be indexed individually.

To index an attribute, add an ``index`` hint to the attribute descriptor with a value of ``true``. To set
the cardinality of an attribute, use the hint ``cardinality`` with a value of ``high`` or ``low`` (see below
for a description of cardinality hints).

.. warning::

    Accumulo data stores have an additional option to create reduced 'join' attribute indices, and will
    use the reduced format by default. See :ref:`accumulo_attribute_indices` for details.

Setting the hint can be done in multiple ways. If you are using a string to indicate your simple feature type
(e.g. through the command line tools, or when using ``SimpleFeatureTypes.createType``), you can append
the hint to the attribute to be indexed, like so:

.. code-block:: java

    // append the hint after the attribute type, separated by a colon
    String spec = "name:String:index=true:cardinality=high,age:Int:index=true,dtg:Date,*geom:Point:srid=4326"
    SimpleFeatureType sft = SimpleFeatureTypes.createType("mySft", spec);

If you have an existing simple feature type, or you are not using ``SimpleFeatureTypes.createType``,
you may set the hint directly in the feature type:

.. code-block:: java

    // set the hint directly
    SimpleFeatureType sft = ...
    sft.getDescriptor("name").getUserData().put("index", "true");
    sft.getDescriptor("name").getUserData().put("cardinality", "high");
    sft.getDescriptor("age").getUserData().put("index", "true");

If you are using TypeSafe configuration files to define your simple feature type, you may include the hint in
the attribute field:

.. code-block:: javascript

    geomesa {
      sfts {
        "mySft" = {
          attributes = [
            { name = name, type = String, index = true, cardinality = high }
            { name = age,  type = Int,    index = true                     }
            { name = dtg,  type = Date                                     }
            { name = geom, type = Point,  srid = 4326                      }
          ]
        }
      }
    }

If you are using the GeoMesa ``SftBuilder``, you may call the overloaded attribute methods:

.. code-block:: scala

    // scala example
    import org.locationtech.geomesa.utils.geotools.SftBuilder.SftBuilder
    import org.locationtech.geomesa.utils.stats.Cardinality

    val sft = new SftBuilder()
        .stringType("name", Opts(index = true, cardinality = Cardinality.HIGH))
        .intType("age", Opts(index = true))
        .date("dtg")
        .geometry("geom", default = true)
        .build("mySft")

Cardinality Hints
^^^^^^^^^^^^^^^^^

GeoMesa has a query planner that tries to find the best strategy for answering a given query. In
general, this means using the index that will filter the result set the most, before considering
the entire query filter on the reduced data set. For simple queries, there is often only one
suitable index. However, for mixed queries, there can be multiple options.

For example, given the query ``bbox(geom, -120, -60, 120, 60) AND IN('id-01')``, we could try to
execute against the spatial index using the bounding box, or we could try to execute against the
ID index using the feature ID. In this case, we know that the ID filter will match at most one
record, while the bbox filter could match many records, so we will choose the ID index.

Attributes that are know to have many distinct values, i.e. a high cardinality, are likely to filter
out many false positives through the index structure, and thus a query against the attribute index will
touch relatively few records. Conversely, in the worst case, a Boolean attribute (for example), with only
two distinct values, would likely require scanning half of the entire data set.

Cardinality hints may be used to influence the query planner when considering attribute indices.
If an attribute is marked as having a high cardinality, the attribute index will be prioritized.
Conversely, if an attribute is marked with low cardinality, the attribute index will be de-prioritized.


text:
const ogs = require('../../index');

describe('blacklist', function () {
  it('when website is on the blacklist', function () {
    return ogs({
      url: 'https://www.wikipedia.org/',
      blacklist: ['www.test.com', 'www.wikipedia.org'],
    })
      .then(function () {
        expect().fail('this should not happen');
      })
      .catch(function ({ error, result, response }) {
        console.log('error:', error);
        console.log('result:', result);
        expect(error).to.be.eql(true);
        expect(result.success).to.be.eql(false);
        expect(result.requestUrl).to.be.eql('https://www.wikipedia.org/');
        expect(result.error).to.eql('Host name has been black listed');
        expect(result.errorDetails.toString()).to.eql('Error: Host name has been black listed');
        expect(result).to.have.all.keys(
          'error',
          'errorDetails',
          'requestUrl',
          'success',
        );
        expect(response).to.eql(undefined);
      });
  });
  it('when website is not on the blacklist', function () {
    return ogs({
      url: 'https://www.wikipedia.org/',
      blacklist: ['www.test.com', 'www.google.org'],
    }).then(function ({ error, result, response }) {
      console.log('error:', error);
      console.log('result:', result);
      expect(error).to.be.eql(false);
      expect(result.ogTitle).to.be.eql('Wikipedia');
      expect(result.ogDescription).to.be.eql('Wikipedia is a free online encyclopedia, created and edited by volunteers around the world and hosted by the Wikimedia Foundation.');
      expect(result.favicon).to.be.eql('/static/favicon/wikipedia.ico');
      expect(result.ogLocale).to.be.eql('en');
      expect(result.requestUrl).to.be.eql('https://www.wikipedia.org/');
      expect(result.charset).to.be.eql('utf8');
      expect(result.success).to.be.eql(true);
      expect(result).to.have.all.keys(
        'favicon',
        'ogDescription',
        'ogLocale',
        'ogTitle',
        'requestUrl',
        'success',
        'charset',
      );
      expect(response).to.be.an('object').and.to.not.be.empty;
    });
  });
  it('when blacklist empty', function () {
    return ogs({
      url: 'https://www.wikipedia.org/',
      blacklist: [],
    }).then(function ({ error, result, response }) {
      console.log('error:', error);
      console.log('result:', result);
      expect(error).to.be.eql(false);
      expect(result.ogTitle).to.be.eql('Wikipedia');
      expect(result.ogDescription).to.be.eql('Wikipedia is a free online encyclopedia, created and edited by volunteers around the world and hosted by the Wikimedia Foundation.');
      expect(result.ogLocale).to.be.eql('en');
      expect(result.requestUrl).to.be.eql('https://www.wikipedia.org/');
      expect(result.favicon).to.be.eql('/static/favicon/wikipedia.ico');
      expect(result.charset).to.be.eql('utf8');
      expect(result.success).to.be.eql(true);
      expect(result).to.have.all.keys(
        'favicon',
        'ogDescription',
        'ogTitle',
        'ogLocale',
        'requestUrl',
        'success',
        'charset',
      );
      expect(response).to.be.an('object').and.to.not.be.empty;
    });
  });
});


text:
export default class Command{
	constructor(name){
		this.name=name;
	}
}


text:
require 'spec_helper'

describe Worker::Status do
  include Support::ActiveRecord

  let(:reports) do
    [
      { 'name' => 'ruby-1', 'host' => 'ruby.workers.travis-ci.org', 'state' => 'working', 'payload' => { 'foo' => 'bar' } },
      { 'name' => 'ruby-2', 'host' => 'ruby.workers.travis-ci.org', 'state' => 'ready' },
      { 'name' => 'ruby-3', 'host' => 'ruby.workers.travis-ci.org', 'state' => 'ready' }
    ]
  end

  let(:status) { Worker::Status.new(reports) }

  before :each do
    Worker.create!(:name => 'ruby-1', :host => 'ruby.workers.travis-ci.org', :state => :ready, :last_seen_at => Time.now - 10)
    Worker.create!(:name => 'ruby-2', :host => 'ruby.workers.travis-ci.org', :state => :ready, :last_seen_at => Time.now - 10)
  end

  it 'creates a worker record if missing' do
    lambda { status.run }.should change(Worker, :count).by(1)
  end

  it "updates each worker record's :last_seen_at attribute" do
    status.run
    Worker.all.map(&:last_seen_at).uniq.map(&:to_s).should == [Time.now.to_s]
  end

  it "updates each worker record's :state attribute" do
    status.run
    Worker.all.map(&:state).sort.should == ['ready', 'ready', 'working']
  end

  it 'notifies about the worker creation' do
    Worker.any_instance.stubs(:notify)
    Worker.any_instance.expects(:notify).with(:add).once
    status.run
  end

  it 'notifies about worker state changes' do
    Worker.any_instance.stubs(:notify)
    Worker.any_instance.expects(:notify).with(:update).once
    status.run
  end
end


text:
package model

import "gopkg.in/mgo.v2/bson"

type PersonInfo struct {
	Id          bson.ObjectId `json:"id" bson:"_id"`
	Name        string        `json:"name"`
	Url         string        `json:"url"`
	Tags        []string      `json:"tags"`
	Summary_pic string        `json:"Summary_pic"`
}


text:
anaconda=Miniconda2-latest-Linux-x86_64.sh

if [ ! -f $anaconda ]; then
    echo 'Downloading anaconda...'
    wget https://repo.continuum.io/miniconda/$anaconda

    echo 'Installing default anaconda environment...'
    chmod +x $anaconda
    ./$anaconda -b -f -p /home/ubuntu/anaconda
fi

echo 'Appending /home/ubuntu/anaconda/bin to path in ~/.bashrc file'
export PATH="/home/ubuntu/anaconda/bin:$PATH"
echo "export PATH=/home/ubuntu/anaconda/bin:$PATH" >> ~/.bashrc

echo 'Sourcing .bashrc'
source ~/.bashrc

echo 'Done'


text:
package org.cocos2d.transitions;

import org.cocos2d.nodes.Director;
import org.cocos2d.nodes.Scene;
import org.cocos2d.types.CCSize;
import org.cocos2d.actions.interval.IntervalAction;
import org.cocos2d.actions.interval.MoveBy;

/**
 * SlideInT Transition.
 * Slide in the incoming scene from the top border.
 */
public class SlideInTTransition extends SlideInLTransition {

    public static SlideInTTransition transition(float t, Scene s) {
        return new SlideInTTransition(t, s);
    }

    public SlideInTTransition(float t, Scene s) {
        super(t, s);
    }

    public void sceneOrder() {
        inSceneOnTop = false;
    }

    /**
     * initializes the scenes
     */
    protected void initScenes() {
        CCSize s = Director.sharedDirector().winSize();
        inScene.setPosition(0,s.height-ADJUST_FACTOR);
    }

    protected IntervalAction action() {
        CCSize s = Director.sharedDirector().winSize();
        return MoveBy.action(duration, 0,-(s.height-ADJUST_FACTOR));
    }

}


text:
package org.apache.camel.component.file.remote;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.apache.camel.Exchange;
import org.apache.camel.InvalidPayloadException;
import org.apache.camel.component.file.FileComponent;
import org.apache.camel.component.file.GenericFile;
import org.apache.camel.component.file.GenericFileEndpoint;
import org.apache.camel.component.file.GenericFileExist;
import org.apache.camel.component.file.GenericFileOperationFailedException;
import org.apache.camel.support.ObjectHelper;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.StopWatch;
import org.apache.camel.util.TimeUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * FTP remote file operations
 */
public class FtpOperations implements RemoteFileOperations<FTPFile> {

    protected final Logger log = LoggerFactory.getLogger(getClass());
    protected final FTPClient client;
    protected final FTPClientConfig clientConfig;
    protected FtpEndpoint<FTPFile> endpoint;
    protected FtpClientActivityListener clientActivityListener;

    public FtpOperations(FTPClient client, FTPClientConfig clientConfig) {
        this.client = client;
        this.clientConfig = clientConfig;
    }

    @Override
    public void setEndpoint(GenericFileEndpoint<FTPFile> endpoint) {
        this.endpoint = (FtpEndpoint<FTPFile>) endpoint;
        // setup download listener/logger when we have the endpoint configured
        this.clientActivityListener = new DefaultFtpClientActivityListener(this.endpoint, this.endpoint.getConfiguration().remoteServerInformation());
    }

    public FtpClientActivityListener getClientActivityListener() {
        return clientActivityListener;
    }

    public void setClientActivityListener(FtpClientActivityListener clientActivityListener) {
        this.clientActivityListener = clientActivityListener;
    }

    @Override
    public boolean connect(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException {
        client.setCopyStreamListener(clientActivityListener);

        try {
            return doConnect(configuration, exchange);
        } catch (GenericFileOperationFailedException e) {
            clientActivityListener.onGeneralError(endpoint.getConfiguration().remoteServerInformation(), e.getMessage());
            throw e;
        }
    }

    protected boolean doConnect(RemoteFileConfiguration configuration, Exchange exchange) throws GenericFileOperationFailedException {
        log.trace("Connecting using FTPClient: {}", client);

        String host = configuration.getHost();
        int port = configuration.getPort();
        String username = configuration.getUsername();
        String account = ((FtpConfiguration) configuration).getAccount();

        if (clientConfig != null) {
            log.trace("Configuring FTPClient with config: {}", clientConfig);
            client.configure(clientConfig);
        }

        if (log.isTraceEnabled()) {
            log.trace("Connecting to {} using connection timeout: {}",
                    configuration.remoteServerInformation(), client.getConnectTimeout());
        }

        boolean connected = false;
        int attempt = 0;

        while (!connected) {
            try {
                if (log.isTraceEnabled() && attempt > 0) {
                    log.trace("Reconnect attempt #{} connecting to {}", attempt, configuration.remoteServerInformation());
                }
                clientActivityListener.onConnecting(host);
                client.connect(host, port);
                // must check reply code if we are connected
                int reply = client.getReplyCode();

                if (FTPReply.isPositiveCompletion(reply)) {
                    // yes we could connect
                    connected = true;
                } else {
                    // throw an exception to force the retry logic in the catch exception block
                    throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), "Server refused connection");
                }
            } catch (Exception e) {
                if (client.isConnected()) {
                    log.trace("Disconnecting due to exception during connect");
                    try {
                        client.disconnect(); // ensures socket is closed
                    } catch (IOException ignore) {
                        log.trace("Ignore exception during disconnect: {}", ignore.getMessage());
                    }
                }
                // check if we are interrupted so we can break out
                if (Thread.currentThread().isInterrupted()) {
                    throw new GenericFileOperationFailedException("Interrupted during connecting", new InterruptedException("Interrupted during connecting"));
                }

                GenericFileOperationFailedException failed;
                if (e instanceof GenericFileOperationFailedException) {
                    failed = (GenericFileOperationFailedException) e;
                } else {
                    failed = new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
                }

                log.trace("Cannot connect due: {}", failed.getMessage());
                attempt++;
                if (attempt > endpoint.getMaximumReconnectAttempts()) {
                    throw failed;
                }
                if (endpoint.getReconnectDelay() > 0) {
                    try {
                        Thread.sleep(endpoint.getReconnectDelay());
                    } catch (InterruptedException ie) {
                        // we could potentially also be interrupted during sleep
                        Thread.currentThread().interrupt();
                        throw new GenericFileOperationFailedException("Interrupted during sleeping", ie);
                    }
                }
            } finally {
                if (exchange != null) {
                    // store client reply information after the operation
                    exchange.getIn().setHeader(FtpConstants.FTP_REPLY_CODE, client.getReplyCode());
                    exchange.getIn().setHeader(FtpConstants.FTP_REPLY_STRING, client.getReplyString());
                }
            }
        }

        // we are now connected
        clientActivityListener.onConnected(host);

        // must enter passive mode directly after connect
        if (configuration.isPassiveMode()) {
            log.trace("Using passive mode connections");
            client.enterLocalPassiveMode();
        }

        // must set soTimeout after connect
        if (endpoint.getSoTimeout() > 0) {
            log.trace("Using SoTimeout={}", endpoint.getSoTimeout());
            try {
                client.setSoTimeout(endpoint.getSoTimeout());
            } catch (IOException e) {
                throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
            }
        }

        try {
            clientActivityListener.onLogin(host);
            boolean login;
            if (username != null) {
                if (account != null) {
                    log.trace("Attempting to login user: {} using password: ******** and account: {}", username, account);
                    login = client.login(username, configuration.getPassword(), account);
                } else {
                    log.trace("Attempting to login user: {} using password: ********", username);
                    login = client.login(username, configuration.getPassword());
                }
            } else {
                if (account != null) {
                    // not sure if it makes sense to login anonymous with account?
                    log.trace("Attempting to login anonymous using account: {}", account);
                    login = client.login("anonymous", "", account);
                } else {
                    log.trace("Attempting to login anonymous");
                    login = client.login("anonymous", "");
                }
            }
            log.trace("User {} logged in: {}", username != null ? username : "anonymous", login);
            if (!login) {
                // store replyString, because disconnect() will reset it
                String replyString = client.getReplyString();
                int replyCode = client.getReplyCode();
                clientActivityListener.onLoginFailed(replyCode, replyString);
                // disconnect to prevent connection leaks
                client.disconnect();
                throw new GenericFileOperationFailedException(replyCode, replyString);
            }
            clientActivityListener.onLoginComplete(host);
            client.setFileType(configuration.isBinary() ? FTP.BINARY_FILE_TYPE : FTP.ASCII_FILE_TYPE);
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        } finally {
            if (exchange != null) {
                // store client reply information after the operation
                exchange.getIn().setHeader(FtpConstants.FTP_REPLY_CODE, client.getReplyCode());
                exchange.getIn().setHeader(FtpConstants.FTP_REPLY_STRING, client.getReplyString());
            }
        }

        // site commands
        if (endpoint.getConfiguration().getSiteCommand() != null) {
            // commands can be separated using new line
            Iterator<?> it = ObjectHelper.createIterator(endpoint.getConfiguration().getSiteCommand(), "\n");
            while (it.hasNext()) {
                Object next = it.next();
                String command = endpoint.getCamelContext().getTypeConverter().convertTo(String.class, next);
                log.trace("Site command to send: {}", command);
                if (command != null) {
                    boolean result = sendSiteCommand(command);
                    if (!result) {
                        throw new GenericFileOperationFailedException("Site command: " + command + " returned false");
                    }
                }
            }
        }

        return true;
    }

    @Override
    public boolean isConnected() throws GenericFileOperationFailedException {
        return client.isConnected();
    }

    @Override
    public void disconnect() throws GenericFileOperationFailedException {
        try {
            doDisconnect();
        } catch (GenericFileOperationFailedException e) {
            clientActivityListener.onGeneralError(endpoint.getConfiguration().remoteServerInformation(), e.getMessage());
            throw e;
        }
    }

    @Override
    public void forceDisconnect() throws GenericFileOperationFailedException {
        doDisconnect();
    }

    protected void doDisconnect() throws GenericFileOperationFailedException {
        // logout before disconnecting
        clientActivityListener.onDisconnecting(endpoint.getConfiguration().remoteServerInformation());
        try {
            log.trace("Client logout");
            client.logout();
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        } finally {
            try {
                log.trace("Client disconnect");
                client.disconnect();
            } catch (IOException e) {
                throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
            }
        }
        clientActivityListener.onDisconnected(endpoint.getConfiguration().remoteServerInformation());
    }

    @Override
    public boolean deleteFile(String name) throws GenericFileOperationFailedException {
        log.debug("Deleting file: {}", name);

        boolean result;
        String target = name;
        String currentDir = null;

        try {
            if (endpoint.getConfiguration().isStepwise()) {
                // remember current directory
                currentDir = getCurrentDirectory();
                target = FileUtil.stripPath(name);

                try {
                    changeCurrentDirectory(FileUtil.onlyPath(name));
                } catch (GenericFileOperationFailedException e) {
                    // we could not change directory, try to change back before
                    changeCurrentDirectory(currentDir);
                    throw e;
                }
            }

            // delete the file
            log.trace("Client deleteFile: {}", target);
            result = client.deleteFile(target);

            // change back to previous directory
            if (currentDir != null) {
                changeCurrentDirectory(currentDir);
            }

        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }

        return result;
    }

    @Override
    public boolean renameFile(String from, String to) throws GenericFileOperationFailedException {
        log.debug("Renaming file: {} to: {}", from, to);
        try {
            return client.rename(from, to);
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    @Override
    public boolean buildDirectory(String directory, boolean absolute) throws GenericFileOperationFailedException {
        // must normalize directory first
        directory = endpoint.getConfiguration().normalizePath(directory);

        log.trace("buildDirectory({})", directory);
        try {
            String originalDirectory = client.printWorkingDirectory();

            boolean success;
            try {
                // maybe the full directory already exists
                success = client.changeWorkingDirectory(directory);
                if (!success) {
                    log.trace("Trying to build remote directory: {}", directory);
                    success = client.makeDirectory(directory);
                    if (!success) {
                        // we are here if the server side doesn't create intermediate folders so create the folder one by one
                        success = buildDirectoryChunks(directory);
                    }
                }

                return success;
            } finally {
                // change back to original directory
                if (originalDirectory != null) {
                    changeCurrentDirectory(originalDirectory);
                }
            }
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    @Override
    public boolean retrieveFile(String name, Exchange exchange, long size) throws GenericFileOperationFailedException {
        // store the name of the file to download on the listener
        clientActivityListener.setDownload(true);
        clientActivityListener.setRemoteFileName(name);
        clientActivityListener.setRemoteFileSize(size);
        clientActivityListener.onBeginDownloading(endpoint.getConfiguration().remoteServerInformation(), name);

        boolean answer;
        try {
            log.trace("retrieveFile({})", name);
            if (org.apache.camel.util.ObjectHelper.isNotEmpty(endpoint.getLocalWorkDirectory())) {
                // local work directory is configured so we should store file content as files in this local directory
                answer = retrieveFileToFileInLocalWorkDirectory(name, exchange, endpoint.isResumeDownload());
            } else {
                // store file content directory as stream on the body
                answer = retrieveFileToStreamInBody(name, exchange);
            }
        } catch (GenericFileOperationFailedException e) {
            clientActivityListener.onGeneralError(endpoint.getConfiguration().remoteServerInformation(), e.getMessage());
            throw e;
        }

        if (answer) {
            clientActivityListener.onDownloadComplete(endpoint.getConfiguration().remoteServerInformation(), name);
        }
        return answer;
    }

    @Override
    public void releaseRetrievedFileResources(Exchange exchange) throws GenericFileOperationFailedException {
        InputStream is = exchange.getIn().getHeader(RemoteFileComponent.REMOTE_FILE_INPUT_STREAM, InputStream.class);

        if (is != null) {
            try {
                IOHelper.close(is);
                client.completePendingCommand();
            } catch (IOException e) {
                throw new GenericFileOperationFailedException(e.getMessage(), e);
            }
        }
    }

    @SuppressWarnings("unchecked")
    private boolean retrieveFileToStreamInBody(String name, Exchange exchange) throws GenericFileOperationFailedException {
        boolean result;
        try {
            GenericFile<FTPFile> target = (GenericFile<FTPFile>) exchange.getProperty(FileComponent.FILE_EXCHANGE_FILE);
            org.apache.camel.util.ObjectHelper.notNull(target, "Exchange should have the " + FileComponent.FILE_EXCHANGE_FILE + " set");

            String remoteName = name;
            String currentDir = null;
            if (endpoint.getConfiguration().isStepwise()) {
                // remember current directory
                currentDir = getCurrentDirectory();

                // change directory to path where the file is to be retrieved
                // (must do this as some FTP servers cannot retrieve using absolute path)
                String path = FileUtil.onlyPath(name);
                if (path != null) {
                    changeCurrentDirectory(path);
                }
                // remote name is now only the file name as we just changed directory
                remoteName = FileUtil.stripPath(name);
            }

            log.trace("Client retrieveFile: {}", remoteName);
            if (endpoint.getConfiguration().isStreamDownload()) {
                InputStream is = client.retrieveFileStream(remoteName);
                target.setBody(is);
                exchange.getIn().setHeader(RemoteFileComponent.REMOTE_FILE_INPUT_STREAM, is);
                result = true;
            } else {
                // read the entire file into memory in the byte array
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                result = client.retrieveFile(remoteName, bos);
                // close the stream after done
                IOHelper.close(bos);

                target.setBody(bos.toByteArray());
            }

            // store client reply information after the operation
            exchange.getIn().setHeader(FtpConstants.FTP_REPLY_CODE, client.getReplyCode());
            exchange.getIn().setHeader(FtpConstants.FTP_REPLY_STRING, client.getReplyString());

            // change back to current directory
            if (endpoint.getConfiguration().isStepwise()) {
                changeCurrentDirectory(currentDir);
            }

        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }

        return result;
    }

    @SuppressWarnings("unchecked")
    private boolean retrieveFileToFileInLocalWorkDirectory(String name, Exchange exchange, boolean resumeDownload) throws GenericFileOperationFailedException {
        File temp;
        File local = new File(FileUtil.normalizePath(endpoint.getLocalWorkDirectory()));
        OutputStream os;
        long existingSize = -1;

        try {
            // use relative filename in local work directory
            GenericFile<FTPFile> target = (GenericFile<FTPFile>) exchange.getProperty(FileComponent.FILE_EXCHANGE_FILE);
            org.apache.camel.util.ObjectHelper.notNull(target, "Exchange should have the " + FileComponent.FILE_EXCHANGE_FILE + " set");
            String relativeName = target.getRelativeFilePath();

            temp = new File(local, relativeName + ".inprogress");
            local = new File(local, relativeName);

            // create directory to local work file
            local.mkdirs();

            // delete any local file (as its the temp file that is in the in-progress download)
            if (local.exists()) {
                if (!FileUtil.deleteFile(local)) {
                    throw new GenericFileOperationFailedException("Cannot delete existing local work file: " + local);
                }
            }

            // if a previous file exists then store its current size as its a partial download
            boolean exists = temp.exists();
            if (exists) {
                existingSize = temp.length();
            }

            // if we do not resume download, then delete any existing temp file and create a new to use for in-progress download
            if (!resumeDownload) {
                // delete any existing files
                if (exists && !FileUtil.deleteFile(temp)) {
                    throw new GenericFileOperationFailedException("Cannot delete existing local work file: " + temp);
                }
                // create new temp local work file
                if (!temp.createNewFile()) {
                    throw new GenericFileOperationFailedException("Cannot create new local work file: " + temp);
                }
            }

            // store content as a file in the local work directory in the temp handle
            boolean append = resumeDownload && existingSize > 0;
            os = new FileOutputStream(temp, append);

            // set header with the path to the local work file
            exchange.getIn().setHeader(Exchange.FILE_LOCAL_WORK_PATH, local.getPath());

        } catch (Exception e) {
            throw new GenericFileOperationFailedException("Cannot create new local work file: " + local);
        }

        boolean result;
        try {
            GenericFile<FTPFile> target = (GenericFile<FTPFile>) exchange.getProperty(FileComponent.FILE_EXCHANGE_FILE);
            // store the java.io.File handle as the body
            target.setBody(local);

            String remoteName = name;
            String currentDir = null;
            if (endpoint.getConfiguration().isStepwise()) {
                // remember current directory
                currentDir = getCurrentDirectory();

                // change directory to path where the file is to be retrieved
                // (must do this as some FTP servers cannot retrieve using absolute path)
                String path = FileUtil.onlyPath(name);
                if (path != null) {
                    changeCurrentDirectory(path);
                }
                // remote name is now only the file name as we just changed directory
                remoteName = FileUtil.stripPath(name);
            }

            // the file exists so lets try to resume the download
            if (resumeDownload && existingSize > 0) {
                clientActivityListener.onResumeDownloading(endpoint.getConfiguration().remoteServerInformation(), name, existingSize);
                log.trace("Client restartOffset: {}", existingSize);
                log.debug("Resuming download of file: {} at position: {}", remoteName, existingSize);
                client.setRestartOffset(existingSize);
            }
            log.trace("Client retrieveFile: {}", remoteName);
            result = client.retrieveFile(remoteName, os);

            // store client reply information after the operation
            exchange.getIn().setHeader(FtpConstants.FTP_REPLY_CODE, client.getReplyCode());
            exchange.getIn().setHeader(FtpConstants.FTP_REPLY_STRING, client.getReplyString());

            // change back to current directory
            if (endpoint.getConfiguration().isStepwise()) {
                changeCurrentDirectory(currentDir);
            }

        } catch (IOException e) {
            log.trace("Error occurred during retrieving file: {} to local directory.", name);
            // if we do not attempt to resume download, then attempt to delete the temporary file
            if (!resumeDownload) {
                log.trace("Deleting local work file: {}", name);
                // failed to retrieve the file so we need to close streams and delete in progress file
                // must close stream before deleting file
                IOHelper.close(os, "retrieve: " + name, log);
                boolean deleted = FileUtil.deleteFile(temp);
                if (!deleted) {
                    log.warn("Error occurred during retrieving file: " + name + " to local directory. Cannot delete local work file: " + temp);
                }
            }
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        } finally {
            // need to close the stream before rename it
            IOHelper.close(os, "retrieve: " + name, log);
        }

        log.debug("Retrieve file to local work file result: {}", result);

        if (result) {
            log.trace("Renaming local in progress file from: {} to: {}", temp, local);
            // operation went okay so rename temp to local after we have retrieved the data
            try {
                if (!FileUtil.renameFile(temp, local, false)) {
                    throw new GenericFileOperationFailedException("Cannot rename local work file from: " + temp + " to: " + local);
                }
            } catch (IOException e) {
                throw new GenericFileOperationFailedException("Cannot rename local work file from: " + temp + " to: " + local, e);
            }
        }

        return result;
    }

    @Override
    public boolean storeFile(String name, Exchange exchange, long size) throws GenericFileOperationFailedException {
        // must normalize name first
        name = endpoint.getConfiguration().normalizePath(name);

        // store the name of the file to upload on the listener
        clientActivityListener.setDownload(false);
        clientActivityListener.setRemoteFileName(name);
        clientActivityListener.setRemoteFileSize(size);
        clientActivityListener.onBeginUploading(endpoint.getConfiguration().remoteServerInformation(), name);

        log.trace("storeFile({})", name);

        boolean answer;
        String currentDir = null;
        String path = FileUtil.onlyPath(name);
        String targetName = name;

        try {
            if (path != null && endpoint.getConfiguration().isStepwise()) {
                // must remember current dir so we stay in that directory after the write
                currentDir = getCurrentDirectory();

                // change to path of name
                changeCurrentDirectory(path);

                // the target name should be without path, as we have changed directory
                targetName = FileUtil.stripPath(name);
            }

            // store the file
            answer = doStoreFile(name, targetName, exchange);
        } catch (GenericFileOperationFailedException e) {
            clientActivityListener.onGeneralError(endpoint.getConfiguration().remoteServerInformation(), e.getMessage());
            throw e;
        } finally {
            // change back to current directory if we changed directory
            if (currentDir != null) {
                changeCurrentDirectory(currentDir);
            }
        }

        if (answer) {
            clientActivityListener.onUploadComplete(endpoint.getConfiguration().remoteServerInformation(), name);
        }

        return answer;
    }

    private boolean doStoreFile(String name, String targetName, Exchange exchange) throws GenericFileOperationFailedException {
        log.trace("doStoreFile({})", targetName);

        // if an existing file already exists what should we do?
        if (endpoint.getFileExist() == GenericFileExist.Ignore
                || endpoint.getFileExist() == GenericFileExist.Fail
                || endpoint.getFileExist() == GenericFileExist.Move) {
            boolean existFile = existsFile(targetName);
            if (existFile && endpoint.getFileExist() == GenericFileExist.Ignore) {
                // ignore but indicate that the file was written
                log.trace("An existing file already exists: {}. Ignore and do not override it.", name);
                return true;
            } else if (existFile && endpoint.getFileExist() == GenericFileExist.Fail) {
                throw new GenericFileOperationFailedException("File already exist: " + name + ". Cannot write new file.");
            } else if (existFile && endpoint.getFileExist() == GenericFileExist.Move) {
                // move any existing file first
                this.endpoint.getMoveExistingFileStrategy().moveExistingFile(endpoint, this, targetName);
            }
        }

        InputStream is = null;
        if (exchange.getIn().getBody() == null) {
            // Do an explicit test for a null body and decide what to do
            if (endpoint.isAllowNullBody()) {
                log.trace("Writing empty file.");
                is = new ByteArrayInputStream(new byte[]{});
            } else {
                throw new GenericFileOperationFailedException("Cannot write null body to file: " + name);
            }
        }

        try {
            if (is == null) {
                String charset = endpoint.getCharset();
                if (charset != null) {
                    // charset configured so we must convert to the desired
                    // charset so we can write with encoding
                    is = new ByteArrayInputStream(exchange.getIn().getMandatoryBody(String.class).getBytes(charset));
                    log.trace("Using InputStream {} with charset {}.", is, charset);
                } else {
                    is = exchange.getIn().getMandatoryBody(InputStream.class);
                }
            }

            final StopWatch watch = new StopWatch();
            boolean answer;
            log.debug("About to store file: {} using stream: {}", targetName, is);
            if (endpoint.getFileExist() == GenericFileExist.Append) {
                log.trace("Client appendFile: {}", targetName);
                answer = client.appendFile(targetName, is);
            } else {
                log.trace("Client storeFile: {}", targetName);
                answer = client.storeFile(targetName, is);
            }
            if (log.isDebugEnabled()) {
                long time = watch.taken();
                log.debug("Took {} ({} millis) to store file: {} and FTP client returned: {}",
                        new Object[]{TimeUtils.printDuration(time), time, targetName, answer});
            }

            // store client reply information after the operation
            exchange.getIn().setHeader(FtpConstants.FTP_REPLY_CODE, client.getReplyCode());
            exchange.getIn().setHeader(FtpConstants.FTP_REPLY_STRING, client.getReplyString());

            // after storing file, we may set chmod on the file
            String chmod = endpoint.getConfiguration().getChmod();
            if (org.apache.camel.util.ObjectHelper.isNotEmpty(chmod)) {
                log.debug("Setting chmod: {} on file: {}", chmod, targetName);
                String command = "chmod " + chmod + " " + targetName;
                log.trace("Client sendSiteCommand: {}", command);
                boolean success = client.sendSiteCommand(command);
                log.trace("Client sendSiteCommand successful: {}", success);
            }

            return answer;

        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        } catch (InvalidPayloadException e) {
            throw new GenericFileOperationFailedException("Cannot store file: " + name, e);
        } finally {
            IOHelper.close(is, "store: " + name, log);
        }
    }

    @Override
    public boolean existsFile(String name) throws GenericFileOperationFailedException {
        log.trace("existsFile({})", name);
        if (endpoint.isFastExistsCheck()) {
            return fastExistsFile(name);
        }
        // check whether a file already exists
        String directory = FileUtil.onlyPath(name);
        String onlyName = FileUtil.stripPath(name);
        try {
            String[] names;
            if (directory != null) {
                names = client.listNames(directory);
            } else {
                names = client.listNames();
            }
            // can return either null or an empty list depending on FTP servers
            if (names == null) {
                return false;
            }
            for (String existing : names) {
                log.trace("Existing file: {}, target file: {}", existing, name);
                existing = FileUtil.stripPath(existing);
                if (existing != null && existing.equals(onlyName)) {
                    return true;
                }
            }
            return false;
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    protected boolean fastExistsFile(String name) throws GenericFileOperationFailedException {
        log.trace("fastExistsFile({})", name);
        try {
            String[] names = client.listNames(name);
            if (names == null) {
                return false;
            }
            return names.length >= 1;
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    @Override
    public String getCurrentDirectory() throws GenericFileOperationFailedException {
        log.trace("getCurrentDirectory()");
        try {
            String answer = client.printWorkingDirectory();
            log.trace("Current dir: {}", answer);
            return answer;
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    @Override
    public void changeCurrentDirectory(String path) throws GenericFileOperationFailedException {
        log.trace("changeCurrentDirectory({})", path);
        if (org.apache.camel.util.ObjectHelper.isEmpty(path)) {
            return;
        }

        // must compact path so FTP server can traverse correctly
        // use the ftp utils implementation of the compact path
        path = FtpUtils.compactPath(path);

        // not stepwise should change directory in one operation
        if (!endpoint.getConfiguration().isStepwise()) {
            doChangeDirectory(path);
            return;
        }

        // if it starts with the root path then a little special handling for that
        if (FileUtil.hasLeadingSeparator(path)) {
            // change to root path
            doChangeDirectory(path.substring(0, 1));
            path = path.substring(1);
        }

        // split into multiple dirs
        final String[] dirs = path.split("/|\\\\");

        if (dirs == null || dirs.length == 0) {
            // path was just a relative single path
            doChangeDirectory(path);
            return;
        }

        // there are multiple dirs so do this in chunks
        for (String dir : dirs) {
            doChangeDirectory(dir);
        }
    }

    private void doChangeDirectory(String path) {
        if (path == null || ".".equals(path) || org.apache.camel.util.ObjectHelper.isEmpty(path)) {
            return;
        }

        log.trace("Changing directory: {}", path);
        boolean success;
        try {
            if ("..".equals(path)) {
                changeToParentDirectory();
                success = true;
            } else {
                success = client.changeWorkingDirectory(path);
            }
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
        if (!success) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), "Cannot change directory to: " + path);
        }
    }

    @Override
    public void changeToParentDirectory() throws GenericFileOperationFailedException {
        try {
            client.changeToParentDirectory();
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    @Override
    public List<FTPFile> listFiles() throws GenericFileOperationFailedException {
        log.trace("listFiles()");
        clientActivityListener.onScanningForFiles(endpoint.remoteServerInformation(), null);
        try {
            final List<FTPFile> list = new ArrayList<>();
            FTPFile[] files = client.listFiles();
            // can return either null or an empty list depending on FTP servers
            if (files != null) {
                list.addAll(Arrays.asList(files));
            }
            return list;
        } catch (IOException e) {
            clientActivityListener.onGeneralError(endpoint.getConfiguration().remoteServerInformation(), e.getMessage());
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    @Override
    public List<FTPFile> listFiles(String path) throws GenericFileOperationFailedException {
        log.trace("listFiles({})", path);
        clientActivityListener.onScanningForFiles(endpoint.remoteServerInformation(), path);

        // use current directory if path not given
        if (org.apache.camel.util.ObjectHelper.isEmpty(path)) {
            path = ".";
        }

        try {
            final List<FTPFile> list = new ArrayList<>();
            FTPFile[] files = client.listFiles(path);
            // can return either null or an empty list depending on FTP servers
            if (files != null) {
                list.addAll(Arrays.asList(files));
            }
            return list;
        } catch (IOException e) {
            clientActivityListener.onGeneralError(endpoint.getConfiguration().remoteServerInformation(), e.getMessage());
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    @Override
    public boolean sendNoop() throws GenericFileOperationFailedException {
        log.trace("sendNoOp");
        try {
            return client.sendNoOp();
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    @Override
    public boolean sendSiteCommand(String command) throws GenericFileOperationFailedException {
        log.trace("sendSiteCommand({})", command);
        try {
            return client.sendSiteCommand(command);
        } catch (IOException e) {
            throw new GenericFileOperationFailedException(client.getReplyCode(), client.getReplyString(), e.getMessage(), e);
        }
    }

    protected FTPClient getFtpClient() {
        return client;
    }

    private boolean buildDirectoryChunks(String dirName) throws IOException {
        final StringBuilder sb = new StringBuilder(dirName.length());
        final String[] dirs = dirName.split("/|\\\\");

        boolean success = false;
        for (String dir : dirs) {
            sb.append(dir).append('/');
            // must normalize the directory name
            String directory = endpoint.getConfiguration().normalizePath(sb.toString());

            // do not try to build root folder (/ or \)
            if (!(directory.equals("/") || directory.equals("\\"))) {
                log.trace("Trying to build remote directory by chunk: {}", directory);

                // while creating directory string if directory results in
                // trailing slash, remove it not necessary
                directory = FileUtil.stripTrailingSeparator(directory);

                success = client.makeDirectory(directory);
            }
        }

        return success;
    }

    public FTPClient getClient() {
        return client;
    }

}


text:
package org.jbpm.springboot.samples;

import org.apache.kafka.common.serialization.StringSerializer;
import org.jbpm.services.api.DeploymentService;
import org.jbpm.services.api.ProcessService;
import org.jbpm.springboot.samples.events.listeners.CountDownLatchEventListener;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;
import org.testcontainers.containers.KafkaContainer;

import static org.apache.kafka.clients.producer.ProducerConfig.BOOTSTRAP_SERVERS_CONFIG;
import static org.apache.kafka.clients.producer.ProducerConfig.CLIENT_ID_CONFIG;
import static org.apache.kafka.clients.producer.ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG;
import static org.apache.kafka.clients.producer.ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG;
import static org.jbpm.springboot.samples.KafkaFixture.KAFKA_PROCESS_ID;
import static org.jbpm.springboot.samples.KafkaFixture.KAFKA_RESULT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.IOException;

@RunWith(Parameterized.class)
@SpringBootTest(classes = {JBPMApplication.class, TestAutoConfiguration.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(locations="classpath:application-test.properties")
@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_CLASS)
public class KafkaSampleTest extends KafkaBaseTest {

    @ClassRule
    public static final SpringClassRule scr = new SpringClassRule();

    @Rule
    public final SpringMethodRule smr = new SpringMethodRule();

    @Autowired
    private DeploymentService deploymentService;

    @Autowired
    private ProcessService processService;

    @Autowired
    CountDownLatchEventListener countDownLatchEventListener;

    @Rule
    public KafkaContainer kafka = new KafkaContainer();

    protected static KafkaFixture kafkaFixture = new KafkaFixture();

    protected String deploymentId;

    @BeforeClass
    public static void generalSetup() {
        kafkaFixture.generalSetup();
    }

    @Before
    public void setup() throws IOException, InterruptedException {
        System.setProperty(BOOTSTRAP_SERVERS_CONFIG, kafka.getBootstrapServers());
        System.setProperty(CLIENT_ID_CONFIG, "test_jbpm");
        System.setProperty(KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        System.setProperty(VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());

        kafkaFixture.createTopic(kafka);
        deploymentId = kafkaFixture.setup(deploymentService, strategy);

        countDownLatchEventListener.configure(KAFKA_PROCESS_ID, 1);
        countDownLatchEventListener.setVariable(KAFKA_RESULT);
    }

    @After
    public void cleanup() {
        kafkaFixture.cleanup(deploymentService);
    }

    @Test(timeout = 60000)
    public void testKafkaWIHSendMessage() throws Exception {

        Long processInstanceId = processService.startProcess(deploymentId,
                                                             KAFKA_PROCESS_ID,
                                                             kafkaFixture.getProcessVariables());

        assertTrue(processInstanceId > 0);

        kafkaFixture.assertConsumerMessages(kafka.getBootstrapServers());

        //Countdown decrements the count of the latch before process ends
        countDownLatchEventListener.getCountDown().await();

        assertEquals("success", countDownLatchEventListener.getResult());
    }
}


text:
import pytest

class TestWorkspace:

    @pytest.mark.xfail(reason="Not yet implemented")
    def test_set_source_does_not_throw_an_exception_when_a_none_url_is_specified(self, workspace):
        workspace.set_source(None)

    @pytest.mark.xfail(reason="Not yet implemented")
    def test_set_source_does_not_throw_an_exception_when_an_empty_url_is_specified(self, workspace):
        workspace.set_source("")


text:
<?php

namespace Dingo\Api\Tests\Stubs;

use Dingo\Api\Http\Request;
use Dingo\Api\Transformer\Binding;
use Illuminate\Support\Collection;
use Dingo\Api\Contract\Transformer\Adapter;

class TransformerStub implements Adapter
{
    public function transform($response, $transformer, Binding $binding, Request $request)
    {
        if ($response instanceof Collection) {
            return $response->transform(function ($response) use ($transformer) {
                return $transformer->transform($response);
            })->toArray();
        }

        return $transformer->transform($response);
    }
}


text:
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');

var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);

var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');

var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

var _toArray2 = require('babel-runtime/helpers/toArray');

var _toArray3 = _interopRequireDefault(_toArray2);

var _simpleAssign = require('simple-assign');

var _simpleAssign2 = _interopRequireDefault(_simpleAssign);

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _reactAddonsTransitionGroup = require('react-addons-transition-group');

var _reactAddonsTransitionGroup2 = _interopRequireDefault(_reactAddonsTransitionGroup);

var _dom = require('../utils/dom');

var _dom2 = _interopRequireDefault(_dom);

var _CircleRipple = require('./CircleRipple');

var _CircleRipple2 = _interopRequireDefault(_CircleRipple);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

// Remove the first element of the array
var shift = function shift(_ref) {
  var _ref2 = (0, _toArray3.default)(_ref),
      newArray = _ref2.slice(1);

  return newArray;
};

var TouchRipple = function (_Component) {
  (0, _inherits3.default)(TouchRipple, _Component);

  function TouchRipple(props, context) {
    (0, _classCallCheck3.default)(this, TouchRipple);

    // Touch start produces a mouse down event for compat reasons. To avoid
    // showing ripples twice we skip showing a ripple for the first mouse down
    // after a touch start. Note we don't store ignoreNextMouseDown in this.state
    // to avoid re-rendering when we change it.
    var _this = (0, _possibleConstructorReturn3.default)(this, (TouchRipple.__proto__ || (0, _getPrototypeOf2.default)(TouchRipple)).call(this, props, context));

    _this.handleMouseDown = function (event) {
      // only listen to left clicks
      if (event.button === 0) {
        _this.start(event, false);
      }
    };

    _this.handleMouseUp = function () {
      _this.end();
    };

    _this.handleMouseLeave = function () {
      _this.end();
    };

    _this.handleTouchStart = function (event) {
      event.stopPropagation();
      // If the user is swiping (not just tapping), save the position so we can
      // abort ripples if the user appears to be scrolling.
      if (_this.props.abortOnScroll && event.touches) {
        _this.startListeningForScrollAbort(event);
        _this.startTime = Date.now();
      }
      _this.start(event, true);
    };

    _this.handleTouchEnd = function () {
      _this.end();
    };

    _this.handleTouchMove = function (event) {
      // Stop trying to abort if we're already 300ms into the animation
      var timeSinceStart = Math.abs(Date.now() - _this.startTime);
      if (timeSinceStart > 300) {
        _this.stopListeningForScrollAbort();
        return;
      }

      // If the user is scrolling...
      var deltaY = Math.abs(event.touches[0].clientY - _this.firstTouchY);
      var deltaX = Math.abs(event.touches[0].clientX - _this.firstTouchX);
      // Call it a scroll after an arbitrary 6px (feels reasonable in testing)
      if (deltaY > 6 || deltaX > 6) {
        var currentRipples = _this.state.ripples;
        var ripple = currentRipples[0];
        // This clone will replace the ripple in ReactTransitionGroup with a
        // version that will disappear immediately when removed from the DOM
        var abortedRipple = _react2.default.cloneElement(ripple, { aborted: true });
        // Remove the old ripple and replace it with the new updated one
        currentRipples = shift(currentRipples);
        currentRipples = [].concat((0, _toConsumableArray3.default)(currentRipples), [abortedRipple]);
        _this.setState({ ripples: currentRipples }, function () {
          // Call end after we've set the ripple to abort otherwise the setState
          // in end() merges with this and the ripple abort fails
          _this.end();
        });
      }
    };

    _this.ignoreNextMouseDown = false;

    _this.state = {
      // This prop allows us to only render the ReactTransitionGroup
      // on the first click of the component, making the inital render faster.
      hasRipples: false,
      nextKey: 0,
      ripples: []
    };
    return _this;
  }

  (0, _createClass3.default)(TouchRipple, [{
    key: 'start',
    value: function start(event, isRippleTouchGenerated) {
      var theme = this.context.muiTheme.ripple;

      if (this.ignoreNextMouseDown && !isRippleTouchGenerated) {
        this.ignoreNextMouseDown = false;
        return;
      }

      var ripples = this.state.ripples;

      // Add a ripple to the ripples array
      ripples = [].concat((0, _toConsumableArray3.default)(ripples), [_react2.default.createElement(_CircleRipple2.default, {
        key: this.state.nextKey,
        style: !this.props.centerRipple ? this.getRippleStyle(event) : {},
        color: this.props.color || theme.color,
        opacity: this.props.opacity,
        touchGenerated: isRippleTouchGenerated
      })]);

      this.ignoreNextMouseDown = isRippleTouchGenerated;
      this.setState({
        hasRipples: true,
        nextKey: this.state.nextKey + 1,
        ripples: ripples
      });
    }
  }, {
    key: 'end',
    value: function end() {
      var currentRipples = this.state.ripples;
      this.setState({
        ripples: shift(currentRipples)
      });
      if (this.props.abortOnScroll) {
        this.stopListeningForScrollAbort();
      }
    }

    // Check if the user seems to be scrolling and abort the animation if so

  }, {
    key: 'startListeningForScrollAbort',
    value: function startListeningForScrollAbort(event) {
      this.firstTouchY = event.touches[0].clientY;
      this.firstTouchX = event.touches[0].clientX;
      // Note that when scolling Chrome throttles this event to every 200ms
      // Also note we don't listen for scroll events directly as there's no general
      // way to cover cases like scrolling within containers on the page
      document.body.addEventListener('touchmove', this.handleTouchMove);
    }
  }, {
    key: 'stopListeningForScrollAbort',
    value: function stopListeningForScrollAbort() {
      document.body.removeEventListener('touchmove', this.handleTouchMove);
    }
  }, {
    key: 'getRippleStyle',
    value: function getRippleStyle(event) {
      var el = _reactDom2.default.findDOMNode(this);
      var elHeight = el.offsetHeight;
      var elWidth = el.offsetWidth;
      var offset = _dom2.default.offset(el);
      var isTouchEvent = event.touches && event.touches.length;
      var pageX = isTouchEvent ? event.touches[0].pageX : event.pageX;
      var pageY = isTouchEvent ? event.touches[0].pageY : event.pageY;
      var pointerX = pageX - offset.left;
      var pointerY = pageY - offset.top;
      var topLeftDiag = this.calcDiag(pointerX, pointerY);
      var topRightDiag = this.calcDiag(elWidth - pointerX, pointerY);
      var botRightDiag = this.calcDiag(elWidth - pointerX, elHeight - pointerY);
      var botLeftDiag = this.calcDiag(pointerX, elHeight - pointerY);
      var rippleRadius = Math.max(topLeftDiag, topRightDiag, botRightDiag, botLeftDiag);
      var rippleSize = rippleRadius * 2;
      var left = pointerX - rippleRadius;
      var top = pointerY - rippleRadius;

      return {
        directionInvariant: true,
        height: rippleSize,
        width: rippleSize,
        top: top,
        left: left
      };
    }
  }, {
    key: 'calcDiag',
    value: function calcDiag(a, b) {
      return Math.sqrt(a * a + b * b);
    }
  }, {
    key: 'render',
    value: function render() {
      var _props = this.props,
          children = _props.children,
          style = _props.style;
      var _state = this.state,
          hasRipples = _state.hasRipples,
          ripples = _state.ripples;
      var prepareStyles = this.context.muiTheme.prepareStyles;

      var rippleGroup = void 0;

      if (hasRipples) {
        var mergedStyles = (0, _simpleAssign2.default)({
          height: '100%',
          width: '100%',
          position: 'absolute',
          top: 0,
          left: 0,
          overflow: 'hidden'
        }, style);

        rippleGroup = _react2.default.createElement(
          _reactAddonsTransitionGroup2.default,
          { style: prepareStyles(mergedStyles) },
          ripples
        );
      }

      return _react2.default.createElement(
        'div',
        {
          onMouseUp: this.handleMouseUp,
          onMouseDown: this.handleMouseDown,
          onMouseLeave: this.handleMouseLeave,
          onTouchStart: this.handleTouchStart,
          onTouchEnd: this.handleTouchEnd
        },
        rippleGroup,
        children
      );
    }
  }]);
  return TouchRipple;
}(_react.Component);

TouchRipple.defaultProps = {
  abortOnScroll: true
};
TouchRipple.contextTypes = {
  muiTheme: _react.PropTypes.object.isRequired
};
process.env.NODE_ENV !== "production" ? TouchRipple.propTypes = {
  abortOnScroll: _react.PropTypes.bool,
  centerRipple: _react.PropTypes.bool,
  children: _react.PropTypes.node,
  color: _react.PropTypes.string,
  opacity: _react.PropTypes.number,
  style: _react.PropTypes.object
} : void 0;
exports.default = TouchRipple;


text:
<?php

App::uses('CakeErrorController', 'Controller');

class TestAppsErrorController extends CakeErrorController {

	public $helpers = array(
		'Html',
		'Session',
		'Form',
		'Banana',
	);

}


text:
using System;
using System.Collections.Generic;
using System.Text;

namespace File_Repository
{
    public enum FileAccessLevel
    {
        _public,
        _private
    }
}


text:
package com.opengamma.component.tool;

import java.io.File;
import java.util.Set;

import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import com.opengamma.scripts.Scriptable;
import com.opengamma.util.db.tool.DbCreateOperation;
import com.opengamma.util.db.tool.DbToolContext;

/**
 * Tool for creating database objects using the installation scripts.
 */
@Scriptable
public class DbCreateTool extends AbstractDbTool<DbToolContext> {

  /**
   * Drop existing contents command line option.
   */
  private static final String DROP_EXISTING_OPTION = "d";
  /**
   * A comma-separated list of schema groups to filter by.
   */
  private static final String SCHEMA_NAME_FILTER = "s";

  @Override
  protected Options createOptions() {
    Options options = super.createOptions();
    options.addOption(createDropExistingOption());
    options.addOption(createIncludeSchemaGroupOption());
    return options;
  }

  private static Option createDropExistingOption() {
    return new Option(DROP_EXISTING_OPTION, "drop", false, "whether to drop any existing contents");
  }

  private static Option createIncludeSchemaGroupOption() {
    Option schemaGroupOption = new Option(SCHEMA_NAME_FILTER, "schema-name", false, "a schema group name to include; includes all schemas if none specified");
    schemaGroupOption.setArgs(Option.UNLIMITED_VALUES);
    return schemaGroupOption;
  }

  //-------------------------------------------------------------------------
  @Override
  protected void doRun(boolean write, File outputFile) throws Exception {
    boolean dropExisting = getCommandLine().hasOption(DROP_EXISTING_OPTION);
    if (getCommandLine().hasOption(SCHEMA_NAME_FILTER)) {
      String[] nameArgs = getCommandLine().getOptionValues(SCHEMA_NAME_FILTER);
      Set<String> includeNames = ImmutableSet.copyOf(nameArgs);
      Set<String> allNames = getDbToolContext().getSchemaNames();
      SetView<String> filteredNames = Sets.intersection(allNames, includeNames);
      if (write) {
        System.out.println("Filtered " + allNames + " to " + filteredNames);
      }
      getDbToolContext().setSchemaNames(filteredNames);
    }
    if (getDbToolContext().getSchemaNames().isEmpty()) {
      System.out.println("No schemas specified, or all filtered out");
    } else {
      new DbCreateOperation(getDbToolContext(), write, outputFile, dropExisting).execute();
      if (write) {
        System.out.println("Database objects created successfully");
      }
    }
  }

  //-------------------------------------------------------------------------
  /**
   * Main method to run the tool.
   *
   * @param args  the arguments, not null
   */
  public static void main(String[] args) { //CSIGNORE
    boolean success = new DbCreateTool().initAndRun(args, DbToolContext.class);
    System.exit(success ? 0 : 1);
  }

}


text:
<!doctype html>

		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1">
		<title>MPA Hackathon 2014</title>
		<link rel="stylesheet" href="themes/Bootstrap.css">
		<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile.structure-1.4.0.min.css" />
		<link rel="stylesheet" href="themes/jquery.mobile.icons.min.css" />

MPA Hackathon 2014

Augmenter

Vessel

Voyage

Provider

Stationary

       <form>

Id:
<input class="fields" id="vslRecID_n" type="float"/>

Voyage:
<input class="fields" id="vsl_m" type="float"/>

Vessel:
<input class="fields" id="vsl_m" type="float"/>

Ship Agent:
<input class="fields" id="vsl_m" type="float"/>

Loading:
<input class="fields" id="vslFlag_c" type="float"/>

Load Port ETD:
<input class="fields" id="vslTy_c" type="float"/>

Destination:
<input class="fields" id="vslFlag_c" type="float"/>

Destination Port ETA:
<input class="fields" id="vslTy_c" type="float"/>

SIN ETA:
<input class="fields" id="vslGT_q" type="float"/>

SIN ETD:
<input class="fields" id="vslNT_q" type="float"/>

Terminal:
<input class="fields" id="vslLen_q" type="float"/>

20':
 <input class="fields" id="vslBre_q" type="float"/>
				<input class="fields" id="vslBre_q" type="float"/>

40':
<input class="fields" id="vslRecSt_i" type="float"/>
				<input class="fields" id="vslBre_q" type="float"/>

45':
 <input class="fields" id="vslCraftTy_c" type="float"/>
                <input class="fields" id="vslBre_q" type="float"/>

Open Top:
 <input class="fields" id="vslBre_q" type="float"/>
				<input class="fields" id="vslBre_q" type="float"/>

High Cube:
<input class="fields" id="vslRecSt_i" type="float"/>
				<input class="fields" id="vslBre_q" type="float"/>

DG:
 <input class="fields" id="vslCraftTy_c" type="float"/>
	            <input class="fields" id="vslBre_q" type="float"/>

                <input type="submit" />
            </form>