define(["dojo/_base/declare", "dojo/Deferred", "dojo/store/util/QueryResults"],
	function(declare, Deferred, QueryResults){

	return declare(null, {
		// summary:
		//		This is a dojo/store wrapper for Cordova Contacts API.

		idProperty: "id",

		contactFields: ["id", "displayName", "name", "phoneNumbers", "emails", "addresses"],

		constructor: function(options){
			// summary:
			//		Creates a contacts object store.
			declare.safeMixin(this, options);
		},

		get: function(id){
			//	summary:
			//		Retrieves an object by its identity.
			//	id: Number
			//		The identity to use to lookup the object
			//	returns: Object
			//		The object in the store that matches the given id.
			var deferred = new Deferred();
			this._find([this.idProperty],
				function(contacts){
					// search is by keyword on all fields, so we need to double check
					// we did not get false positive results
					for(var i = 0; i < contacts.length; i++){
						if(contacts[i][this.idProperty] == id){
							deferred.resolve(contacts[i]);
							return;
						}
					}
					deferred.reject(new Error(this.idProperty + " not match."));
				},
				deferred, id);
			return deferred.promise;
		},

		getIdentity: function(object){
			// summary:
			//		Returns an object's identity
			// object: Object
			//		The object to get the identity from
			//	returns: String|Number
			return object[this.idProperty];
		},

		query: function(query, options){
			var deferred = new Deferred();
			this._find(query?query:"",
				function(contacts){
					deferred.resolve(contacts);
				},
				deferred, options);
			// TODO: what about queryEngine?
			return new QueryResults(deferred.promise);
		},

		// All the code below depends on Cordova Contacts API

		_find: function(query, success, deferred, options){
			var opts = new ContactFindOptions();
			var fields = (options && options.contactFields) || this.contactFields;
			opts.filter = query;
			opts.multiple = options.hasOwnerProperty("multiple") ? options.multiple : true;
			navigator.contacts.find(fields, success, function(error){deferred.reject(error)}, opts);
		},

		put: function(object){
			var contact = typeof object.save === "function" ? object : navigator.contacts.create(object);
			var id = this.getIdentity(contact);
			var deferred = new Deferred();
			if(typeof id != "undefined"){
				contact.save(function(contact){deferred.resolve(contact)}, function(error){deferred.reject(error)});
			}else{
				deferred.reject(new Error("contact must have an id"));
			}
			return deferred.promise;
		},

		add: function(object, directives){
			if(directives && directives.hasOwnProperty(this.idProperty)){
				object.id = directives.id;
			}
			var deferred = new Deferred();
			if(object.hasOwnProperty(this.idProperty)){
				// if the object has a save method it has been created, use it, otherwise create it before
				var contact = typeof object.save === "function" ? object : navigator.contacts.create(object);
				contact.save(function(contact){deferred.resolve(contact)}, function(error){deferred.reject(error)});
			}else{
				deferred.reject(new Error("object must has an "+this.idProperty+" property"));
			}
			return deferred.promise;
		},

		remove: function(id){
			var deferred = new Deferred();
			var object = this.get(id);
			object.remove(function(contact){deferred.resolve(contact)}, function(error){deferred.reject(error)});
			return deferred.promise;
		}
	});
});

@@ -222,29 +222,8 @@
 I.%0A%0A
-%09%09idProperty: %22id%22,%0A%0A
 %09%09co
@@ -305,16 +305,16 @@
 sses%22%5D,%0A
+
 %0A%09%09const
@@ -712,31 +712,20 @@
 ._find(%5B
-this.idProperty
+%22id%22
 %5D,%0A%09%09%09%09f
@@ -928,31 +928,20 @@
 acts%5Bi%5D%5B
-this.idProperty
+%22id%22
 %5D == id)
@@ -1045,27 +1045,11 @@
 ror(
-this.idProperty + %22
+%22id
  not
@@ -1314,31 +1314,20 @@
  object%5B
-this.idProperty
+%22id%22
 %5D;%0A%09%09%7D,%0A
@@ -1869,16 +1869,28 @@
 ltiple =
+ (options &&
  options
@@ -1918,16 +1918,17 @@
 ltiple%22)
+)
  ? optio
@@ -2565,39 +2565,28 @@
 OwnProperty(
-this.idProperty
+%22id%22
 ))%7B%0A%09%09%09%09obje
@@ -2675,31 +2675,20 @@
 roperty(
-this.idProperty
+%22id%22
 ))%7B%0A%09%09%09%09
@@ -2876,16 +2876,16 @@
 bject);%0A
+
 %09%09%09%09cont
@@ -2985,101 +2985,8 @@
 %7D);%0A
-%09%09%09%7Delse%7B%0A%09%09%09%09deferred.reject(new Error(%22object must has an %22+this.idProperty+%22 property%22));%0A
 %09%09%09%7D

fix issue with options being null + id not configurable + id can't be set on BB so can't force it in "add"