if(!dojo._hasResource["voila.data.DWRReadStore"]){
	dojo._hasResource["voila.data.DWRReadStore"] = true;
	dojo.provide("voila.data.DWRReadStore");
	
	dojo.require("dojo.data.util.simpleFetch");
	
	dojo.declare("voila.data.DWRReadStore", null,{
	    // The DWRReadStore implements the dojo.data.api.Read API and reads
	    // data from the server using DWR
		constructor: function(params){
		    this._features = {'dojo.data.api.Read':true};        
		    this._dwrMethod = params.dwrMethod;
		    this._dwrDetailMethod = params.dwrDetailMethod;
		    this._items = [];
		    this._loadComplete = false;
		    this._maxCount = 200 || params.maxCount;
		    this._minChars = 0 || params.minChars;
		    this._lastSearch = null;
		    this._loadInProgress = false;
		    this._idAttr = params.idAttr;
		},
		
	    getFeatures: function(){
	        return this._features; 
	    },
		
	    fetchItemByIdentity: function(param){
	    	if (param.identity && param.identity != null && param.identity != "null") {
	        	var filter = {};
	        	dojo.setObject(this._idAttr, param.identity, filter);
	            this._dwrDetailMethod(filter, param.onItem);
	    	}
	    },
		
	    getIdentity: function(item){
	    	return dojo.getObject(this._idAttr, false, item);
	    },

	    _fetchItems: function(args,findCallback,errorCallback){
	        var self = this;
	        // If the data has already been return the previously loaded data
            if(this._dwrMethod){
            	var query = args.queryFrom || {} ;
            	var lastValue;
            	//Fix query params by removing the "*" jolly characters from the text since we use LIKE query method filtering
            	for (var key in args.query) {
            		if (args.query[key] == "") {
                        findCallback([], args);
                        return;
            		}
            		lastValue = args.query[key].replace("\*", "");
            		dojo.setObject(key, lastValue, query);
            	}
            	//Test if we are in an onBlur case
            	if (args.start == undefined || args.count == undefined) {
            		//onBlur requested and the field is blank, skip querying and levae it blank (case when the user want to clear the field)
            		if (lastValue == "") {
                        findCallback([], args);
                        return;
            		} else {
            			//This is the case when the user type something and blur the field with no autocomplete. In this case we want to match automatically
            			//the first filtered records and select it.
            			args.start = 0;
            			args.count = 1;
            		}
            	}
                if(!this._loadInProgress) {
                    this._loadInProgress = true;
                    //The call to DWR !!!!!!!!!!!!!!!!!!!!!!
                    this._dwrMethod(query, args.queryTo || {}, args.criteria, args.start, (args.count == Infinity ? 0 : args.count), args.orderBy, function(data){
                        try{
                        	self._items = [];
                        	for (var i=0; i<args.start; i++) {
                        		self._items[i] = {};
                        	}
                        	self._items = self._items.concat(data.list);
                            self._loadComplete = true;
                            self._loadInProgress = false;
                            self._lastSearch = self._widgetValue;
                            
                            if (args.count != Infinity) {
	                            args.maxOptions = data.size;
                            }

                            findCallback(self._items, args);
                        }catch(e){
                            self._loadComplete = true;
                            self._loadInProgress = false;
                            errorCallback(e, args);
                        }
                    });
	            }else{
	                errorCallback(new Error("DWR Method is undefined."), args);
	            }
	        }
	    },

	    getValue: function(item, attribute, defaultValue){
	    	return dojo.getObject(attribute, false, item);
	    },

	    close: function(request){
	         // We do not have any special cleanup requirements
	    }
	});
	
	dojo.extend(voila.data.DWRReadStore, dojo.data.util.simpleFetch);
}
