text: define("dojo/rpc/RpcService", [
  	"../_base/array", "../_base/declare", "../_base/Deferred", "../_base/kernel","../_base/lang",
  	"../_base/url", "../_base/xhr"
  ], function(array, declare, Deferred, kernel, lang, _Url, xhr){
  
  // module:
  //		dojo/rpc/RpcService
  
  return declare("dojo.rpc.RpcService", null, {
  	// summary:
  	//		TODOC
  
  	constructor: function(args){
  		// summary:
  		//		Take a string as a url to retrieve an smd or an object that is an smd or partial smd to use
  		//		as a definition for the service
  		//
  		// args: object
  		//		Takes a number of properties as kwArgs for defining the service.  It also
  		//		accepts a string.  When passed a string, it is treated as a url from
  		//		which it should synchronously retrieve an smd file.  Otherwise it is a kwArgs
  		//		object.  It accepts serviceUrl, to manually define a url for the rpc service
  		//		allowing the rpc system to be used without an smd definition. strictArgChecks
  		//		forces the system to verify that the # of arguments provided in a call
  		//		matches those defined in the smd.  smdString allows a developer to pass
  		//		a jsonString directly, which will be converted into an object or alternatively
  		//		smdObject is accepts an smdObject directly.
  		//
  		if(args){
  			//if the arg is a string, we assume it is a url to retrieve an smd definition from
  			if( (lang.isString(args)) || (args instanceof _Url)){
  				if (args instanceof _Url){
  					var url = args + "";
  				}else{
  					url = args;
  				}
  				var def = xhr.get({
  					url: url,
  					handleAs: "json-comment-optional",
  					sync: true
  				});
  
  				def.addCallback(this, "processSmd");
  				def.addErrback(function(){
  					throw new Error("Unable to load SMD from " + args);
  				});
  
  			}else if(args.smdStr){
  				this.processSmd(kernel.eval("("+args.smdStr+")"));
  			}else{
  				// otherwise we assume it's an arguments object with the following
  				// (optional) properties:
  				//		- serviceUrl
  				//		- strictArgChecks
  				//		- smdStr
  				//		- smdObj
  
  				if(args.serviceUrl){
  					this.serviceUrl = args.serviceUrl;
  				}
  
  				this.timeout = args.timeout || 0;
  
  				if("strictArgChecks" in args){
  					this.strictArgChecks = args.strictArgChecks;
  				}
  
  				this.processSmd(args);
  			}
  		}
  	},
  
  	strictArgChecks: true,
  	serviceUrl: "",
  
  	parseResults: function(obj){
  		// summary:
  		//		parse the results coming back from an rpc request.  this
  		//		base implementation, just returns the full object
  		//		subclasses should parse and only return the actual results
  		// obj: Object
  		//		Object that is the return results from an rpc request
  		return obj;
  	},
  
  	errorCallback: function(/* dojo/_base/Deferred */ deferredRequestHandler){
  		// summary:
  		//		create callback that calls the Deferred errback method
  		// deferredRequestHandler: Deferred
  		//		The deferred object handling a request.
  		return function(data){
  			deferredRequestHandler.errback(data.message);
  		};
  	},
  
  	resultCallback: function(/* dojo/_base/Deferred */ deferredRequestHandler){
  		// summary:
  		//		create callback that calls the Deferred's callback method
  		// deferredRequestHandler: Deferred
  		//		The deferred object handling a request.
  
  		return lang.hitch(this,
  			function(obj){
  				if(obj.error!=null){
  					var err;
  					if(typeof obj.error == 'object'){
  						err = new Error(obj.error.message);
  						err.code = obj.error.code;
  						err.error = obj.error.error;
  					}else{
  						err = new Error(obj.error);
  					}
  					err.id = obj.id;
  					err.errorObject = obj;
  					deferredRequestHandler.errback(err);
  				}else{
  					deferredRequestHandler.callback(this.parseResults(obj));
  				}
  			}
  		);
  	},
  
  	generateMethod: function(/*string*/ method, /*array*/ parameters, /*string*/ url){
  		// summary:
  		//		generate the local bind methods for the remote object
  		// method: string
  		//		The name of the method we are generating
  		// parameters: array
  		//		the array of parameters for this call.
  		// url: string
  		//		the service url for this call
  
  		return lang.hitch(this, function(){
  			var deferredRequestHandler = new Deferred();
  
  			// if params weren't specified, then we can assume it's varargs
  			if( (this.strictArgChecks) &&
  				(parameters != null) &&
  				(arguments.length != parameters.length)
  			){
  				// put error stuff here, no enough params
  				throw new Error("Invalid number of parameters for remote method.");
  			}else{
  				this.bind(method, lang._toArray(arguments), deferredRequestHandler, url);
  			}
  
  			return deferredRequestHandler;
  		});
  	},
  
  	processSmd: function(object){
  		// summary:
  		//		callback method for receipt of a smd object.  Parse the smd
  		//		and generate functions based on the description
  		// object:
  		//		smd object defining this service.
  
  		if(object.methods){
  			array.forEach(object.methods, function(m){
  				if(m && m.name){
  					this[m.name] = this.generateMethod(	m.name,
  										m.parameters,
  										m.url||m.serviceUrl||m.serviceURL);
  					if(!lang.isFunction(this[m.name])){
  						throw new Error("RpcService: Failed to create" + m.name + "()");
  						/*console.log("RpcService: Failed to create", m.name, "()");*/
  					}
  				}
  			}, this);
  		}
  
  		this.serviceUrl = object.serviceUrl||object.serviceURL;
  		this.required = object.required;
  		this.smd = object;
  	}
  });
  
  });
  