Commits

Anonymous committed cd4a62c

Comments (0)

Files changed (297)

src/java/com/opensymphony/webwork/static/dojo/AdapterRegistry.js

+if(!dojo._hasResource["dojo.AdapterRegistry"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.AdapterRegistry"] = true;
+dojo.provide("dojo.AdapterRegistry");
+
+dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
+	//	summary:
+	//		A registry to make contextual calling/searching easier.
+	//	description:
+	//		Objects of this class keep list of arrays in the form [name, check,
+	//		wrap, directReturn] that are used to determine what the contextual
+	//		result of a set of checked arguments is. All check/wrap functions
+	//		in this registry should be of the same arity.
+	//	example:
+	//	|	// create a new registry
+	//	|	var reg = new dojo.AdapterRegistry();
+	//	|	reg.register("handleString",
+	//	|		dojo.isString,
+	//	|		function(str){
+	//	|			// do something with the string here
+	//	|		}
+	//	|	);
+	//	|	reg.register("handleArr",
+	//	|		dojo.isArray,
+	//	|		function(arr){
+	//	|			// do something with the array here
+	//	|		}
+	//	|	);
+	//	|
+	//	|	// now we can pass reg.match() *either* an array or a string and
+	//	|	// the value we pass will get handled by the right function
+	//	|	reg.match("someValue"); // will call the first function
+	//	|	reg.match(["someValue"]); // will call the second
+
+	this.pairs = [];
+	this.returnWrappers = returnWrappers || false; // Boolean
+}
+
+dojo.extend(dojo.AdapterRegistry, {
+	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
+		//	summary: 
+		//		register a check function to determine if the wrap function or
+		//		object gets selected
+		//	name:
+		//		a way to identify this matcher.
+		//	check:
+		//		a function that arguments are passed to from the adapter's
+		//		match() function.  The check function should return true if the
+		//		given arguments are appropriate for the wrap function.
+		//	directReturn:
+		//		If directReturn is true, the value passed in for wrap will be
+		//		returned instead of being called. Alternately, the
+		//		AdapterRegistry can be set globally to "return not call" using
+		//		the returnWrappers property. Either way, this behavior allows
+		//		the registry to act as a "search" function instead of a
+		//		function interception library.
+		//	override:
+		//		If override is given and true, the check function will be given
+		//		highest priority. Otherwise, it will be the lowest priority
+		//		adapter.
+		this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
+	},
+
+	match: function(/* ... */){
+		// summary:
+		//		Find an adapter for the given arguments. If no suitable adapter
+		//		is found, throws an exception. match() accepts any number of
+		//		arguments, all of which are passed to all matching functions
+		//		from the registered pairs.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[1].apply(this, arguments)){
+				if((pair[3])||(this.returnWrappers)){
+					return pair[2];
+				}else{
+					return pair[2].apply(this, arguments);
+				}
+			}
+		}
+		throw new Error("No match found");
+	},
+
+	unregister: function(name){
+		// summary: Remove a named adapter from the registry
+
+		// FIXME: this is kind of a dumb way to handle this. On a large
+		// registry this will be slow-ish and we can use the name as a lookup
+		// should we choose to trade memory for speed.
+		for(var i = 0; i < this.pairs.length; i++){
+			var pair = this.pairs[i];
+			if(pair[0] == name){
+				this.pairs.splice(i, 1);
+				return true;
+			}
+		}
+		return false;
+	}
+});
+
+}

src/java/com/opensymphony/webwork/static/dojo/DeferredList.js

+if(!dojo._hasResource["dojo.DeferredList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.DeferredList"] = true;
+dojo.provide("dojo.DeferredList");
+dojo.declare("dojo.DeferredList", dojo.Deferred, {
+	constructor: function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*Boolean?*/ fireOnOneErrback, /*Boolean?*/ consumeErrors, /*Function?*/ canceller){
+		// summary:
+		//		Provides event handling for a group of Deferred objects.
+		// description:
+		//		DeferredList takes an array of existing deferreds and returns a new deferred of its own
+		//		this new deferred will typically have its callback fired when all of the deferreds in
+		//		the given list have fired their own deferreds.  The parameters `fireOnOneCallback` and
+		//		fireOnOneErrback, will fire before all the deferreds as appropriate
+		//
+		//	list:
+		//		The list of deferreds to be synchronizied with this DeferredList
+		//	fireOnOneCallback:
+		//		Will cause the DeferredLists callback to be fired as soon as any
+		//		of the deferreds in its list have been fired instead of waiting until
+		//		the entire list has finished
+		//	fireonOneErrback:
+		//		Will cause the errback to fire upon any of the deferreds errback
+		//	canceller:
+		//		A deferred canceller function, see dojo.Deferred
+		this.list = list;
+		this.resultList = new Array(this.list.length);
+
+		// Deferred init
+		this.chain = [];
+		this.id = this._nextId();
+		this.fired = -1;
+		this.paused = 0;
+		this.results = [null, null];
+		this.canceller = canceller;
+		this.silentlyCancelled = false;
+
+		if (this.list.length === 0 && !fireOnOneCallback) {
+			this.callback(this.resultList);
+		}
+
+		this.finishedCount = 0;
+		this.fireOnOneCallback = fireOnOneCallback;
+		this.fireOnOneErrback = fireOnOneErrback;
+		this.consumeErrors = consumeErrors;
+
+		var index = 0;
+
+		dojo.forEach(this.list, function(d, index) {
+			d.addCallback(this, function(r) { this._cbDeferred(index, true, r); return r; });
+			d.addErrback(this, function(r) { this._cbDeferred(index, false, r); return r; });
+			index++;
+		},this);
+	},
+
+	_cbDeferred: function (index, succeeded, result) {
+		// summary:
+		//	The DeferredLists' callback handler
+
+		this.resultList[index] = [succeeded, result]; this.finishedCount += 1;
+		if (this.fired !== 0) {
+			if (succeeded && this.fireOnOneCallback) {
+				this.callback([index, result]);
+			} else if (!succeeded && this.fireOnOneErrback) {
+			this.errback(result);
+			} else if (this.finishedCount == this.list.length) {
+				this.callback(this.resultList);
+			}
+		}
+		if (!succeeded && this.consumeErrors) {
+			result = null;
+		}
+		return result;
+	},
+
+	gatherResults: function (deferredList) {
+		// summary:	
+		//	Gathers the results of the deferreds for packaging
+		//	as the parameters to the Deferred Lists' callback
+
+		var d = new dojo.DeferedList(deferredList, false, true, false);
+		d.addCallback(function (results) {
+			var ret = [];
+			for (var i = 0; i < results.length; i++) {
+				ret.push(results[i][1]);
+			}
+			return ret;
+		});
+		return d;
+	}
+});
+
+}

src/java/com/opensymphony/webwork/static/dojo/LICENSE

+Dojo is availble under *either* the terms of the modified BSD license *or* the
+Academic Free License version 2.1. As a recipient of Dojo, you may choose which
+license to receive this code under (except as noted in per-module LICENSE
+files). Some modules may not be the copyright of the Dojo Foundation. These
+modules contain explicit declarations of copyright in both the LICENSE files in
+the directories in which they reside and in the code itself. No external
+contributions are allowed under licenses which are fundamentally incompatible
+with the AFL or BSD licenses that Dojo is distributed under.
+
+The text of the AFL and BSD licenses is reproduced below. 
+
+-------------------------------------------------------------------------------
+The "New" BSD License:
+**********************
+
+Copyright (c) 2005-2007, The Dojo Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice, this
+    list of conditions and the following disclaimer.
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+  * Neither the name of the Dojo Foundation nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------------------
+The Academic Free License, v. 2.1:
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.

src/java/com/opensymphony/webwork/static/dojo/NodeList-fx.js

+if(!dojo._hasResource["dojo.NodeList-fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.NodeList-fx"] = true;
+dojo.provide("dojo.NodeList-fx");
+dojo.require("dojo.fx");
+
+dojo.extend(dojo.NodeList, {
+	_anim: function(obj, method, args){
+		var anims = [];
+		args = args||{};
+		this.forEach(function(item){
+			var tmpArgs = { node: item };
+			dojo.mixin(tmpArgs, args);
+			anims.push(obj[method](tmpArgs));
+		});
+		return dojo.fx.combine(anims); // dojo._Animation
+	},
+
+	wipeIn: function(args){
+		//	summary:
+		//		wipe in all elements of this NodeList. Returns an instance of dojo._Animation
+		//	example:
+		//		Fade in all tables with class "blah":
+		//		|	dojo.query("table.blah").wipeIn().play();
+		return this._anim(dojo.fx, "wipeIn", args); // dojo._Animation
+	},
+
+	wipeOut: function(args){
+		//	summary:
+		//		wipe out all elements of this NodeList. Returns an instance of dojo._Animation
+		//	example:
+		//		Wipe out all tables with class "blah":
+		//		|	dojo.query("table.blah").wipeOut().play();
+		return this._anim(dojo.fx, "wipeOut", args); // dojo._Animation
+	},
+
+	slideTo: function(args){
+		//	summary:
+		//		slide all elements of the node list to the specified place.
+		//		Returns an instance of dojo._Animation
+		//	example:
+		//		|	Move all tables with class "blah" to 300/300:
+		//		|	dojo.query("table.blah").slideTo({
+		//		|		left: 40,
+		//		|		top: 50
+		//		|	}).play();
+		return this._anim(dojo.fx, "slideTo", args); // dojo._Animation
+	},
+
+
+	fadeIn: function(args){
+		//	summary:
+		//		fade in all elements of this NodeList. Returns an instance of dojo._Animation
+		//	example:
+		//		Fade in all tables with class "blah":
+		//		|	dojo.query("table.blah").fadeIn().play();
+		return this._anim(dojo, "fadeIn", args); // dojo._Animation
+	},
+
+	fadeOut: function(args){
+		//	summary:
+		//		fade out all elements of this NodeList. Returns an instance of dojo._Animation
+		//	example:
+		//		Fade out all elements with class "zork":
+		//		|	dojo.query(".zork").fadeOut().play();
+		//	example:
+		//		Fade them on a delay and do something at the end:
+		//		|	var fo = dojo.query(".zork").fadeOut();
+		//		|	dojo.connect(fo, "onEnd", function(){ /*...*/ });
+		//		|	fo.play();
+		return this._anim(dojo, "fadeOut", args); // dojo._Animation
+	},
+
+	animateProperty: function(args){
+		//	summary:
+		//		see dojo.animateProperty(). Animate all elements of this
+		//		NodeList across the properties specified.
+		//	example:
+		//	|	dojo.query(".zork").animateProperty({
+		//	|		duration: 500,
+		//	|		properties: { 
+		//	|			color:		{ start: "black", end: "white" },
+		//	|			left:		{ end: 300 } 
+		//	|		} 
+		//	|	}).play();
+		return this._anim(dojo, "animateProperty", args); // dojo._Animation
+	}
+});
+
+}

src/java/com/opensymphony/webwork/static/dojo/OpenAjax.js

+/*******************************************************************************
+ * OpenAjax.js
+ *
+ * Reference implementation of the OpenAjax Hub, as specified by OpenAjax Alliance.
+ * Specification is under development at: 
+ *
+ *   http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification
+ *
+ * Copyright 2006-2007 OpenAjax Alliance
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
+ * use this file except in compliance with the License. You may obtain a copy 
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0 . Unless 
+ * required by applicable law or agreed to in writing, software distributed 
+ * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+ * CONDITIONS OF ANY KIND, either express or implied. See the License for the 
+ * specific language governing permissions and limitations under the License.
+ *
+ ******************************************************************************/
+
+// prevent re-definition of the OpenAjax object
+if(!window["OpenAjax"]){
+	OpenAjax = new function(){
+		var t = true;
+		var f = false;
+		var g = window;
+		var libs;
+		var ooh = "org.openajax.hub.";
+
+		var h = {};
+		this.hub = h;
+		h.implementer = "http://openajax.org";
+		h.implVersion = "0.6";
+		h.specVersion = "0.6";
+		h.implExtraData = {};
+		var libs = {};
+		h.libraries = libs;
+
+		h.registerLibrary = function(prefix, nsURL, version, extra){
+			libs[prefix] = {
+				prefix: prefix,
+				namespaceURI: nsURL,
+				version: version,
+				extraData: extra 
+			};
+			this.publish(ooh+"registerLibrary", libs[prefix]);
+		}
+		h.unregisterLibrary = function(prefix){
+			this.publish(ooh+"unregisterLibrary", libs[prefix]);
+			delete libs[prefix];
+		}
+
+		h._subscriptions = { c:{}, s:[] };
+		h._cleanup = [];
+		h._subIndex = 0;
+		h._pubDepth = 0;
+
+		h.subscribe = function(name, callback, scope, subscriberData, filter){
+			if(!scope){
+				scope = window;
+			}
+			var handle = name + "." + this._subIndex;
+			var sub = { scope: scope, cb: callback, fcb: filter, data: subscriberData, sid: this._subIndex++, hdl: handle };
+			var path = name.split(".");
+	 		this._subscribe(this._subscriptions, path, 0, sub);
+			return handle;
+		}
+
+		h.publish = function(name, message){
+			var path = name.split(".");
+			this._pubDepth++;
+			this._publish(this._subscriptions, path, 0, name, message);
+			this._pubDepth--;
+			if((this._cleanup.length > 0) && (this._pubDepth == 0)){
+				for(var i = 0; i < this._cleanup.length; i++){ 
+					this.unsubscribe(this._cleanup[i].hdl);
+				}
+				delete(this._cleanup);
+				this._cleanup = [];
+			}
+		}
+
+		h.unsubscribe = function(sub){
+			var path = sub.split(".");
+			var sid = path.pop();
+			this._unsubscribe(this._subscriptions, path, 0, sid);
+		}
+		
+		h._subscribe = function(tree, path, index, sub){
+			var token = path[index];
+			if(index == path.length){
+				tree.s.push(sub);
+			}else{ 
+				if(typeof tree.c == "undefined"){
+					 tree.c = {};
+				}
+				if(typeof tree.c[token] == "undefined"){
+					tree.c[token] = { c: {}, s: [] }; 
+					this._subscribe(tree.c[token], path, index + 1, sub);
+				}else{
+					this._subscribe( tree.c[token], path, index + 1, sub);
+				}
+			}
+		}
+
+		h._publish = function(tree, path, index, name, msg){
+			if(typeof tree != "undefined"){
+				var node;
+				if(index == path.length) {
+					node = tree;
+				}else{
+					this._publish(tree.c[path[index]], path, index + 1, name, msg);
+					this._publish(tree.c["*"], path, index + 1, name, msg);			
+					node = tree.c["**"];
+				}
+				if(typeof node != "undefined"){
+					var callbacks = node.s;
+					var max = callbacks.length;
+					for(var i = 0; i < max; i++){
+						if(callbacks[i].cb){
+							var sc = callbacks[i].scope;
+							var cb = callbacks[i].cb;
+							var fcb = callbacks[i].fcb;
+							var d = callbacks[i].data;
+							if(typeof cb == "string"){
+								// get a function object
+								cb = sc[cb];
+							}
+							if(typeof fcb == "string"){
+								// get a function object
+								fcb = sc[fcb];
+							}
+							if((!fcb) || 
+							   (fcb.call(sc, name, msg, d))) {
+								cb.call(sc, name, msg, d);
+							}
+						}
+					}
+				}
+			}
+		}
+			
+		h._unsubscribe = function(tree, path, index, sid) {
+			if(typeof tree != "undefined") {
+				if(index < path.length) {
+					var childNode = tree.c[path[index]];
+					this._unsubscribe(childNode, path, index + 1, sid);
+					if(childNode.s.length == 0) {
+						for(var x in childNode.c) 
+					 		return;		
+						delete tree.c[path[index]];	
+					}
+					return;
+				}
+				else {
+					var callbacks = tree.s;
+					var max = callbacks.length;
+					for(var i = 0; i < max; i++) 
+						if(sid == callbacks[i].sid) {
+							if(this._pubDepth > 0) {
+								callbacks[i].cb = null;	
+								this._cleanup.push(callbacks[i]);						
+							}
+							else
+								callbacks.splice(i, 1);
+							return; 	
+						}
+				}
+			}
+		}
+		// The following function is provided for automatic testing purposes.
+		// It is not expected to be deployed in run-time OpenAjax Hub implementations.
+		h.reinit = function()
+		{
+			for (var lib in OpenAjax.hub.libraries) {
+				delete OpenAjax.hub.libraries[lib];
+			}
+			OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "0.6", {});
+
+			delete OpenAjax._subscriptions;
+			OpenAjax._subscriptions = {c:{},s:[]};
+			delete OpenAjax._cleanup;
+			OpenAjax._cleanup = [];
+			OpenAjax._subIndex = 0;
+			OpenAjax._pubDepth = 0;
+		}
+	};
+	// Register the OpenAjax Hub itself as a library.
+	OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "0.6", {});
+
+}

src/java/com/opensymphony/webwork/static/dojo/_base.js

+if(!dojo._hasResource["dojo._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base"] = true;
+dojo.provide("dojo._base");
+dojo.require("dojo._base.lang");
+dojo.require("dojo._base.declare");
+dojo.require("dojo._base.connect");
+dojo.require("dojo._base.Deferred");
+dojo.require("dojo._base.json");
+dojo.require("dojo._base.array");
+dojo.require("dojo._base.Color");
+dojo.requireIf(dojo.isBrowser, "dojo._base.window");
+dojo.requireIf(dojo.isBrowser, "dojo._base.event");
+dojo.requireIf(dojo.isBrowser, "dojo._base.html");
+dojo.requireIf(dojo.isBrowser, "dojo._base.NodeList");
+dojo.requireIf(dojo.isBrowser, "dojo._base.query");
+dojo.requireIf(dojo.isBrowser, "dojo._base.xhr");
+dojo.requireIf(dojo.isBrowser, "dojo._base.fx");
+
+(function(){
+	if(djConfig.require){
+		for(var x=0; x<djConfig.require.length; x++){
+			dojo["require"](djConfig.require[x]);
+		}
+	}
+})();
+
+}

src/java/com/opensymphony/webwork/static/dojo/_base/Color.js

+if(!dojo._hasResource["dojo._base.Color"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.Color"] = true;
+dojo.provide("dojo._base.Color");
+dojo.require("dojo._base.array");
+dojo.require("dojo._base.lang");
+
+dojo.Color = function(/*Array|String|Object*/ color){
+	// summary:
+	//		takes a named string, hex string, array of rgb or rgba values,
+	//		an object with r, g, b, and a properties, or another dojo.Color object
+	if(color){ this.setColor(color); }
+};
+
+// FIXME: there's got to be a more space-efficient way to encode or discover these!!  Use hex?
+dojo.Color.named = {
+	black:      [0,0,0],
+	silver:     [192,192,192],
+	gray:       [128,128,128],
+	white:      [255,255,255],
+	maroon:		[128,0,0],
+	red:        [255,0,0],
+	purple:		[128,0,128],
+	fuchsia:	[255,0,255],
+	green:	    [0,128,0],
+	lime:	    [0,255,0],
+	olive:		[128,128,0],
+	yellow:		[255,255,0],
+	navy:       [0,0,128],
+	blue:       [0,0,255],
+	teal:		[0,128,128],
+	aqua:		[0,255,255]
+};
+
+
+dojo.extend(dojo.Color, {
+	r: 255, g: 255, b: 255, a: 1,
+	_set: function(r, g, b, a){
+		var t = this; t.r = r; t.g = g; t.b = b; t.a = a;
+	},
+	setColor: function(/*Array|String|Object*/ color){
+		// summary:
+		//		takes a named string, hex string, array of rgb or rgba values,
+		//		an object with r, g, b, and a properties, or another dojo.Color object
+		var d = dojo;
+		if(d.isString(color)){
+			d.colorFromString(color, this);
+		}else if(d.isArray(color)){
+			d.colorFromArray(color, this);
+		}else{
+			this._set(color.r, color.g, color.b, color.a);
+			if(!(color instanceof d.Color)){ this.sanitize(); }
+		}
+		return this;	// dojo.Color
+	},
+	sanitize: function(){
+		// summary:
+		//		makes sure that the object has correct attributes
+		// description: 
+		//		the default implementation does nothing, include dojo.colors to
+		//		augment it to real checks
+		return this;	// dojo.Color
+	},
+	toRgb: function(){
+		// summary: returns 3 component array of rgb values
+		var t = this;
+		return [t.r, t.g, t.b];	// Array
+	},
+	toRgba: function(){
+		// summary: returns a 4 component array of rgba values
+		var t = this;
+		return [t.r, t.g, t.b, t.a];	// Array
+	},
+	toHex: function(){
+		// summary: returns a css color string in hexadecimal representation
+		var arr = dojo.map(["r", "g", "b"], function(x){
+			var s = this[x].toString(16);
+			return s.length < 2 ? "0" + s : s;
+		}, this);
+		return "#" + arr.join("");	// String
+	},
+	toCss: function(/*Boolean?*/ includeAlpha){
+		// summary: returns a css color string in rgb(a) representation
+		var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
+		return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")";	// String
+	},
+	toString: function(){
+		// summary: returns a visual representation of the color
+		return this.toCss(true); // String
+	}
+});
+
+dojo.blendColors = function(
+	/*dojo.Color*/ start, 
+	/*dojo.Color*/ end, 
+	/*Number*/ weight,
+	/*dojo.Color?*/ obj
+){
+	// summary: 
+	//		blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
+	//		can reuse a previously allocated dojo.Color object for the result
+	var d = dojo, t = obj || new dojo.Color();
+	d.forEach(["r", "g", "b", "a"], function(x){
+		t[x] = start[x] + (end[x] - start[x]) * weight;
+		if(x != "a"){ t[x] = Math.round(t[x]); }
+	});
+	return t.sanitize();	// dojo.Color
+};
+
+dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
+	// summary: get rgb(a) array from css-style color declarations
+	var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
+	return m && dojo.colorFromArray(m[1].split(/\s*,\s*/), obj);	// dojo.Color
+};
+
+dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
+	// summary: converts a hex string with a '#' prefix to a color object.
+	//	Supports 12-bit #rgb shorthand.
+	var d = dojo, t = obj || new d.Color(),
+		bits = (color.length == 4) ? 4 : 8,
+		mask = (1 << bits) - 1;
+	color = Number("0x" + color.substr(1));
+	if(isNaN(color)){
+		return null; // dojo.Color
+	}
+	d.forEach(["b", "g", "r"], function(x){
+		var c = color & mask;
+		color >>= bits;
+		t[x] = bits == 4 ? 17 * c : c;
+	});
+	t.a = 1;
+	return t;	// dojo.Color
+};
+
+dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
+	// summary: builds a color from 1, 2, 3, or 4 element array
+	var t = obj || new dojo.Color();
+	t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
+	if(isNaN(t.a)){ t.a = 1; }
+	return t.sanitize();	// dojo.Color
+};
+
+dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
+	//	summary:
+	//		parses str for a color value.
+	//	description:
+	//		Acceptable input values for str may include arrays of any form
+	//		accepted by dojo.colorFromArray, hex strings such as "#aaaaaa", or
+	//		rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
+	//		10, 50)"
+	//	returns:
+	//		a dojo.Color object. If obj is passed, it will be the return value.
+	var a = dojo.Color.named[str];
+	return a && dojo.colorFromArray(a, obj) || dojo.colorFromRgb(str, obj) || dojo.colorFromHex(str, obj);
+};
+
+}

src/java/com/opensymphony/webwork/static/dojo/_base/Deferred.js

+if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.Deferred"] = true;
+dojo.provide("dojo._base.Deferred");
+dojo.require("dojo._base.lang");
+
+dojo.Deferred = function(/*Function?*/ canceller){
+	// summary:
+	//		Encapsulates a sequence of callbacks in response to a value that
+	//		may not yet be available.  This is modeled after the Deferred class
+	//		from Twisted <http://twistedmatrix.com>.
+	// description:
+	//		JavaScript has no threads, and even if it did, threads are hard.
+	//		Deferreds are a way of abstracting non-blocking events, such as the
+	//		final response to an XMLHttpRequest. Deferreds create a promise to
+	//		return a response a some point in the future and an easy way to
+	//		register your interest in receiving that response.
+	//
+	//		The most important methods for Deffered users are:
+	//
+	//			* addCallback(handler)
+	//			* addErrback(handler)
+	//			* callback(result)
+	//			* errback(result)
+	//
+	//		In general, when a function returns a Deferred, users then "fill
+	//		in" the second half of the contract by registering callbacks and
+	//		error handlers. You may register as many callback and errback
+	//		handlers as you like and they will be executed in the order
+	//		registered when a result is provided. Usually this result is
+	//		provided as the result of an asynchronous operation. The code
+	//		"managing" the Deferred (the code that made the promise to provide
+	//		an answer later) will use the callback() and errback() methods to
+	//		communicate with registered listeners about the result of the
+	//		operation. At this time, all registered result handlers are called
+	//		*with the most recent result value*.
+	//
+	//		Deferred callback handlers are treated as a chain, and each item in
+	//		the chain is required to return a value that will be fed into
+	//		successive handlers. The most minimal callback may be registered
+	//		like this:
+	//
+	//		|	var d = new dojo.Deferred();
+	//		|	d.addCallback(function(result){ return result; });
+	//
+	//		Perhaps the most common mistake when first using Deferreds is to
+	//		forget to return a value (in most cases, the value you were
+	//		passed).
+	//
+	//		The sequence of callbacks is internally represented as a list of
+	//		2-tuples containing the callback/errback pair.  For example, the
+	//		following call sequence:
+	//		
+	//		|	var d = new dojo.Deferred();
+	//		|	d.addCallback(myCallback);
+	//		|	d.addErrback(myErrback);
+	//		|	d.addBoth(myBoth);
+	//		|	d.addCallbacks(myCallback, myErrback);
+	//
+	//		is translated into a Deferred with the following internal
+	//		representation:
+	//
+	//		|	[
+	//		|		[myCallback, null],
+	//		|		[null, myErrback],
+	//		|		[myBoth, myBoth],
+	//		|		[myCallback, myErrback]
+	//		|	]
+	//
+	//		The Deferred also keeps track of its current status (fired).  Its
+	//		status may be one of three things:
+	//
+	//			* -1: no value yet (initial condition)
+	//			* 0: success
+	//			* 1: error
+	//	
+	//		A Deferred will be in the error state if one of the following three
+	//		conditions are met:
+	//
+	//			1. The result given to callback or errback is "instanceof" Error
+	//			2. The previous callback or errback raised an exception while
+	//			   executing
+	//			3. The previous callback or errback returned a value
+	//			   "instanceof" Error
+	//
+	//		Otherwise, the Deferred will be in the success state. The state of
+	//		the Deferred determines the next element in the callback sequence
+	//		to run.
+	//
+	//		When a callback or errback occurs with the example deferred chain,
+	//		something equivalent to the following will happen (imagine
+	//		that exceptions are caught and returned):
+	//
+	//		|	// d.callback(result) or d.errback(result)
+	//		|	if(!(result instanceof Error)){
+	//		|		result = myCallback(result);
+	//		|	}
+	//		|	if(result instanceof Error){
+	//		|		result = myErrback(result);
+	//		|	}
+	//		|	result = myBoth(result);
+	//		|	if(result instanceof Error){
+	//		|		result = myErrback(result);
+	//		|	}else{
+	//		|		result = myCallback(result);
+	//		|	}
+	//
+	//		The result is then stored away in case another step is added to the
+	//		callback sequence.	Since the Deferred already has a value
+	//		available, any new callbacks added will be called immediately.
+	//
+	//		There are two other "advanced" details about this implementation
+	//		that are useful:
+	//
+	//		Callbacks are allowed to return Deferred instances themselves, so
+	//		you can build complicated sequences of events with ease.
+	//
+	//		The creator of the Deferred may specify a canceller.  The canceller
+	//		is a function that will be called if Deferred.cancel is called
+	//		before the Deferred fires. You can use this to implement clean
+	//		aborting of an XMLHttpRequest, etc. Note that cancel will fire the
+	//		deferred with a CancelledError (unless your canceller returns
+	//		another kind of error), so the errbacks should be prepared to
+	//		handle that error for cancellable Deferreds.
+	// example:
+	//	|	var deferred = new dojo.Deferred();
+	//	|	setTimeout(function(){ deferred.callback({success: true}); }, 1000);
+	//	|	return deferred;
+	// example:
+	//		Deferred objects are often used when making code asynchronous. It
+	//		may be easiest to write functions in a synchronous manner and then
+	//		split code using a deferred to trigger a response to a long-lived
+	//		operation. For example, instead of register a callback function to
+	//		denote when a rendering operation completes, the function can
+	//		simply return a deferred:
+	//
+	//		|	// callback style:
+	//		|	function renderLotsOfData(data, callback){
+	//		|		var success = false
+	//		|		try{
+	//		|			for(var x in data){
+	//		|				renderDataitem(data[x]);
+	//		|			}
+	//		|			success = true;
+	//		|		}catch(e){ }
+	//		|		if(callback){
+	//		|			callback(success);
+	//		|		}
+	//		|	}
+	//
+	//		|	// using callback style
+	//		|	renderLotsOfData(someDataObj, function(success){
+	//		|		// handles success or failure
+	//		|		if(!success){
+	//		|			promptUserToRecover();
+	//		|		}
+	//		|	});
+	//		|	// NOTE: no way to add another callback here!!
+	// example:
+	//		Using a Deferred doesn't simplify the sending code any, but it
+	//		provides a standard interface for callers and senders alike,
+	//		providing both with a simple way to service multiple callbacks for
+	//		an operation and freeing both sides from worrying about details
+	//		such as "did this get called already?". With Deferreds, new
+	//		callbacks can be added at any time.
+	//
+	//		|	// Deferred style:
+	//		|	function renderLotsOfData(data){
+	//		|		var d = new dojo.Deferred();
+	//		|		try{
+	//		|			for(var x in data){
+	//		|				renderDataitem(data[x]);
+	//		|			}
+	//		|			d.callback(true);
+	//		|		}catch(e){ 
+	//		|			d.errback(new Error("rendering failed"));
+	//		|		}
+	//		|		return d;
+	//		|	}
+	//
+	//		|	// using Deferred style
+	//		|	renderLotsOfData(someDataObj).addErrback(function(){
+	//		|		promptUserToRecover();
+	//		|	});
+	//		|	// NOTE: addErrback and addCallback both return the Deferred
+	//		|	// again, so we could chain adding callbacks or save the
+	//		|	// deferred for later should we need to be notified again.
+	// example:
+	//		In this example, renderLotsOfData is syncrhonous and so both
+	//		versions are pretty artificial. Putting the data display on a
+	//		timeout helps show why Deferreds rock:
+	//
+	//		|	// Deferred style and async func
+	//		|	function renderLotsOfData(data){
+	//		|		var d = new dojo.Deferred();
+	//		|		setTimeout(function(){
+	//		|			try{
+	//		|				for(var x in data){
+	//		|					renderDataitem(data[x]);
+	//		|				}
+	//		|				d.callback(true);
+	//		|			}catch(e){ 
+	//		|				d.errback(new Error("rendering failed"));
+	//		|			}
+	//		|		}, 100);
+	//		|		return d;
+	//		|	}
+	//
+	//		|	// using Deferred style
+	//		|	renderLotsOfData(someDataObj).addErrback(function(){
+	//		|		promptUserToRecover();
+	//		|	});
+	//
+	//		Note that the caller doesn't have to change his code at all to
+	//		handle the asynchronous case.
+
+	this.chain = [];
+	this.id = this._nextId();
+	this.fired = -1;
+	this.paused = 0;
+	this.results = [null, null];
+	this.canceller = canceller;
+	this.silentlyCancelled = false;
+};
+
+dojo.extend(dojo.Deferred, {
+	/*
+	makeCalled: function(){
+		// summary:
+		//		returns a new, empty deferred, which is already in the called
+		//		state. Calling callback() or errback() on this deferred will
+		//		yeild an error and adding new handlers to it will result in
+		//		them being called immediately.
+		var deferred = new dojo.Deferred();
+		deferred.callback();
+		return deferred;
+	},
+
+	toString: function(){
+		var state;
+		if(this.fired == -1){
+			state = 'unfired';
+		}else{
+			state = this.fired ? 'success' : 'error';
+		}
+		return 'Deferred(' + this.id + ', ' + state + ')';
+	},
+	*/
+
+	_nextId: (function(){
+		var n = 1;
+		return function(){ return n++; };
+	})(),
+
+	cancel: function(){
+		// summary:	
+		//		Cancels a Deferred that has not yet received a value, or is
+		//		waiting on another Deferred as its value.
+		// description:
+		//		If a canceller is defined, the canceller is called. If the
+		//		canceller did not return an error, or there was no canceller,
+		//		then the errback chain is started.
+		var err;
+		if(this.fired == -1){
+			if(this.canceller){
+				err = this.canceller(this);
+			}else{
+				this.silentlyCancelled = true;
+			}
+			if(this.fired == -1){
+				if(!(err instanceof Error)){
+					var res = err;
+					err = new Error("Deferred Cancelled");
+					err.dojoType = "cancel";
+					err.cancelResult = res;
+				}
+				this.errback(err);
+			}
+		}else if(	(this.fired == 0) &&
+					(this.results[0] instanceof dojo.Deferred)
+		){
+			this.results[0].cancel();
+		}
+	},
+			
+
+	_resback: function(res){
+		// summary:
+		//		The private primitive that means either callback or errback
+		this.fired = ((res instanceof Error) ? 1 : 0);
+		this.results[this.fired] = res;
+		this._fire();
+	},
+
+	_check: function(){
+		if(this.fired != -1){
+			if(!this.silentlyCancelled){
+				throw new Error("already called!");
+			}
+			this.silentlyCancelled = false;
+			return;
+		}
+	},
+
+	callback: function(res){
+		// summary:	Begin the callback sequence with a non-error value.
+		
+		/*
+		callback or errback should only be called once on a given
+		Deferred.
+		*/
+		this._check();
+		this._resback(res);
+	},
+
+	errback: function(/*Error*/res){
+		// summary: 
+		//		Begin the callback sequence with an error result.
+		this._check();
+		if(!(res instanceof Error)){
+			res = new Error(res);
+		}
+		this._resback(res);
+	},
+
+	addBoth: function(/*Function||Object*/cb, /*Optional, String*/cbfn){
+		// summary:
+		//		Add the same function as both a callback and an errback as the
+		//		next element on the callback sequence.	This is useful for code
+		//		that you want to guarantee to run, e.g. a finalizer.
+		var enclosed = dojo.hitch(cb, cbfn);
+		if(arguments.length > 2){
+			enclosed = dojo.partial(enclosed, arguments, 2);
+		}
+		return this.addCallbacks(enclosed, enclosed);
+	},
+
+	addCallback: function(cb, cbfn){
+		// summary: 
+		//		Add a single callback to the end of the callback sequence.
+		var enclosed = dojo.hitch(cb, cbfn);
+		if(arguments.length > 2){
+			enclosed = dojo.partial(enclosed, arguments, 2);
+		}
+		return this.addCallbacks(enclosed, null);
+	},
+
+	addErrback: function(cb, cbfn){
+		// summary: 
+		//		Add a single callback to the end of the callback sequence.
+		var enclosed = dojo.hitch(cb, cbfn);
+		if(arguments.length > 2){
+			enclosed = dojo.partial(enclosed, arguments, 2);
+		}
+		return this.addCallbacks(null, enclosed);
+	},
+
+	addCallbacks: function(cb, eb){
+		// summary: 
+		//		Add separate callback and errback to the end of the callback
+		//		sequence.
+		this.chain.push([cb, eb])
+		if(this.fired >= 0){
+			this._fire();
+		}
+		return this;
+	},
+
+	_fire: function(){
+		// summary: 
+		//		Used internally to exhaust the callback sequence when a result
+		//		is available.
+		var chain = this.chain;
+		var fired = this.fired;
+		var res = this.results[fired];
+		var self = this;
+		var cb = null;
+		while(
+			(chain.length > 0) &&
+			(this.paused == 0)
+		){
+			// Array
+			var f = chain.shift()[fired];
+			if(!f){ continue; }
+			try{
+				res = f(res);
+				fired = ((res instanceof Error) ? 1 : 0);
+				if(res instanceof dojo.Deferred){
+					cb = function(res){
+						self._resback(res);
+						// inlined from _pause()
+						self.paused--;
+						if(
+							(self.paused == 0) && 
+							(self.fired >= 0)
+						){
+							self._fire();
+						}
+					}
+					// inlined from _unpause
+					this.paused++;
+				}
+			}catch(err){
+				console.debug(err);
+				fired = 1;
+				res = err;
+			}
+		}
+		this.fired = fired;
+		this.results[fired] = res;
+		if((cb)&&(this.paused)){
+			// this is for "tail recursion" in case the dependent
+			// deferred is already fired
+			res.addBoth(cb);
+		}
+	}
+});
+
+}

src/java/com/opensymphony/webwork/static/dojo/_base/NodeList.js

+if(!dojo._hasResource["dojo._base.NodeList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo._base.NodeList"] = true;
+dojo.provide("dojo._base.NodeList");
+dojo.require("dojo._base.lang");
+dojo.require("dojo._base.array");
+
+(function(){
+
+	var d = dojo;
+
+	var tnl = function(arr){
+		arr.constructor = dojo.NodeList;
+		dojo._mixin(arr, dojo.NodeList.prototype);
+		return arr;
+	}
+
+	dojo.NodeList = function(){
+		//	summary:
+		//		dojo.NodeList is as subclass of Array which adds syntactic 
+		//		sugar for chaining, common iteration operations, animation, 
+		//		and node manipulation. NodeLists are most often returned as
+		//		the result of dojo.query() calls.
+		//	example:
+		//		create a node list from a node
+		//		|	new dojo.NodeList(dojo.byId("foo"));
+
+		return tnl(Array.apply(null, arguments));
+	}
+
+	dojo.NodeList._wrap = tnl;
+
+	dojo.extend(dojo.NodeList, {
+		// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
+
+		// FIXME: handle return values for #3244
+		//		http://trac.dojotoolkit.org/ticket/3244
+		
+		// FIXME:
+		//		need to wrap or implement:
+		//			join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
+		//			reduce
+		//			reduceRight
+
+		slice: function(/*===== begin, end =====*/){
+			// summary:
+			//		Returns a new NodeList, maintaining this one in place
+			// description:
+			//		This method behaves exactly like the Array.slice method
+			//		with the caveat that it returns a dojo.NodeList and not a
+			//		raw Array. For more details, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice
+			// begin: Integer
+			//		Can be a positive or negative integer, with positive
+			//		integers noting the offset to begin at, and negative
+			//		integers denoting an offset from the end (i.e., to the left
+			//		of the end)
+			// end: Integer?
+			//		Optional parameter to describe what position relative to
+			//		the NodeList's zero index to end the slice at. Like begin,
+			//		can be positive or negative.
+			var a = dojo._toArray(arguments);
+			return tnl(a.slice.apply(this, a));
+		},
+
+		splice: function(/*===== index, howmany, item =====*/){
+			// summary:
+			//		Returns a new NodeList, manipulating this NodeList based on
+			//		the arguments passed, potentially splicing in new elements
+			//		at an offset, optionally deleting elements
+			// description:
+			//		This method behaves exactly like the Array.splice method
+			//		with the caveat that it returns a dojo.NodeList and not a
+			//		raw Array. For more details, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice
+			// index: Integer
+			//		begin can be a positive or negative integer, with positive
+			//		integers noting the offset to begin at, and negative
+			//		integers denoting an offset from the end (i.e., to the left
+			//		of the end)
+			// howmany: Integer?
+			//		Optional parameter to describe what position relative to
+			//		the NodeList's zero index to end the slice at. Like begin,
+			//		can be positive or negative.
+			// item: Object...?
+			//		Any number of optional parameters may be passed in to be
+			//		spliced into the NodeList
+			// returns:
+			//		dojo.NodeList
+			var a = dojo._toArray(arguments);
+			return tnl(a.splice.apply(this, a));
+		},
+
+		concat: function(/*===== item =====*/){
+			// summary:
+			//		Returns a new NodeList comprised of items in this NodeList
+			//		as well as items passed in as parameters
+			// description:
+			//		This method behaves exactly like the Array.concat method
+			//		with the caveat that it returns a dojo.NodeList and not a
+			//		raw Array. For more details, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat
+			// item: Object...?
+			//		Any number of optional parameters may be passed in to be
+			//		spliced into the NodeList
+			// returns:
+			//		dojo.NodeList
+			var a = dojo._toArray(arguments, 0, [this]);
+			return tnl(a.concat.apply([], a));
+		},
+		
+		indexOf: function(/*Object*/ value, /*Integer?*/ fromIndex){
+			//	summary:
+			//		see dojo.indexOf(). The primary difference is that the acted-on 
+			//		array is implicitly this NodeList
+			// value:
+			//		The value to search for.
+			// fromIndex:
+			//		The loction to start searching from. Optional. Defaults to 0.
+			//	description:
+			//		For more details on the behavior of indexOf, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
+			//	returns:
+			//		Positive Integer or 0 for a match, -1 of not found.
+			return d.indexOf(this, value, fromIndex); // Integer
+		},
+
+		lastIndexOf: function(/*===== value, fromIndex =====*/){
+			// summary:
+			//		see dojo.lastIndexOf(). The primary difference is that the
+			//		acted-on array is implicitly this NodeList
+			//	description:
+			//		For more details on the behavior of lastIndexOf, see:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
+			// value: Object
+			//		The value to search for.
+			// fromIndex: Integer?
+			//		The loction to start searching from. Optional. Defaults to 0.
+			// returns:
+			//		Positive Integer or 0 for a match, -1 of not found.
+			return d.lastIndexOf.apply(d, d._toArray(arguments, 0, [this])); // Integer
+		},
+
+		every: function(/*Function*/callback, /*Object?*/thisObject){
+			//	summary:
+			//		see dojo.every() and:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every
+			//		Takes the same structure of arguments and returns as
+			//		dojo.every() with the caveat that the passed array is
+			//		implicitly this NodeList
+			return d.every(this, callback, thisObject); // Boolean
+		},
+
+		some: function(/*Function*/callback, /*Object?*/thisObject){
+			//	summary:
+			//		see dojo.some() and:
+			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
+			//		Takes the same structure of arguments and returns as
+			//		dojo.some() with the caveat that the passed array is
+			//		implicitly this NodeList
+			return d.some(this, callback, thisObject); // Boolean
+		},
+
+		map: function(/*Function*/ func, /*Function?*/ obj){
+			//	summary:
+			//		see dojo.map(). The primary difference is that the acted-on
+			//		array is implicitly this NodeList and the return is a
+			//		dojo.NodeList (a subclass of Array)
+
+			return d.map(this, func, obj, d.NodeList); // dojo.NodeList
+		},
+
+		forEach: function(callback, thisObj){
+			//	summary:
+			//		see dojo.forEach(). The primary difference is that the acted-on 
+			//		array is implicitly this NodeList
+
+			d.forEach(this, callback, thisObj);
+			return this; // dojo.NodeList non-standard return to allow easier chaining
+		},
+
+		// custom methods
+		
+		coords: function(){
+			//	summary:
+			// 		Returns the box objects all elements in a node list as
+			// 		an Array (*not* a NodeList)
+			
+			return d.map(this, d.coords);
+		},