You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2007/08/25 01:47:38 UTC

svn commit: r569576 [3/10] - in /struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo: ./ src/ src/animation/ src/cal/ src/charting/ src/charting/svg/ src/charting/vml/ src/collections/ src/crypto/ src/data/ src/data/core...

Modified: struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js?rev=569576&r1=569575&r2=569576&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js (original)
+++ struts/struts2/trunk/plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js Fri Aug 24 16:47:20 2007
@@ -99,8 +99,8 @@
 //TODOC:  HOW TO DOC THIS?
 dojo.version = {
 	// summary: version number of this instance of dojo.
-	major: 0, minor: 4, patch: 2, flag: "",
-	revision: Number("$Rev: 7616 $".match(/[0-9]+/)[0]),
+	major: 0, minor: 4, patch: 3, flag: "",
+	revision: Number("$Rev: 8617 $".match(/[0-9]+/)[0]),
 	toString: function(){
 		with(dojo.version){
 			return major + "." + minor + "." + patch + flag + " (" + revision + ")";	// String
@@ -1390,8 +1390,10 @@
 		return true;
 	}
 
+	dojo.hostenv._djInitFired = false;
 	//	BEGIN DOMContentLoaded, from Dean Edwards (http://dean.edwards.name/weblog/2006/06/again/)
 	function dj_load_init(e){
+		dojo.hostenv._djInitFired = true;
 		// allow multiple calls, only first one will take effect
 		// A bug in khtml calls events callbacks for document for event which isnt supported
 		// for example a created contextmenu event calls DOMContentLoaded, workaround
@@ -1658,6 +1660,78 @@
 dojo.requireIf(djConfig["debugAtAllCosts"] && !window.widget && !djConfig["useXDomain"], "dojo.browser_debug");
 dojo.requireIf(djConfig["debugAtAllCosts"] && !window.widget && djConfig["useXDomain"], "dojo.browser_debug_xd");
 
+dojo.provide("dojo.string.common");
+
+dojo.string.trim = function(/* string */str, /* integer? */wh){
+	//	summary
+	//	Trim whitespace from str.  If wh > 0, trim from start, if wh < 0, trim from end, else both
+	if(!str.replace){ return str; }
+	if(!str.length){ return str; }
+	var re = (wh > 0) ? (/^\s+/) : (wh < 0) ? (/\s+$/) : (/^\s+|\s+$/g);
+	return str.replace(re, "");	//	string
+}
+
+dojo.string.trimStart = function(/* string */str) {
+	//	summary
+	//	Trim whitespace at the beginning of 'str'
+	return dojo.string.trim(str, 1);	//	string
+}
+
+dojo.string.trimEnd = function(/* string */str) {
+	//	summary
+	//	Trim whitespace at the end of 'str'
+	return dojo.string.trim(str, -1);
+}
+
+dojo.string.repeat = function(/* string */str, /* integer */count, /* string? */separator) {
+	//	summary
+	//	Return 'str' repeated 'count' times, optionally placing 'separator' between each rep
+	var out = "";
+	for(var i = 0; i < count; i++) {
+		out += str;
+		if(separator && i < count - 1) {
+			out += separator;
+		}
+	}
+	return out;	//	string
+}
+
+dojo.string.pad = function(/* string */str, /* integer */len/*=2*/, /* string */ c/*='0'*/, /* integer */dir/*=1*/) {
+	//	summary
+	//	Pad 'str' to guarantee that it is at least 'len' length with the character 'c' at either the 
+	//	start (dir=1) or end (dir=-1) of the string
+	var out = String(str);
+	if(!c) {
+		c = '0';
+	}
+	if(!dir) {
+		dir = 1;
+	}
+	while(out.length < len) {
+		if(dir > 0) {
+			out = c + out;
+		} else {
+			out += c;
+		}
+	}
+	return out;	//	string
+}
+
+dojo.string.padLeft = function(/* string */str, /* integer */len, /* string */c) {
+	//	summary
+	//	same as dojo.string.pad(str, len, c, 1)
+	return dojo.string.pad(str, len, c, 1);	//	string
+}
+
+dojo.string.padRight = function(/* string */str, /* integer */len, /* string */c) {
+	//	summary
+	//	same as dojo.string.pad(str, len, c, -1)
+	return dojo.string.pad(str, len, c, -1);	//	string
+}
+
+dojo.provide("dojo.string");
+
+
 dojo.provide("dojo.lang.common");
 
 dojo.lang.inherits = function(/*Function*/subclass, /*Function*/superclass){
@@ -1902,364 +1976,91 @@
 
 // end Crockford functions
 
-dojo.provide("dojo.lang.array");
+dojo.provide("dojo.lang.extras");
 
 
 
-// FIXME: Is this worthless since you can do: if(name in obj)
-// is this the right place for this?
+dojo.lang.setTimeout = function(/*Function*/func, /*int*/delay /*, ...*/){
+	// summary:
+	//		Sets a timeout in milliseconds to execute a function in a given
+	//		context with optional arguments.
+	// usage:
+	//		dojo.lang.setTimeout(Object context, function func, number delay[, arg1[, ...]]);
+	//		dojo.lang.setTimeout(function func, number delay[, arg1[, ...]]);
 
-dojo.lang.mixin(dojo.lang, {
-	has: function(/*Object*/obj, /*String*/name){
-		// summary: is there a property with the passed name in obj?
-		try{
-			return typeof obj[name] != "undefined"; // Boolean
-		}catch(e){ return false; } // Boolean
-	},
+	var context = window, argsStart = 2;
+	if(!dojo.lang.isFunction(func)){
+		context = func;
+		func = delay;
+		delay = arguments[2];
+		argsStart++;
+	}
 
-	isEmpty: function(/*Object*/obj){
-		// summary:
-		//		can be used to determine if the passed object is "empty". In
-		//		the case of array-like objects, the length, property is
-		//		examined, but for other types of objects iteration is used to
-		//		examine the iterable "surface area" to determine if any
-		//		non-prototypal properties have been assigned. This iteration is
-		//		prototype-extension safe.
-		if(dojo.lang.isObject(obj)){
-			var tmp = {};
-			var count = 0;
-			for(var x in obj){
-				if(obj[x] && (!tmp[x])){
-					count++;
-					break;
-				} 
-			}
-			return count == 0; // boolean
-		}else if(dojo.lang.isArrayLike(obj) || dojo.lang.isString(obj)){
-			return obj.length == 0; // boolean
-		}
-	},
+	if(dojo.lang.isString(func)){
+		func = context[func];
+	}
+	
+	var args = [];
+	for (var i = argsStart; i < arguments.length; i++){
+		args.push(arguments[i]);
+	}
+	return dojo.global().setTimeout(function(){ func.apply(context, args); }, delay); // int
+}
 
-	map: function(/*Array*/arr, /*Object|Function*/obj, /*Function?*/unary_func){
-		// summary:
-		//		returns a new array constituded from the return values of
-		//		passing each element of arr into unary_func. The obj parameter
-		//		may be passed to enable the passed function to be called in
-		//		that scope. In environments that support JavaScript 1.6, this
-		//		function is a passthrough to the built-in map() function
-		//		provided by Array instances. For details on this, see:
-		// 			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map
-		// examples:
-		//		dojo.lang.map([1, 2, 3, 4], function(item){ return item+1 });
-		//		// returns [2, 3, 4, 5]
-		var isString = dojo.lang.isString(arr);
-		if(isString){
-			// arr: String
-			arr = arr.split("");
-		}
-		if(dojo.lang.isFunction(obj)&&(!unary_func)){
-			unary_func = obj;
-			obj = dj_global;
-		}else if(dojo.lang.isFunction(obj) && unary_func){
-			// ff 1.5 compat
-			var tmpObj = obj;
-			obj = unary_func;
-			unary_func = tmpObj;
+dojo.lang.clearTimeout = function(/*int*/timer){
+	// summary: clears timer by number from the execution queue
+
+	// FIXME:
+	//		why do we have this function? It's not portable outside of browser
+	//		environments and it's a stupid wrapper on something that browsers
+	//		provide anyway.
+	dojo.global().clearTimeout(timer);
+}
+
+dojo.lang.getNameInObj = function(/*Object*/ns, /*unknown*/item){
+	// summary: 
+	//		looks for a value in the object ns with a value matching item and
+	//		returns the property name
+	// ns: if null, dj_global is used
+	// item: value to return a name for
+	if(!ns){ ns = dj_global; }
+
+	for(var x in ns){
+		if(ns[x] === item){
+			return new String(x); // String
 		}
-		if(Array.map){
-			var outArr = Array.map(arr, unary_func, obj);
-		}else{
-			var outArr = [];
-			for(var i=0;i<arr.length;++i){
-				outArr.push(unary_func.call(obj, arr[i]));
+	}
+	return null; // null
+}
+
+dojo.lang.shallowCopy = function(/*Object*/obj, /*Boolean?*/deep){
+	// summary:
+	//		copies object obj one level deep, or full depth if deep is true
+	var i, ret;	
+
+	if(obj === null){ /*obj: null*/ return null; } // null
+	
+	if(dojo.lang.isObject(obj)){
+		// obj: Object	
+		ret = new obj.constructor();
+		for(i in obj){
+			if(dojo.lang.isUndefined(ret[i])){
+				ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i];
 			}
 		}
-		if(isString) {
-			return outArr.join(""); // String
-		} else {
-			return outArr; // Array
+	}else if(dojo.lang.isArray(obj)){
+		// obj: Array
+		ret = [];
+		for(i=0; i<obj.length; i++){
+			ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i];
 		}
-	},
+	}else{
+		// obj: Object
+		ret = obj;
+	}
 
-	reduce: function(/*Array*/arr, initialValue, /*Object|Function*/obj, /*Function*/binary_func){
-		// summary:
-		// 		similar to Python's builtin reduce() function. The result of
-		// 		the previous computation is passed as the first argument to
-		// 		binary_func along with the next value from arr. The result of
-		// 		this call is used along with the subsequent value from arr, and
-		// 		this continues until arr is exhausted. The return value is the
-		// 		last result. The "obj" and "initialValue" parameters may be
-		// 		safely omitted and the order of obj and binary_func may be
-		// 		reversed. The default order of the obj and binary_func argument
-		// 		will probably be reversed in a future release, and this call
-		// 		order is supported today.
-		// examples:
-		//		dojo.lang.reduce([1, 2, 3, 4], function(last, next){ return last+next});
-		//		returns 10
-		var reducedValue = initialValue;
-		if(arguments.length == 2){
-			binary_func = initialValue;
-			reducedValue = arr[0];
-			arr = arr.slice(1);
-		}else if(arguments.length == 3){
-			if(dojo.lang.isFunction(obj)){
-				binary_func = obj;
-				obj = null;
-			}
-		}else{
-			// un-fsck the default order
-			// FIXME:
-			//		could be wrong for some strange function object cases. Not
-			//		sure how to test for them.
-			if(dojo.lang.isFunction(obj)){
-				var tmp = binary_func;
-				binary_func = obj;
-				obj = tmp;
-			}
-		}
-
-		var ob = obj || dj_global;
-		dojo.lang.map(arr, 
-			function(val){
-				reducedValue = binary_func.call(ob, reducedValue, val);
-			}
-		);
-		return reducedValue;
-	},
-
-	forEach: function(/*Array*/anArray, /*Function*/callback, /*Object?*/thisObject){
-		// summary:
-		//		for every item in anArray, call callback with that item as its
-		//		only parameter. Return values are ignored. This funciton
-		//		corresponds (and wraps) the JavaScript 1.6 forEach method. For
-		//		more details, see:
-		//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach
-		if(dojo.lang.isString(anArray)){
-			// anArray: String
-			anArray = anArray.split(""); 
-		}
-		if(Array.forEach){
-			Array.forEach(anArray, callback, thisObject);
-		}else{
-			// FIXME: there are several ways of handilng thisObject. Is dj_global always the default context?
-			if(!thisObject){
-				thisObject=dj_global;
-			}
-			for(var i=0,l=anArray.length; i<l; i++){ 
-				callback.call(thisObject, anArray[i], i, anArray);
-			}
-		}
-	},
-
-	_everyOrSome: function(/*Boolean*/every, /*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
-		if(dojo.lang.isString(arr)){ 
-			//arr: String
-			arr = arr.split(""); 
-		}
-		if(Array.every){
-			return Array[ every ? "every" : "some" ](arr, callback, thisObject);
-		}else{
-			if(!thisObject){
-				thisObject = dj_global;
-			}
-			for(var i=0,l=arr.length; i<l; i++){
-				var result = callback.call(thisObject, arr[i], i, arr);
-				if(every && !result){
-					return false; // Boolean
-				}else if((!every)&&(result)){
-					return true; // Boolean
-				}
-			}
-			return Boolean(every); // Boolean
-		}
-	},
-
-	every: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
-		// summary:
-		//		determines whether or not every item in the array satisfies the
-		//		condition implemented by callback. thisObject may be used to
-		//		scope the call to callback. The function signature is derived
-		//		from the JavaScript 1.6 Array.every() function. More
-		//		information on this can be found here:
-		//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every
-		// examples:
-		//		dojo.lang.every([1, 2, 3, 4], function(item){ return item>1; });
-		//		// returns false
-		//		dojo.lang.every([1, 2, 3, 4], function(item){ return item>0; });
-		//		// returns true 
-		return this._everyOrSome(true, arr, callback, thisObject); // Boolean
-	},
-
-	some: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
-		// summary:
-		//		determines whether or not any item in the array satisfies the
-		//		condition implemented by callback. thisObject may be used to
-		//		scope the call to callback. The function signature is derived
-		//		from the JavaScript 1.6 Array.some() function. More
-		//		information on this can be found here:
-		//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
-		// examples:
-		//		dojo.lang.some([1, 2, 3, 4], function(item){ return item>1; });
-		//		// returns true
-		//		dojo.lang.some([1, 2, 3, 4], function(item){ return item<1; });
-		//		// returns false
-		return this._everyOrSome(false, arr, callback, thisObject); // Boolean
-	},
-
-	filter: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
-		// summary:
-		//		returns a new Array with those items from arr that match the
-		//		condition implemented by callback.thisObject may be used to
-		//		scope the call to callback. The function signature is derived
-		//		from the JavaScript 1.6 Array.filter() function, although
-		//		special accomidation is made in our implementation for strings.
-		//		More information on the JS 1.6 API can be found here:
-		//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter
-		// examples:
-		//		dojo.lang.some([1, 2, 3, 4], function(item){ return item>1; });
-		//		// returns [2, 3, 4]
-		var isString = dojo.lang.isString(arr);
-		if(isString){ /*arr: String*/arr = arr.split(""); }
-		var outArr;
-		if(Array.filter){
-			outArr = Array.filter(arr, callback, thisObject);
-		}else{
-			if(!thisObject){
-				if(arguments.length >= 3){ dojo.raise("thisObject doesn't exist!"); }
-				thisObject = dj_global;
-			}
-
-			outArr = [];
-			for(var i = 0; i < arr.length; i++){
-				if(callback.call(thisObject, arr[i], i, arr)){
-					outArr.push(arr[i]);
-				}
-			}
-		}
-		if(isString){
-			return outArr.join(""); // String
-		} else {
-			return outArr; // Array
-		}
-	},
-
-	unnest: function(/* ... */){
-		// summary:
-		//		Creates a 1-D array out of all the arguments passed,
-		//		unravelling any array-like objects in the process
-		// usage:
-		//		unnest(1, 2, 3) ==> [1, 2, 3]
-		//		unnest(1, [2, [3], [[[4]]]]) ==> [1, 2, 3, 4]
-
-		var out = [];
-		for(var i = 0; i < arguments.length; i++){
-			if(dojo.lang.isArrayLike(arguments[i])){
-				var add = dojo.lang.unnest.apply(this, arguments[i]);
-				out = out.concat(add);
-			}else{
-				out.push(arguments[i]);
-			}
-		}
-		return out; // Array
-	},
-
-	toArray: function(/*Object*/arrayLike, /*Number*/startOffset){
-		// summary:
-		//		Converts an array-like object (i.e. arguments, DOMCollection)
-		//		to an array. Returns a new Array object.
-		var array = [];
-		for(var i = startOffset||0; i < arrayLike.length; i++){
-			array.push(arrayLike[i]);
-		}
-		return array; // Array
-	}
-});
-
-dojo.provide("dojo.lang.extras");
-
-
-
-dojo.lang.setTimeout = function(/*Function*/func, /*int*/delay /*, ...*/){
-	// summary:
-	//		Sets a timeout in milliseconds to execute a function in a given
-	//		context with optional arguments.
-	// usage:
-	//		dojo.lang.setTimeout(Object context, function func, number delay[, arg1[, ...]]);
-	//		dojo.lang.setTimeout(function func, number delay[, arg1[, ...]]);
-
-	var context = window, argsStart = 2;
-	if(!dojo.lang.isFunction(func)){
-		context = func;
-		func = delay;
-		delay = arguments[2];
-		argsStart++;
-	}
-
-	if(dojo.lang.isString(func)){
-		func = context[func];
-	}
-	
-	var args = [];
-	for (var i = argsStart; i < arguments.length; i++){
-		args.push(arguments[i]);
-	}
-	return dojo.global().setTimeout(function(){ func.apply(context, args); }, delay); // int
-}
-
-dojo.lang.clearTimeout = function(/*int*/timer){
-	// summary: clears timer by number from the execution queue
-
-	// FIXME:
-	//		why do we have this function? It's not portable outside of browser
-	//		environments and it's a stupid wrapper on something that browsers
-	//		provide anyway.
-	dojo.global().clearTimeout(timer);
-}
-
-dojo.lang.getNameInObj = function(/*Object*/ns, /*unknown*/item){
-	// summary: 
-	//		looks for a value in the object ns with a value matching item and
-	//		returns the property name
-	// ns: if null, dj_global is used
-	// item: value to return a name for
-	if(!ns){ ns = dj_global; }
-
-	for(var x in ns){
-		if(ns[x] === item){
-			return new String(x); // String
-		}
-	}
-	return null; // null
-}
-
-dojo.lang.shallowCopy = function(/*Object*/obj, /*Boolean?*/deep){
-	// summary:
-	//		copies object obj one level deep, or full depth if deep is true
-	var i, ret;	
-
-	if(obj === null){ /*obj: null*/ return null; } // null
-	
-	if(dojo.lang.isObject(obj)){
-		// obj: Object	
-		ret = new obj.constructor();
-		for(i in obj){
-			if(dojo.lang.isUndefined(ret[i])){
-				ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i];
-			}
-		}
-	}else if(dojo.lang.isArray(obj)){
-		// obj: Array
-		ret = [];
-		for(i=0; i<obj.length; i++){
-			ret[i] = deep ? dojo.lang.shallowCopy(obj[i], deep) : obj[i];
-		}
-	}else{
-		// obj: Object
-		ret = obj;
-	}
-
-	return ret; // Object
-}
+	return ret; // Object
+}
 
 dojo.lang.firstValued = function(/* ... */){
 	// summary: Return the first argument that isn't undefined
@@ -2309,4781 +2110,5364 @@
 	}
 }
 
-dojo.provide("dojo.lang.declare");
-
-
+dojo.provide("dojo.io.common");
 
 
-dojo.lang.declare = function(	/*String*/ className, 
-								/*Function|Array*/ superclass, 
-								/*Function?*/ init, 
-								/*Object|Array*/ props){
-	/*
-	 *	summary: Create a feature-rich constructor with a compact notation
-	 *	className: the name of the constructor (loosely, a "class")
-	 * 	superclass:
-	 *		may be a Function, or an Array of Functions. If "superclass" is an
-	 *		array, the first element is used as the prototypical ancestor and
-	 *		any following Functions become mixin ancestors.
-	 *	init: an initializer function
-	 *	props:
-	 *		an object (or array of objects) whose properties are copied to the
-	 *		created prototype
-	 *	description:
-	 *		Create a constructor using a compact notation for inheritance and
-	 *		prototype extension. "superclass" argument may be a Function, or an
-	 *		array of Functions. 
-	 *
-	 *		If "superclass" is an array, the first element is used as the
-	 *		prototypical ancestor and any following Functions become mixin
-	 *		ancestors. 
-	 * 
-	 *		All "superclass(es)" must be Functions (not mere Objects).
-	 *
-	 *		Using mixin ancestors provides a type of multiple inheritance.
-	 *		Mixin ancestors prototypical properties are copied to the subclass,
-	 *		and any inializater/constructor is invoked. 
-	 *
-	 *		Properties of object "props" are copied to the constructor
-	 *		prototype. If "props" is an array, properties of each object in the
-	 *		array are copied to the constructor prototype.
-	 *
-	 *		name of the class ("className" argument) is stored in
-	 *		"declaredClass" property
-	 * 
-	 *		Initializer functions are called when an object is instantiated
-	 *		from this constructor.
-	 * 
-	 *		Aliased as "dojo.declare"
-	 *
-	 * Usage:
-	 *
-	 *		dojo.declare("my.classes.bar", my.classes.foo,
-	 *			function(){
-	 *				// initialization function
-	 *				this.myComplicatedObject = new ReallyComplicatedObject(); 
-	 *			},
-	 *			{ // properties to be added to the class prototype
-	 *				someValue: 2,
-	 *				someMethod: function(){ 
-	 *					doStuff(); 
-	 *				}
-	 *			}
-	 *		);
-	 *
-	 */
-	if((dojo.lang.isFunction(props))||((!props)&&(!dojo.lang.isFunction(init)))){ 
-		// parameter juggling to support omitting init param (also allows
-		// reordering init and props arguments)
-		var temp = props;
-		props = init;
-		init = temp;
-	}	
-	var mixins = [ ];
-	if(dojo.lang.isArray(superclass)){
-		mixins = superclass;
-		superclass = mixins.shift();
-	}
-	if(!init){
-		init = dojo.evalObjPath(className, false);
-		if((init)&&(!dojo.lang.isFunction(init))){ init = null };
-	}
-	var ctor = dojo.lang.declare._makeConstructor();
-	var scp = (superclass ? superclass.prototype : null);
-	if(scp){
-		scp.prototyping = true;
-		ctor.prototype = new superclass();
-		scp.prototyping = false; 
-	}
-	ctor.superclass = scp;
-	ctor.mixins = mixins;
-	for(var i=0,l=mixins.length; i<l; i++){
-		dojo.lang.extend(ctor, mixins[i].prototype);
-	}
-	ctor.prototype.initializer = null;
-	ctor.prototype.declaredClass = className;
-	if(dojo.lang.isArray(props)){
-		dojo.lang.extend.apply(dojo.lang, [ctor].concat(props));
-	}else{
-		dojo.lang.extend(ctor, (props)||{});
-	}
-	dojo.lang.extend(ctor, dojo.lang.declare._common);
-	ctor.prototype.constructor = ctor;
-	ctor.prototype.initializer = (ctor.prototype.initializer)||(init)||(function(){});
-	var created = dojo.parseObjPath(className, null, true);
-	created.obj[created.prop] = ctor;
-	return ctor; // Function
-}
-
-dojo.lang.declare._makeConstructor = function(){
-	return function(){ 
-		// get the generational context (which object [or prototype] should be constructed)
-		var self = this._getPropContext();
-		var s = self.constructor.superclass;
-		if((s)&&(s.constructor)){
-			if(s.constructor==arguments.callee){
-				// if this constructor is invoked directly (my.ancestor.call(this))
-				this._inherited("constructor", arguments);
-			}else{
-				this._contextMethod(s, "constructor", arguments);
-			}
-		}
-		var ms = (self.constructor.mixins)||([]);
-		for(var i=0, m; (m=ms[i]); i++) {
-			(((m.prototype)&&(m.prototype.initializer))||(m)).apply(this, arguments);
-		}
-		if((!this.prototyping)&&(self.initializer)){
-			self.initializer.apply(this, arguments);
-		}
-	}
-}
 
-dojo.lang.declare._common = {
-	_getPropContext: function(){ return (this.___proto||this); },
-	// caches ptype context and calls method on it
-	_contextMethod: function(ptype, method, args){
-		var result, stack = this.___proto;
-		this.___proto = ptype;
-		try { result = ptype[method].apply(this,(args||[])); }
-		catch(e) { throw e; }	
-		finally { this.___proto = stack; }
-		return result;
-	},
-	_inherited: function(prop, args){
-		// summary:
-		//		Searches backward thru prototype chain to find nearest
-		//		ancestral instance of prop. Internal use only.
-		var p = this._getPropContext();
-		do{
-			if((!p.constructor)||(!p.constructor.superclass)){ return; }
-			p = p.constructor.superclass;
-		}while(!(prop in p));
-		return (dojo.lang.isFunction(p[prop]) ? this._contextMethod(p, prop, args) : p[prop]);
-	},
-	inherited: function(prop, args){
-		dojo.deprecated("'inherited' method is dangerous, do not up-call! 'inherited' is slated for removal in 0.5; name your super class (or use superclass property) instead.", "0.5");
-		this._inherited(prop, args);
+/******************************************************************************
+ *	Notes about dojo.io design:
+ *	
+ *	The dojo.io.* package has the unenviable task of making a lot of different
+ *	types of I/O feel natural, despite a universal lack of good (or even
+ *	reasonable!) I/O capability in the host environment. So lets pin this down
+ *	a little bit further.
+ *
+ *	Rhino:
+ *		perhaps the best situation anywhere. Access to Java classes allows you
+ *		to do anything one might want in terms of I/O, both synchronously and
+ *		async. Can open TCP sockets and perform low-latency client/server
+ *		interactions. HTTP transport is available through Java HTTP client and
+ *		server classes. Wish it were always this easy.
+ *
+ *	xpcshell:
+ *		XPCOM for I/O.
+ *
+ *	spidermonkey:
+ *		S.O.L.
+ *
+ *	Browsers:
+ *		Browsers generally do not provide any useable filesystem access. We are
+ *		therefore limited to HTTP for moving information to and from Dojo
+ *		instances living in a browser.
+ *
+ *		XMLHTTP:
+ *			Sync or async, allows reading of arbitrary text files (including
+ *			JS, which can then be eval()'d), writing requires server
+ *			cooperation and is limited to HTTP mechanisms (POST and GET).
+ *
+ *		<iframe> hacks:
+ *			iframe document hacks allow browsers to communicate asynchronously
+ *			with a server via HTTP POST and GET operations. With significant
+ *			effort and server cooperation, low-latency data transit between
+ *			client and server can be acheived via iframe mechanisms (repubsub).
+ *
+ *		SVG:
+ *			Adobe's SVG viewer implements helpful primitives for XML-based
+ *			requests, but receipt of arbitrary text data seems unlikely w/o
+ *			<![CDATA[]]> sections.
+ *
+ *
+ *	A discussion between Dylan, Mark, Tom, and Alex helped to lay down a lot
+ *	the IO API interface. A transcript of it can be found at:
+ *		http://dojotoolkit.org/viewcvs/viewcvs.py/documents/irc/irc_io_api_log.txt?rev=307&view=auto
+ *	
+ *	Also referenced in the design of the API was the DOM 3 L&S spec:
+ *		http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html
+ ******************************************************************************/
+
+// a map of the available transport options. Transports should add themselves
+// by calling add(name)
+dojo.io.transports = [];
+dojo.io.hdlrFuncNames = [ "load", "error", "timeout" ]; // we're omitting a progress() event for now
+
+dojo.io.Request = function(/*String*/ url, /*String*/ mimetype, /*String*/ transport, /*String or Boolean*/ changeUrl){
+// summary:
+//		Constructs a Request object that is used by dojo.io.bind().
+// description:
+//		dojo.io.bind() will create one of these for you if
+//		you call dojo.io.bind() with an plain object containing the bind parameters.
+//		This method can either take the arguments specified, or an Object containing all of the parameters that you
+//		want to use to create the dojo.io.Request (similar to how dojo.io.bind() is called.
+//		The named parameters to this constructor represent the minimum set of parameters need
+	if((arguments.length == 1)&&(arguments[0].constructor == Object)){
+		this.fromKwArgs(arguments[0]);
+	}else{
+		this.url = url;
+		if(mimetype){ this.mimetype = mimetype; }
+		if(transport){ this.transport = transport; }
+		if(arguments.length >= 4){ this.changeUrl = changeUrl; }
 	}
 }
 
-dojo.declare = dojo.lang.declare;
+dojo.lang.extend(dojo.io.Request, {
 
-dojo.provide("dojo.lang.func");
+	/** The URL to hit */
+	url: "",
+	
+	/** The mime type used to interrpret the response body */
+	mimetype: "text/plain",
+	
+	/** The HTTP method to use */
+	method: "GET",
+	
+	/** An Object containing key-value pairs to be included with the request */
+	content: undefined, // Object
+	
+	/** The transport medium to use */
+	transport: undefined, // String
+	
+	/** If defined the URL of the page is physically changed */
+	changeUrl: undefined, // String
+	
+	/** A form node to use in the request */
+	formNode: undefined, // HTMLFormElement
+	
+	/** Whether the request should be made synchronously */
+	sync: false,
+	
+	bindSuccess: false,
 
+	/** Cache/look for the request in the cache before attempting to request?
+	 *  NOTE: this isn't a browser cache, this is internal and would only cache in-page
+	 */
+	useCache: false,
 
-dojo.lang.hitch = function(/*Object*/thisObject, /*Function|String*/method){
-	// summary: 
-	//		Returns a function that will only ever execute in the a given scope
-	//		(thisObject). This allows for easy use of object member functions
-	//		in callbacks and other places in which the "this" keyword may
-	//		otherwise not reference the expected scope. Note that the order of
-	//		arguments may be reversed in a future version.
-	// thisObject: the scope to run the method in
-	// method:
-	//		a function to be "bound" to thisObject or the name of the method in
-	//		thisObject to be used as the basis for the binding
-	// usage:
-	//		dojo.lang.hitch(foo, "bar")(); // runs foo.bar() in the scope of foo
-	//		dojo.lang.hitch(foo, myFunction); // returns a function that runs myFunction in the scope of foo
+	/** Prevent the browser from caching this by adding a query string argument to the URL */
+	preventCache: false,
 
-	// FIXME:
-	//		should this be extended to "fixate" arguments in a manner similar
-	//		to dojo.lang.curry, but without the default execution of curry()?
-	var fcn = (dojo.lang.isString(method) ? thisObject[method] : method) || function(){};
-	return function(){
-		return fcn.apply(thisObject, arguments); // Function
-	};
-}
+	jsonFilter: function(value){
+		if(	(this.mimetype == "text/json-comment-filtered")||
+			(this.mimetype == "application/json-comment-filtered")
+		){
+			var cStartIdx = value.indexOf("\/*");
+			var cEndIdx = value.lastIndexOf("*\/");
+			if((cStartIdx == -1)||(cEndIdx == -1)){
+				dojo.debug("your JSON wasn't comment filtered!"); // FIXME: throw exception instead?
+				return "";
+			}
+			return value.substring(cStartIdx+2, cEndIdx);
+		}
+		dojo.debug("please consider using a mimetype of text/json-comment-filtered to avoid potential security issues with JSON endpoints");
+		return value;
+	},
+	
+	// events stuff
+	load: function(/*String*/type, /*Object*/data, /*Object*/transportImplementation, /*Object*/kwArgs){
+		// summary:
+		//		Called on successful completion of a bind.
+		//		type: String
+		//				A string with value "load"
+		//		data: Object
+		//				The object representing the result of the bind. The actual structure
+		//				of the data object will depend on the mimetype that was given to bind
+		//				in the bind arguments.
+		//		transportImplementation: Object
+		//				The object that implements a particular transport. Structure is depedent
+		//				on the transport. For XMLHTTPTransport (dojo.io.BrowserIO), it will be the
+		//				XMLHttpRequest object from the browser.
+		//		kwArgs: Object
+		//				Object that contains the request parameters that were given to the
+		//				bind call. Useful for storing and retrieving state from when bind
+		//				was called.
+	},
+	error: function(/*String*/type, /*Object*/error, /*Object*/transportImplementation, /*Object*/kwArgs){
+		// summary:
+		//		Called when there is an error with a bind.
+		//		type: String
+		//				A string with value "error"
+		//		error: Object
+		//				The error object. Should be a dojo.io.Error object, but not guaranteed.
+		//		transportImplementation: Object
+		//				The object that implements a particular transport. Structure is depedent
+		//				on the transport. For XMLHTTPTransport (dojo.io.BrowserIO), it will be the
+		//				XMLHttpRequest object from the browser.
+		//		kwArgs: Object
+		//				Object that contains the request parameters that were given to the
+		//				bind call. Useful for storing and retrieving state from when bind
+		//				was called.
+	},
+	timeout: function(/*String*/type, /*Object*/empty, /*Object*/transportImplementation, /*Object*/kwArgs){
+		// summary:
+		//		Called when there is an error with a bind. Only implemented in certain transports at this time.
+		//		type: String
+		//				A string with value "timeout"
+		//		empty: Object
+		//				Should be null. Just a spacer argument so that load, error, timeout and handle have the
+		//				same signatures.
+		//		transportImplementation: Object
+		//				The object that implements a particular transport. Structure is depedent
+		//				on the transport. For XMLHTTPTransport (dojo.io.BrowserIO), it will be the
+		//				XMLHttpRequest object from the browser. May be null for the timeout case for
+		//				some transports.
+		//		kwArgs: Object
+		//				Object that contains the request parameters that were given to the
+		//				bind call. Useful for storing and retrieving state from when bind
+		//				was called.
+	},
+	handle: function(/*String*/type, /*Object*/data, /*Object*/transportImplementation, /*Object*/kwArgs){
+		// summary:
+		//		The handle method can be defined instead of defining separate load, error and timeout
+		//		callbacks.
+		//		type: String
+		//				A string with the type of callback: "load", "error", or "timeout".
+		//		data: Object
+		//				See the above callbacks for what this parameter could be.
+		//		transportImplementation: Object
+		//				The object that implements a particular transport. Structure is depedent
+		//				on the transport. For XMLHTTPTransport (dojo.io.BrowserIO), it will be the
+		//				XMLHttpRequest object from the browser.
+		//		kwArgs: Object
+		//				Object that contains the request parameters that were given to the
+		//				bind call. Useful for storing and retrieving state from when bind
+		//				was called.	
+	},
 
-dojo.lang.anonCtr = 0;
-dojo.lang.anon = {};
+	//FIXME: change IframeIO.js to use timeouts?
+	// The number of seconds to wait until firing a timeout callback.
+	// If it is zero, that means, don't do a timeout check.
+	timeoutSeconds: 0,
+	
+	// the abort method needs to be filled in by the transport that accepts the
+	// bind() request
+	abort: function(){ },
+	
+	// backButton: function(){ },
+	// forwardButton: function(){ },
 
-dojo.lang.nameAnonFunc = function(/*Function*/anonFuncPtr, /*Object*/thisObj, /*Boolean*/searchForNames){
-	// summary:
-	//		Creates a reference to anonFuncPtr in thisObj with a completely
-	//		unique name. The new name is returned as a String.  If
-	//		searchForNames is true, an effort will be made to locate an
-	//		existing reference to anonFuncPtr in thisObj, and if one is found,
-	//		the existing name will be returned instead. The default is for
-	//		searchForNames to be false.
-	var nso = (thisObj|| dojo.lang.anon);
-	if( (searchForNames) ||
-		((dj_global["djConfig"])&&(djConfig["slowAnonFuncLookups"] == true)) ){
-		for(var x in nso){
-			try{
-				if(nso[x] === anonFuncPtr){
-					return x;
-				}
-			}catch(e){} // window.external fails in IE embedded in Eclipse (Eclipse bug #151165)
+	fromKwArgs: function(/*Object*/ kwArgs){
+		// summary:
+		//		Creates a dojo.io.Request from a simple object (kwArgs object).
+
+		// normalize args
+		if(kwArgs["url"]){ kwArgs.url = kwArgs.url.toString(); }
+		if(kwArgs["formNode"]) { kwArgs.formNode = dojo.byId(kwArgs.formNode); }
+		if(!kwArgs["method"] && kwArgs["formNode"] && kwArgs["formNode"].method) {
+			kwArgs.method = kwArgs["formNode"].method;
 		}
-	}
-	var ret = "__"+dojo.lang.anonCtr++;
-	while(typeof nso[ret] != "undefined"){
-		ret = "__"+dojo.lang.anonCtr++;
-	}
-	nso[ret] = anonFuncPtr;
-	return ret; // String
-}
+		
+		// backwards compatibility
+		if(!kwArgs["handle"] && kwArgs["handler"]){ kwArgs.handle = kwArgs.handler; }
+		if(!kwArgs["load"] && kwArgs["loaded"]){ kwArgs.load = kwArgs.loaded; }
+		if(!kwArgs["changeUrl"] && kwArgs["changeURL"]) { kwArgs.changeUrl = kwArgs.changeURL; }
 
-dojo.lang.forward = function(funcName){
-	// summary:
-	// 		Returns a function that forwards a method call to
-	// 		this.funcName(...).  Unlike dojo.lang.hitch(), the "this" scope is
-	// 		not fixed on a single object. Ported from MochiKit.
-	return function(){
-		return this[funcName].apply(this, arguments);
-	}; // Function
-}
-
-dojo.lang.curry = function(thisObj, func /* args ... */){
-	// summary:
-	//		similar to the curry() method found in many functional programming
-	//		environments, this function returns an "argument accumulator"
-	//		function, bound to a particular scope, and "primed" with a variable
-	//		number of arguments. The curry method is unique in that it returns
-	//		a function that may return other "partial" function which can be
-	//		called repeatedly. New functions are returned until the arity of
-	//		the original function is reached, at which point the underlying
-	//		function (func) is called in the scope thisObj with all of the
-	//		accumulated arguments (plus any extras) in positional order.
-	// examples:
-	//		assuming a function defined like this:
-	//			var foo = {
-	//				bar: function(arg1, arg2, arg3){
-	//					dojo.debug.apply(dojo, arguments);
-	//				}
-	//			};
-	//		
-	//		dojo.lang.curry() can be used most simply in this way:
-	//		
-	//			tmp = dojo.lang.curry(foo, foo.bar, "arg one", "thinger");
-	//			tmp("blah", "this is superfluous");
-	//			// debugs: "arg one thinger blah this is superfluous"
-	//			tmp("blah");
-	//			// debugs: "arg one thinger blah"
-	//			tmp();
-	//			// returns a function exactly like tmp that expects one argument
-	//
-	//		other intermittent functions could be created until the 3
-	//		positional arguments are filled:
-	//
-	//			tmp = dojo.lang.curry(foo, foo.bar, "arg one");
-	//			tmp2 = tmp("arg two");
-	//			tmp2("blah blah");
-	//			// debugs: "arg one arg two blah blah"
-	//			tmp2("oy");
-	//			// debugs: "arg one arg two oy"
-	//
-	//		curry() can also be used to call the function if enough arguments
-	//		are passed in the initial invocation:
-	//
-	//			dojo.lang.curry(foo, foo.bar, "one", "two", "three", "four");
-	//			// debugs: "one two three four"
-	//			dojo.lang.curry(foo, foo.bar, "one", "two", "three");
-	//			// debugs: "one two three"
+		// encoding fun!
+		kwArgs.encoding = dojo.lang.firstValued(kwArgs["encoding"], djConfig["bindEncoding"], "");
 
+		kwArgs.sendTransport = dojo.lang.firstValued(kwArgs["sendTransport"], djConfig["ioSendTransport"], false);
 
-	// FIXME: the order of func and thisObj should be changed!!!
-	var outerArgs = [];
-	thisObj = thisObj||dj_global;
-	if(dojo.lang.isString(func)){
-		func = thisObj[func];
-	}
-	for(var x=2; x<arguments.length; x++){
-		outerArgs.push(arguments[x]);
-	}
-	// since the event system replaces the original function with a new
-	// join-point runner with an arity of 0, we check to see if it's left us
-	// any clues about the original arity in lieu of the function's actual
-	// length property
-	var ecount = (func["__preJoinArity"]||func.length) - outerArgs.length;
-	// borrowed from svend tofte
-	function gather(nextArgs, innerArgs, expected){
-		var texpected = expected;
-		var totalArgs = innerArgs.slice(0); // copy
-		for(var x=0; x<nextArgs.length; x++){
-			totalArgs.push(nextArgs[x]);
-		}
-		// check the list of provided nextArgs to see if it, plus the
-		// number of innerArgs already supplied, meets the total
-		// expected.
-		expected = expected-nextArgs.length;
-		if(expected<=0){
-			var res = func.apply(thisObj, totalArgs);
-			expected = texpected;
-			return res;
-		}else{
-			return function(){
-				return gather(arguments,// check to see if we've been run
-										// with enough args
-							totalArgs,	// a copy
-							expected);	// how many more do we need to run?;
-			};
+		var isFunction = dojo.lang.isFunction;
+		for(var x=0; x<dojo.io.hdlrFuncNames.length; x++){
+			var fn = dojo.io.hdlrFuncNames[x];
+			if(kwArgs[fn] && isFunction(kwArgs[fn])){ continue; }
+			if(kwArgs["handle"] && isFunction(kwArgs["handle"])){
+				kwArgs[fn] = kwArgs.handle;
+			}
+			// handler is aliased above, shouldn't need this check
+			/* else if(dojo.lang.isObject(kwArgs.handler)){
+				if(isFunction(kwArgs.handler[fn])){
+					kwArgs[fn] = kwArgs.handler[fn]||kwArgs.handler["handle"]||function(){};
+				}
+			}*/
 		}
+		dojo.lang.mixin(this, kwArgs);
 	}
-	return gather([], outerArgs, ecount);
+
+});
+
+dojo.io.Error = function(/*String*/ msg, /*String*/ type, /*Number*/num){
+	// summary:
+	//		Constructs an object representing a bind error.
+	this.message = msg;
+	this.type =  type || "unknown"; // must be one of "io", "parse", "unknown"
+	this.number = num || 0; // per-substrate error number, not normalized
 }
 
-dojo.lang.curryArguments = function(/*Object*/thisObj, /*Function*/func, /*Array*/args, /*Integer, optional*/offset){
+dojo.io.transports.addTransport = function(/*String*/name){
 	// summary:
-	//		similar to dojo.lang.curry(), except that a list of arguments to
-	//		start the curry with may be provided as an array instead of as
-	//		positional arguments. An offset may be specified from the 0 index
-	//		to skip some elements in args.
-	var targs = [];
-	var x = offset||0;
-	for(x=offset; x<args.length; x++){
-		targs.push(args[x]); // ensure that it's an arr
-	}
-	return dojo.lang.curry.apply(dojo.lang, [thisObj, func].concat(targs));
+	//		Used to register transports that can support bind calls.
+	this.push(name);
+	// FIXME: do we need to handle things that aren't direct children of the
+	// dojo.io module? (say, dojo.io.foo.fooTransport?)
+	this[name] = dojo.io[name];
 }
 
-dojo.lang.tryThese = function(/*...*/){
+// binding interface, the various implementations register their capabilities
+// and the bind() method dispatches
+dojo.io.bind = function(/*dojo.io.Request or Object*/request){
 	// summary:
-	//		executes each function argument in turn, returning the return value
-	//		from the first one which does not throw an exception in execution.
-	//		Any number of functions may be passed.
-	for(var x=0; x<arguments.length; x++){
+	//		Binding interface for IO. Loading different IO transports, like
+	//		dojo.io.BrowserIO or dojo.io.IframeIO, will register with bind
+	//		to handle particular types of bind calls.
+	//		request: Object
+	//				Object containing bind arguments. This object is converted to
+	//				a dojo.io.Request object, and that request object is the return
+	//				value for this method.
+	if(!(request instanceof dojo.io.Request)){
 		try{
-			if(typeof arguments[x] == "function"){
-				var ret = (arguments[x]());
-				if(ret){
-					return ret;
-				}
+			request = new dojo.io.Request(request);
+		}catch(e){ dojo.debug(e); }
+	}
+
+	// if the request asks for a particular implementation, use it
+	var tsName = "";
+	if(request["transport"]){
+		tsName = request["transport"];
+		if(!this[tsName]){
+			dojo.io.sendBindError(request, "No dojo.io.bind() transport with name '"
+				+ request["transport"] + "'.");
+			return request; //dojo.io.Request
+		}
+		if(!this[tsName].canHandle(request)){
+			dojo.io.sendBindError(request, "dojo.io.bind() transport with name '"
+				+ request["transport"] + "' cannot handle this type of request.");
+			return request;	//dojo.io.Request
+		}
+	}else{
+		// otherwise we do our best to auto-detect what available transports
+		// will handle 
+		for(var x=0; x<dojo.io.transports.length; x++){
+			var tmp = dojo.io.transports[x];
+			if((this[tmp])&&(this[tmp].canHandle(request))){
+				tsName = tmp;
+				break;
 			}
-		}catch(e){
-			dojo.debug(e);
+		}
+		if(tsName == ""){
+			dojo.io.sendBindError(request, "None of the loaded transports for dojo.io.bind()"
+				+ " can handle the request.");
+			return request; //dojo.io.Request
 		}
 	}
+	this[tsName].bind(request);
+	request.bindSuccess = true;
+	return request; //dojo.io.Request
 }
 
-dojo.lang.delayThese = function(/*Array*/farr, /*Function, optional*/cb, /*Integer*/delay, /*Function, optional*/onend){
+dojo.io.sendBindError = function(/* Object */request, /* String */message){
 	// summary:
-	//		executes a series of functions contained in farr, but spaces out
-	//		calls to each function by the millisecond delay provided. If cb is
-	//		provided, it will be called directly after each item in farr is
-	//		called and if onend is passed, it will be called when all items
-	//		have completed executing.
+	//		Used internally by dojo.io.bind() to return/raise a bind error.
 
-	/**
-	 * alternate: (array funcArray, function callback, function onend)
-	 * alternate: (array funcArray, function callback)
-	 * alternate: (array funcArray)
-	 */
-	if(!farr.length){ 
-		if(typeof onend == "function"){
-			onend();
-		}
-		return;
-	}
-	if((typeof delay == "undefined")&&(typeof cb == "number")){
-		delay = cb;
-		cb = function(){};
-	}else if(!cb){
-		cb = function(){};
-		if(!delay){ delay = 0; }
+	//Need to be careful since not all hostenvs support setTimeout.
+	if((typeof request.error == "function" || typeof request.handle == "function")
+		&& (typeof setTimeout == "function" || typeof setTimeout == "object")){
+		var errorObject = new dojo.io.Error(message);
+		setTimeout(function(){
+			request[(typeof request.error == "function") ? "error" : "handle"]("error", errorObject, null, request);
+		}, 50);
+	}else{
+		dojo.raise(message);
 	}
-	setTimeout(function(){
-		(farr.shift())();
-		cb();
-		dojo.lang.delayThese(farr, cb, delay, onend);
-	}, delay);
 }
 
-dojo.provide("dojo.event.common");
-
-
-
+dojo.io.queueBind = function(/*dojo.io.Request or Object*/request){
+	// summary:
+	//		queueBind will use dojo.io.bind() but guarantee that only one bind
+	//		call is handled at a time.
+	// description:
+	//		If queueBind is called while a bind call
+	//		is in process, it will queue up the other calls to bind and call them
+	//		in order as bind calls complete.
+	//		request: Object
+	//			Same sort of request object as used for dojo.io.bind().
+	if(!(request instanceof dojo.io.Request)){
+		try{
+			request = new dojo.io.Request(request);
+		}catch(e){ dojo.debug(e); }
+	}
 
+	// make sure we get called if/when we get a response
+	var oldLoad = request.load;
+	request.load = function(){
+		dojo.io._queueBindInFlight = false;
+		var ret = oldLoad.apply(this, arguments);
+		dojo.io._dispatchNextQueueBind();
+		return ret;
+	}
 
-// TODO: connection filter functions
-//			these are functions that accept a method invocation (like around
-//			advice) and return a boolean based on it. That value determines
-//			whether or not the connection proceeds. It could "feel" like around
-//			advice for those who know what it is (calling proceed() or not),
-//			but I think presenting it as a "filter" and/or calling it with the
-//			function args and not the MethodInvocation might make it more
-//			palletable to "normal" users than around-advice currently is
-// TODO: execution scope mangling
-//			YUI's event facility by default executes listeners in the context
-//			of the source object. This is very odd, but should probably be
-//			supported as an option (both for the source and for the dest). It
-//			can be thought of as a connection-specific hitch().
-// TODO: more resiliency for 4+ arguments to connect()
-
-dojo.event = new function(){
-	this._canTimeout = dojo.lang.isFunction(dj_global["setTimeout"])||dojo.lang.isAlien(dj_global["setTimeout"]);
-
-	// FIXME: where should we put this method (not here!)?
-	function interpolateArgs(args, searchForNames){
-		var dl = dojo.lang;
-		var ao = {
-			srcObj: dj_global,
-			srcFunc: null,
-			adviceObj: dj_global,
-			adviceFunc: null,
-			aroundObj: null,
-			aroundFunc: null,
-			adviceType: (args.length>2) ? args[0] : "after",
-			precedence: "last",
-			once: false,
-			delay: null,
-			rate: 0,
-			adviceMsg: false,
-			maxCalls: -1
-		};
+	var oldErr = request.error;
+	request.error = function(){
+		dojo.io._queueBindInFlight = false;
+		var ret = oldErr.apply(this, arguments);
+		dojo.io._dispatchNextQueueBind();
+		return ret;
+	}
 
-		switch(args.length){
-			case 0: return;
-			case 1: return;
-			case 2:
-				ao.srcFunc = args[0];
-				ao.adviceFunc = args[1];
-				break;
-			case 3:
-				if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isString(args[2]))){
-					ao.adviceType = "after";
-					ao.srcObj = args[0];
-					ao.srcFunc = args[1];
-					ao.adviceFunc = args[2];
-				}else if((dl.isString(args[1]))&&(dl.isString(args[2]))){
-					ao.srcFunc = args[1];
-					ao.adviceFunc = args[2];
-				}else if((dl.isObject(args[0]))&&(dl.isString(args[1]))&&(dl.isFunction(args[2]))){
-					ao.adviceType = "after";
-					ao.srcObj = args[0];
-					ao.srcFunc = args[1];
-					var tmpName  = dl.nameAnonFunc(args[2], ao.adviceObj, searchForNames);
-					ao.adviceFunc = tmpName;
-				}else if((dl.isFunction(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))){
-					ao.adviceType = "after";
-					ao.srcObj = dj_global;
-					var tmpName  = dl.nameAnonFunc(args[0], ao.srcObj, searchForNames);
-					ao.srcFunc = tmpName;
-					ao.adviceObj = args[1];
-					ao.adviceFunc = args[2];
-				}
-				break;
-			case 4:
-				if((dl.isObject(args[0]))&&(dl.isObject(args[2]))){
-					// we can assume that we've got an old-style "connect" from
-					// the sigslot school of event attachment. We therefore
-					// assume after-advice.
-					ao.adviceType = "after";
-					ao.srcObj = args[0];
-					ao.srcFunc = args[1];
-					ao.adviceObj = args[2];
-					ao.adviceFunc = args[3];
-				}else if((dl.isString(args[0]))&&(dl.isString(args[1]))&&(dl.isObject(args[2]))){
-					ao.adviceType = args[0];
-					ao.srcObj = dj_global;
-					ao.srcFunc = args[1];
-					ao.adviceObj = args[2];
-					ao.adviceFunc = args[3];
-				}else if((dl.isString(args[0]))&&(dl.isFunction(args[1]))&&(dl.isObject(args[2]))){
-					ao.adviceType = args[0];
-					ao.srcObj = dj_global;
-					var tmpName  = dl.nameAnonFunc(args[1], dj_global, searchForNames);
-					ao.srcFunc = tmpName;
-					ao.adviceObj = args[2];
-					ao.adviceFunc = args[3];
-				}else if((dl.isString(args[0]))&&(dl.isObject(args[1]))&&(dl.isString(args[2]))&&(dl.isFunction(args[3]))){
-					ao.srcObj = args[1];
-					ao.srcFunc = args[2];
-					var tmpName  = dl.nameAnonFunc(args[3], dj_global, searchForNames);
-					ao.adviceObj = dj_global;
-					ao.adviceFunc = tmpName;
-				}else if(dl.isObject(args[1])){
-					ao.srcObj = args[1];
-					ao.srcFunc = args[2];
-					ao.adviceObj = dj_global;
-					ao.adviceFunc = args[3];
-				}else if(dl.isObject(args[2])){
-					ao.srcObj = dj_global;
-					ao.srcFunc = args[1];
-					ao.adviceObj = args[2];
-					ao.adviceFunc = args[3];
-				}else{
-					ao.srcObj = ao.adviceObj = ao.aroundObj = dj_global;
-					ao.srcFunc = args[1];
-					ao.adviceFunc = args[2];
-					ao.aroundFunc = args[3];
-				}
-				break;
-			case 6:
-				ao.srcObj = args[1];
-				ao.srcFunc = args[2];
-				ao.adviceObj = args[3]
-				ao.adviceFunc = args[4];
-				ao.aroundFunc = args[5];
-				ao.aroundObj = dj_global;
-				break;
-			default:
-				ao.srcObj = args[1];
-				ao.srcFunc = args[2];
-				ao.adviceObj = args[3]
-				ao.adviceFunc = args[4];
-				ao.aroundObj = args[5];
-				ao.aroundFunc = args[6];
-				ao.once = args[7];
-				ao.delay = args[8];
-				ao.rate = args[9];
-				ao.adviceMsg = args[10];
-				ao.maxCalls = (!isNaN(parseInt(args[11]))) ? args[11] : -1;
-				break;
-		}
+	dojo.io._bindQueue.push(request);
+	dojo.io._dispatchNextQueueBind();
+	return request; //dojo.io.Request
+}
 
-		if(dl.isFunction(ao.aroundFunc)){
-			var tmpName  = dl.nameAnonFunc(ao.aroundFunc, ao.aroundObj, searchForNames);
-			ao.aroundFunc = tmpName;
+dojo.io._dispatchNextQueueBind = function(){
+	// summary:
+	//	Private method used by dojo.io.queueBind().
+	if(!dojo.io._queueBindInFlight){
+		dojo.io._queueBindInFlight = true;
+		if(dojo.io._bindQueue.length > 0){
+			dojo.io.bind(dojo.io._bindQueue.shift());
+		}else{
+			dojo.io._queueBindInFlight = false;
 		}
+	}
+}
+dojo.io._bindQueue = [];
+dojo.io._queueBindInFlight = false;
 
-		if(dl.isFunction(ao.srcFunc)){
-			ao.srcFunc = dl.getNameInObj(ao.srcObj, ao.srcFunc);
+dojo.io.argsFromMap = function(/*Object*/map, /*String?*/encoding, /*String?*/last){
+	// summary:
+	//		Converts name/values pairs in the map object to an URL-encoded string
+	//		with format of name1=value1&name2=value2...
+	//		map: Object
+	//			Object that has the contains the names and values.
+	//		encoding: String?
+	//			String to specify how to encode the name and value. If the encoding string
+	//			contains "utf" (case-insensitive), then encodeURIComponent is used. Otherwise
+	//			dojo.string.encodeAscii is used.
+	//		last: String?
+	//			The last parameter in the list. Helps with final string formatting?
+	var enc = /utf/i.test(encoding||"") ? encodeURIComponent : dojo.string.encodeAscii;
+	var mapped = [];
+	var control = new Object();
+	for(var name in map){
+		var domap = function(elt){
+			var val = enc(name)+"="+enc(elt);
+			mapped[(last == name) ? "push" : "unshift"](val);
 		}
-
-		if(dl.isFunction(ao.adviceFunc)){
-			ao.adviceFunc = dl.getNameInObj(ao.adviceObj, ao.adviceFunc);
+		if(!control[name]){
+			var value = map[name];
+			// FIXME: should be isArrayLike?
+			if (dojo.lang.isArray(value)){
+				dojo.lang.forEach(value, domap);
+			}else{
+				domap(value);
+			}
 		}
+	}
+	return mapped.join("&"); //String
+}
 
-		if((ao.aroundObj)&&(dl.isFunction(ao.aroundFunc))){
-			ao.aroundFunc = dl.getNameInObj(ao.aroundObj, ao.aroundFunc);
-		}
+dojo.io.setIFrameSrc = function(/*DOMNode*/ iframe, /*String*/ src, /*Boolean*/ replace){
+	//summary:
+	//		Sets the URL that is loaded in an IFrame. The replace parameter indicates whether
+	//		location.replace() should be used when changing the location of the iframe.
+	try{
+		var r = dojo.render.html;
+		// dojo.debug(iframe);
+		if(!replace){
+			if(r.safari){
+				iframe.location = src;
+			}else{
+				frames[iframe.name].location = src;
+			}
+		}else{
+			// Fun with DOM 0 incompatibilities!
+			var idoc;
+			if(r.ie){
+				idoc = iframe.contentWindow.document;
+			}else if(r.safari){
+				idoc = iframe.document;
+			}else{ //  if(r.moz){
+				idoc = iframe.contentWindow;
+			}
 
-		if(!ao.srcObj){
-			dojo.raise("bad srcObj for srcFunc: "+ao.srcFunc);
-		}
-		if(!ao.adviceObj){
-			dojo.raise("bad adviceObj for adviceFunc: "+ao.adviceFunc);
+			//For Safari (at least 2.0.3) and Opera, if the iframe
+			//has just been created but it doesn't have content
+			//yet, then iframe.document may be null. In that case,
+			//use iframe.location and return.
+			if(!idoc){
+				iframe.location = src;
+				return;
+			}else{
+				idoc.location.replace(src);
+			}
 		}
-		
-		if(!ao.adviceFunc){
-			dojo.debug("bad adviceFunc for srcFunc: "+ao.srcFunc);
-			dojo.debugShallow(ao);
-		} 
-		
-		return ao;
+	}catch(e){ 
+		dojo.debug(e); 
+		dojo.debug("setIFrameSrc: "+e); 
 	}
+}
 
-	this.connect = function(/*...*/){
-		// summary:
-		//		dojo.event.connect is the glue that holds most Dojo-based
-		//		applications together. Most combinations of arguments are
-		//		supported, with the connect() method attempting to disambiguate
-		//		the implied types of positional parameters. The following will
-		//		all work:
-		//			dojo.event.connect("globalFunctionName1", "globalFunctionName2");
-		//			dojo.event.connect(functionReference1, functionReference2);
-		//			dojo.event.connect("globalFunctionName1", functionReference2);
-		//			dojo.event.connect(functionReference1, "globalFunctionName2");
-		//			dojo.event.connect(scope1, "functionName1", "globalFunctionName2");
-		//			dojo.event.connect("globalFunctionName1", scope2, "functionName2");
-		//			dojo.event.connect(scope1, "functionName1", scope2, "functionName2");
-		//			dojo.event.connect("after", scope1, "functionName1", scope2, "functionName2");
-		//			dojo.event.connect("before", scope1, "functionName1", scope2, "functionName2");
-		//			dojo.event.connect("around", 	scope1, "functionName1", 
-		//											scope2, "functionName2",
-		//											aroundFunctionReference);
-		//			dojo.event.connect("around", 	scope1, "functionName1", 
-		//											scope2, "functionName2",
-		//											scope3, "aroundFunctionName");
-		//			dojo.event.connect("before-around", 	scope1, "functionName1", 
-		//													scope2, "functionName2",
-		//													aroundFunctionReference);
-		//			dojo.event.connect("after-around", 		scope1, "functionName1", 
-		//													scope2, "functionName2",
-		//													aroundFunctionReference);
-		//			dojo.event.connect("after-around", 		scope1, "functionName1", 
-		//													scope2, "functionName2",
-		//													scope3, "aroundFunctionName");
-		//			dojo.event.connect("around", 	scope1, "functionName1", 
-		//											scope2, "functionName2",
-		//											scope3, "aroundFunctionName", true, 30);
-		//			dojo.event.connect("around", 	scope1, "functionName1", 
-		//											scope2, "functionName2",
-		//											scope3, "aroundFunctionName", null, null, 10);
-		// adviceType: 
-		//		Optional. String. One of "before", "after", "around",
-		//		"before-around", or "after-around". FIXME
-		// srcObj:
-		//		the scope in which to locate/execute the named srcFunc. Along
-		//		with srcFunc, this creates a way to dereference the function to
-		//		call. So if the function in question is "foo.bar", the
-		//		srcObj/srcFunc pair would be foo and "bar", where "bar" is a
-		//		string and foo is an object reference.
-		// srcFunc:
-		//		the name of the function to connect to. When it is executed,
-		//		the listener being registered with this call will be called.
-		//		The adviceType defines the call order between the source and
-		//		the target functions.
-		// adviceObj:
-		//		the scope in which to locate/execute the named adviceFunc.
-		// adviceFunc:
-		//		the name of the function being conected to srcObj.srcFunc
-		// aroundObj:
-		//		the scope in which to locate/execute the named aroundFunc.
-		// aroundFunc:
-		//		the name of, or a reference to, the function that will be used
-		//		to mediate the advice call. Around advice requires a special
-		//		unary function that will be passed a "MethodInvocation" object.
-		//		These objects have several important properties, namely:
-		//			- args
-		//				a mutable array of arguments to be passed into the
-		//				wrapped function
-		//			- proceed
-		//				a function that "continues" the invocation. The result
-		//				of this function is the return of the wrapped function.
-		//				You can then manipulate this return before passing it
-		//				back out (or take further action based on it).
-		// once:
-		//		boolean that determines whether or not this connect() will
-		//		create a new connection if an identical connect() has already
-		//		been made. Defaults to "false".
-		// delay:
-		//		an optional delay (in ms), as an integer, for dispatch of a
-		//		listener after the source has been fired.
-		// rate:
-		//		an optional rate throttling parameter (integer, in ms). When
-		//		specified, this particular connection will not fire more than
-		//		once in the interval specified by the rate
-		// adviceMsg:
-		//		boolean. Should the listener have all the parameters passed in
-		//		as a single argument?
-
-		/*
-				ao.adviceType = args[0];
-				ao.srcObj = args[1];
-				ao.srcFunc = args[2];
-				ao.adviceObj = args[3]
-				ao.adviceFunc = args[4];
-				ao.aroundObj = args[5];
-				ao.aroundFunc = args[6];
-				ao.once = args[7];
-				ao.delay = args[8];
-				ao.rate = args[9];
-				ao.adviceMsg = args[10];
-				ao.maxCalls = args[11];
-		*/
-		if(arguments.length == 1){
-			var ao = arguments[0];
-		}else{
-			var ao = interpolateArgs(arguments, true);
+/*
+dojo.io.sampleTranport = new function(){
+	this.canHandle = function(kwArgs){
+		// canHandle just tells dojo.io.bind() if this is a good transport to
+		// use for the particular type of request.
+		if(	
+			(
+				(kwArgs["mimetype"] == "text/plain") ||
+				(kwArgs["mimetype"] == "text/html") ||
+				(kwArgs["mimetype"] == "text/javascript")
+			)&&(
+				(kwArgs["method"] == "get") ||
+				( (kwArgs["method"] == "post") && (!kwArgs["formNode"]) )
+			)
+		){
+			return true;
 		}
-		/*
-		if(dojo.lang.isString(ao.srcFunc) && (ao.srcFunc.toLowerCase() == "onkey") ){
-			if(dojo.render.html.ie){
-				ao.srcFunc = "onkeydown";
-				this.connect(ao);
+
+		return false;
+	}
+
+	this.bind = function(kwArgs){
+		var hdlrObj = {};
+
+		// set up a handler object
+		for(var x=0; x<dojo.io.hdlrFuncNames.length; x++){
+			var fn = dojo.io.hdlrFuncNames[x];
+			if(typeof kwArgs.handler == "object"){
+				if(typeof kwArgs.handler[fn] == "function"){
+					hdlrObj[fn] = kwArgs.handler[fn]||kwArgs.handler["handle"];
+				}
+			}else if(typeof kwArgs[fn] == "function"){
+				hdlrObj[fn] = kwArgs[fn];
+			}else{
+				hdlrObj[fn] = kwArgs["handle"]||function(){};
 			}
-			ao.srcFunc = "onkeypress";
 		}
-		*/
 
-		if(dojo.lang.isArray(ao.srcObj) && ao.srcObj!=""){
-			var tmpAO = {};
-			for(var x in ao){
-				tmpAO[x] = ao[x];
+		// build a handler function that calls back to the handler obj
+		var hdlrFunc = function(evt){
+			if(evt.type == "onload"){
+				hdlrObj.load("load", evt.data, evt);
+			}else if(evt.type == "onerr"){
+				var errObj = new dojo.io.Error("sampleTransport Error: "+evt.msg);
+				hdlrObj.error("error", errObj);
 			}
-			var mjps = [];
-			dojo.lang.forEach(ao.srcObj, function(src){
-				if((dojo.render.html.capable)&&(dojo.lang.isString(src))){
-					src = dojo.byId(src);
-					// dojo.debug(src);
-				}
-				tmpAO.srcObj = src;
-				// dojo.debug(tmpAO.srcObj, tmpAO.srcFunc);
-				// dojo.debug(tmpAO.adviceObj, tmpAO.adviceFunc);
-				mjps.push(dojo.event.connect.call(dojo.event, tmpAO));
-			});
-			return mjps;
 		}
 
-		// FIXME: just doing a "getForMethod()" seems to be enough to put this into infinite recursion!!
-		var mjp = dojo.event.MethodJoinPoint.getForMethod(ao.srcObj, ao.srcFunc);
-		if(ao.adviceFunc){
-			var mjp2 = dojo.event.MethodJoinPoint.getForMethod(ao.adviceObj, ao.adviceFunc);
-		}
+		// the sample transport would attach the hdlrFunc() when sending the
+		// request down the pipe at this point
+		var tgtURL = kwArgs.url+"?"+dojo.io.argsFromMap(kwArgs.content);
+		// sampleTransport.sendRequest(tgtURL, hdlrFunc);
+	}
 
-		mjp.kwAddAdvice(ao);
+	dojo.io.transports.addTransport("sampleTranport");
+}
+*/
 
-		// advanced users might want to fsck w/ the join point manually
-		return mjp; // a MethodJoinPoint object
-	}
+dojo.provide("dojo.lang.array");
 
-	this.log = function(/*object or funcName*/ a1, /*funcName*/ a2){
-		// summary:
-		//		a function that will wrap and log all calls to the specified
-		//		a1.a2() function. If only a1 is passed, it'll be used as a
-		//		function or function name on the global context. Logging will
-		//		be sent to dojo.debug
-		// a1:
-		//		if a2 is passed, this should be an object. If not, it can be a
-		//		function or function name.
-		// a2:
-		//		a function name
-		var kwArgs;
-		if((arguments.length == 1)&&(typeof a1 == "object")){
-			kwArgs = a1;
-		}else{
-			kwArgs = {
-				srcObj: a1,
-				srcFunc: a2
-			};
-		}
-		kwArgs.adviceFunc = function(){
-			var argsStr = [];
-			for(var x=0; x<arguments.length; x++){
-				argsStr.push(arguments[x]);
-			}
-			dojo.debug("("+kwArgs.srcObj+")."+kwArgs.srcFunc, ":", argsStr.join(", "));
-		};
-		this.kwConnect(kwArgs);
-	}
 
-	this.connectBefore = function(){
-		// summary:
-		//	 	takes the same parameters as dojo.event.connect(), except that
-		//	 	the advice type will always be "before"
-		var args = ["before"];
-		for(var i = 0; i < arguments.length; i++){ args.push(arguments[i]); }
-		return this.connect.apply(this, args); // a MethodJoinPoint object
-	}
 
-	this.connectAround = function(){
-		// summary:
-		//	 	takes the same parameters as dojo.event.connect(), except that
-		//	 	the advice type will always be "around"
-		var args = ["around"];
-		for(var i = 0; i < arguments.length; i++){ args.push(arguments[i]); }
-		return this.connect.apply(this, args); // a MethodJoinPoint object
-	}
+// FIXME: Is this worthless since you can do: if(name in obj)
+// is this the right place for this?
 
-	this.connectOnce = function(){
-		// summary:
-		//	 	takes the same parameters as dojo.event.connect(), except that
-		//	 	the "once" flag will always be set to "true"
-		var ao = interpolateArgs(arguments, true);
-		ao.once = true;
-		return this.connect(ao); // a MethodJoinPoint object
-	}
+dojo.lang.mixin(dojo.lang, {
+	has: function(/*Object*/obj, /*String*/name){
+		// summary: is there a property with the passed name in obj?
+		try{
+			return typeof obj[name] != "undefined"; // Boolean
+		}catch(e){ return false; } // Boolean
+	},
 
-	this.connectRunOnce = function(){
+	isEmpty: function(/*Object*/obj){
 		// summary:
-		//	 	takes the same parameters as dojo.event.connect(), except that
-		//	 	the "maxCalls" flag will always be set to 1
-		var ao = interpolateArgs(arguments, true);
-		ao.maxCalls = 1;
-		return this.connect(ao); // a MethodJoinPoint object
-	}
-
-	this._kwConnectImpl = function(kwArgs, disconnect){
-		var fn = (disconnect) ? "disconnect" : "connect";
-		if(typeof kwArgs["srcFunc"] == "function"){
-			kwArgs.srcObj = kwArgs["srcObj"]||dj_global;
-			var tmpName  = dojo.lang.nameAnonFunc(kwArgs.srcFunc, kwArgs.srcObj, true);
-			kwArgs.srcFunc = tmpName;
-		}
-		if(typeof kwArgs["adviceFunc"] == "function"){
-			kwArgs.adviceObj = kwArgs["adviceObj"]||dj_global;
-			var tmpName  = dojo.lang.nameAnonFunc(kwArgs.adviceFunc, kwArgs.adviceObj, true);
-			kwArgs.adviceFunc = tmpName;
+		//		can be used to determine if the passed object is "empty". In
+		//		the case of array-like objects, the length, property is
+		//		examined, but for other types of objects iteration is used to
+		//		examine the iterable "surface area" to determine if any
+		//		non-prototypal properties have been assigned. This iteration is
+		//		prototype-extension safe.
+		if(dojo.lang.isObject(obj)){
+			var tmp = {};
+			var count = 0;
+			for(var x in obj){
+				if(obj[x] && (!tmp[x])){
+					count++;
+					break;
+				} 
+			}
+			return count == 0; // boolean
+		}else if(dojo.lang.isArrayLike(obj) || dojo.lang.isString(obj)){
+			return obj.length == 0; // boolean
 		}
-		kwArgs.srcObj = kwArgs["srcObj"]||dj_global;
-		kwArgs.adviceObj = kwArgs["adviceObj"]||kwArgs["targetObj"]||dj_global;
-		kwArgs.adviceFunc = kwArgs["adviceFunc"]||kwArgs["targetFunc"];
-		// pass kwargs to avoid unrolling/repacking
-		return dojo.event[fn](kwArgs);
-	}
+	},
 
-	this.kwConnect = function(/*Object*/ kwArgs){
+	map: function(/*Array*/arr, /*Object|Function*/obj, /*Function?*/unary_func){
 		// summary:
-		//		A version of dojo.event.connect() that takes a map of named
-		//		parameters instead of the positional parameters that
-		//		dojo.event.connect() uses. For many advanced connection types,
-		//		this can be a much more readable (and potentially faster)
-		//		alternative.
-		// kwArgs:
-		// 		An object that can have the following properties:
-		//			- adviceType
-		//			- srcObj
-		//			- srcFunc
-		//			- adviceObj
-		//			- adviceFunc 
-		//			- aroundObj
-		//			- aroundFunc
-		//			- once
-		//			- delay
-		//			- rate
-		//			- adviceMsg
-		//		As with connect, only srcFunc and adviceFunc are generally
-		//		required
+		//		returns a new array constituded from the return values of
+		//		passing each element of arr into unary_func. The obj parameter
+		//		may be passed to enable the passed function to be called in
+		//		that scope. In environments that support JavaScript 1.6, this
+		//		function is a passthrough to the built-in map() function
+		//		provided by Array instances. For details on this, see:
+		// 			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map
+		// examples:
+		//		dojo.lang.map([1, 2, 3, 4], function(item){ return item+1 });
+		//		// returns [2, 3, 4, 5]
+		var isString = dojo.lang.isString(arr);
+		if(isString){
+			// arr: String
+			arr = arr.split("");
+		}
+		if(dojo.lang.isFunction(obj)&&(!unary_func)){
+			unary_func = obj;
+			obj = dj_global;
+		}else if(dojo.lang.isFunction(obj) && unary_func){
+			// ff 1.5 compat
+			var tmpObj = obj;
+			obj = unary_func;
+			unary_func = tmpObj;
+		}
+		if(Array.map){
+			var outArr = Array.map(arr, unary_func, obj);
+		}else{
+			var outArr = [];
+			for(var i=0;i<arr.length;++i){
+				outArr.push(unary_func.call(obj, arr[i]));
+			}
+		}
+		if(isString) {
+			return outArr.join(""); // String
+		} else {
+			return outArr; // Array
+		}
+	},
 
-		return this._kwConnectImpl(kwArgs, false); // a MethodJoinPoint object
+	reduce: function(/*Array*/arr, initialValue, /*Object|Function*/obj, /*Function*/binary_func){
+		// summary:
+		// 		similar to Python's builtin reduce() function. The result of
+		// 		the previous computation is passed as the first argument to
+		// 		binary_func along with the next value from arr. The result of
+		// 		this call is used along with the subsequent value from arr, and
+		// 		this continues until arr is exhausted. The return value is the
+		// 		last result. The "obj" and "initialValue" parameters may be
+		// 		safely omitted and the order of obj and binary_func may be
+		// 		reversed. The default order of the obj and binary_func argument
+		// 		will probably be reversed in a future release, and this call
+		// 		order is supported today.
+		// examples:
+		//		dojo.lang.reduce([1, 2, 3, 4], function(last, next){ return last+next});
+		//		returns 10
+		var reducedValue = initialValue;
+		if(arguments.length == 2){
+			binary_func = initialValue;
+			reducedValue = arr[0];
+			arr = arr.slice(1);
+		}else if(arguments.length == 3){
+			if(dojo.lang.isFunction(obj)){
+				binary_func = obj;
+				obj = null;
+			}
+		}else{
+			// un-fsck the default order
+			// FIXME:
+			//		could be wrong for some strange function object cases. Not
+			//		sure how to test for them.
+			if(dojo.lang.isFunction(obj)){
+				var tmp = binary_func;
+				binary_func = obj;
+				obj = tmp;
+			}
+		}
 
-	}
+		var ob = obj || dj_global;
+		dojo.lang.map(arr, 
+			function(val){
+				reducedValue = binary_func.call(ob, reducedValue, val);
+			}
+		);
+		return reducedValue;
+	},
 
-	this.disconnect = function(){
+	forEach: function(/*Array*/anArray, /*Function*/callback, /*Object?*/thisObject){
 		// summary:
-		//		Takes the same parameters as dojo.event.connect() but destroys
-		//		an existing connection instead of building a new one. For
-		//		multiple identical connections, multiple disconnect() calls
-		//		will unroll one each time it's called.
-		if(arguments.length == 1){
-			var ao = arguments[0];
+		//		for every item in anArray, call callback with that item as its
+		//		only parameter. Return values are ignored. This funciton
+		//		corresponds (and wraps) the JavaScript 1.6 forEach method. For
+		//		more details, see:
+		//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:forEach
+		if(dojo.lang.isString(anArray)){
+			// anArray: String
+			anArray = anArray.split(""); 
+		}
+		if(Array.forEach){
+			Array.forEach(anArray, callback, thisObject);
 		}else{
-			var ao = interpolateArgs(arguments, true);
+			// FIXME: there are several ways of handilng thisObject. Is dj_global always the default context?
+			if(!thisObject){
+				thisObject=dj_global;
+			}
+			for(var i=0,l=anArray.length; i<l; i++){ 
+				callback.call(thisObject, anArray[i], i, anArray);
+			}
 		}
-		if(!ao.adviceFunc){ return; } // nothing to disconnect
-		if(dojo.lang.isString(ao.srcFunc) && (ao.srcFunc.toLowerCase() == "onkey") ){
-			if(dojo.render.html.ie){
-				ao.srcFunc = "onkeydown";
-				this.disconnect(ao);
+	},
+
+	_everyOrSome: function(/*Boolean*/every, /*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
+		if(dojo.lang.isString(arr)){ 
+			//arr: String
+			arr = arr.split(""); 
+		}
+		if(Array.every){
+			return Array[ every ? "every" : "some" ](arr, callback, thisObject);
+		}else{
+			if(!thisObject){
+				thisObject = dj_global;
 			}
-			ao.srcFunc = "onkeypress";
+			for(var i=0,l=arr.length; i<l; i++){
+				var result = callback.call(thisObject, arr[i], i, arr);
+				if(every && !result){
+					return false; // Boolean
+				}else if((!every)&&(result)){
+					return true; // Boolean
+				}
+			}
+			return Boolean(every); // Boolean
 		}
-		if(!ao.srcObj[ao.srcFunc]){ return null; } // prevent un-necessaray joinpoint creation
-		var mjp = dojo.event.MethodJoinPoint.getForMethod(ao.srcObj, ao.srcFunc, true);
-		mjp.removeAdvice(ao.adviceObj, ao.adviceFunc, ao.adviceType, ao.once); // a MethodJoinPoint object
-		return mjp;
-	}
+	},
 
-	this.kwDisconnect = function(kwArgs){
+	every: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
 		// summary:
-		//		Takes the same parameters as dojo.event.kwConnect() but
-		//		destroys an existing connection instead of building a new one.
-		return this._kwConnectImpl(kwArgs, true);
-	}
-}
+		//		determines whether or not every item in the array satisfies the
+		//		condition implemented by callback. thisObject may be used to
+		//		scope the call to callback. The function signature is derived
+		//		from the JavaScript 1.6 Array.every() function. More
+		//		information on this can be found here:
+		//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every
+		// examples:
+		//		dojo.lang.every([1, 2, 3, 4], function(item){ return item>1; });
+		//		// returns false
+		//		dojo.lang.every([1, 2, 3, 4], function(item){ return item>0; });
+		//		// returns true 
+		return this._everyOrSome(true, arr, callback, thisObject); // Boolean
+	},
 
-// exactly one of these is created whenever a method with a joint point is run,
-// if there is at least one 'around' advice.
-dojo.event.MethodInvocation = function(/*dojo.event.MethodJoinPoint*/join_point, /*Object*/obj, /*Array*/args){
-	// summary:
-	//		a class the models the call into a function. This is used under the
-	//		covers for all method invocations on both ends of a
-	//		connect()-wrapped function dispatch. This allows us to "pickle"
-	//		calls, such as in the case of around advice.
-	// join_point:
-	//		a dojo.event.MethodJoinPoint object that represents a connection
-	// obj:
-	//		the scope the call will execute in
-	// args:
-	//		an array of parameters that will get passed to the callee
-	this.jp_ = join_point;
-	this.object = obj;
-	this.args = [];
-	// make sure we don't lock into a mutable object which can change under us.
-	// It's ok if the individual items change, though.
-	for(var x=0; x<args.length; x++){
-		this.args[x] = args[x];
-	}
-	// the index of the 'around' that is currently being executed.
-	this.around_index = -1;
-}
+	some: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
+		// summary:
+		//		determines whether or not any item in the array satisfies the
+		//		condition implemented by callback. thisObject may be used to
+		//		scope the call to callback. The function signature is derived
+		//		from the JavaScript 1.6 Array.some() function. More
+		//		information on this can be found here:
+		//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
+		// examples:
+		//		dojo.lang.some([1, 2, 3, 4], function(item){ return item>1; });
+		//		// returns true
+		//		dojo.lang.some([1, 2, 3, 4], function(item){ return item<1; });
+		//		// returns false
+		return this._everyOrSome(false, arr, callback, thisObject); // Boolean
+	},
 
-dojo.event.MethodInvocation.prototype.proceed = function(){
-	// summary:
-	//		proceed with the method call that's represented by this invocation
-	//		object
-	this.around_index++;
-	if(this.around_index >= this.jp_.around.length){
-		return this.jp_.object[this.jp_.methodname].apply(this.jp_.object, this.args);
-		// return this.jp_.run_before_after(this.object, this.args);
-	}else{
-		var ti = this.jp_.around[this.around_index];
-		var mobj = ti[0]||dj_global;
-		var meth = ti[1];
-		return mobj[meth].call(mobj, this);
-	}
-} 
-
-
-dojo.event.MethodJoinPoint = function(/*Object*/obj, /*String*/funcName){
-	this.object = obj||dj_global;
-	this.methodname = funcName;
-	this.methodfunc = this.object[funcName];
-	this.squelch = false;
-	// this.before = [];
-	// this.after = [];
-	// this.around = [];
-}
-
-dojo.event.MethodJoinPoint.getForMethod = function(/*Object*/obj, /*String*/funcName){
-	// summary:
-	//		"static" class function for returning a MethodJoinPoint from a
-	//		scoped function. If one doesn't exist, one is created.
-	// obj:
-	//		the scope to search for the function in
-	// funcName:
-	//		the name of the function to return a MethodJoinPoint for
-	if(!obj){ obj = dj_global; }
-	var ofn = obj[funcName];
-	if(!ofn){
-		// supply a do-nothing method implementation
-		ofn = obj[funcName] = function(){};
-		if(!obj[funcName]){
-			// e.g. cannot add to inbuilt objects in IE6
-			dojo.raise("Cannot set do-nothing method on that object "+funcName);
-		}
-	}else if((typeof ofn != "function")&&(!dojo.lang.isFunction(ofn))&&(!dojo.lang.isAlien(ofn))){
-		// FIXME: should we throw an exception here instead?
-		return null; 
-	}
-	// we hide our joinpoint instance in obj[funcName + '$joinpoint']
-	var jpname = funcName + "$joinpoint";
-	var jpfuncname = funcName + "$joinpoint$method";
-	var joinpoint = obj[jpname];
-	if(!joinpoint){
-		var isNode = false;
-		if(dojo.event["browser"]){
-			if( (obj["attachEvent"])||
-				(obj["nodeType"])||
-				(obj["addEventListener"]) ){
-				isNode = true;
-				dojo.event.browser.addClobberNodeAttrs(obj, [jpname, jpfuncname, funcName]);
+	filter: function(/*Array*/arr, /*Function*/callback, /*Object?*/thisObject){
+		// summary:
+		//		returns a new Array with those items from arr that match the
+		//		condition implemented by callback.thisObject may be used to
+		//		scope the call to callback. The function signature is derived
+		//		from the JavaScript 1.6 Array.filter() function, although
+		//		special accomidation is made in our implementation for strings.
+		//		More information on the JS 1.6 API can be found here:
+		//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:filter
+		// examples:
+		//		dojo.lang.some([1, 2, 3, 4], function(item){ return item>1; });
+		//		// returns [2, 3, 4]
+		var isString = dojo.lang.isString(arr);
+		if(isString){ /*arr: String*/arr = arr.split(""); }
+		var outArr;
+		if(Array.filter){
+			outArr = Array.filter(arr, callback, thisObject);
+		}else{
+			if(!thisObject){
+				if(arguments.length >= 3){ dojo.raise("thisObject doesn't exist!"); }
+				thisObject = dj_global;
 			}
-		}
-		var origArity = ofn.length;
-		obj[jpfuncname] = ofn;
-		// joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, funcName);
-		joinpoint = obj[jpname] = new dojo.event.MethodJoinPoint(obj, jpfuncname);
 
-		if(!isNode){
-			obj[funcName] = function(){ 
-				// var args = [];
-				// for(var x=0; x<arguments.length; x++){
-					// args.push(arguments[x]);
-				// }
-				// return joinpoint.run.apply(joinpoint, args); 
-				return joinpoint.run.apply(joinpoint, arguments); 
+			outArr = [];
+			for(var i = 0; i < arr.length; i++){
+				if(callback.call(thisObject, arr[i], i, arr)){
+					outArr.push(arr[i]);
+				}
 			}
-		}else{
-			obj[funcName] = function(){ 
-				var args = [];
+		}
+		if(isString){
+			return outArr.join(""); // String
+		} else {
+			return outArr; // Array
+		}
+	},
 
-				if(!arguments.length){
-					var evt = null;
-					try{
-						if(obj.ownerDocument){
-							evt = obj.ownerDocument.parentWindow.event;
-						}else if(obj.documentElement){
-							evt = obj.documentElement.ownerDocument.parentWindow.event;
-						}else if(obj.event){ //obj is a window
-							evt = obj.event;
-						}else{
-							evt = window.event;
-						}
-					}catch(e){
-						evt = window.event;
-					}
+	unnest: function(/* ... */){
+		// summary:
+		//		Creates a 1-D array out of all the arguments passed,
+		//		unravelling any array-like objects in the process
+		// usage:
+		//		unnest(1, 2, 3) ==> [1, 2, 3]
+		//		unnest(1, [2, [3], [[[4]]]]) ==> [1, 2, 3, 4]
 
-					if(evt){
-						args.push(dojo.event.browser.fixEvent(evt, this));
-					}
-				}else{
-					for(var x=0; x<arguments.length; x++){
-						if((x==0)&&(dojo.event.browser.isEvent(arguments[x]))){
-							args.push(dojo.event.browser.fixEvent(arguments[x], this));
-						}else{
-							args.push(arguments[x]);
-						}
-					}
-				}
-				// return joinpoint.run.apply(joinpoint, arguments); 
-				return joinpoint.run.apply(joinpoint, args); 
+		var out = [];
+		for(var i = 0; i < arguments.length; i++){
+			if(dojo.lang.isArrayLike(arguments[i])){
+				var add = dojo.lang.unnest.apply(this, arguments[i]);
+				out = out.concat(add);
+			}else{
+				out.push(arguments[i]);
 			}
 		}
-		obj[funcName].__preJoinArity = origArity;
-	}
-	return joinpoint; // dojo.event.MethodJoinPoint
-}
+		return out; // Array
+	},
 
-dojo.lang.extend(dojo.event.MethodJoinPoint, {
-	squelch: false,
+	toArray: function(/*Object*/arrayLike, /*Number*/startOffset){
+		// summary:
+		//		Converts an array-like object (i.e. arguments, DOMCollection)
+		//		to an array. Returns a new Array object.
+		var array = [];
+		for(var i = startOffset||0; i < arrayLike.length; i++){
+			array.push(arrayLike[i]);
+		}
+		return array; // Array
+	}
+});
 
-	unintercept: function(){
-		// summary: 
-		//		destroy the connection to all listeners that may have been
-		//		registered on this joinpoint
-		this.object[this.methodname] = this.methodfunc;
-		this.before = [];
-		this.after = [];
-		this.around = [];
-	},
+dojo.provide("dojo.lang.func");
 
-	disconnect: dojo.lang.forward("unintercept"),
 
-	run: function(){
-		// summary:
-		//		execute the connection represented by this join point. The
-		//		arguments passed to run() will be passed to the function and
-		//		its listeners.
-		var obj = this.object||dj_global;
-		var args = arguments;
+dojo.lang.hitch = function(/*Object*/thisObject, /*Function|String*/method /*, ...*/){
+	// summary: 
+	//		Returns a function that will only ever execute in the a given scope
+	//		(thisObject). This allows for easy use of object member functions
+	//		in callbacks and other places in which the "this" keyword may
+	//		otherwise not reference the expected scope. Any number of default
+	//		positional arguments may be passed as parameters beyond "method".
+	//		Each of these values will be used to "placehold" (similar to curry)
+	//		for the hitched function. Note that the order of arguments may be
+	//		reversed in a future version.
+	// thisObject: the scope to run the method in
+	// method:
+	//		a function to be "bound" to thisObject or the name of the method in
+	//		thisObject to be used as the basis for the binding
+	// usage:
+	//		dojo.lang.hitch(foo, "bar")(); // runs foo.bar() in the scope of foo
+	//		dojo.lang.hitch(foo, myFunction); // returns a function that runs myFunction in the scope of foo
 
-		// optimization. We only compute once the array version of the arguments
-		// pseudo-arr in order to prevent building it each time advice is unrolled.
-		var aargs = [];
-		for(var x=0; x<args.length; x++){
-			aargs[x] = args[x];
+	var args = [];
+	for(var x=2; x<arguments.length; x++){
+		args.push(arguments[x]);
+	}
+	var fcn = (dojo.lang.isString(method) ? thisObject[method] : method) || function(){};
+	return function(){
+		var ta = args.concat([]); // make a copy
+		for(var x=0; x<arguments.length; x++){
+			ta.push(arguments[x]);
 		}
+		return fcn.apply(thisObject, ta); // Function
+		// return fcn.apply(thisObject, arguments); // Function
+	};
+}
 
-		var unrollAdvice  = function(marr){ 
-			if(!marr){
-				dojo.debug("Null argument to unrollAdvice()");
-				return;
-			}
-		  
-			var callObj = marr[0]||dj_global;
-			var callFunc = marr[1];
-			
-			if(!callObj[callFunc]){
-				dojo.raise("function \"" + callFunc + "\" does not exist on \"" + callObj + "\"");
-			}
-			
-			var aroundObj = marr[2]||dj_global;
-			var aroundFunc = marr[3];
-			var msg = marr[6];
-			var maxCount = marr[7];
-			if(maxCount > -1){
-				if(maxCount == 0){
-					return;
-				}
-				marr[7]--;
-			}
-			var undef;
+dojo.lang.anonCtr = 0;
+dojo.lang.anon = {};
 
-			var to = {
-				args: [],
-				jp_: this,
-				object: obj,
-				proceed: function(){
-					return callObj[callFunc].apply(callObj, to.args);
+dojo.lang.nameAnonFunc = function(/*Function*/anonFuncPtr, /*Object*/thisObj, /*Boolean*/searchForNames){
+	// summary:
+	//		Creates a reference to anonFuncPtr in thisObj with a completely
+	//		unique name. The new name is returned as a String.  If
+	//		searchForNames is true, an effort will be made to locate an
+	//		existing reference to anonFuncPtr in thisObj, and if one is found,
+	//		the existing name will be returned instead. The default is for
+	//		searchForNames to be false.
+	var nso = (thisObj|| dojo.lang.anon);
+	if( (searchForNames) ||
+		((dj_global["djConfig"])&&(djConfig["slowAnonFuncLookups"] == true)) ){
+		for(var x in nso){
+			try{
+				if(nso[x] === anonFuncPtr){
+					return x;
 				}
-			};
-			to.args = aargs;
-
-			var delay = parseInt(marr[4]);
-			var hasDelay = ((!isNaN(delay))&&(marr[4]!==null)&&(typeof marr[4] != "undefined"));
-			if(marr[5]){
-				var rate = parseInt(marr[5]);
-				var cur = new Date();
-				var timerSet = false;
-				if((marr["last"])&&((cur-marr.last)<=rate)){
-					if(dojo.event._canTimeout){
-						if(marr["delayTimer"]){
-							clearTimeout(marr.delayTimer);
-						}
-						var tod = parseInt(rate*2); // is rate*2 naive?
-						var mcpy = dojo.lang.shallowCopy(marr);
-						marr.delayTimer = setTimeout(function(){
-							// FIXME: on IE at least, event objects from the
-							// browser can go out of scope. How (or should?) we
-							// deal with it?
-							mcpy[5] = 0;
-							unrollAdvice(mcpy);
-						}, tod);
-					}
-					return;
-				}else{
-					marr.last = cur;
-				}
-			}
+			}catch(e){} // window.external fails in IE embedded in Eclipse (Eclipse bug #151165)
+		}
+	}
+	var ret = "__"+dojo.lang.anonCtr++;
+	while(typeof nso[ret] != "undefined"){
+		ret = "__"+dojo.lang.anonCtr++;
+	}
+	nso[ret] = anonFuncPtr;
+	return ret; // String
+}
 
-			// FIXME: need to enforce rates for a connection here!
+dojo.lang.forward = function(funcName){
+	// summary:
+	// 		Returns a function that forwards a method call to
+	// 		this.funcName(...).  Unlike dojo.lang.hitch(), the "this" scope is
+	// 		not fixed on a single object. Ported from MochiKit.
+	return function(){
+		return this[funcName].apply(this, arguments);
+	}; // Function
+}
 
-			if(aroundFunc){
-				// NOTE: around advice can't delay since we might otherwise depend
-				// on execution order!
-				aroundObj[aroundFunc].call(aroundObj, to);
-			}else{
-				// var tmjp = dojo.event.MethodJoinPoint.getForMethod(obj, methname);
-				if((hasDelay)&&((dojo.render.html)||(dojo.render.svg))){  // FIXME: the render checks are grotty!
-					dj_global["setTimeout"](function(){
-						if(msg){
-							callObj[callFunc].call(callObj, to); 
-						}else{
-							callObj[callFunc].apply(callObj, args); 
-						}
-					}, delay);
-				}else{ // many environments can't support delay!
-					if(msg){
-						callObj[callFunc].call(callObj, to); 
-					}else{
-						callObj[callFunc].apply(callObj, args); 
-					}
-				}
-			}
-		};
+dojo.lang.curry = function(thisObj, func /* args ... */){
+	// summary:
+	//		similar to the curry() method found in many functional programming
+	//		environments, this function returns an "argument accumulator"
+	//		function, bound to a particular scope, and "primed" with a variable
+	//		number of arguments. The curry method is unique in that it returns
+	//		a function that may return other "partial" function which can be
+	//		called repeatedly. New functions are returned until the arity of
+	//		the original function is reached, at which point the underlying
+	//		function (func) is called in the scope thisObj with all of the
+	//		accumulated arguments (plus any extras) in positional order.
+	// examples:
+	//		assuming a function defined like this:
+	//			var foo = {
+	//				bar: function(arg1, arg2, arg3){
+	//					dojo.debug.apply(dojo, arguments);
+	//				}
+	//			};
+	//		
+	//		dojo.lang.curry() can be used most simply in this way:
+	//		
+	//			tmp = dojo.lang.curry(foo, foo.bar, "arg one", "thinger");
+	//			tmp("blah", "this is superfluous");
+	//			// debugs: "arg one thinger blah this is superfluous"
+	//			tmp("blah");
+	//			// debugs: "arg one thinger blah"
+	//			tmp();
+	//			// returns a function exactly like tmp that expects one argument
+	//
+	//		other intermittent functions could be created until the 3
+	//		positional arguments are filled:
+	//
+	//			tmp = dojo.lang.curry(foo, foo.bar, "arg one");
+	//			tmp2 = tmp("arg two");
+	//			tmp2("blah blah");
+	//			// debugs: "arg one arg two blah blah"
+	//			tmp2("oy");
+	//			// debugs: "arg one arg two oy"
+	//
+	//		curry() can also be used to call the function if enough arguments
+	//		are passed in the initial invocation:
+	//
+	//			dojo.lang.curry(foo, foo.bar, "one", "two", "three", "four");
+	//			// debugs: "one two three four"
+	//			dojo.lang.curry(foo, foo.bar, "one", "two", "three");
+	//			// debugs: "one two three"
 
-		var unRollSquelch = function(){
-			if(this.squelch){
-				try{
-					return unrollAdvice.apply(this, arguments);
-				}catch(e){ 
-					dojo.debug(e);
-				}
-			}else{
-				return unrollAdvice.apply(this, arguments);
-			}
-		};
 
-		if((this["before"])&&(this.before.length>0)){
-			// pass a cloned array, if this event disconnects this event forEach on this.before wont work
-			dojo.lang.forEach(this.before.concat(new Array()), unRollSquelch);
+	// FIXME: the order of func and thisObj should be changed!!!
+	var outerArgs = [];
+	thisObj = thisObj||dj_global;
+	if(dojo.lang.isString(func)){
+		func = thisObj[func];
+	}
+	for(var x=2; x<arguments.length; x++){
+		outerArgs.push(arguments[x]);
+	}
+	// since the event system replaces the original function with a new
+	// join-point runner with an arity of 0, we check to see if it's left us
+	// any clues about the original arity in lieu of the function's actual
+	// length property
+	var ecount = (func["__preJoinArity"]||func.length) - outerArgs.length;

[... 8855 lines stripped ...]