cleanup html/js, adding support for contacts, cleanup device stuff
diff --git a/Res/index.html b/Res/index.html
index 3187835..683c390 100755
--- a/Res/index.html
+++ b/Res/index.html
@@ -2,73 +2,61 @@
 <html>

 	<head>

 		<title>PhoneGap Test App</title>

-		<script type="text/javascript" src="phonegap/phonegap.js" />

-		<script type="text/javascript" src="main.js" />

+		<script type="text/javascript" src="phonegap/phonegap.js"></script>

+		<script type="text/javascript" src="main.js"></script>

+    <style type="text/css">

+      div { text-align: "center"; display: "block"}

+    </style>

 	</head>

 	<body>

-		 <h2>PhoneGap test</h2>

+		 <h2>PhoneGap Sample</h2>

      <ul id="debuglist">Debug Output</ul>

+     <!-- Geolocation -->

      <div>

-        <!-- Geolocation -->

        <h3>Geolocation</h3>

-       <p align="center">

         <input onclick="getCurrentPosition()" type="submit" value="GeoLocation.GetLastKnownLocation">

-       </p>

-       <p align="center">

         <input onclick="toggleWatchPosition(this)" type="submit" value="GeoLocation.StartWatching">

-       </p>

-       <p align="center">

         <div id="geolocation" style="display:none;">

           altitude: 0,longitude: 0, altitude: 0

         </div>

-       </p>

      </div>

      <!-- Accelerometer -->

      <div>

        <h3>Accelerometer</h3>

-       <p align="center">

-        <input onclick="getCurrentAcceleration()" type="submit" value="Accelerometer.getCurrentAcceleration()">

-       </p>

-       <p align="center">

+        <input onclick="getCurrentAcceleration()" type="submit" value="Accelerometer.getCurrentAcceleration">

         <input onclick="toggleStartSensor(this)" type="submit" value="Accelerometer.watchAcceleration">

-       </p>

-       <p align="center">

         <div id="accelerometer" style="display:none;">

           x: 0, y: 0, z: 0, timestamp: 0 

         </div>

-       </p>

      </div>

+     <!-- Network -->

      <div>

-       <p align="center">

-        <input onclick="hostIsReachable('http://phonegap.com')" type="submit" value="Network.isReachable()">

-       </p>

-       <p align="center">

+        <h3>Network</h3>

+        <input onclick="hostIsReachable('http://phonegap.com')" type="submit" value="Network.isReachable">

         <div id="network" style="display:none;">

           Network Information

         </div>

-       </p>

      </div>

      <div>

+     <!-- Device -->

      <div>

-       <p align="center">

+        <h3>Device</h3>

         <input onclick="getSystemInfo()" type="submit" value="Device.GetSystemInfo">

-       </p>

-       <p align="center">

         <div id="system" style="display:none;">

           System Information

         </div>

-       </p>

      </div>

+     <!-- DebugConsole -->

      <div>

-       <p align="center">

+        <h3>DebugConsole</h3>

         <input type="text" id="log_statement" />

         <input onclick="Log()" type="submit" value="console.log">

-       </p>

      </div>

+     <!-- Contact -->

+     <h3>Contact</h3>

      <div>

-       <p align="center">

-        <input onclick="launchExternalBrowser()" type="submit" style="width: 100; height: 40;" value="Browser">

-       </p>

+        <input onclick="createContact()" type="submit" value="Contact.create">

+        <input onclick="saveContact()" type="submit" value="Contact.save">

      </div>

 	</body>

 </html>

diff --git a/Res/main.js b/Res/main.js
index bddb242..3a3bea3 100755
--- a/Res/main.js
+++ b/Res/main.js
@@ -1,4 +1,11 @@
+/*

+* PhoneGap Sample App

+*

+*/

+

+// Geolocation

 var watchLocationID = null;

+

 function onGeoLocationSuccess(position) {

     var element = document.getElementById('geolocation');

     element.innerHTML = 'Latitude: '  + position.coords.latitude      + '<br />' +

@@ -6,8 +13,6 @@
                         '<hr />'      + element.innerHTML;

 }

 

-// onError Callback receives a PositionError object

-//

 function onGeoLocationError(error) {

     debugPrint('code: '    + error.code    + '\n' +

           'message: ' + error.message + '\n');

@@ -50,8 +55,6 @@
 // Acceleration

 var watchAccelerationID = null;

 

-// onSuccess: Get a snapshot of the current acceleration

-//

 function onAccelerationSuccess(acceleration) {

     var element = document.getElementById('accelerometer');

     element.innerHTML = 'Acceleration X: ' + acceleration.x + '<br />' +

@@ -60,22 +63,15 @@
                         'Timestamp: '      + acceleration.timestamp + '<br />';

 }

 

-// onError: Failed to get the acceleration

-//

 function onAccelerationError() {

     alert('onError!');

 }

 

 function startWatchAcceleration() {

+  var options = { frequency: 3000 };

+  watchAccelerationID = navigator.accelerometer.watchAcceleration(onAccelerationSuccess, onAccelerationError, options);

+}

 

-        // Update acceleration every 3 seconds

-        var options = { frequency: 3000 };

-

-        watchAccelerationID = navigator.accelerometer.watchAcceleration(onAccelerationSuccess, onAccelerationError, options);

-    }

-

-// Stop watching the acceleration

-//

 function stopWatchAcceleration() {

     if (watchAccelerationID) {

         navigator.accelerometer.clearWatch(watchAccelerationID);

@@ -111,14 +107,15 @@
 		alert(e.message);

 	}

 }

-

+// Utility Function

 function debugPrint(body) {

     var list = document.getElementById("debuglist");

     var item = document.createElement("li");

     item.appendChild(document.createTextNode(body));

     list.appendChild(item);

 }

-// any url gets rendered in the stock web browser

+

+// Stock Browser Test (Any URL request launches Stock browser) 

 function launchExternalBrowser() {

   window.location = "http://www.phonegap.com";

 }

@@ -144,7 +141,23 @@
   }

 }

 

-// Logging

+// System

+function getSystemInfo() {

+  try {

+    var system = document.getElementById("system");

+    system.style.display = "block";

+    system.innerHTML = 'Device Name: '     + device.name     + '<br />' + 

+                       'Device PhoneGap: ' + device.phonegap + '<br />' + 

+                       'Device Platform: ' + device.platform + '<br />' + 

+                       'Device UUID: '     + device.uuid     + '<br />' + 

+                       'Device Version: '  + device.version  + '<br />';

+  } catch(e) {

+    debugPrint("Error Occured: "+e.message);

+  }

+  

+}

+

+// DebugConsole 

 function Log() {

   var log_statement = document.getElementById("log_statement").value;

   console.log(log_statement); 

@@ -152,3 +165,10 @@
   console.error(log_statement); 

   console.log({test:'pouet', test2:['pouet1', 'pouet2']});

 }

+

+// Contacts

+function createContact() {

+  var myContact = navigator.service.contacts.create({displayName: "Test User"});

+  myContact.gender = "male";

+  console.log("The contact, "+myContact.displayName + ", is of the "+myContact.gender +" gender");

+}

diff --git a/Res/phonegap/contact.js b/Res/phonegap/contact.js
index 6fd3bef..65f4417 100644
--- a/Res/phonegap/contact.js
+++ b/Res/phonegap/contact.js
@@ -1,32 +1,30 @@
-
 /*
  * PhoneGap is available under *either* the terms of the modified BSD license *or* the
  * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
- * 
+ *
  * Copyright (c) 2005-2010, Nitobi Software Inc.
  * Copyright (c) 2010, IBM Corporation
  */
 
 /**
- * Contains information about a single contact.  
- * @param {DOMString} id unique identifier
- * @param {DOMString} displayName
- * @param {ContactName} name 
- * @param {DOMString} nickname
- * @param {ContactField[]} phoneNumbers array of phone numbers
- * @param {ContactField[]} emails array of email addresses
- * @param {ContactAddress[]} addresses array of addresses
- * @param {ContactField[]} ims instant messaging user ids
- * @param {ContactOrganization[]} organizations 
- * @param {DOMString} revision date contact was last updated
- * @param {Date} birthday contact's birthday
- * @param {DOMString} gender contact's gender
- * @param {DOMString} note user notes about contact
- * @param {ContactField[]} photos
- * @param {DOMString[]} categories 
- * @param {ContactField[]} urls contact's web sites
- * @param {DOMString} timezone time zone 
- */
+* Contains information about a single contact.
+* @param {DOMString} id unique identifier
+* @param {DOMString} displayName
+* @param {ContactName} name
+* @param {DOMString} nickname
+* @param {ContactField[]} phoneNumbers array of phone numbers
+* @param {ContactField[]} emails array of email addresses
+* @param {ContactAddress[]} addresses array of addresses
+* @param {ContactField[]} ims instant messaging user ids
+* @param {ContactOrganization[]} organizations
+* @param {DOMString} revision date contact was last updated
+* @param {DOMString} birthday contact's birthday
+* @param {DOMString} gender contact's gender
+* @param {DOMString} note user notes about contact
+* @param {ContactField[]} photos
+* @param {ContactField[]} urls contact's web sites
+* @param {DOMString} timezone UTC time zone offset
+*/
 var Contact = function(id, displayName, name, nickname, phoneNumbers, emails, addresses,
     ims, organizations, revision, birthday, gender, note, photos, categories, urls, timezone) {
     this.id = id || null;
@@ -38,88 +36,375 @@
     this.addresses = addresses || null; // ContactAddress[]
     this.ims = ims || null; // ContactField[]
     this.organizations = organizations || null; // ContactOrganization[]
-    this.revision = revision || null;
-    this.birthday = birthday || null;
+    this.revision = revision || null; // JS Date
+    this.birthday = birthday || null; // JS Date
     this.gender = gender || null;
     this.note = note || null;
     this.photos = photos || null; // ContactField[]
-    this.categories = categories || null; // DOMString[]
+    this.categories = categories || null; 
     this.urls = urls || null; // ContactField[]
-    this.timezone = timezone;
+    this.timezone = timezone || null;
 };
 
 /**
- * Contact name.
- * @param formatted full name formatted for display
- * @param familyName family or last name
- * @param givenName given or first name
- * @param middle middle name
- * @param prefix honorific prefix or title
- * @param suffix honorific suffix
- */
+* Converts Dates to milliseconds before sending to iOS
+*/
+Contact.prototype.convertDatesOut = function()
+{
+	var dates = new Array("revision", "birthday");
+	for (var i=0; i<dates.length; i++){
+		var value = this[dates[i]];
+		if (value){
+			if (!value instanceof Date){
+				try {
+					value = new Date(value);
+				} catch(exception){
+					value = null;
+				}
+			}
+			if (value instanceof Date){
+				value = value.valueOf();
+			}
+			this[dates[i]] = value;
+		}
+	}
+	
+};
+/**
+* Converts milliseconds to JS Date when returning from iOS
+*/
+Contact.prototype.convertDatesIn = function()
+{
+	var dates = new Array("revision", "birthday");
+	for (var i=0; i<dates.length; i++){
+		var value = this[dates[i]];
+		if (value){
+			try {
+				this[dates[i]] = new Date(parseFloat(value));
+			} catch (exception){
+				console.log("exception creating date");
+			}
+		}
+	}
+};
+/**
+* Removes contact from device storage.
+* @param successCB success callback
+* @param errorCB error callback (optional)
+*/
+Contact.prototype.remove = function(successCB, errorCB) {
+	if (this.id == null) {
+        var errorObj = new ContactError();
+        errorObj.code = ContactError.NOT_FOUND_ERROR;
+        errorCB(errorObj);
+    }
+    else {
+        PhoneGap.exec(successCB, errorCB, "Contacts", "remove", [{ "contact": this}]);
+    }
+};
+/**
+* iOS ONLY
+* displays contact via iOS UI
+*
+* @param errorCB error callback
+*/
+Contact.prototype.display = function(successCB, errorCB, options) { 
+	if (this.id == null) {
+        var errorObj = new ContactError();
+        errorObj.code = ContactError.NOT_FOUND_ERROR;
+        errorCB(errorObj);
+    }
+    else {
+        PhoneGap.exec(successCB, errorCB, "Contacts","displayContact", [this.id, options]);
+    }
+};
+
+/**
+* Creates a deep copy of this Contact.
+* With the contact ID set to null.
+* @return copy of this Contact
+*/
+Contact.prototype.clone = function() {
+    var clonedContact = PhoneGap.clone(this);
+    clonedContact.id = null;
+    // Loop through and clear out any id's in phones, emails, etc.
+    if (clonedContact.phoneNumbers) {
+    	for (i=0; i<clonedContact.phoneNumbers.length; i++) {
+    		clonedContact.phoneNumbers[i].id = null;
+    	}
+    }
+    if (clonedContact.emails) {
+    	for (i=0; i<clonedContact.emails.length; i++) {
+    		clonedContact.emails[i].id = null;
+    	}
+    }
+    if (clonedContact.addresses) {
+    	for (i=0; i<clonedContact.addresses.length; i++) {
+    		clonedContact.addresses[i].id = null;
+    	}
+    }
+    if (clonedContact.ims) {
+    	for (i=0; i<clonedContact.ims.length; i++) {
+    		clonedContact.ims[i].id = null;
+    	}
+    }
+    if (clonedContact.organizations) {
+    	for (i=0; i<clonedContact.organizations.length; i++) {
+    		clonedContact.organizations[i].id = null;
+    	}
+    }
+    if (clonedContact.photos) {
+    	for (i=0; i<clonedContact.photos.length; i++) {
+    		clonedContact.photos[i].id = null;
+    	}
+    }
+    if (clonedContact.urls) {
+    	for (i=0; i<clonedContact.urls.length; i++) {
+    		clonedContact.urls[i].id = null;
+    	}
+    }
+    return clonedContact;
+};
+
+/**
+* Persists contact to device storage.
+* @param successCB success callback
+* @param errorCB error callback - optional
+*/
+Contact.prototype.save = function(successCB, errorCB) {
+	// don't modify the original contact
+	var cloned = PhoneGap.clone(this);
+	cloned.convertDatesOut(); 
+	PhoneGap.exec(successCB, errorCB, "Contacts","save", [{"contact": cloned}]);
+};
+
+/**
+* Contact name.
+* @param formatted
+* @param familyName
+* @param givenName
+* @param middle
+* @param prefix
+* @param suffix
+*/
 var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) {
-    this.formatted = formatted || null;
-    this.familyName = familyName || null;
-    this.givenName = givenName || null;
-    this.middleName = middle || null;
-    this.honorificPrefix = prefix || null;
-    this.honorificSuffix = suffix || null;
+    this.formatted = formatted != "undefined" ? formatted : null;
+    this.familyName = familyName != "undefined" ? familyName : null;
+    this.givenName = givenName != "undefined" ? givenName : null;
+    this.middleName = middle != "undefined" ? middle : null;
+    this.honorificPrefix = prefix != "undefined" ? prefix : null;
+    this.honorificSuffix = suffix != "undefined" ? suffix : null;
 };
 
 /**
- * Generic contact field.
- * @param type contains the type of information for this field, e.g. 'home', 'mobile'
- * @param value contains the value of this field
- * @param pref indicates whether this instance is preferred 
- */
-var ContactField = function(type, value, pref) {
-    this.type = type || null;
-    this.value = value || null;
-    this.pref = pref || false;
+* Generic contact field.
+* @param type
+* @param value
+* @param primary
+* @param id
+*/
+var ContactField = function(type, value, pref, id) {
+    this.type = type != "undefined" ? type : null;
+    this.value = value != "undefined" ? value : null;
+    this.pref = pref != "undefined" ? pref : null;
+    this.id = id != "undefined" ? id : null;
 };
 
 /**
- * Contact address.
- * @param formatted full physical address, formatted for display
- * @param streetAddress street address
- * @param locality locality or city
- * @param region region or state
- * @param postalCode postal or zip code
- * @param country country name
- */
-var ContactAddress = function(formatted, streetAddress, locality, region, postalCode, country) {
-    this.formatted = formatted || null;
-    this.streetAddress = streetAddress || null;
-    this.locality = locality || null;
-    this.region = region || null;
-    this.postalCode = postalCode || null;
-    this.country = country || null;
+* Contact address.
+* @param formatted
+* @param streetAddress
+* @param locality
+* @param region
+* @param postalCode
+* @param country
+*/
+var ContactAddress = function(formatted, streetAddress, locality, region, postalCode, country, id) {
+    this.formatted = formatted != "undefined" ? formatted : null;
+    this.streetAddress = streetAddress != "undefined" ? streetAddress : null;
+    this.locality = locality != "undefined" ? locality : null;
+    this.region = region != "undefined" ? region : null;
+    this.postalCode = postalCode != "undefined" ? postalCode : null;
+    this.country = country != "undefined" ? country : null;
+    this.id = id != "undefined" ? id : null;
 };
 
 /**
- * Contact organization.
- * @param name name of organization
- * @param dept department
- * @param title job title
- */
-var ContactOrganization = function(name, dept, title) {
-    this.name = name || null;
-    this.department = dept || null;
-    this.title = title || null;
+* Contact organization.
+* @param name
+* @param dept
+* @param title
+* @param startDate
+* @param endDate
+* @param location
+* @param desc
+*/
+var ContactOrganization = function(name, dept, title, startDate, endDate, location, desc) {
+    this.name = name != "undefined" ? name : null;
+    this.department = dept != "undefined" ? dept : null;
+    this.title = title != "undefined" ? title : null;
+    this.startDate = startDate != "undefined" ? startDate : null;
+    this.endDate = endDate != "undefined" ? endDate : null;
+    this.location = location != "undefined" ? location : null;
+    this.description = desc != "undefined" ? desc : null;
 };
 
 /**
- * Represents a group of Contacts. 
- */
+* Contact account.
+* @param domain
+* @param username
+* @param userid
+*/
+var ContactAccount = function(domain, username, userid) {
+    this.domain = domain != "undefined" ? domain : null;
+    this.username = username != "undefined" ? username : null;
+    this.userid = userid != "undefined" ? userid : null;
+}
+
+/**
+* Represents a group of Contacts.
+*/
 var Contacts = function() {
     this.inProgress = false;
-    this.records = [];
+    this.records = new Array();
+    this.resultsCallback = null;
+    this.errorCallback = null;
+};
+/**
+* Returns an array of Contacts matching the search criteria.
+* @param fields that should be searched
+* @param successCB success callback
+* @param errorCB error callback (optional)
+* @param {ContactFindOptions} options that can be applied to contact searching
+* @return array of Contacts matching search criteria
+*/
+Contacts.prototype.find = function(fields, successCB, errorCB, options) {
+	var theOptions = options || null;
+	if (theOptions != null){
+		// convert updatedSince to ms
+		var value = theOptions.updatedSince
+		if (value != ''){
+			if (!value instanceof Date){
+				try {
+					value = new Date(value);
+				} catch(exception){
+					value = null;
+				}
+			}
+			if (value instanceof Date){
+				theOptions.updatedSince = value.valueOf();
+			}
+		}
+	}
+
+	PhoneGap.exec(successCB, errorCB, "Contacts","search", [{"fields":fields, "findOptions":theOptions}]);
+	
+};
+/**
+* need to turn the array of JSON strings representing contact objects into actual objects
+* @param array of JSON strings with contact data
+* @return call results callback with array of Contact objects
+*  This function is called from objective C Contacts.search() method.
+*/
+Contacts.prototype._findCallback = function(pluginResult) {
+	var contacts = new Array();
+	try {
+		for (var i=0; i<pluginResult.message.length; i++) {
+			var newContact = navigator.service.contacts.create(pluginResult.message[i]); 
+			newContact.convertDatesIn();
+			contacts.push(newContact);
+		}
+		pluginResult.message = contacts;
+	} catch(e){
+			console.log("Error parsing contacts: " +e);
+	}
+	return pluginResult;
+}
+
+/**
+* need to turn the JSON string representing contact object into actual object
+* @param JSON string with contact data
+* Call stored results function with  Contact object
+*  This function is called from objective C Contacts remove and save methods
+*/
+Contacts.prototype._contactCallback = function(pluginResult)
+{
+	var newContact = null;
+	if (pluginResult.message){
+		try {
+			newContact = navigator.service.contacts.create(pluginResult.message);
+			newContact.convertDatesIn();
+		} catch(e){
+			console.log("Error parsing contact");
+		}
+	}
+	pluginResult.message = newContact;
+	return pluginResult;
+	
+};
+/** 
+* Need to return an error object rather than just a single error code
+* @param error code
+* Call optional error callback if found.
+* Called from objective c find, remove, and save methods on error.
+*/
+Contacts.prototype._errCallback = function(pluginResult)
+{
+	var errorObj = new ContactError();
+   	errorObj.code = pluginResult.message;
+	pluginResult.message = errorObj;
+	return pluginResult;
+};
+// iPhone only api to create a new contact via the GUI
+Contacts.prototype.newContactUI = function(successCallback) { 
+    PhoneGap.exec(successCallback, null, "Contacts","newContact", []);
+};
+// iPhone only api to select a contact via the GUI
+Contacts.prototype.chooseContact = function(successCallback, options) {
+    PhoneGap.exec(successCallback, null, "Contacts","chooseContact", options);
 };
 
-var ContactError = function(code) {
-    this.code = code;
+
+/**
+* This function creates a new contact, but it does not persist the contact
+* to device storage. To persist the contact to device storage, invoke
+* contact.save().
+* @param properties an object who's properties will be examined to create a new Contact
+* @returns new Contact object
+*/
+Contacts.prototype.create = function(properties) {
+    var contact = new Contact();
+    for (i in properties) {
+        if (contact[i]!='undefined') {
+            contact[i]=properties[i];
+        }
+    }
+    return contact;
 };
 
+/**
+ * ContactFindOptions.
+ * @param filter used to match contacts against
+ * @param multiple boolean used to determine if more than one contact should be returned
+ * @param updatedSince return only contact records that have been updated on or after the given time
+ */
+var ContactFindOptions = function(filter, multiple, updatedSince) {
+    this.filter = filter || '';
+    this.multiple = multiple || true;
+    this.updatedSince = updatedSince || '';
+};
+
+/**
+ *  ContactError.
+ *  An error code assigned by an implementation when an error has occurred
+ */
+var ContactError = function() {
+    this.code=null;
+};
+
+/**
+ * Error codes
+ */
 ContactError.UNKNOWN_ERROR = 0;
 ContactError.INVALID_ARGUMENT_ERROR = 1;
 ContactError.NOT_FOUND_ERROR = 2;
@@ -130,142 +415,10 @@
 ContactError.PERMISSION_DENIED_ERROR = 20;
 
 /**
- * This function creates a new contact, but it does not persist the contact
- * to device storage.  To persist the contact to device storage, invoke
- * <code>contact.save()</code>.
+ * Add the contact interface into the browser.
  */
-Contacts.prototype.create = function(properties) {
-    var contact = new Contact();
-    for (var i in properties) {
-        if (contact[i] !== 'undefined') {
-            contact[i] = properties[i];
-        }
-    }
-    return contact;
-};
-
-/**
- * Persists contact to device storage.
- */
-Contact.prototype.save = function(success, fail) {
-    
-    try {
-        // save the contact and store it's unique id
-        this.id = BlackBerryContacts.saveToDevice(this);        
-        if (success) {
-            success(this);
-        }
-    } catch (e) {
-        console.log('Error saving contact: ' + e);
-        if (fail) {
-            fail(new ContactError(ContactError.UNKNOWN_ERROR));
-        }
-    }
-};
-
-/**
- * Removes contact from device storage.
- * @param success success callback
- * @param fail error callback
- */
-Contact.prototype.remove = function(success, fail) {
-
-    try {
-        // retrieve contact from device by id
-        var bbContact = null;
-        if (this.id) {
-            bbContact = BlackBerryContacts.findByUniqueId(this.id);
-        }
-        
-        // if contact was found, remove it
-        if (bbContact) {
-            console.log('removing contact: ' + bbContact.uid);
-            bbContact.remove();
-            if (success) {
-                success(this);
-            }
-        }
-        // attempting to remove a contact that hasn't been saved
-        else if (fail) { 
-            fail(new ContactError(ContactError.NOT_FOUND_ERROR));            
-        }
-    } 
-    catch (e) {
-        console.log('Error removing contact ' + this.id + ": " + e);
-        if (fail) { 
-            fail(new ContactError(ContactError.UNKNOWN_ERROR));
-        }
-    }
-};
-
-/**
- * Creates a deep copy of this Contact.
- * @return copy of this Contact
- */
-Contact.prototype.clone = function() {
-    var clonedContact = PhoneGap.clone(this);
-    clonedContact.id = null;
-    return clonedContact;
-};
-
-/**
- * Returns an array of Contacts matching the search criteria.
- * @return array of Contacts matching search criteria
- */
-Contacts.prototype.find = function(fields, success, fail, options) {
-
-    // default is to return multiple contacts (-1 on BlackBerry)
-    var numContacts = -1;
-
-    // search options
-    var filter = null;
-    if (options) {
-        // return multiple objects?
-        if (options.multiple === false) {
-            numContacts = 1;
-        }
-        filter = options.filter;
-    }
-    
-    // build the filter expression to use in find operation 
-    var filterExpression = BlackBerryContacts.buildFilterExpression(fields, filter); 
-
-    // find matching contacts
-    // Note: the filter expression can be null here, in which case, the find won't filter
-    var bbContacts = blackberry.pim.Contact.find(filterExpression, null, numContacts);
-    
-    // convert to Contact from blackberry.pim.Contact
-    var contacts = [];
-    for (var i in bbContacts) {
-        if (bbContacts[i]) { 
-            // W3C Contacts API specification states that only the fields
-            // in the search filter should be returned, so we create 
-            // a new Contact object, copying only the fields specified
-            contacts.push(BlackBerryContacts.createContact(bbContacts[i], fields));
-        }
-    }
-    
-    // return results
-    if (success && success instanceof Function) {
-        success(contacts);
-    } else {
-        console.log("Error invoking Contacts.find success callback.");
-    }
-};
-
-/**
- * Contact search criteria.
- * @param filter string-based search filter with which to search and filter contacts
- * @param multiple indicates whether multiple contacts should be returned (defaults to true)
- * @param updatedSince return only records that have been updated after the specified timm
- */
-var ContactFindOptions = function(filter, multiple, updatedSince) {
-    this.filter = filter || '';
-    this.multiple = multiple || true;
-    this.updatedSince = updatedSince || '';
-};
-
-PhoneGap.addConstructor(function() {
-    if(typeof navigator.service === "undefined") navigator.service = new Object();
-    if(typeof navigator.service.contacts === "undefined") navigator.service.contacts = new Contacts();
+PhoneGap.addConstructor(function() { 
+    if(typeof navigator.service == "undefined") navigator.service = new Object();
+    if(typeof navigator.service.contacts == "undefined") navigator.service.contacts = new Contacts();
 });
+
diff --git a/Res/phonegap/device.js b/Res/phonegap/device.js
index 9b91214..f4a6241 100644
--- a/Res/phonegap/device.js
+++ b/Res/phonegap/device.js
@@ -13,14 +13,13 @@
  * @constructor
  */
 function Device() {
-  // this.platform = phonegap.device.platform;
-  // this.version  = blackberry.system.softwareVersion;
-  // this.name     = blackberry.system.model;
-  // this.uuid     = phonegap.device.uuid;
-  // this.phonegap = phonegap.device.phonegap;
+  this.platform = null;
+  this.version  = null;
+  this.name     = null;
+  this.uuid     = null;
 };
 
 PhoneGap.addConstructor(function() {
-  navigator.device = window.device = new Device();
-  PhoneGap.onPhoneGapInfoReady.fire();
+  navigator.device = window.device = window.device || new Device();
+//  PhoneGap.onPhoneGapInfoReady.fire();
 });
diff --git a/Res/phonegap/phonegap.base.js b/Res/phonegap/phonegap.base.js
index 8667a58..fd2b19a 100644
--- a/Res/phonegap/phonegap.base.js
+++ b/Res/phonegap/phonegap.base.js
@@ -52,7 +52,7 @@
  * Boolean flag indicating if the PhoneGap API is available and initialized.
  */ // TODO: Remove this, it is unused here ... -jm
 PhoneGap.available = function() {
-  return DeviceInfo.uuid != undefined;
+  return window.device.uuid != undefined;
 }
 
 /**
diff --git a/Res/phonegap/phonegap.bat b/Res/phonegap/phonegap.bat
index 04ddc6f..70fdbf4 100755
--- a/Res/phonegap/phonegap.bat
+++ b/Res/phonegap/phonegap.bat
@@ -1 +1 @@
-copy /B phonegap.base.js+geolocation.js+position.js+accelerometer.js+network.js+debugconsole.js phonegap.js
+copy /B phonegap.base.js+geolocation.js+position.js+accelerometer.js+network.js+debugconsole.js+contact.js+device.js phonegap.js
diff --git a/inc/Contacts.h b/inc/Contacts.h
new file mode 100755
index 0000000..a9a3e0b
--- /dev/null
+++ b/inc/Contacts.h
@@ -0,0 +1,26 @@
+/*

+ * Contacts.h

+ *

+ *  Created on: Mar 25, 2011

+ *      Author: Anis Kadri

+ */

+

+#ifndef CONTACTS_H_

+#define CONTACTS_H_

+

+#include <FApp.h>

+#include "PhoneGapCommand.h"

+using namespace Osp::Base::Collection;

+using namespace Osp::App;

+

+class Contacts: public PhoneGapCommand {

+public:

+	Contacts(Web* pWeb);

+	virtual ~Contacts();

+public:

+	void Run(const String& command);

+	void Create();

+	void Find();

+};

+

+#endif /* CONTACTS_H_ */

diff --git a/inc/WebForm.h b/inc/WebForm.h
index 0fa75b6..93e5134 100755
--- a/inc/WebForm.h
+++ b/inc/WebForm.h
@@ -13,9 +13,14 @@
 #include "Network.h"

 #include "DebugConsole.h"

 

-using namespace Osp::Web::Controls;

 using namespace Osp::Base;

 using namespace Osp::Base::Collection;

+using namespace Osp::App;

+using namespace Osp::Ui;

+using namespace Osp::Ui::Controls;

+using namespace Osp::System;

+using namespace Osp::Graphics;

+using namespace Osp::Web::Controls;

 

 class WebForm :

 	public Osp::Ui::Controls::Form,

diff --git a/manifest.xml b/manifest.xml
index 8e85fe8..3c39ac0 100755
--- a/manifest.xml
+++ b/manifest.xml
@@ -17,6 +17,9 @@
         <Privilege>

             <Name>LOCATION</Name>

         </Privilege>

+        <Privilege>

+        	<Name>ADDRESSBOOK</Name>

+    	</Privilege>

 	</Privileges>

 	<DeviceProfile>

 		<APIVersion>1.2</APIVersion>

diff --git a/src/Contacts.cpp b/src/Contacts.cpp
new file mode 100755
index 0000000..eb9390f
--- /dev/null
+++ b/src/Contacts.cpp
@@ -0,0 +1,48 @@
+/*

+ * Contacts.cpp

+ *

+ *  Created on: Mar 25, 2011

+ *      Author: Anis Kadri

+ */

+

+#include "../inc/Contacts.h"

+

+Contacts::Contacts(Web* pWeb) : PhoneGapCommand(pWeb) {

+	// TODO Auto-generated constructor stub

+

+}

+

+Contacts::~Contacts() {

+	// TODO Auto-generated destructor stub

+}

+

+void

+Contacts::Run(const String& command) {

+	if(!command.IsEmpty()) {

+

+	}

+}

+

+void

+Contacts::Create() {

+	ArrayList* pDataList = null;

+	pDataList = new ArrayList();

+	pDataList->Construct();

+	String* pData = null;

+	pData = new String(L"phone:+919899045670");

+	pDataList->Add(*pData);

+

+	AppControl* pAc = AppManager::FindAppControlN(APPCONTROL_CONTACT,OPERATION_ADD);

+	if(pAc)

+	{

+		pAc->Start(pDataList, null);

+		delete pAc;

+	}

+	pDataList->RemoveAll(true);

+	delete pDataList;

+}

+

+void

+Contacts::Find() {

+

+}

diff --git a/src/Device.cpp b/src/Device.cpp
index 14331d9..740c235 100755
--- a/src/Device.cpp
+++ b/src/Device.cpp
@@ -52,7 +52,7 @@
 

     if(r == E_SUCCESS) {

     	String res;

-    	res.Format(1024, L"DeviceInfo = {platform: 'bada', version:'%S', name:'n/a', gap: '0.9.4', uuid: '%S'}", platformVersion.GetPointer(), imei.GetPointer());

+    	res.Format(1024, L"window.device={platform:'bada',version:'%S',name:'n/a',phonegap:'0.9.4',uuid:'%S'}", platformVersion.GetPointer(), imei.GetPointer());

     	AppLogDebug("%S", res.GetPointer());

     	pWeb->EvaluateJavascriptN(res);

     }

diff --git a/src/WebForm.cpp b/src/WebForm.cpp
index 6361f01..1b8ff84 100755
--- a/src/WebForm.cpp
+++ b/src/WebForm.cpp
@@ -1,13 +1,5 @@
 #include "WebForm.h"

 

-using namespace Osp::App;

-using namespace Osp::Base;

-using namespace Osp::Ui;

-using namespace Osp::Ui::Controls;

-using namespace Osp::System;

-using namespace Osp::Graphics;

-using namespace Osp::Web::Controls;

-

 WebForm::WebForm(void)

 	:__pWeb(null), __phonegapCommand(null)

 {