text: dojo._xdResourceLoaded({
  depends: [["provide", "dojox.data.PicasaStore"],
  ["require", "dojo.data.util.simpleFetch"],
  ["require", "dojo.io.script"],
  ["require", "dojo.date.stamp"]],
  defineResource: function(dojo){if(!dojo._hasResource["dojox.data.PicasaStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  dojo._hasResource["dojox.data.PicasaStore"] = true;
  dojo.provide("dojox.data.PicasaStore");
  
  dojo.require("dojo.data.util.simpleFetch");
  dojo.require("dojo.io.script");
  dojo.require("dojo.date.stamp");
  
  dojo.declare("dojox.data.PicasaStore", null, {
  	constructor: function(/*Object*/args){
  		//	summary:
  		//		Initializer for the PicasaStore store.  
  		//	description:
  		//		The PicasaStore is a Datastore interface to one of the basic services
  		//		of the Picasa service, the public photo feed.  This does not provide
  		//		access to all the services of Picasa.
  		//		This store cannot do * and ? filtering as the picasa service 
  		//		provides no interface for wildcards.
  		if(args && args.label){
  			this.label = args.label;
  		}
  	},
  
  	_picasaUrl: "http://picasaweb.google.com/data/feed/api/all",
  
  	_storeRef: "_S",
  
  	label: "title",
  
  	_assertIsItem: function(/* item */ item){
  		//	summary:
  		//      This function tests whether the item passed in is indeed an item in the store.
  		//	item: 
  		//		The item to test for being contained by the store.
  		if(!this.isItem(item)){ 
  			throw new Error("dojox.data.PicasaStore: a function was passed an item argument that was not an item");
  		}
  	},
  
  	_assertIsAttribute: function(/* attribute-name-string */ attribute){
  		//	summary:
  		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
  		//	attribute: 
  		//		The attribute to test for being contained by the store.
  		if(typeof attribute !== "string"){ 
  			throw new Error("dojox.data.PicasaStore: a function was passed an attribute argument that was not an attribute name string");
  		}
  	},
  
  	getFeatures: function(){
  		//	summary: 
  		//      See dojo.data.api.Read.getFeatures()
  		return {
  			'dojo.data.api.Read': true
  		};
  	},
  
  	getValue: function(item, attribute){
  		//	summary: 
  		//      See dojo.data.api.Read.getValue()
  		var values = this.getValues(item, attribute);
  		if(values){
  			return values[0];
  		}
  		return undefined;
  	},
  
  	getAttributes: function(item){
  		//	summary: 
  		//      See dojo.data.api.Read.getAttributes()
  		return ["id", "published", "updated", "category", "title$type", "title", "summary$type", "summary", "rights$type", "rights", "link", "author", "gphoto$id", "gphoto$name", "location"]; 
  	},
  
  	hasAttribute: function(item, attribute){
  		//	summary: 
  		//      See dojo.data.api.Read.hasAttributes()
  		if(this.getValue(item,attribute)){
  			return true;
  		}
  		return false;
  	},
  
  	isItemLoaded: function(item){
  		 //	summary: 
  		 //      See dojo.data.api.Read.isItemLoaded()
  		 return this.isItem(item);
  	},
  
  	loadItem: function(keywordArgs){
  		//	summary: 
  		//      See dojo.data.api.Read.loadItem()
  	},
  
  	getLabel: function(item){
  		//	summary: 
  		//      See dojo.data.api.Read.getLabel()
  		return this.getValue(item,this.label);
  	},
  	
  	getLabelAttributes: function(item){
  		//	summary: 
  		//      See dojo.data.api.Read.getLabelAttributes()
  		return [this.label];
  	},
  
  	containsValue: function(item, attribute, value){
  		//	summary: 
  		//      See dojo.data.api.Read.containsValue()
  		var values = this.getValues(item,attribute);
  		for(var i = 0; i < values.length; i++){
  			if(values[i] === value){
  				return true;
  			}
  		}
  		return false;
  	},
  
  	getValues: function(item, attribute){
  		//	summary: 
  		//      See dojo.data.api.Read.getValue()
  
  		this._assertIsItem(item);
  		this._assertIsAttribute(attribute);
  		if(attribute === "title"){
  			return [this._unescapeHtml(item.title)];
  		}else if(attribute === "author"){
  			return [this._unescapeHtml(item.author[0].name)];
  		}else if(attribute === "datePublished"){
  			return [dojo.date.stamp.fromISOString(item.published)];
  		}else if(attribute === "dateTaken"){
  			return [dojo.date.stamp.fromISOString(item.date_taken)];
  		}else if(attribute === "imageUrlSmall"){
  			return [item.media.thumbnail[1].url];
  		}else if(attribute === "imageUrl"){
  			return [item.content$src];
  		}else if(attribute === "imageUrlMedium"){
  			return [item.media.thumbnail[2].url];
  		}else if(attribute === "link"){
  			return [item.link[1]];
  		}else if(attribute === "tags"){
  			return item.tags.split(" ");
  		}else if(attribute === "description"){
  			return [this._unescapeHtml(item.summary)];
  		}
  		return undefined;
  	},
  
  	isItem: function(item){
  		//	summary: 
  		//      See dojo.data.api.Read.isItem()
  		if(item && item[this._storeRef] === this){
  			return true;
  		}
  		return false;
  	},
  	
  	close: function(request){
  		//	summary: 
  		//      See dojo.data.api.Read.close()
  	},
  
  	_fetchItems: function(request, fetchHandler, errorHandler){
  		//	summary:
  		//		Fetch picasa items that match to a query
  		//	request:
  		//		A request object
  		//	fetchHandler:
  		//		A function to call for fetched items
  		//	errorHandler:
  		//		A function to call on error
  
  		if(!request.query){
  			request.query={};
  		}
  
  		//Build up the content to send the request for.
  		var content = {alt: "jsonm", pp: "1", psc: "G"};
  		content['start-index'] = "1";
  		if(request.query.start){
  			content['start-index'] = request.query.start;
  		}
  		if(request.query.tags){
  			content.q = request.query.tags;
  		}
  		if(request.query.userid){
  			content.uname = request.query.userid;
  		}
  		if(request.query.userids){
  			content.ids = request.query.userids;
  		}
  		if(request.query.lang){
  			content.hl = request.query.lang;
  		}
  		if(request.count){
  			content['max-results'] = request.count;
  		}else{
  			content['max-results'] = "20";
  		}
  
  		//Linking this up to Picasa is a JOY!
  		var self = this;
  		var handle = null;
  		var myHandler = function(data){
  			if(handle !== null){
  				dojo.disconnect(handle);
  			}
  
  			//Process the items...
  			fetchHandler(self._processPicasaData(data), request);
  		};
  		var getArgs = {
  			url: this._picasaUrl,
  			// preventCache: true,
  			content: content,
  			callbackParamName: 'callback',
  			handle: myHandler
  		};
  		var deferred = dojo.io.script.get(getArgs);
  		
  		deferred.addErrback(function(error){
  			dojo.disconnect(handle);
  			errorHandler(error, request);
  		});
  	},
  
  	_processPicasaData: function(data){
  		var items = [];
  		if(data.feed){
  			items = data.feed.entry;
  			//Add on the store ref so that isItem can work.
  			for(var i = 0; i < items.length; i++){
  				var item = items[i];
  				item[this._storeRef] = this;
  			}
  		}
  		return items;
  	},
  
  	_unescapeHtml: function(str){
  		// summary: Utility function to un-escape XML special characters in an HTML string.
  		// description: Utility function to un-escape XML special characters in an HTML string.
  		// str: String.
  		//   The string to un-escape
  		// returns: HTML String converted back to the normal text (unescaped) characters (<,>,&, ", etc,).
  		//
  		//TODO: Check to see if theres already compatible escape() in dojo.string or dojo.html
  		str = str.replace(/&amp;/gm, "&").replace(/&lt;/gm, "<").replace(/&gt;/gm, ">").replace(/&quot;/gm, "\"");
  		str = str.replace(/&#39;/gm, "'"); 
  		return str;
  	}
  });
  dojo.extend(dojox.data.PicasaStore,dojo.data.util.simpleFetch);										  
  
  }
  
  }});