/*****************************
 Aquilegia ECMAScript Library
 
 Copyright(C) 2007-2008 Futoshi Takeo.
 http://www.aquilegia.info/ael/license
******************************/

var userAgent = new Ael.env.UserAgent();
Ael.test({

	"es#isNaN" : function(){
		this.assertFalse(isNaN(1));
		this.assertFalse(isNaN("1"));
		this.assertFalse(isNaN(true));
		this.assertFalse(isNaN(new Date()));
		this.assertFalse(isNaN(""));
		this.assertFalse(isNaN(null));
		this.assertFalse(isNaN(Number.NEGATIVE_INFINITY));
		this.assertFalse(isNaN(Number.POSITIVE_INFINITY));
		this.assertTrue(isNaN(NaN));
		this.assertTrue(isNaN(void 0));
	},

	"es#typeof" : function(){
		this.assertEquals("object", typeof null);
		this.assertEquals("object", typeof {});
		this.assertEquals("object", typeof []);
		this.assertEquals("object", typeof (new function(){}));
		this.assertEquals("boolean", typeof true);
		this.assertEquals("boolean", typeof false);
		this.assertEquals("number", typeof 1);
		this.assertEquals("number", typeof 1.1);
		this.assertEquals("number", typeof Infinity);
		this.assertEquals("number", typeof Number.NEGATIVE_INFINITY);
		this.assertEquals("number", typeof Number.POSITIVE_INFINITY);
		this.assertEquals("number", typeof NaN);
		this.assertEquals("string", typeof "");
		this.assertEquals("function", typeof Object);
		this.assertEquals("function", typeof function(){});
		this.assertEquals("undefined", typeof void 0);
		
		this.assertEquals("object", typeof new Object());
		this.assertEquals("object", typeof new Array());
		this.assertEquals("object", typeof new Boolean(true));
		this.assertEquals("object", typeof new Boolean(false));
		this.assertEquals("object", typeof new Number(1));
		this.assertEquals("object", typeof new Number(1.1));
		this.assertEquals("object", typeof new Number(Infinity));
		this.assertEquals("object", typeof new Number(Number.NEGATIVE_INFINITY));
		this.assertEquals("object", typeof new Number(Number.POSITIVE_INFINITY));
		this.assertEquals("object", typeof new Number(NaN));
		this.assertEquals("object", typeof new String(""));
		if(!userAgent.isAIR())
			this.assertEquals("function", typeof new Function());
	},
	
//	"es#Date" : function(){
//		this.assertEquals("true", Date(2001, 1, 2, 3, 4, 5, 6, 7));
//		this.assertEquals("true", (new Date(2001, 1, 2, 3, 4, 5, 6, 7)).toString());
//	},
	
	"es#RegExp" : function(){
		this.assertEquals(4, ("a b c d".match(/([A-Z])+/ig) || []).length);
/*
		var e = new RegExp(/([A-Z])+/ig);
		this.assertEquals(4, ("a b c d".match(e) || []).length);
		this.assertEquals(4, ("a b c d".match(new RegExp("([A-Z])+", "ig")) || []).length);
		if((userAgent.isNN6() || Ael().Rhino) && !userAgent.isSafari() && !userAgent.isAIR()){
			this.assertEquals("/(?:)/", new RegExp().toString());
			this.assertEquals("/undefined/", new RegExp(void 0).toString());
			this.assertEquals("/(?:)/", new RegExp("").toString());
		}else{
			this.assertEquals("//", new RegExp().toString());
			this.assertEquals("//", new RegExp(void 0).toString());
			this.assertEquals("//", new RegExp("").toString());
		}
*/
	},
	
	"es#Array" : function(){
		if(Array.prototype.indexOf){
			var array = ["0", 1, NaN, 1];
			this.assertEquals(0, array.indexOf("0"));
			this.assertEquals(1, array.indexOf(1));
			this.assertEquals(1, array.indexOf(1, 0));
			this.assertEquals(1, array.indexOf(1, 1));
			this.assertEquals(3, array.indexOf(1, 2));
			this.assertEquals(3, array.indexOf(1, 3));
			this.assertEquals(3, array.indexOf(1, -1));
			this.assertEquals(3, array.indexOf(1, -2));
			this.assertEquals(1, array.indexOf(1, -3));
			this.assertEquals(1, array.indexOf(1, -4));
			this.assertEquals(1, array.indexOf(1, null));
			this.assertEquals(1, array.indexOf(1, void 0));
			this.assertEquals(1, array.indexOf(1, NaN));
			this.assertEquals(-1, array.indexOf(1, 4));
			if(Ael().Rhino){
				this.assertEquals(1, array.indexOf(1, Number.MAX_VALUE));
			}else{
				this.assertEquals(-1, array.indexOf(1, Number.MAX_VALUE));
			}
			this.assertEquals(-1, array.indexOf(new String("0")));
			this.assertEquals(-1, array.indexOf(new Number(1)));
			this.assertEquals(-1, array.indexOf(NaN));
			this.assertEquals(-1, array.indexOf(0));
			this.assertEquals(-1, array.indexOf(null));
			this.assertEquals(-1, array.indexOf(void 0));
		}
		
		if(Array.prototype.lastIndexOf){
			var array = [1, "0", NaN, 1];
			this.assertEquals(1, array.lastIndexOf("0"));
			this.assertEquals(3, array.lastIndexOf(1));
			this.assertEquals(0, array.lastIndexOf(1, 1));
			this.assertEquals(0, array.lastIndexOf(1, 2));
			this.assertEquals(3, array.lastIndexOf(1, 3));
			this.assertEquals(3, array.lastIndexOf(1, -1));
			this.assertEquals(0, array.lastIndexOf(1, -2));
			this.assertEquals(0, array.lastIndexOf(1, -3));
			if(userAgent.isChrome()){
				this.assertEquals(3, array.lastIndexOf(1, null));
				this.assertEquals(3, array.lastIndexOf(1, void 0));
				this.assertEquals(0, array.lastIndexOf(1, NaN));
				this.assertEquals(0, array.lastIndexOf(1, {}));
			}else if(userAgent.isSafari() || userAgent.isAIR() || (userAgent.isOpera() && userAgent.ownVersion >= 9.50)){
				this.assertEquals(0, array.lastIndexOf(1, null));
				this.assertEquals(3, array.lastIndexOf(1, void 0));
				this.assertEquals(3, array.lastIndexOf(1, NaN));
				this.assertEquals(3, array.lastIndexOf(1, {}));
			}else{
				this.assertEquals(0, array.lastIndexOf(1, null));
				this.assertEquals(0, array.lastIndexOf(1, void 0));
				this.assertEquals(0, array.lastIndexOf(1, NaN));
				this.assertEquals(0, array.lastIndexOf(1, {}));
			}
			this.assertEquals(0, array.lastIndexOf(1, true));
			this.assertEquals(0, array.lastIndexOf(1, false));
			this.assertEquals(0, array.lastIndexOf(1, ""));
			this.assertEquals(-1, array.lastIndexOf(new String("0")));
			this.assertEquals(-1, array.lastIndexOf(new Number(1)));
			this.assertEquals(-1, array.lastIndexOf(NaN));
			this.assertEquals(-1, array.lastIndexOf(0));
			this.assertEquals(-1, array.lastIndexOf(null));
			if(Ael().Rhino){
				this.assertEquals(4, array.lastIndexOf(void 0));
			}else{
				this.assertEquals(-1, array.lastIndexOf(void 0));
			}
			this.assertEquals(-1, [].lastIndexOf("0"));
			if(Ael().Rhino){
				this.assertEquals(0, [].lastIndexOf(void 0));
			}else{
				this.assertEquals(-1, [].lastIndexOf(void 0));
			}
		}
	}
});

Ael.test({
	"Ael#private-apply" : function(){
		var o = Ael().apply({a1:1,a:"2"}, ["a", "b", "c"]);
		this.assertEquals(1, o["a1"]);
		this.assertEquals("2", o["a"]);
		this.assertEquals("a", o["0"]);
		this.assertEquals("b", o["1"]);
		this.assertEquals("c", o["2"]);
		this.assertEquals(5, Ael(o).keys().length);
		o = Ael().apply({a:1,b:"b2"}, null);
		this.assertEquals(1, o["a"]);
		this.assertEquals("b2", o["b"]);
		this.assertEquals(2, Ael(o).keys().length);
		o = Ael().apply({a:1,b:"b2"}, void 0);
		this.assertEquals(1, o["a"]);
		this.assertEquals("b2", o["b"]);
		this.assertEquals(2, Ael(o).keys().length);
		o = Ael().apply(null, {a:1,b:"b2"});
		this.assertEquals(null, o);
		o = Ael().apply(void 0, {a:1,b:"b2"});
		this.assertEquals(void 0, o);
	},
	
	"Ael#static-isArray" : function(){
		this.assertTrue(Ael.isArray([]));
		this.assertTrue(Ael.isArray(new Array("a")));
		this.assertFalse(Ael.isArray({}));
		this.assertFalse(Ael.isArray(void 0));
		this.assertFalse(Ael.isArray(null));
	},
	
	"Ael#static-isObject" : function(){
		this.assertTrue(Ael.isObject({}));
		this.assertTrue(Ael.isObject([]));
		this.assertTrue(Ael.isObject(new Number(1)));
		this.assertTrue(Ael.isObject(new Number(NaN)));
		this.assertTrue(Ael.isObject(new String("a")));
		this.assertTrue(Ael.isObject(new Boolean(false)));
		this.assertTrue(Ael.isObject(new function(){}));
		this.assertTrue(Ael.isObject(function(){}));
		this.assertFalse(Ael.isObject(1));
		this.assertFalse(Ael.isObject("a"));
		this.assertFalse(Ael.isObject(true));
		this.assertFalse(Ael.isObject(false));
		this.assertFalse(Ael.isObject(NaN));
		this.assertFalse(Ael.isObject(null));
		this.assertFalse(Ael.isObject(void 0));
	},
	
	"Ael#static-isBoolean" : function(){
		this.assertTrue(Ael.isBoolean(true));
		this.assertTrue(Ael.isBoolean(false));
		this.assertTrue(Ael.isBoolean(new Boolean(true)));
		this.assertFalse(Ael.isBoolean({}));
		this.assertFalse(Ael.isBoolean(1));
		this.assertFalse(Ael.isBoolean(""));
		this.assertFalse(Ael.isBoolean(function(){}));
		this.assertFalse(Ael.isBoolean(NaN));
		this.assertFalse(Ael.isBoolean(null));
		this.assertFalse(Ael.isBoolean(void 0));
	},
	
	"Ael#static-isNumber" : function(){
		this.assertTrue(Ael.isNumber(0));
		this.assertTrue(Ael.isNumber(1.1));
		this.assertTrue(Ael.isNumber(NaN));
		this.assertTrue(Ael.isNumber(Infinity));
		this.assertTrue(Ael.isNumber(Number.NEGATIVE_INFINITY));
		this.assertTrue(Ael.isNumber(Number.POSITIVE_INFINITY));
		this.assertTrue(Ael.isNumber(new Number(1)));
		this.assertFalse(Ael.isNumber({}));
		this.assertFalse(Ael.isNumber(true));
		this.assertFalse(Ael.isNumber(""));
		this.assertFalse(Ael.isNumber(function(){}));
		this.assertFalse(Ael.isNumber(null));
		this.assertFalse(Ael.isNumber(void 0));
	},
	
	"Ael#static-isString" : function(){
		this.assertTrue(Ael.isString(""));
		this.assertTrue(Ael.isString(new String("")));
		this.assertFalse(Ael.isString({}));
		this.assertFalse(Ael.isString(true));
		this.assertFalse(Ael.isString(1));
		this.assertFalse(Ael.isString(function(){}));
		this.assertFalse(Ael.isString(NaN));
		this.assertFalse(Ael.isString(null));
		this.assertFalse(Ael.isString(void 0));
	},
	
	"Ael#static-isFunction" : function(){
		this.assertTrue(Ael.isFunction(function(){}));
		if(!userAgent.isAIR())
			this.assertTrue(Ael.isFunction(new Function("")));
		this.assertTrue(Ael.isFunction(Object));
		this.assertFalse(Ael.isFunction(new function(){}));
		this.assertFalse(Ael.isFunction({}));
		this.assertFalse(Ael.isFunction(true));
		this.assertFalse(Ael.isFunction(1));
		this.assertFalse(Ael.isFunction(""));
		this.assertFalse(Ael.isFunction(NaN));
		this.assertFalse(Ael.isFunction(null));
		this.assertFalse(Ael.isFunction(void 0));
	},
	
	"Ael#static-isUndefined" : function(){
		this.assertTrue(Ael.isUndefined(void 0));
		this.assertFalse(Ael.isUndefined({}));
		this.assertFalse(Ael.isUndefined(null));
	},
	
	"Ael#static-isNull" : function(){
		this.assertTrue(Ael.isNull(null));
		this.assertFalse(Ael.isNull({}));
		this.assertFalse(Ael.isNull(void 0));
	},
	
	"Ael#static-isNoU" : function(){
		this.assertTrue(Ael.isNoU(void 0));
		this.assertTrue(Ael.isNoU(null));
		this.assertFalse(Ael.isNoU(false));
	},
	
	"Ael#static-isNaN" : function(){
		this.assertTrue(Ael.isNaN(NaN));
		this.assertFalse(Ael.isNaN(0));
		this.assertFalse(Ael.isNaN(1.1));
		this.assertFalse(Ael.isNaN(Infinity));
		this.assertFalse(Ael.isNaN(Number.NEGATIVE_INFINITY));
		this.assertFalse(Ael.isNaN(Number.POSITIVE_INFINITY));
		this.assertFalse(Ael.isNaN(new Number(1)));
		this.assertFalse(Ael.isNaN({}));
		this.assertFalse(Ael.isNaN(true));
		this.assertFalse(Ael.isNaN(""));
		this.assertFalse(Ael.isNaN(function(){}));
		this.assertFalse(Ael.isNaN(null));
		this.assertFalse(Ael.isNaN(void 0));
	},
	
	"Ael#static-isArguments" : function(){
		this.assertTrue(Ael.isArguments(arguments));
		this.assertFalse(Ael.isArguments({}));
		this.assertFalse(Ael.isArguments([]));
	},
	
	"Ael#static-isNative" : function(){
		this.assertTrue(Ael.isNative(Object.constructor));
		this.assertTrue(Ael.isNative(Boolean.constructor));
		this.assertTrue(Ael.isNative(Number.constructor));
		this.assertTrue(Ael.isNative(String.constructor));
		this.assertTrue(Ael.isNative(Function.constructor));
		this.assertFalse(Ael.isNative(function(){}));
		this.assertFalse(Ael.isNative(NaN));
		this.assertFalse(Ael.isNative(null));
		this.assertFalse(Ael.isNative(void 0));
	},
	
	"Ael#static-instanceOf" : function(){
		this.assertTrue(Ael.instanceOf({}, Object));
		this.assertTrue(Ael.instanceOf(false, Boolean));
		this.assertTrue(Ael.instanceOf(new Boolean(false), Boolean));
		this.assertTrue(Ael.instanceOf(0, Number));
		this.assertTrue(Ael.instanceOf(new Number(0), Number));
		this.assertTrue(Ael.instanceOf("aiueo", String));
		this.assertTrue(Ael.instanceOf(new String(), String));
		this.assertTrue(Ael.instanceOf(/ /gi, RegExp));
		this.assertTrue(Ael.instanceOf(new RegExp(" ", "gi"), RegExp));
		var c = (function(){}).constructor;
		this.assertTrue(Ael.instanceOf(function(){}, c === Function?Function:c));
		var f = function(){};
		this.assertTrue(Ael.instanceOf(new f(), f));
		if(!userAgent.isAIR()){
			this.assertTrue(Ael.instanceOf(new Function(""), Function));
			this.assertTrue(Ael.instanceOf(Function(""), Function));
		}
		this.assertFalse(Ael.instanceOf(false, Object));
		this.assertFalse(Ael.instanceOf(new Boolean(false), Object));
		this.assertFalse(Ael.instanceOf(0, Object));
		this.assertFalse(Ael.instanceOf(new Number(0), Object));
		this.assertFalse(Ael.instanceOf("aiueo", Object));
		this.assertFalse(Ael.instanceOf(new String(), Object));
		this.assertFalse(Ael.instanceOf(function(){}, Object));
		this.assertFalse(Ael.instanceOf(new function(){}, Object));
		if(!userAgent.isAIR()){
			this.assertFalse(Ael.instanceOf(new Function(""), Object));
			this.assertFalse(Ael.instanceOf(Function(""), Object));
		}
		this.assertFalse(Ael.instanceOf(null, Object));
		this.assertFalse(Ael.instanceOf(void 0, Object));
	},
	
	"Ael#ael-apply" : function(){
		this.assertPropertiesEquals({a:"a", b:"b", c:"c"}, Ael({}).apply({a:"a", b:"b", c:"c"}));
		this.assertPropertiesEquals({d:1, a:"a", b:"b", c:"c"}, Ael({d:1}).apply({a:"a", b:"b", c:"c"}));
		this.assertPropertiesEquals({d:1}, Ael({d:1}).apply(0));
		this.assertPropertiesEquals({d:1}, Ael({d:1}).apply(NaN));
		this.assertPropertiesEquals({d:1}, Ael({d:1}).apply(null));
		this.assertPropertiesEquals({d:1}, Ael({d:1}).apply(void 0));
	},
	
	"Ael#ael-clear" : function(){
		this.assertEquals(void 0, Ael({}).clear());
		this.assertArrayEquals([], Ael({}).$clear().keys());
		var v = {a:"a",b:"b"};
		var c = Ael(v).$clear();
		this.assertArrayEquals([], c.keys());
		this.assertEquals(v, c.val());
		v = new Boolean(true);
		v.a = "a";
		v.b = "b";
		c = Ael(v).$clear();
		this.assertArrayEquals([], c.keys());
		this.assertEquals(v, c.val());
		v = new Number(123);
		v.a = "a";
		v.b = "b";
		c = Ael(v).$clear();
		this.assertArrayEquals([], c.keys());
		this.assertEquals(v, c.val());
		v = new String("aiueo");
		v.a = "a";
		v.b = "b";
		c = Ael(v).$clear();
		if(userAgent.isIECompatible()
				|| Ael().WSH
				|| Ael().Rhino
				|| userAgent.userAgent.indexOf("Gecko/2002") !== -1){
			this.assertArrayEquals([], c.keys());
		}else{
			this.assertArrayEquals(["0","1","2","3","4"], c.keys());
		}
		this.assertEquals(v, c.val());
		
		this.assertArrayEquals([], Ael(true).$clear().keys());
		this.assertArrayEquals([], Ael(0).$clear().keys());
		this.assertArrayEquals([], Ael(NaN).$clear().keys());
		this.assertArrayEquals([], Ael("").$clear().keys());
		this.assertArrayEquals([], Ael(null).$clear().keys());
		this.assertArrayEquals([], Ael(void 0).$clear().keys());
	},
	
	"Ael#ael-clone_shallow" : function(){
		this.assertEquals(void 0, Ael(void 0).clone());
		this.assertEquals(null, Ael(null).clone());
		this.assertNaN(Ael(NaN).clone());
		this.assertTrue(Ael(true).clone());
		this.assertEquals("aiueo", Ael("aiueo").clone());
		this.assertEquals(10, Ael(10).clone());
		
		this.assertTrue(true == Ael(new Boolean(true)).clone());
		this.assertTrue("aiueo" == Ael(new String("aiueo")).clone());
		this.assertTrue(10 == Ael(new Number(10)).clone());
		this.assertArrayEquals([], Ael([]).clone());
		
		var v = new Boolean(true);
		this.assertNotEquals(v, Ael(v).clone());
		this.assertTrue(true == Ael(v).clone());
		v = new String("aiueo");
		this.assertNotEquals(v, Ael(v).clone());
		this.assertTrue("aiueo" == Ael(v).clone());
		v = new Number(10);
		this.assertNotEquals(v, Ael(v).clone());
		this.assertTrue(10 == Ael(v).clone());
		v = [];
		this.assertNotEquals(v, Ael(v).clone());
		this.assertArrayEquals([], Ael(v).clone());
		v = function(){return "aiueo";};
		if(userAgent.isAIR()){
			this.assertEquals(v, Ael(v).clone());
		}else{
			this.assertNotEquals(v, Ael(v).clone());
			this.assertEquals("aiueo", Ael(v).clone()());
		}
	},
	
	"Ael#ael-clone_deep" : function(){
		this.assertEquals(void 0, Ael(void 0).clone(true));
		this.assertEquals(null, Ael(null).clone(true));
		this.assertNaN(Ael(NaN).clone(true));
		this.assertTrue(Ael(true).clone(true));
		this.assertEquals("aiueo", Ael("aiueo").clone(true));
		this.assertEquals(10, Ael(10).clone(true));
		
		this.assertTrue(true == Ael(new Boolean(true)).clone(true));
		this.assertTrue("aiueo" == Ael(new String("aiueo")).clone(true));
		this.assertTrue(10 == Ael(new Number(10)).clone(true));
		this.assertArrayEquals([], Ael([]).clone(true));
		
		var v = new Boolean(true);
		this.assertNotEquals(v, Ael(v).clone(true));
		this.assertTrue(true == Ael(v).clone(true));
		v = new String("aiueo");
		this.assertNotEquals(v, Ael(v).clone(true));
		this.assertTrue("aiueo" == Ael(v).clone(true));
		v = new Number(10);
		this.assertNotEquals(v, Ael(v).clone(true));
		this.assertTrue(10 == Ael(v).clone(true));
		v = [];
		this.assertNotEquals(v, Ael(v).clone(true));
		this.assertArrayEquals([], Ael(v).clone(true));
		v = function(){return "aiueo";};
		if(userAgent.isAIR()){
			this.assertEquals(v, Ael(v).clone(true));
		}else{
			this.assertNotEquals(v, Ael(v).clone(true));
			this.assertEquals("aiueo", Ael(v).clone(true)());
		}
		
		v = [false, 11, "aa", null, void 0, NaN];
		var result = Ael(v).clone(true);
		this.assertNotEquals(v, result);
		this.assertEquals(v.toString(), result.toString());
		this.assertArrayEquals(v, result);
		
		v = {a: false, b:11, c:"aa", d:null, e:void 0, "1":NaN, f:{a:"oa", b:1, c: true, d: null, e: [10]}, g:["aa", 1, true, null, {a: "d"}]};
		result = Ael(v).clone(true);
		this.assertNotEquals(v, result);
		if(Ael().Rhino){
			Ael(v)._keys().$sort().equals(Ael(result)._keys().sort());
		}else{
			this.assertPropertiesEquals(v, result);
		}
		
		v = function(){return "aiueo"};
		v.toString = function(){return "kakikukeko"};
		v.valueOf = function(){return "sasisuseso"};
		result = Ael(v).clone(true);
		if(userAgent.isAIR()){
			this.assertEquals(result, v);
		}else{
			this.assertEquals("aiueo", v());
			this.assertEquals("kakikukeko", v.toString());
			this.assertEquals("sasisuseso", v.valueOf());
			this.assertNotEquals(v, result);
			this.assertEquals("aiueo", result());
			this.assertEquals("kakikukeko", result.toString());
			this.assertEquals("sasisuseso", result.valueOf());
		}
		
		if(!userAgent.isAIR()){
			v = new Function('\tvar aiueo = "aiueo";\nreturn "aiueo";');
			result = Ael(v).clone(true);
			this.assertNotEquals(v, result);
			if(userAgent.isOpera() && userAgent.ownVersion >= 9.60){
				this.assertEquals("", Ael(v).name());
				v = eval('function(\n){\tvar aiueo = "aiueo";\nreturn "aiueo";}');
				this.assertEquals(v.toString(), result.toString());
			}else{
				this.assertEquals("anonymous", Ael(v).name());
				this.assertEquals(v.toString(), result.toString());
			}
		}
		
		v = function(){return "aiueo";};
		result = Ael(v).clone(true);
		if(userAgent.isAIR()){
			this.assertEquals(result, v);
		}else{
			this.assertNotEquals(v, result);
			this.assertEquals("", Ael(v).name());
			this.assertEquals(v.toString(), result.toString());
		}
	},
	
	"Ael#ael-compare" : function(){
		//boolean < function < number < object < string < undefined
		
		//A == B
		this.assertEquals(0, Ael(false).compare(false));
		this.assertEquals(0, Ael(20).compare(20));
		this.assertEquals(0, Ael("aiueo").compare("aiueo"));
		this.assertEquals(0, Ael(function(aiueo){aiueo}).compare(function(aiueo){aiueo}));
		this.assertEquals(0, Ael({a: 1, b: 2}).compare({c: 3, d: 4}));
		this.assertEquals(0, Ael(["a", "b"]).compare(["a", "b"]));
		this.assertEquals(0, Ael(NaN).compare(NaN));
		this.assertEquals(0, Ael(null).compare(null));
		this.assertEquals(0, Ael(void 0).compare(void 0));
		
		//A < B
		this.assertEquals(-1, Ael(false).compare(true));
		this.assertEquals(-1, Ael(20).compare(21));
		this.assertEquals(-1, Ael("aiueo").compare("aiueoa"));
		this.assertEquals(-1, Ael(function(){}).compare(function(a){}));
		var o1 = {};
		var o2 = {};
		o1.toString = function(){return "{a: 1, b: 2}"};
		o2.toString = function(){return "{a: 2, b: 2}"};
		this.assertEquals(-1, Ael(o1).compare(o2));
		this.assertEquals(-1, Ael(["a", "b", "c"]).compare(["a", "c", "c"]));
		this.assertEquals(-1, Ael(null).compare({}));
		
		this.assertEquals(-1, Ael(true).compare(function(){}));
		this.assertEquals(-1, Ael(true).compare(NaN));
		this.assertEquals(-1, Ael(true).compare(null));
		this.assertEquals(-1, Ael(true).compare(""));
		this.assertEquals(-1, Ael(true).compare(void 0));
		this.assertEquals(-1, Ael(function(){}).compare(NaN));
		this.assertEquals(-1, Ael(function(){}).compare(null));
		this.assertEquals(-1, Ael(function(){}).compare(""));
		this.assertEquals(-1, Ael(function(){}).compare(void 0));
		this.assertEquals(-1, Ael(NaN).compare(null));
		this.assertEquals(-1, Ael(NaN).compare(""));
		this.assertEquals(-1, Ael(NaN).compare(void 0));
		this.assertEquals(-1, Ael(null).compare(""));
		this.assertEquals(-1, Ael(null).compare(void 0));
		this.assertEquals(-1, Ael("").compare(void 0));
		function a(){};
		function b(){};
		this.assertEquals(-1, Ael(a).compare(b));
		this.assertEquals(-1, Ael(new a).compare(new b));
		
		//A > B
		this.assertEquals(1, Ael(true).compare(false));
		this.assertEquals(1, Ael(21).compare(20));
		this.assertEquals(1, Ael("aiueoa").compare("aiueo"));
		this.assertEquals(1, Ael(function(a){}).compare(function(){}));
		o1.toString = function(){return "{a: 2, b: 2}"};
		o2.toString = function(){return "{a: 1, b: 2}"};
		this.assertEquals(1, Ael(o1).compare(o2));
		this.assertEquals(1, Ael(["a", "c", "c"]).compare(["a", "b", "c"]));
		this.assertEquals(1, Ael({}).compare(null));
		this.assertEquals(1, Ael(b).compare(a));
		this.assertEquals(1, Ael(new b).compare(new a));
		
		this.assertEquals(1, Ael(void 0).compare(true));
		this.assertEquals(1, Ael(void 0).compare(function(){}));
		this.assertEquals(1, Ael(void 0).compare(NaN));
		this.assertEquals(1, Ael(void 0).compare(null));
		this.assertEquals(1, Ael(void 0).compare(""));
		this.assertEquals(1, Ael("").compare(true));
		this.assertEquals(1, Ael("").compare(function(){}));
		this.assertEquals(1, Ael("").compare(NaN));
		this.assertEquals(1, Ael("").compare(null));
		this.assertEquals(1, Ael(null).compare(true));
		this.assertEquals(1, Ael(null).compare(function(){}));
		this.assertEquals(1, Ael(null).compare(NaN));
		this.assertEquals(1, Ael(NaN).compare(true));
		this.assertEquals(1, Ael(NaN).compare(function(){}));
		this.assertEquals(1, Ael(function(){}).compare(true));
	},
	
	"Ael#ael-copy" : function(){
		var a = Ael({});
		this.assertEquals(a.val(), a.copy().val());
		this.assertTrue(a.equals(a.copy().val()));
		this.assertFalse(a === a.copy());
		this.assertFalse(a.equals(a.copy()));
		this.assertFalse(a === a.copy());
		this.assertFalse(a == a.copy());
		a = Ael("  aiueo  ");
		this.assertEquals("aiueo", a.copy().trim());
	},
	
	"Ael#ael-equals" : function(){
		var object = {};
		this.assertTrue(Ael(object).equals(object));
		this.assertTrue(Ael(true).equals(true));
		this.assertTrue(Ael(false).equals(false));
		this.assertTrue(Ael(1).equals(1));
		this.assertTrue(Ael("").equals(""));
		this.assertTrue(Ael(NaN).equals(NaN));
		this.assertTrue(Ael(null).equals(null));
		this.assertTrue(Ael(void 0).equals(void 0));
		this.assertFalse(Ael(new Boolean(true)).equals(true));
		this.assertFalse(Ael(new String("a")).equals(new String("a")));
		this.assertFalse(Ael("0").equals(0));
		this.assertFalse(Ael(null).equals(void 0));
		this.assertFalse(Ael(void 0).equals(null));
	},
	
	"Ael#ael-each" : function(){
		var tester = this;
		var object = {a: 0, b: 1, c: 2, d: 3};
		result = {};
		this.assertEquals(void 0, Ael(object).each(function(v, i, k){
			tester.assertEquals(Ael(result).keys().length, i);
			tester.assertEquals(String.fromCharCode(97 + v), k);
			result[k] = v;
		}));
		this.assertPropertiesEquals({a: 0, b: 1, c: 2, d: 3}, result);
		result = {};
		this.assertEquals(void 0, Ael(object).each(function(v, i, k){
			if(i === 2)
				return v;
			result[k] = v;
		}));
		this.assertEquals(Ael({a: 0, b: 1, c: 2}).keys().length, 3);
	},
	
	"Ael#ael-hasOwn" : function(){
		var o = {};
		o.aiueo = void 0;
		this.assertTrue(Ael(o).hasOwn("aiueo"));
		var f = function(){};
		f.prototype.aiueo = void 0;
		o = new f();
		o.aiueo = void 0;
		this.assertTrue(Ael(o).hasOwn("aiueo"));
		this.assertTrue(Ael(function(){}).hasOwn("prototype"));
		o = [];
		o.aiueo = void 0;
		o[0] = void 0;
		this.assertTrue(Ael(o).hasOwn("aiueo"));
		this.assertTrue(Ael(o).hasOwn("0"));
		var a = function(){};
		a.prototype = {aiueo: null};
		o = new a();
		if(userAgent.isIE4() || userAgent.isIE5()){		//IE5.5未満は真を返す
			this.assertTrue(Ael(o).hasOwn("aiueo"));
		}else{
			this.assertFalse(Ael(o).hasOwn("aiueo"));
		}
		o = new f();
		this.assertFalse(Ael(o).hasOwn("aiueo"));
		this.assertFalse(Ael({}).hasOwn("constructor"));
		this.assertFalse(Ael({}).hasOwn("valueOf"));
		this.assertFalse(Ael({}).hasOwn("toString"));
		this.assertFalse(Ael(NaN).hasOwn("toString"));
		this.assertFalse(Ael(null).hasOwn());
		this.assertFalse(Ael(void 0).hasOwn());
		this.assertFalse(Ael("").hasOwn(null));
		this.assertFalse(Ael("").hasOwn(void 0));
	},
	
	"Ael#ael-keys" : function(){
		var o = {};
		o.a = "av";
		o.b = "bv";
		o.c = "cv";
		var props = Ael(o).keys();
		this.assertEquals(3, props.length);
		this.assertEquals("a", props[0]);
		this.assertEquals("b", props[1]);
		this.assertEquals("c", props[2]);
	},
	
	"Ael#ael-toArray" : function(){
		this.assertArrayEquals([], Ael([]).toArray());
		this.assertArrayEquals([1,2,3], Ael([1,2,3]).toArray());
		var a = new Array(1,2,3);
		a.aiueo = "aiueo";
		this.assertArrayEquals([1,2,3], Ael(a).toArray());
		this.assertNotEquals(a, Ael(a).toArray());
		this.assertEquals(void 0, Ael(a).toArray().aiueo);
		
		this.assertArrayEquals([], Ael(true).toArray());
		this.assertArrayEquals([], Ael(false).toArray());
		this.assertArrayEquals([], Ael(123).toArray());
		this.assertArrayEquals([], Ael(0.12E+100).toArray());
		this.assertArrayEquals([], Ael("").toArray());
		this.assertArrayEquals([], Ael("aiueo").toArray());
		this.assertArrayEquals([], Ael(void 0).toArray());
		this.assertArrayEquals([], Ael(null).toArray());
		this.assertArrayEquals([], Ael(NaN).toArray());
		this.assertArrayEquals([], Ael(Number.NEGATIVE_INFINITY).toArray());
		this.assertArrayEquals([], Ael(Number.POSITIVE_INFINITY).toArray());
		this.assertArrayEquals([], Ael({}).toArray());
		
		this.assertArrayEquals([true], Ael(true).toArray(true));
		this.assertArrayEquals([false], Ael(false).toArray(true));
		this.assertArrayEquals([123], Ael(123).toArray(true));
		this.assertArrayEquals([0.12E+100], Ael(0.12E+100).toArray(true));
		this.assertArrayEquals([""], Ael("").toArray(true));
		this.assertArrayEquals(["aiueo"], Ael("aiueo").toArray(true));
		this.assertArrayEquals([void 0], Ael(void 0).toArray(true));
		this.assertArrayEquals([null], Ael(null).toArray(true));
		a = Ael(NaN).toArray(true);
		this.assertEquals(1, a.length);
		this.assertNaN(a[0]);
		this.assertArrayEquals([Number.NEGATIVE_INFINITY], Ael(Number.NEGATIVE_INFINITY).toArray(true));
		this.assertArrayEquals([Number.POSITIVE_INFINITY], Ael(Number.POSITIVE_INFINITY).toArray(true));
		var v = {};
		this.assertArrayEquals([v], Ael(v).toArray(true));
		this.assertArrayEquals([], Ael([]).toArray(true));
		this.assertArrayEquals([1,2,3], Ael([1,2,3]).toArray(true));
	},
	
	"Ael#ael-toBoolean" : function(){
		this.assertTrue(Ael(true).toBoolean());
		this.assertTrue(Ael(123).toBoolean());
		this.assertTrue(Ael(0.12E+100).toBoolean());
		this.assertTrue(Ael("aiueo").toBoolean());
		this.assertTrue(Ael(Number.NEGATIVE_INFINITY).toBoolean());
		this.assertTrue(Ael(Number.POSITIVE_INFINITY).toBoolean());
		this.assertTrue(Ael({}).toBoolean());
		this.assertTrue(Ael([]).toBoolean());
		this.assertFalse(Ael(false).toBoolean());
		this.assertFalse(Ael("").toBoolean());
		this.assertFalse(Ael(void 0).toBoolean());
		this.assertFalse(Ael(null).toBoolean());
		this.assertFalse(Ael(NaN).toBoolean());
	},
	
	"Ael#ael-toJSONString" : function(){
		var o = {
			"boolean" : true,
			"number" : -12.34e5,
			"string" : "aiueo\"\\\/\b\f\n\r\tあいうえお",
			"Boolean" : new Boolean(true),
			"Number" : new Number(-12.34e5),
			"String" : new String("aiueo\"\\\/\b\f\n\r\tあいうえお"),
			"Date" : new Date(2007,0,2,3,4,5),
			"Array" : ["1",2,false],
			"Object" : {"a":"1", "b":2, "c":false}
		};
		var expect = '{"boolean":true,"number":-1234000,"string":"aiueo\\\"\\\\\\/\\b\\f\\n\\r\\tあいうえお",'
				+ '"Boolean":true,"Number":-1234000,"String":"aiueo\\\"\\\\\\/\\b\\f\\n\\r\\tあいうえお","Date":"'
				+ (new Date(2007,0,2,3,4,5)).toUTCString() + '",'
				+ '"Array":["1",2,false],"Object":{"a":"1","b":2,"c":false}}';
		var json = Ael(o).toJSONString(true);
		if(!Ael().Rhino){
			this.assertEquals(expect, json);
		}
		
		var decode = eval("(" + json + ")");
		if(Ael().Rhino){
			Ael(o)._keys().$sort().equals(Ael(decode)._keys().sort());
		}else{
			this.assertArrayEquals(Ael(o).keys(), Ael(decode).keys());
		}
		this.assertEquals(true, decode["boolean"]);
		this.assertEquals(-1234000, decode["number"]);
		this.assertEquals("aiueo\"\\\/\b\f\n\r\tあいうえお", decode["string"]);
		this.assertEquals(true, decode["Boolean"]);
		this.assertEquals(-1234000, decode["Number"]);
		this.assertEquals("aiueo\"\\\/\b\f\n\r\tあいうえお", decode["String"]);
		this.assertEquals((new Date(2007,0,2,3,4,5)).toUTCString(), decode["Date"]);
		this.assertArrayEquals(["1",2,false], decode["Array"]);
		this.assertPropertiesEquals({"a":"1", "b":2, "c":false}, decode["Object"]);
	},
	
	"Ael#ael-toNumber" : function(){
		this.assertEquals(1, Ael(true).toNumber());
		this.assertEquals(0, Ael(false).toNumber());
		this.assertEquals(123, Ael(123).toNumber());
		this.assertEquals(0.12E+100, Ael(0.12E+100).toNumber());
		this.assertEquals(0, Ael("").toNumber());
		this.assertNaN(Ael("aiueo").toNumber());
		this.assertNaN(Ael(void 0).toNumber());
		this.assertEquals(0, Ael(null).toNumber());
		this.assertNaN(Ael(NaN).toNumber());
		this.assertFalse(isFinite(Ael(Number.NEGATIVE_INFINITY).toNumber()));
		this.assertFalse(isFinite(Ael(Number.POSITIVE_INFINITY).toNumber()));
		this.assertNaN(Ael({}).toNumber());
		this.assertEquals(0, Ael([]).toNumber());
	},
	
	"Ael#ael-toString" : function(){
		this.assertEquals("true", Ael(true).toString());
		this.assertEquals("false", Ael(false).toString());
		this.assertEquals("123", Ael(123).toString());
		this.assertEquals("1.2e+99", Ael(0.12E+100).toString());
		this.assertEquals("", Ael("").toString());
		this.assertEquals("aiueo", Ael("aiueo").toString());
		this.assertEquals("undefined", Ael(void 0).toString());
		this.assertEquals("null", Ael(null).toString());
		this.assertEquals("NaN", Ael(NaN).toString());
		this.assertEquals("-Infinity", Ael(Number.NEGATIVE_INFINITY).toString());
		this.assertEquals("Infinity", Ael(Number.POSITIVE_INFINITY).toString());
		this.assertEquals("[object Object]", Ael({}).toString());
		this.assertEquals("", Ael([]).toString());
		this.assertEquals("1,2,3", Ael([1,2,3]).toString());
	}
});

Ael.test({
	"Ael.lang.Array#ael-arraycopy" : function(){
		var a = [1,2,3,4,5,6,7,8];
		this.assertArrayEquals([], Ael(a).arraycopy(0, [], 0, 0));
		this.assertArrayEquals([1,2,3,4,5,6,7,8], Ael(a).arraycopy(0, [], 0, 8));
		this.assertArrayEquals([8], Ael(a).arraycopy(7, [], 0, 1));
		this.assertArrayEquals([1], Ael(a).arraycopy(0, [], 0, 1));
		this.assertArrayEquals([3,4,5,6], Ael(a).arraycopy(2, [], 0, 4));
		this.assertArrayEquals([,1,2], Ael(a).arraycopy(0, [], 1, 2));
		this.assertArrayEquals([], Ael(a).arraycopy(0, [], -1, 2));
		this.assertArrayEquals([], Ael(a).arraycopy(-1, [], 0, 2));
		this.assertArrayEquals([,,,void 0], Ael(a).arraycopy(100, [], 2, 2));
		this.assertArrayEquals([void 0, void 0], Ael([]).arraycopy(0, [], 0, 2));
		this.assertEquals(null, Ael(a).arraycopy(0, null, 0, 2));
		this.assertEquals(void 0, Ael(a).arraycopy(0, void 0, 0, 2));
	},
	
	"Ael.lang.Array#ael-clear" : function(){
		this.assertEquals(void 0, Ael([]).clear());
		this.assertEquals(0, Ael([]).$clear().val().length);
		this.assertEquals(0, Ael([1,2,3,4]).$clear().val().length);
	},
	
	"Ael.lang.Array#ael-contains" : function(){
		var array = ["",void 0,null,NaN,0];
		this.assertTrue(Ael([1,2,3,4]).contains(2));
		this.assertTrue(Ael(array).contains(""));
		this.assertTrue(Ael(array).contains(void 0));
		this.assertTrue(Ael(array).contains(null));
		this.assertTrue(Ael(array).contains(0));
		this.assertFalse(Ael(array).contains(NaN));
		this.assertFalse(Ael([]).contains("a"));
		this.assertFalse(Ael([]).contains());
	},
	
	"Ael.lang.Array#ael-each" : function(){
		var tester = this;
		var array = ["a", "b", "c", "d"];
		var result = [];
		this.assertEquals(void 0, Ael(array).each(function(v, i, k){
			tester.assertEquals(result.length, i);
			tester.assertEquals(void 0, k);
			result[result.length] = v;
		}));
		this.assertArrayEquals(["a", "b", "c", "d"], result);
		
		result = [];
		this.assertEquals(void 0, Ael(array).each(function(v, i, k){
			if("c" === v)
				return v;
			result[result.length] = v;
		}));
		this.assertArrayEquals(["a", "b"], result);
	},
	
	"Ael.lang.Array#ael-indexOf" : function(){
		var array = ["0", 1, NaN, 1];
		this.assertEquals(0, Ael(array).indexOf("0"));
		this.assertEquals(1, Ael(array).indexOf(1));
		this.assertEquals(1, Ael(array).indexOf(1, 0));
		this.assertEquals(1, Ael(array).indexOf(1, 1));
		this.assertEquals(3, Ael(array).indexOf(1, 2));
		this.assertEquals(3, Ael(array).indexOf(1, 3));
		this.assertEquals(3, Ael(array).indexOf(1, -1));
		this.assertEquals(3, Ael(array).indexOf(1, -2));
		this.assertEquals(1, Ael(array).indexOf(1, -3));
		this.assertEquals(1, Ael(array).indexOf(1, -4));
		this.assertEquals(1, Ael(array).indexOf(1, null));
		this.assertEquals(1, Ael(array).indexOf(1, void 0));
		this.assertEquals(1, Ael(array).indexOf(1, NaN));
		this.assertEquals(-1, Ael(array).indexOf(1, 4));
		this.assertEquals(-1, Ael(array).indexOf(1, Number.MAX_VALUE));
		this.assertEquals(-1, Ael(array).indexOf(new String("0")));
		this.assertEquals(-1, Ael(array).indexOf(new Number(1)));
		this.assertEquals(-1, Ael(array).indexOf(NaN));
		this.assertEquals(-1, Ael(array).indexOf(0));
		this.assertEquals(-1, Ael(array).indexOf(null));
		this.assertEquals(-1, Ael(array).indexOf(void 0));
	},
	
	"Ael.lang.Array#ael-lastIndexOf" : function(){
		var array = [1, "0", NaN, 1];
		this.assertEquals(1, Ael(array).lastIndexOf("0"));
		this.assertEquals(3, Ael(array).lastIndexOf(1));
		this.assertEquals(0, Ael(array).lastIndexOf(1, 1));
		this.assertEquals(0, Ael(array).lastIndexOf(1, 2));
		this.assertEquals(3, Ael(array).lastIndexOf(1, 3));
		this.assertEquals(3, Ael(array).lastIndexOf(1, -1));
		this.assertEquals(0, Ael(array).lastIndexOf(1, -2));
		this.assertEquals(0, Ael(array).lastIndexOf(1, -3));
		this.assertEquals(0, Ael(array).lastIndexOf(1, null));
		this.assertEquals(0, Ael(array).lastIndexOf(1, void 0));
		this.assertEquals(0, Ael(array).lastIndexOf(1, NaN));
		this.assertEquals(0, Ael(array).lastIndexOf(1, {}));
		this.assertEquals(0, Ael(array).lastIndexOf(1, true));
		this.assertEquals(0, Ael(array).lastIndexOf(1, false));
		this.assertEquals(0, Ael(array).lastIndexOf(1, ""));
		this.assertEquals(-1, Ael(array).lastIndexOf(new String("0")));
		this.assertEquals(-1, Ael(array).lastIndexOf(new Number(1)));
		this.assertEquals(-1, Ael(array).lastIndexOf(NaN));
		this.assertEquals(-1, Ael(array).lastIndexOf(0));
		this.assertEquals(-1, Ael(array).lastIndexOf(null));
		this.assertEquals(-1, Ael(array).lastIndexOf(void 0));
		this.assertEquals(-1, Ael([]).lastIndexOf("0"));
		this.assertEquals(-1, Ael([]).lastIndexOf());
	},
	
	"Ael.lang.Array#ael-map" : function(){
		this.assertArrayEquals([100,201,302,403,504], Ael([0, 1, 2, 3, 4]).map(function(v, i){
			return v + (100 * (i+1));
		}));
		this.assertArrayEquals([], Ael([]).map());
		this.assertArrayEquals([], Ael([1,2,3]).map());
		this.assertArrayEquals([], Ael([]).map(function(){}));
		this.assertArrayEquals([void 0, void 0, void 0], Ael([1,2,3]).map(function(){}));
		var a= [1,2,3];
		this.assertArrayEquals([a,a,a], Ael(a).map(function(v, i, a){
			return a;
		}));
	},
	
	"Ael.lang.Array#ael-filter" : function(){
		this.assertArrayEquals([12,130,44], Ael([12, 5, 8, 130, 44]).filter(function(v){
			return v >= 10;
		}));
	},
	
	"Ael.lang.Array#ael-some" : function(){
		this.assertTrue(Ael([0, 1, 2, 3, 4]).some(function(v, i){
			return v === 3;
		}));
		this.assertFalse(Ael([0, 1, 2, 3, 4]).some(function(v, i){
			return v > 4;
		}));
	},
	
	"Ael.lang.Array#ael-every" : function(){
		this.assertTrue(Ael([0, 1, 2, 3, 4]).every(function(v, i){
			return v < 10;
		}));
		this.assertFalse(Ael([0, 1, 2, 3, 4]).every(function(v, i){
			return v < 4;
		}));
	},
	
	"Ael.lang.Array#ael-push" : function(){
		var array = [];
		this.assertEquals(0, Ael(array).push());
		this.assertArrayEquals([], array);
		this.assertEquals(1, Ael(array).push("a"));
		this.assertArrayEquals(["a"], array);
		this.assertEquals(2, Ael(array).push(NaN));
		this.assertArrayEquals(["a", NaN], array);
		this.assertEquals(3, Ael(array).push(null));
		this.assertArrayEquals(["a", NaN, null], array);
		this.assertEquals(4, Ael(array).push(void 0));
		this.assertArrayEquals(["a", NaN, null, void 0], array);
	},
	
	"Ael.lang.Array#ael-concat" : function(){
		var o = Ael(["a", "b", "c"]).concat();
		this.assertArrayEquals(["a", "b", "c"], o);
		o = Ael(["a", "b", "c"]).concat(["d", "e"]);
		this.assertArrayEquals(["a", "b", "c", "d", "e"], o);
		o = Ael(["a", "b", "c"]).concat(["d", "e"], [1,2]);
		this.assertArrayEquals(["a", "b", "c", "d", "e", 1, 2], o);
		o = Ael(["a", "b", "c"]).concat(null);
		this.assertArrayEquals(["a", "b", "c", null], o);
		o = Ael(["a", "b", "c"]).concat(void 0);
		this.assertArrayEquals(["a", "b", "c", void 0], o);
		o = Ael(["a"]).concat(true, false, NaN);
		this.assertArrayEquals(["a", true, false, NaN], o);
		o = Ael([]).concat(void 0, ["a", "b", "c"], null, ["d", "e"]);
		this.assertArrayEquals([void 0, "a", "b", "c", null, "d", "e"], o);
		o = Ael([]).concat(null);
		this.assertArrayEquals([null], o);
		o = Ael([]).concat(void 0);
		this.assertArrayEquals([void 0], o);
	},
	
	"Ael.lang.Array#ael-join" : function(){
		var a = [1,2,"a",3,"b"];
		this.assertEquals("1,2,a,3,b", Ael(a).join());
		this.assertEquals("1++2++a++3++b", Ael(a).join("++"));
		this.assertEquals("1null2nullanull3nullb", Ael(a).join(null));
		this.assertEquals("1NaN2NaNaNaN3NaNb", Ael(a).join(NaN));
		this.assertEquals("1,2,a,3,b", Ael(a).join(void 0));
	},
	
	"Ael.lang.Array#ael-reverse" : function(){
		this.assertArrayEquals([], Ael([]).reverse());
		this.assertArrayEquals(["b",3,"a",2,1], Ael([1,2,"a",3,"b"]).reverse());
	},
	
	"Ael.lang.Array#ael-pop" : function(){
		var a = [1,2,"a"];
		this.assertEquals("a", Ael(a).pop());
		this.assertEquals(2, a.length);
		this.assertEquals(2, Ael(a).pop());
		this.assertEquals(1, a.length);
		this.assertEquals(1, Ael(a).pop());
		this.assertEquals(0, a.length);
		this.assertEquals(void 0, Ael(a).pop());
		this.assertEquals(0, a.length);
	},
	
	"Ael.lang.Array#ael-shift" : function(){
		var a = [1,[2,"a"],3];
		this.assertEquals(1, Ael(a).shift());
		this.assertEquals(2, a.length);
		this.assertArrayEquals([2,"a"], Ael(a).shift());
		this.assertEquals(1, a.length);
		this.assertEquals(3, Ael(a).shift());
		this.assertEquals(0, a.length);
		this.assertEquals(void 0, Ael(a).shift());
		this.assertEquals(0, a.length);
	},
	
	"Ael.lang.Array#ael-size" : function(){
		this.assertEquals(0, Ael([]).size());
		this.assertEquals(1, Ael(["a"]).size());
		this.assertEquals(5, Ael(["a","b","c","d","e"]).size());
	},
	
	"Ael.lang.Array#ael-slice" : function(){
		var a = [1,2,3,4,5];
		this.assertArrayEquals([1,2,3], Ael(a).slice(0,3));
		this.assertArrayEquals([4,5], Ael(a).slice(3));
		this.assertArrayEquals([2,3,4], Ael(a).slice(1, -1));
		this.assertArrayEquals([3], Ael(a).slice(-3,-2));
		this.assertArrayEquals([1,2,3,4,5], Ael(a).slice());
		this.assertArrayEquals([], Ael(a).slice(5));
		this.assertArrayEquals([,,,,,1,2,3,4,5,,,,,void 0], Ael(a).slice(-10,10));
		this.assertArrayEquals([1,2,3,4,5,,,,,void 0], Ael(a).slice(void 0,10));
		this.assertArrayEquals([1,2,3,4,5,,,,,void 0], Ael(a).slice(null,10));
	},
	
	"Ael.lang.Array#ael-sort" : function(){
		var a = new Array(3,4,1,-1,2,0);
		this.assertArrayEquals([-1,0,1,2,3,4], Ael(a).sort());
		this.assertArrayEquals([4,3,2,1,0,-1], Ael(a).sort(function(v1, v2){
			return Ael(v2).compare(v1);
		}));
		var a = ["c","a","b"];
		this.assertArrayEquals(["a","b","c"], Ael(a).sort());
		this.assertArrayEquals(["a","b","c"], Ael(a).sort(function(v1, v2){
			return Ael(v1).compare(v2);
		}));
		var a = [null,void 0,NaN,0,false,true,""];
		this.assertArrayEquals(["",0,NaN,false,null,true,void 0], Ael(a).sort());
		this.assertArrayEquals([false,true,0,NaN,null,"",void 0], Ael(a).sort(function(v1, v2){
			return Ael(v1).compare(v2);
		}));
		var a = ["い","う","お","え","あ"];
		this.assertArrayEquals(["あ","い","う","え","お"], Ael(a).sort());
		this.assertArrayEquals(["あ","い","う","え","お"], Ael(a).sort(function(v1, v2){
			return Ael(v1).compare(v2);
		}));
		this.assertArrayEquals([], Ael([]).sort());
		
		//["",void 0,null,NaN,0]	Mozilla
		//[NaN,null,"",0,void 0]	Firefox2
		//["",0,NaN,null,void 0]	Firefox1
		//[null,NaN,0,"",void 0]	Safari	AIR
		//[null,void 0,NaN,"",0]	Dreamweaver, Netscape7
		//[NaN,"",0,null,void 0]	Chrome
		//[0,NaN,null,"",void 0]	Chrome1.0.154+
		//["",null,NaN,0,void 0]	IE, Opera, Rhino, Firefox3
		//["",0,null,NaN,void 0]	Opera9.5+
		var expected = userAgent.isNN()
				?userAgent.isFirefox()
					?userAgent.userAgent.indexOf("Firefox/3") !== -1
						?["",null,NaN,0,void 0]
						:userAgent.userAgent.indexOf("Firefox/1") !== -1
							?[null,0,NaN,"",void 0]
							:[NaN,null,"",0,void 0]
					:userAgent.userAgent.indexOf("Netscape/7") !== -1
						?[null,void 0,NaN,"",0]
						:userAgent.isJaxer()
							?["",null,NaN,0,void 0]
							:["",void 0,null,NaN,0]
				:userAgent.isChrome()
//					?[NaN,"",0,null,void 0]
					?[0,NaN,null,"",void 0]
					:userAgent.isSafari() || userAgent.isAIR()
						?[null,NaN,0,"",void 0]
						:userAgent.isDreamweaver()
							?[null,void 0,NaN,"",0]
							:(userAgent.isOpera() && userAgent.ownVersion >= 9.50)
								?["",0,null,NaN,void 0]
								:["",null,NaN,0,void 0];
		this.assertArrayEquals(expected, Ael(["",void 0,null,NaN,0]).sort(function(v1, v2){
			return 0;
		}));
	},
	
	"Ael.lang.Array#ael-splice" : function(){
		var a = [1,2,3,4,5,6,7,8];
		this.assertArrayEquals([5,6,7,8], Ael(a).splice(4));
		this.assertArrayEquals([1,2,3,4], a);
		this.assertArrayEquals([2,3], Ael(a).splice(1,2));
		this.assertArrayEquals([1,4], a);
		this.assertArrayEquals([4], Ael(a).splice(1,1));
		this.assertArrayEquals([1], a);
		this.assertArrayEquals([1], Ael(a).splice(0));
		this.assertArrayEquals([], a);
		this.assertArrayEquals([], Ael(a).splice(1,1));
		a = [1,2,3,4,5,6,7,8];
		this.assertArrayEquals([], Ael(a).splice(0. -3));
		this.assertArrayEquals([1,2,3,4,5,6,7,8], a);
		this.assertArrayEquals([], Ael(a).splice(-5, 1));
		this.assertArrayEquals([1,2,3,4,5,6,7,8], a);
	},
	
	"Ael.lang.Array#ael-unshift" : function(){
		var a = [];
		this.assertEquals(0, Ael(a).unshift());
		this.assertArrayEquals([], a);
		this.assertEquals(1, Ael(a).unshift(1));
		this.assertArrayEquals([1], a);
		this.assertEquals(3, Ael(a).unshift(2, "a"));
		this.assertArrayEquals([2,"a",1], a);
		this.assertEquals(3, Ael(a).unshift());
		this.assertArrayEquals([2,"a",1], a);
		this.assertEquals(4, Ael(a).unshift(null));
		this.assertArrayEquals([null,2,"a",1], a);
		this.assertEquals(5, Ael(a).unshift(void 0));
		this.assertArrayEquals([void 0,null,2,"a",1], a);
		this.assertEquals(6, Ael(a).unshift(NaN));
		this.assertArrayEquals([NaN,void 0,null,2,"a",1], a);
		this.assertEquals(6, Ael(a).unshift());
		this.assertArrayEquals([NaN,void 0,null,2,"a",1], a);
	},
	
	"Ael.lang.Array#ael-within" : function(){
		var a = Ael(["1","2","3"]);
		this.assertTrue(a.within(0));
		this.assertTrue(a.within(2));
		this.assertFalse(a.within(4294967295));
		this.assertFalse(a.within(-1));
		this.assertFalse(a.within(3));
		this.assertFalse(a.within(4294967296));
		this.assertFalse(a.within({}));
		this.assertFalse(a.within(NaN));
		this.assertFalse(a.within(null));
		this.assertFalse(a.within(void 0));
	},
	
	"Ael.lang.Array#ael-toJSONString" : function(){
		this.assertEquals('[]', Ael([]).toJSONString());
		this.assertEquals('["\\u0061"]', Ael(["a"]).toJSONString());
		this.assertEquals('["a"]', Ael(["a"]).toJSONString(true));
		this.assertEquals('[1,true,false,null,"\\u0061",{}]', Ael([1, true, false, null, void 0, NaN, "a", {}]).toJSONString());
		this.assertEquals('[1,true,false,null,"a",{}]', Ael([1, true, false, null, void 0, NaN, "a", {}]).toJSONString(true));
	}
});

Ael.test({
	"Ael.lang.Boolean#ael-toJSONString" : function(){
		this.assertEquals("true", Ael(true).toJSONString());
		this.assertEquals("false", Ael(false).toJSONString());
		this.assertEquals("true", Ael(new Boolean(true)).toJSONString());
		this.assertEquals("false", Ael(new Boolean(false)).toJSONString());
	}
});

Ael.test({
	"Ael.lang.Date#ael-clear" : function(){
		this.assertEquals(void 0, Ael(new Date()).clear());
		this.assertEquals(0, Ael(new Date(0)).$clear().val().getTime());
		this.assertEquals(0, Ael(new Date()).$clear().val().getTime());
	},
	
	"Ael.lang.Date#ael-toJSONString" : function(){
		if(userAgent.isIE() || Ael().WSH){
			this.assertEquals("\"Thu, 1 Feb 2001 18:04:05 UTC\"", Ael(new Date(2001, 1, 2, 3, 4, 5, 6, 7)).toJSONString());
		}else{
			this.assertEquals("\"Thu, 01 Feb 2001 18:04:05 GMT\"", Ael(new Date(2001, 1, 2, 3, 4, 5, 6, 7)).toJSONString());
		}
	}
});

Ael.test({
	"Ael.lang.Function#ael-call" : function(){
		var aiueo = function(v1, v2){
			return this.isString(v1) + "_"+v1+"_"+v2;
		};
		this.assertEquals("true_v1_v2", Ael(aiueo).call(["v1", "v2"], Ael));
	},
	
	"Ael.lang.Function#ael-chain" : function(){
		var super1 = function(){
			return "super1";
		};
		super1.c1 = function(){
			return "super1.c1";
		};
		super1.c2 = function(){
			return "super1.c2";
		};
		super1.prototype.p1 = function(){
			return "super1.p1";
		};
		super1.prototype.p2 = function(){
			return "super1.p2";
		};
		
		var sub1 = function(){
			return "sub1";
		};
		Ael(sub1).chain(super1);
		sub1.prototype.p1 = function(){
			return "sub1.p1";
		};
		sub1.prototype.p3 = function(){
			return "sub1.p3";
		};
		var s = new sub1();
		this.assertEquals("sub1.p1", s.p1());
		this.assertEquals("super1.p2", s.p2());
		this.assertEquals("sub1.p3", s.p3());
		
		var sub2 = userAgent.isAIR()
				?function(){}
				:new Function();
		Ael(sub2).chain({
			p1 : function(){
				return "object.p1";
			},
			p2 : function(){
				return "object.p2";
			}
		});
		s = new sub2();
		sub2.prototype.p2 = function(){
			return "sub2.p2";
		};
		this.assertEquals("object.p1", s.p1());
		this.assertEquals("sub2.p2", s.p2());
	},
	
	"Ael.lang.Function#ael-clear" : function(){
		this.assertEquals(void 0, Ael(function(){}).clear());
		var fn = function(){};
		fn.a = "a";
		fn.b = "b";
		fn.c = "c";
		if(userAgent.isIECompatible()
				|| Ael().WSH
				|| (Ael().Rhino && !Array.prototype.indexOf)
				|| userAgent.isDreamweaver()
				|| userAgent.userAgent.indexOf("Netscape/7") !== -1
				|| userAgent.userAgent.indexOf("Gecko/2002") !== -1){
			this.assertEquals(0, Ael(function(){}).$clear().keys().length);
			this.assertArrayEquals(["a","b","c"], Ael(fn)._keys().sort());
			this.assertArrayEquals([], Ael(fn).$clear().keys());
		}else if(userAgent.isJaxer()){
			this.assertEquals(2, Ael(function(){}).$clear().keys().length);
			this.assertArrayEquals(["a","b","c","prototype","runat"], Ael(fn)._keys().sort());
			this.assertArrayEquals(["prototype","runat"], Ael(fn).$clear().keys());
		}else{
			this.assertEquals(1, Ael(function(){}).$clear().keys().length);
			this.assertArrayEquals(["a","b","c","prototype"], Ael(fn)._keys().sort());
			this.assertArrayEquals(["prototype"], Ael(fn).$clear().keys());
		}
	},
	
	"Ael.lang.Function#ael-curry" : function(){
		var f = function(a, b, c, d){
			return a + b + c + d;
		};
		this.assertEquals(10, f(1,2,3,4));
		f = Ael(f).curry([1]);
		this.assertEquals(10, f(2,3,4));
		f = Ael(f).curry([2,3]);
		this.assertEquals(10, f(4));
		f = Ael(f).curry([4,5]);
		this.assertEquals(10, f());
		
		var o = {aiueo: "aiueo"};
		f = function(a,b){
			return this.aiueo + a + b;
		}
		f = Ael(f).curry(["_a", "_b"], o);
		this.assertEquals("aiueo_a_b", f());
		
		f = function(a, b, c, d){
			return a + b + c + d;
		};
		f = Ael(f).curry();
		this.assertEquals(10, f(1,2,3,4));
		f = Ael(f).curry(10);
		this.assertEquals(10, f(1,2,3,4));
		
		f = function(a, b, c){
			return a + ":" + b + ":" + c;
		};
		f = Ael(f).curry([void 0, NaN, null]);
		this.assertEquals("undefined:NaN:null", f(1,2,3));
		
		f = function(){
			return this;
		}
		f = Ael(f).curry(void 0, void 0);
		this.assertTrue(Ael.isObject(f()));
	},
	
	"Ael.lang.Function#ael-defer" : function(){
		if(!Ael().global.setInterval
				|| userAgent.isDreamweaver()
				|| userAgent.isJaxer())
			return;
		
		var self = this,
			start = new Date(),
			count = 0;
		var id = Ael(function(){
			var a = arguments;
			self.assertEquals("a123", this.a + a[0] + a[1] + a[2]);
			var diff = new Date() - start;
			self.assertTrue(2500 <= diff && diff < 3500);
			self.assertEquals(3, count);
		}).defer({
			ms : 1000,
			arguments : [1,2,3],
			scope : {a:"a"},
			condition : function(){
				count++;
				return count > 2;
			}
		});
		this.assertTrue(Ael.isNumber(id));
		
		var ccount = 0,
			rcount = 0;
		id = Ael(function(){
			rcount++;
			if(rcount > 3){
				self.assertEquals(6, ccount);
				self.assertEquals(4, rcount);
				Ael().global.clearInterval(id);
			}
		}).defer({
			ms : 180,
			interval : true,
			condition : function(){
				ccount++;
				return ccount > 2;
			}
		});
	},
	
	"Ael.lang.Function#ael-interceptor" : function(){
		var self = this, actual = Ael([]), x;
		var fn = function(string){
			actual.push("fn: " + string);
		};
		var interceptor = Ael(fn).interceptor();
		interceptor.before = function(string){
			actual.push("before: " + string);
			self.assertEquals(void 0, this.x);
			this.x = 0;
		}  
		interceptor.around = function(string){
			actual.push("around: " + string);
			this.proceed(arguments);
			this.x++;  
		}
		interceptor.after = function(string){
			actual.push("after: " + string);
			x = "x: " + this.x;
		}
		interceptor("aiueo");
		
		this.assertArrayEquals(["before: aiueo", "around: aiueo", "fn: aiueo", "after: aiueo"], actual.val());
		this.assertEquals("x: 1", x);
		
		interceptor("aiueo");
		
		this.assertArrayEquals(["before: aiueo", "around: aiueo", "fn: aiueo", "after: aiueo",
				"before: aiueo", "around: aiueo", "fn: aiueo", "after: aiueo"], actual.val());
		this.assertEquals("x: 1", x);
	},
	
	"@deprecated Ael.lang.Function#ael-name" : function(){
		this.assertEquals("", Ael(function(){}).name());
		if(userAgent.isAIR()){
			this.assertEquals("", Ael(Array).name());
			this.assertEquals("", Ael(Boolean).name());
			this.assertEquals("", Ael(Date).name());
			this.assertEquals("", Ael(Function).name());
			this.assertEquals("", Ael(Number).name());
			this.assertEquals("", Ael(Object).name());
			this.assertEquals("", Ael(RegExp).name());
			this.assertEquals("", Ael(String).name());
		}else{
			this.assertEquals("anonymous", Ael(new Function()).name());
			this.assertEquals("Array", Ael(Array).name());
			this.assertEquals("Boolean", Ael(Boolean).name());
			this.assertEquals("Date", Ael(Date).name());
			this.assertEquals("Function", Ael(Function).name());
			this.assertEquals("Number", Ael(Number).name());
			this.assertEquals("Object", Ael(Object).name());
			this.assertEquals("RegExp", Ael(RegExp).name());
			this.assertEquals("String", Ael(String).name());
		}
	},
	
	"Ael.lang.Function#ael-timer" : function(){
		if(!Ael().global.setInterval
				|| userAgent.isDreamweaver()
				|| userAgent.isJaxer())
			return;
		
		this.expect({
			amount : 1,
			timeout : 5000
		});
		
		var self = this;
		var start = new Date();
		var id = Ael(function(){
			var diff = new Date() - start;
			self.assertWith(1000, 1020, diff);
		}).timer({
			ms : 1000
		});
	},
	
	"Ael.lang.Function#ael-timer [relative]" : function(){
		if(!Ael().global.setInterval
				|| userAgent.isDreamweaver()
				|| userAgent.isJaxer())
			return;
		
		this.expect({
			amount : 10,
			timeout : 5000
		});
		
		var self = this;
		var start = new Date();
		var count = 0;
		var task = Ael(function(){
			var c = new Date();
			var diff = c - start;
			self.assertWith(100, 150, diff);
			start = c;
			count++;
			if(10 <= count)
				Ael(task).abort();
		}).timer({
			ms : 100,
			interval : true
		});
	},
	
	"Ael.lang.Function#ael-timer [absolute]" : function(){
		if(!Ael().global.setInterval
				|| userAgent.isDreamweaver()
				|| userAgent.isJaxer())
			return;
		
		this.expect({
			amount : 1,
			timeout : 5000
		});
		
		var self = this;
		var start = new Date();
		var count = 0;
		var task = Ael(function(){
			count++;
			if(10 <= count){
				Ael(task).abort();
				var diff = new Date() - start;
				self.assertWith(1000, 1050, diff);
			}
		}).timer({
			ms : 100,
			interval : true,
			absolute : true
		});
	},
	
	"Ael.lang.Function#ael-try_" : function(){
		if(!Ael().global.setInterval
				|| userAgent.isDreamweaver()
				|| userAgent.isJaxer())
			return;
		
		this.expect({
			amount : 15,
			timeout : 3000
		});
		var self = this;
		var id = Ael(function(){
			window.aiueo.aiueo;
			eval("throw new Error()");
		}).try_({
			catch_: function(e){
				self.assertEquals("string", typeof e.name);
				self.assertEquals("string", typeof e.message);
				self.assertEquals("string", typeof e.stack);
				self.assertEquals("number", typeof e.line);
				self.assertEquals("string", typeof e.url);
			},
			ms : 1000
		});
		this.assertTrue(Ael.isNumber(id));
		
		id = Ael(function(){
			window.aiueo.aiueo;
			eval("throw new Error()");
		}).try_({
			catch_: function(e){
				self.assertEquals("string", typeof e.name);
				self.assertEquals("string", typeof e.message);
				self.assertEquals("string", typeof e.stack);
				self.assertEquals("number", typeof e.line);
				self.assertEquals("string", typeof e.url);
			},
			finally_: function(){
				self.assertTrue(true);
			},
			ms : 1050
		});
		this.assertTrue(Ael.isNumber(id));
		
		id = Ael(function(){
			window.aiueo.aiueo;
			eval("throw new Error()");
		}).try_({
			catch_:null,
			finally_: function(){
				self.assertTrue(true);
			},
			ms : 1100
		});
		this.assertTrue(Ael.isNumber(id));
	}
});

Ael.test({
	"Ael.lang.Task#ael-abort" : function(){
		if(!Ael().global.setInterval
				|| userAgent.isDreamweaver()
				|| userAgent.isJaxer())
			return;
		
		this.expect({
			amount : 1,
			timeout : 5000
		});
		
		var self = this;
		var task = Ael(function(){
			self.fail();
		}).timer({
			ms : 100,
			interval : true
		});
		Ael(task).abort();
		Ael(function(){
			self.assertTrue(true);
		}).timer({
			ms : 2000
		});
	}
});

Ael.test({
	"Ael.lang.Number#ael-isInteger" : function(){
		this.assertTrue(Ael(0).isInteger());
		this.assertTrue(Ael(1).isInteger());
		this.assertTrue(Ael(-1).isInteger());
		this.assertTrue(Ael(Number.MAX_VALUE).isInteger());
		this.assertFalse(Ael(Number.MIN_VALUE).isInteger());
		this.assertFalse(Ael(Number.POSITIVE_INFINITY).isInteger());
		this.assertFalse(Ael(Number.NEGATIVE_INFINITY).isInteger());
		this.assertFalse(Ael(0.1).isInteger());
		this.assertFalse(Ael(NaN).isInteger());
	},
	
	"Ael.lang.Number#ael-isDecimal" : function(){
		this.assertTrue(Ael(0.1).isDecimal());
		this.assertTrue(Ael(-1.1).isDecimal());
		this.assertTrue(Ael(Number.MIN_VALUE).isDecimal());
		this.assertFalse(Ael(0).isDecimal());
		this.assertFalse(Ael(Number.MAX_VALUE).isDecimal());
		this.assertFalse(Ael(Number.POSITIVE_INFINITY).isDecimal());
		this.assertFalse(Ael(Number.NEGATIVE_INFINITY).isDecimal());
		this.assertFalse(Ael(1).isDecimal());
		this.assertFalse(Ael(NaN).isDecimal());
	},
	
	"Ael.lang.Number#ael-toJSONString" : function(){
		this.assertEquals("0", Ael(0).toJSONString());
		this.assertEquals("1", Ael(1).toJSONString());
		this.assertEquals("0.1", Ael(0.1).toJSONString());
		this.assertEquals("-1.1", Ael(-1.1).toJSONString());
		this.assertEquals("5e-324", Ael(Number.MIN_VALUE).toJSONString());
		this.assertEquals("1.7976931348623157e+308", Ael(Number.MAX_VALUE).toJSONString());
		this.assertEquals("", Ael(Number.POSITIVE_INFINITY).toJSONString());
		this.assertEquals("", Ael(Number.NEGATIVE_INFINITY).toJSONString());
		this.assertEquals("", Ael(NaN).toJSONString());
	}
});

Ael.test({
	"Ael.lang.Null#ael-toJSONString" : function(){
		this.assertEquals("null", Ael(null).toJSONString());
	}
});

Ael.test({
	"Ael.lang.RegExp#ael-clone" : function(){
/*
		if(userAgent.isIE()){
			this.assertEquals("/^[\\w_]*.+ ?/igm", Ael(/^[\w_]*.+ ?/igm).clone().toString());
			this.assertEquals("/^[\\w_]*.+ ?/igm", Ael(new RegExp("^[\\w_]*.+ ?", "igm")).clone().toString());
		}else{
			this.assertEquals("/^[\\w_]*.+ ?/gim", Ael(/^[\w_]*.+ ?/igm).clone().toString());
			this.assertEquals("/^[\\w_]*.+ ?/gim", Ael(new RegExp("^[\\w_]*.+ ?", "igm")).clone().toString());
		}
*/
	},
	
	"Ael.lang.RegExp#ael-test" : function(){
		var r = true, e = Ael(/([a-z])/gi);
		for(var i=0; i<10; i++)
			r = r && e.test("a i u e o");
		this.assertEquals(10, i);
		this.assertTrue(r);
		this.assertFalse(e.test("1"));
	}
});

Ael.test({
	"Ael.lang.String#ael-each" : function(){
		var tester = this, result = [];
		this.assertEquals(void 0, Ael("").each(function(v, i){
			result[result.length] = v;
		}));
		this.assertArrayEquals([], result);
		
		result = [];
		this.assertEquals(void 0, Ael("abcd").each(function(v, i){
			tester.assertEquals(result.length, i);
			result[result.length] = v;
		}));
		this.assertArrayEquals(["a", "b", "c", "d"], result);
		
		result = [];
		this.assertEquals(void 0, Ael("abcd").each(function(v, i){
			if(2 < i)
				return v;
			result[result.length] = v;
		}));
		this.assertArrayEquals(["a", "b", "c"], result);
		
		var s = "", expected = [];
		for(var i=0; i<257; i++)
			s += expected[expected.length] = String.fromCharCode(i);
		result = [];
		this.assertEquals(void 0, Ael(s).each(function(v, i){
			result[result.length] = v;
		}));
		this.assertArrayEquals(expected, result);
	},
	
	"Ael.lang.String#ael-endsWith" : function(){
		this.assertTrue(Ael("1").endsWith("1"));
		this.assertTrue(Ael("123aiueo").endsWith("aiueo"));
		this.assertTrue(Ael("1").endsWith(""));
		this.assertTrue(Ael("").endsWith(""));
		this.assertFalse(Ael("123aiueo").endsWith("e"));
		this.assertFalse(Ael("").endsWith(0));
		this.assertFalse(Ael("").endsWith(NaN));
		this.assertFalse(Ael("").endsWith(Number.POSITIVE_INFINITY));
		this.assertFalse(Ael("").endsWith(Number.NEGATIVE_INFINITY));
		this.assertFalse(Ael("").endsWith([]));
		this.assertFalse(Ael("").endsWith({}));
		this.assertFalse(Ael("").endsWith(null));
		this.assertFalse(Ael("").endsWith(void 0));
	},
	
	"Ael.lang.String#ael-format" : function(){
		this.assertEquals("", Ael("").format());
		this.assertEquals("undefined", Ael("{0}").format());
		this.assertEquals("undefined", Ael("{9999999999999999999999999999999999999999999999999}").format());
		this.assertEquals("aiueo", Ael("aiueo").format());
		this.assertEquals("{０}", Ael("{０}").format("a"));
		this.assertEquals("a[0]i[2]u[1]e[3]o[2]", Ael("a{0}i{2}u{1}e{3}o{2}").format("[0]","[1]","[2]","[3]"));
		this.assertEquals("a[null]i[undefined]u[NaN]e[[object Object]]o", Ael("a[{0}]i[{1}]u[{2}]e[{3}]o").format(null, void 0, NaN, {}));
		if(userAgent.isAIR()){
			this.assertEquals("a[true]i[false]u[123]e[" + function(){}.toString() + "]o", Ael("a[{0}]i[{1}]u[{2}]e[{3}]o").format(true, false, 123, function(){}));
		}else{
			this.assertEquals("a[true]i[false]u[123]e[" + new Function().toString() + "]o", Ael("a[{0}]i[{1}]u[{2}]e[{3}]o").format(true, false, 123, new Function()));
		}
		var a = Ael("{0}");
		for(var i=0; i<257; i++){
			var s = String.fromCharCode(i);
			this.assertEquals(s, a.format(s));
		} 
	},
	
	"Ael.lang.String#ael-indexOf" : function(){
		var s = Ael("aiueo");
		this.assertEquals(0, s.indexOf("a"));
		this.assertEquals(1, s.indexOf("iu"));
		this.assertEquals(3, s.indexOf("e"));
		this.assertEquals(4, s.indexOf("o"));
		this.assertEquals(0, Ael("").indexOf(""));
		this.assertEquals(0, s.indexOf("a", 0));
		this.assertEquals(-1, s.indexOf("a", 1));
		this.assertEquals(-1, s.indexOf("a", 5));
		this.assertEquals(-1, s.indexOf("a", 5.01));
		this.assertEquals(-1, s.indexOf("a", 4.99));
		this.assertEquals(-1, s.indexOf("a", 2147483648));
		this.assertEquals(0, s.indexOf("a", -2147483647));
		this.assertEquals(1, s.indexOf("i", true));
		this.assertEquals(0, s.indexOf("a", false));
		this.assertEquals(0, s.indexOf("a", null));
		this.assertEquals(0, s.indexOf("a", void 0));
		this.assertEquals(0, s.indexOf("a", NaN));
		this.assertEquals(0, s.indexOf("a", Number.POSITIVE_INFINITY));
		this.assertEquals(0, s.indexOf("a", Number.NEGATIVE_INFINITY));
		this.assertEquals(0, s.indexOf("", true));
		this.assertEquals(0, s.indexOf("", false));
		this.assertEquals(0, s.indexOf("", null));
		this.assertEquals(0, s.indexOf("", void 0));
		this.assertEquals(0, s.indexOf("", NaN));
		this.assertEquals(0, s.indexOf("", Number.POSITIVE_INFINITY));
		this.assertEquals(0, s.indexOf("", Number.NEGATIVE_INFINITY));
		this.assertEquals(-1, s.indexOf("a".charCodeAt(0)));
		this.assertEquals(-1, s.indexOf(null));
		this.assertEquals(-1, s.indexOf(void 0));
		this.assertEquals(-1, s.indexOf(NaN));
		for(var i=0; i<257; i++){
			var s = String.fromCharCode(i);
			this.assertEquals(0, Ael(s + "a").indexOf(s));
		}
	},
	
	"Ael.lang.String#ael-isEmpty" : function(){
		this.assertTrue(Ael("").isEmpty());
		this.assertTrue(Ael(new String("")).isEmpty());
		this.assertFalse(Ael("a").isEmpty());
		this.assertFalse(Ael(new String("a")).isEmpty());
	},
	
	"Ael.lang.String#ael-lastIndexOf" : function(){
		var s = Ael("aiueo");
		this.assertEquals(0, s.lastIndexOf("a"));
		this.assertEquals(1, s.lastIndexOf("iu"));
		this.assertEquals(3, s.lastIndexOf("e"));
		this.assertEquals(4, s.lastIndexOf("o"));
		this.assertEquals(0, Ael("").lastIndexOf(""));
		this.assertEquals(4, s.lastIndexOf("o", 4));
		this.assertEquals(-1, s.lastIndexOf("o", 3));
		this.assertEquals(-1, s.lastIndexOf("o", 0));
		this.assertEquals(-1, s.lastIndexOf("o", -5));
		this.assertEquals(1, s.lastIndexOf("i", true));
		this.assertEquals(0, s.lastIndexOf("a", false));
		this.assertEquals(0, s.lastIndexOf("a", null));
		this.assertEquals(0, s.lastIndexOf("a", void 0));
		this.assertEquals(0, s.lastIndexOf("a", NaN));
		this.assertEquals(0, s.lastIndexOf("a", Number.POSITIVE_INFINITY));
		this.assertEquals(0, s.lastIndexOf("a", Number.NEGATIVE_INFINITY));
		this.assertEquals(-1, s.lastIndexOf("o".charCodeAt(0)));
		this.assertEquals(-1, s.lastIndexOf(null));
		this.assertEquals(-1, s.lastIndexOf(void 0));
		this.assertEquals(-1, s.lastIndexOf(NaN));
		for(var i=0; i<257; i++){
			var s = String.fromCharCode(i);
			this.assertEquals(0, Ael(s).lastIndexOf(s));
		}
	},
	
	"Ael.lang.String#ael-size" : function(){
		this.assertEquals(0, Ael("").size());
		this.assertEquals(1, Ael("1").size());
		this.assertEquals(5, Ael("aiueo").size());
		var v = "";
		for(var i=0; i<500; i++)
			v += "0123456789";
		this.assertEquals(5000, Ael(v).size());
	},
	
	"Ael.lang.String#ael-startsWith" : function(){
		this.assertTrue(Ael("1").startsWith("1"));
		this.assertTrue(Ael("123aiueo").startsWith("123"));
		this.assertTrue(Ael("1").startsWith(""));
		this.assertTrue(Ael("").startsWith(""));
		this.assertFalse(Ael("123aiueo").startsWith("2"));
		this.assertFalse(Ael("").startsWith(0));
		this.assertFalse(Ael("").startsWith(NaN));
		this.assertFalse(Ael("").startsWith(Number.POSITIVE_INFINITY));
		this.assertFalse(Ael("").startsWith(Number.NEGATIVE_INFINITY));
		this.assertFalse(Ael("").startsWith([]));
		this.assertFalse(Ael("").startsWith({}));
		this.assertFalse(Ael("").startsWith(null));
		this.assertFalse(Ael("").startsWith(void 0));
	},
	
	"Ael.lang.String#ael-toJSONString" : function(){
		this.assertEquals('""', Ael("").toJSONString());
		this.assertEquals('"\\u0061\\u0069\\u0075\\u0065\\u006f"', Ael("aiueo").toJSONString());
		var meta = {
			"\\u0008" : "\\b",
			"\\u0009" : "\\t",
			"\\u000a" : "\\n",
			"\\u000c" : "\\f",
			"\\u000d" : "\\r",
			"\\u0022" : "\\\"",
			"\\u002f" : "\\/",
			"\\u005c" : "\\\\"
		};
		for(var i=0; i<257; i++){
			var s = String.fromCharCode(i);
			var c = "000" + i.toString(16);
			c = "\\u" + c.substring(c.length - 4);
			var len = meta[c]?4:8;
			c = meta[c] || c;
			var a = Ael(s);
			var j = a.toJSONString();
			this.assertEquals(len, j.length);
			this.assertEquals('"'+ c +'"', j);
			if(!Ael.isUndefined(Ael().global["json_parse"])){
				this.assertEquals(JSON.stringify(s).replace("/", "\\/"), a.toJSONString(true));
				this.assertEquals(s, json_parse(j));
			}
		}
		this.assertEquals('"\\"\\/\\b\\f\\n\\r\\t\\\\"', Ael("\"\/\b\f\n\r\t\\").toJSONString());
		this.assertEquals('"\\"\\/\\b\\f\\n\\r\\t\\\\"', Ael("\"\/\b\f\n\r\t\\").toJSONString(true));
		this.assertEquals('"\\u0061\\u0069\\u0075\\u0065\\u006f\\u3042\\u3044\\u3046\\u3048\\u304a"', Ael("aiueoあいうえお").toJSONString());
		this.assertEquals('"aiueoあいうえお"', Ael("aiueoあいうえお").toJSONString(true));
	},
	
	"Ael.lang.String#ael-trim" : function(){
		this.assertEquals("", Ael("").trim());
		this.assertEquals("\naiueo\n", Ael("  \naiueo\n  ").trim());
		this.assertEquals("\naiueo\n", Ael(new String("  \naiueo\n  ")).trim());
		this.assertEquals("2", Ael(" 2 ").trim(2));
		this.assertEquals("aiueo", Ael("\t  \naiueo\n \t ").trim(" \t\n"));
		this.assertEquals("", Ael("\t \n aiueo\n \t ").trim(" \t\naiueo"));
		this.assertEquals("\naiueo\n", Ael("  \naiueo\n  ").trim(void 0));
		this.assertEquals("\naiueo\n", Ael("  \naiueo\n  ").trim(null));
		this.assertEquals("NaN", Ael("NaN").trim(NaN));
	}
});

Ael.test({
	"Ael.lang.Undefined#ael-toJSONString" : function(){
		this.assertEquals("", Ael(void 0).toJSONString());
	}
});

Ael.test({
	"Ael.lang.Class#ael-ael" : function(){
		this.assertEquals(Ael(Ael).properties()["ael void each"], Ael(Ael).ael("each"));
		this.assertEquals(void 0, Ael(Ael).ael("aiueo"));
	},
	
	"Ael.lang.Class#ael-instance" : function(){
		this.assertEquals(Ael(Ael.test.Assert).properties()["instance successful"], Ael(Ael.test.Assert).instance("successful"));
		this.assertEquals(void 0, Ael(Ael.test.Assert).instance("aiueo"));
	},
	
	"Ael.lang.Class#ael-prototype" : function(){
		this.assertEquals(Ael(Ael.test.Assert).properties()["prototype initialize"], Ael(Ael.test.Assert).prototype("initialize"));
		this.assertEquals(void 0, Ael(Ael.test.Assert).prototype("aiueo"));
	},
	
	"Ael.lang.Class#ael-static_" : function(){
		this.assertEquals(Ael(Ael).properties()["static isObject"], Ael(Ael).static_("isObject"));
		this.assertEquals(void 0, Ael(Ael.test.Assert).static_("aiueo"));
	}
});

Ael.test({
	"Ael.extend" : function(){
		var N = Ael.namespace();
		this.assertEquals(void 0, N("").aiueo);
		
		N.extend().install({
			id: "test.Ael.extend",
			version: 0.1,
			fn: function(Ael){
				Ael(Ael.lang.String).properties({
					"ael aiueo": function(){
						return "aiueo";
					}
				});
			}
		});
		N.extend("test.Ael.extend");
		this.assertEquals("aiueo", N("").aiueo());
		this.assertEquals(void 0, N(0).aiueo);
		
		N.extend().install({
			id: "test.Ael.extend",
			version: 0.2,
			fn: function(Ael){
				Ael(Ael.lang.String).properties({
					"ael aiueo": function(){
						return "12345";
					}
				});
				Ael(Ael.lang.Number).properties({
					"ael kakiku": function(){
						return "kakiku";
					}
				});
			}
		});
		N.extend("test.Ael.a");
		N.extend("test.Ael.a","test.Ael.b");
		this.assertEquals("aiueo", N("").aiueo());
		N.extend("test.Ael.extend");
		this.assertEquals("12345", N("").aiueo());
		this.assertEquals("kakiku", N(0).kakiku());
	},
	
	"Ael.extend#static-install" : function(){
		var N = Ael.namespace();
		N.extend().install({
			id: "test.Ael.extend.install1",
			version: 0.1,
			fn: function(Ael){
				Ael(Ael.lang.String).properties({
					"ael install1": function(){
						return "install1";
					}
				});
			}
		});
		N.extend().install({
			id: "test.Ael.extend.install2",
			fn: function(Ael){
				Ael(Ael.lang.String).properties({
					"ael install2": function(){
						return "install2";
					}
				});
			}
		});
		N.extend().install({
			id: "test.Ael.extend.install3",
			version: 0.1,
			dependencies: ["test.Ael.extend.install1","test.Ael.extend.install2"],
			fn: function(Ael){
				Ael(Ael.lang.String).properties({
					"ael install3": function(){
						return "install3";
					}
				});
			}
		});
		this.assertArrayEquals(
				[void 0,void 0,void 0],
				[N("").install1,N("").install2,N("").install3]);
		
		N.extend("test.Ael.extend.install1");
		this.assertArrayEquals(
				["install1",void 0,void 0],
				[N("").install1(),N("").install2,N("").install3]);
		
		N.extend("test.Ael.extend.install3");
		this.assertArrayEquals(
				["install1","install2","install3"],
				[N("").install1(),N("").install2(),N("").install3()]);
	}
});
