text: define("dojo/Stateful", ["./_base/declare", "./_base/lang", "./_base/array", "dojo/when"], function(declare, lang, array, when){
  	// module:
  	//		dojo/Stateful
  
  return declare("dojo.Stateful", null, {
  	// summary:
  	//		Base class for objects that provide named properties with optional getter/setter
  	//		control and the ability to watch for property changes
  	//
  	//		The class also provides the functionality to auto-magically manage getters
  	//		and setters for object attributes/properties.
  	//		
  	//		Getters and Setters should follow the format of _xxxGetter or _xxxSetter where 
  	//		the xxx is a name of the attribute to handle.  So an attribute of "foo" 
  	//		would have a custom getter of _fooGetter and a custom setter of _fooSetter.
  	//
  	// example:
  	//	|	var obj = new dojo.Stateful();
  	//	|	obj.watch("foo", function(){
  	//	|		console.log("foo changed to " + this.get("foo"));
  	//	|	});
  	//	|	obj.set("foo","bar");
  
  	// _attrPairNames: Hash
  	//		Used across all instances a hash to cache attribute names and their getter 
  	//		and setter names.
  	_attrPairNames: {},
  
  	_getAttrNames: function(name){
  		// summary:
  		//		Helper function for get() and set().
  		//		Caches attribute name values so we don't do the string ops every time.
  		// tags:
  		//		private
  
  		var apn = this._attrPairNames;
  		if(apn[name]){ return apn[name]; }
  		return (apn[name] = {
  			s: "_" + name + "Setter",
  			g: "_" + name + "Getter"
  		});
  	},
  
  	postscript: function(/*Object?*/ params){
  		// Automatic setting of params during construction
  		if (params){ this.set(params); }
  	},
  
  	_get: function(name, names){
  		// summary:
  		//		Private function that does a get based off a hash of names
  		// names:
  		//		Hash of names of custom attributes
  		return typeof this[names.g] === "function" ? this[names.g]() : this[name];
  	},
  	get: function(/*String*/name){
  		// summary:
  		//		Get a property on a Stateful instance.
  		// name:
  		//		The property to get.
  		// returns:
  		//		The property value on this Stateful instance.
  		// description:
  		//		Get a named property on a Stateful object. The property may
  		//		potentially be retrieved via a getter method in subclasses. In the base class
  		//		this just retrieves the object's property.
  		//		For example:
  		//	|	stateful = new dojo.Stateful({foo: 3});
  		//	|	stateful.get("foo") // returns 3
  		//	|	stateful.foo // returns 3
  
  		return this._get(name, this._getAttrNames(name)); //Any
  	},
  	set: function(/*String*/name, /*Object*/value){
  		// summary:
  		//		Set a property on a Stateful instance
  		// name:
  		//		The property to set.
  		// value:
  		//		The value to set in the property.
  		// returns:
  		//		The function returns this dojo.Stateful instance.
  		// description:
  		//		Sets named properties on a stateful object and notifies any watchers of
  		//		the property. A programmatic setter may be defined in subclasses.
  		//		For example:
  		//	|	stateful = new dojo.Stateful();
  		//	|	stateful.watch(function(name, oldValue, value){
  		//	|		// this will be called on the set below
  		//	|	}
  		//	|	stateful.set(foo, 5);
  		//
  		//	set() may also be called with a hash of name/value pairs, ex:
  		//	|	myObj.set({
  		//	|		foo: "Howdy",
  		//	|		bar: 3
  		//	|	})
  		//	This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
  
  		// If an object is used, iterate through object
  		if(typeof name === "object"){
  			for(var x in name){
  				if(name.hasOwnProperty(x) && x !="_watchCallbacks"){
  					this.set(x, name[x]);
  				}
  			}
  			return this;
  		}
  
  		var names = this._getAttrNames(name),
  			oldValue = this._get(name, names),
  			setter = this[names.s],
  			result;
  		if(typeof setter === "function"){
  			// use the explicit setter
  			result = setter.apply(this, Array.prototype.slice.call(arguments, 1));
  		}else{
  			// no setter so set attribute directly
  			this[name] = value;
  		}
  		if(this._watchCallbacks){
  			var self = this;
  			// If setter returned a promise, wait for it to complete, otherwise call watches immediatly
  			when(result, function(){
  				self._watchCallbacks(name, oldValue, value);
  			});
  		}
  		return this; // dojo/Stateful
  	},
  	_changeAttrValue: function(name, value){
  		// summary:
  		//		Internal helper for directly changing an attribute value.
  		//
  		// name: String
  		//		The property to set.
  		// value: Mixed
  		//		The value to set in the property.
  		//
  		// description:
  		//		Directly change the value of an attribute on an object, bypassing any 
  		//		accessor setter.  Also handles the calling of watch and emitting events. 
  		//		It is designed to be used by descendent class when there are two values 
  		//		of attributes that are linked, but calling .set() is not appropriate.
  
  		var oldValue = this.get(name);
  		this[name] = value;
  		if(this._watchCallbacks){
  			this._watchCallbacks(name, oldValue, value);
  		}
  		return this; // dojo/Stateful
  	},
  	watch: function(/*String?*/name, /*Function*/callback){
  		// summary:
  		//		Watches a property for changes
  		// name:
  		//		Indicates the property to watch. This is optional (the callback may be the
  		//		only parameter), and if omitted, all the properties will be watched
  		// returns:
  		//		An object handle for the watch. The unwatch method of this object
  		//		can be used to discontinue watching this property:
  		//		|	var watchHandle = obj.watch("foo", callback);
  		//		|	watchHandle.unwatch(); // callback won't be called now
  		// callback:
  		//		The function to execute when the property changes. This will be called after
  		//		the property has been changed. The callback will be called with the |this|
  		//		set to the instance, the first argument as the name of the property, the
  		//		second argument as the old value and the third argument as the new value.
  
  		var callbacks = this._watchCallbacks;
  		if(!callbacks){
  			var self = this;
  			callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
  				var notify = function(propertyCallbacks){
  					if(propertyCallbacks){
  						propertyCallbacks = propertyCallbacks.slice();
  						for(var i = 0, l = propertyCallbacks.length; i < l; i++){
  							propertyCallbacks[i].call(self, name, oldValue, value);
  						}
  					}
  				};
  				notify(callbacks['_' + name]);
  				if(!ignoreCatchall){
  					notify(callbacks["*"]); // the catch-all
  				}
  			}; // we use a function instead of an object so it will be ignored by JSON conversion
  		}
  		if(!callback && typeof name === "function"){
  			callback = name;
  			name = "*";
  		}else{
  			// prepend with dash to prevent name conflicts with function (like "name" property)
  			name = '_' + name;
  		}
  		var propertyCallbacks = callbacks[name];
  		if(typeof propertyCallbacks !== "object"){
  			propertyCallbacks = callbacks[name] = [];
  		}
  		propertyCallbacks.push(callback);
  
  		// TODO: Remove unwatch in 2.0
  		var handle = {};
  		handle.unwatch = handle.remove = function(){
  			var index = array.indexOf(propertyCallbacks, callback);
  			if(index > -1){
  				propertyCallbacks.splice(index, 1);
  			}
  		};
  		return handle; //Object
  	}
  
  });
  
  });
  