test('[validate] incorrect, argument object, UI property set, bad type', function (t) {
	t.plan(3);
	
	//TEST
	var result = validate({UI:"some bad type"});
	t.ok(result.msg.match(/Required argument: UI/), "tells you what's wrong");
	t.ok(result.msg.match(/should be object/), "how to fix it");
	t.notOk(result.valid);
});
test('[validate] incorrect, argument object, UI right type, no input namespace', function (t) {
	t.plan(3);
	
	//TEST
	var result = validate({UI:{}});
	t.ok(result.msg.match(/Required argument: UI/), "tells you what's wrong");
	t.ok(result.msg.match(/should have namespace 'input'/), "how to fix it");
	t.notOk(result.valid);
});
test('[validate] incorrect, bad arguments', function (t) {
	t.plan(2);
	
	//TEST
	
	var result = validate("some bad argument");
	t.ok(result.msg.match(/Requires argument object/), 'what argument caused the problem');
	t.notOk(result.valid);
});
test('[validate] incorrect, argument object, UI property right type, array wrong type', function (t) {
	t.plan(3);
	
	var ui = SETUP();
	
	//TEST
	var result = validate({UI:ui, array:"some bad type"});
	t.ok(result.msg.match(/Required argument: array/), "tells you what's wrong");
	t.ok(result.msg.match(/should be type array_UI/), "how to fix it");
	t.notOk(result.valid);
	
	TEARDOWN();
});
test('[validate] incorrect, argument object, UI right type, no stage namespace', function (t) {
	t.plan(3);
	
	var mock_ui = {
		input : {},
		output : {},
	}
	
	//TEST
	var result = validate({UI:mock_ui});
	t.ok(result.msg.match(/Required argument: UI/), "tells you what's wrong");
	t.ok(result.msg.match(/should have namespace 'stage'/), "how to fix it");
	t.notOk(result.valid);
});
test('[validate] incorrect, argument object, UI property right type, array right type, arrow not set', function (t) {
	t.plan(3);
	
	//SETUP
	var ui = SETUP();
	var array_UI = require('lib/UI/array_UI');
	var array = array_UI({length:1});
	
	//TEST
	var result = validate({UI:ui, array:array});
	t.ok(result.msg.match(/Required argument: arrow/), "tells you what's wrong");
	t.ok(result.msg.match(/should be type array_arrow_UI/), "how to fix it");
	t.notOk(result.valid);
	
	TEARDOWN();
});
test('[validate] correct', function (t) {
	//SETUP
	var ui = SETUP();
	
	var array_UI = require('lib/UI/array_UI');
	var array = array_UI({length:1});
	var arrow = array._.arrow;
	
	var result = validate({UI:ui, array:array, arrow:arrow});
	
	//TEST
	t.ok(result.valid, "arguments are correct");
	t.ok(check.undefined(result.msg));
	
	TEARDOWN();
	t.end();
});
function array_binary_search(options) {
	if (!(this instanceof array_binary_search)) return new array_binary_search(options);
	
	this._state = this._INIT;
	
	//requires arguments
	var validate = require('lib/lesson/util/array_lesson_argument_validate.js');
	var result = validate(options);
	
	if (!result.valid) {
		throw new TypeError(result.msg);
	}
		
	this._UI = options.UI;
	this._array = options.array;
	this._arrow = options.arrow;
	
	if (check.undefined(options.value)) {
		throw new TypeError("Required argument: value, should be a value possible to find the array.");
	}
	this._value = options.value;
	
	this._state = this._READY;
};