text: define("dijit/registry", [
  	"dojo/_base/array", // array.forEach array.map
  	"dojo/_base/window", // win.body
  	"./main"	// dijit._scopeName
  ], function(array, win, dijit){
  
  	// module:
  	//		dijit/registry
  
  	var _widgetTypeCtr = {}, hash = {};
  
  	var registry =  {
  		// summary:
  		//		Registry of existing widget on page, plus some utility methods.
  
  		// length: Number
  		//		Number of registered widgets
  		length: 0,
  
  		add: function(widget){
  			// summary:
  			//		Add a widget to the registry. If a duplicate ID is detected, a error is thrown.
  			// widget: dijit/_WidgetBase
  			//		Any dijit/_WidgetBase subclass.
  			if(hash[widget.id]){
  				throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
  			}
  			hash[widget.id] = widget;
  			this.length++;
  		},
  
  		remove: function(/*String*/ id){
  			// summary:
  			//		Remove a widget from the registry. Does not destroy the widget; simply
  			//		removes the reference.
  			if(hash[id]){
  				delete hash[id];
  				this.length--;
  			}
  		},
  
  		byId: function(/*String|Widget*/ id){
  			// summary:
  			//		Find a widget by it's id.
  			//		If passed a widget then just returns the widget.
  			return typeof id == "string" ? hash[id] : id;	// dijit/_WidgetBase
  		},
  
  		byNode: function(/*DOMNode*/ node){
  			// summary:
  			//		Returns the widget corresponding to the given DOMNode
  			return hash[node.getAttribute("widgetId")]; // dijit/_WidgetBase
  		},
  
  		toArray: function(){
  			// summary:
  			//		Convert registry into a true Array
  			//
  			// example:
  			//		Work with the widget .domNodes in a real Array
  			//		|	array.map(registry.toArray(), function(w){ return w.domNode; });
  
  			var ar = [];
  			for(var id in hash){
  				ar.push(hash[id]);
  			}
  			return ar;	// dijit/_WidgetBase[]
  		},
  
  		getUniqueId: function(/*String*/widgetType){
  			// summary:
  			//		Generates a unique id for a given widgetType
  
  			var id;
  			do{
  				id = widgetType + "_" +
  					(widgetType in _widgetTypeCtr ?
  						++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
  			}while(hash[id]);
  			return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
  		},
  
  		findWidgets: function(root, skipNode){
  			// summary:
  			//		Search subtree under root returning widgets found.
  			//		Doesn't search for nested widgets (ie, widgets inside other widgets).
  			// root: DOMNode
  			//		Node to search under.
  			// skipNode: DOMNode
  			//		If specified, don't search beneath this node (usually containerNode).
  
  			var outAry = [];
  
  			function getChildrenHelper(root){
  				for(var node = root.firstChild; node; node = node.nextSibling){
  					if(node.nodeType == 1){
  						var widgetId = node.getAttribute("widgetId");
  						if(widgetId){
  							var widget = hash[widgetId];
  							if(widget){	// may be null on page w/multiple dojo's loaded
  								outAry.push(widget);
  							}
  						}else if(node !== skipNode){
  							getChildrenHelper(node);
  						}
  					}
  				}
  			}
  
  			getChildrenHelper(root);
  			return outAry;
  		},
  
  		_destroyAll: function(){
  			// summary:
  			//		Code to destroy all widgets and do other cleanup on page unload
  
  			// Clean up focus manager lingering references to widgets and nodes
  			dijit._curFocus = null;
  			dijit._prevFocus = null;
  			dijit._activeStack = [];
  
  			// Destroy all the widgets, top down
  			array.forEach(registry.findWidgets(win.body()), function(widget){
  				// Avoid double destroy of widgets like Menu that are attached to <body>
  				// even though they are logically children of other widgets.
  				if(!widget._destroyed){
  					if(widget.destroyRecursive){
  						widget.destroyRecursive();
  					}else if(widget.destroy){
  						widget.destroy();
  					}
  				}
  			});
  		},
  
  		getEnclosingWidget: function(/*DOMNode*/ node){
  			// summary:
  			//		Returns the widget whose DOM tree contains the specified DOMNode, or null if
  			//		the node is not contained within the DOM tree of any widget
  			while(node){
  				var id = node.nodeType == 1 && node.getAttribute("widgetId");
  				if(id){
  					return hash[id];
  				}
  				node = node.parentNode;
  			}
  			return null;
  		},
  
  		// In case someone needs to access hash.
  		// Actually, this is accessed from WidgetSet back-compatibility code
  		_hash: hash
  	};
  
  	dijit.registry = registry;
  
  	return registry;
  });
  