You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ia...@apache.org on 2014/04/25 20:12:25 UTC

[2/6] CB-6521: Remove development branch

http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/blob/fc255252/src/ios/CDVContacts.m
----------------------------------------------------------------------
diff --git a/src/ios/CDVContacts.m b/src/ios/CDVContacts.m
deleted file mode 100644
index 56ca2ab..0000000
--- a/src/ios/CDVContacts.m
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-#import "CDVContacts.h"
-#import <UIKit/UIKit.h>
-#import <Cordova/NSArray+Comparisons.h>
-#import <Cordova/NSDictionary+Extensions.h>
-//#import "CDVNotification.h"
-
-@implementation CDVContactsPicker
-
-@synthesize allowsEditing;
-@synthesize callbackId;
-@synthesize options;
-@synthesize pickedContactDictionary;
-
-@end
-@implementation CDVNewContactsController
-
-@synthesize callbackId;
-
-@end
-
-@implementation CDVContacts
-
-// no longer used since code gets AddressBook for each operation.
-// If address book changes during save or remove operation, may get error but not much we can do about it
-// If address book changes during UI creation, display or edit, we don't control any saves so no need for callback
-
-/*void addressBookChanged(ABAddressBookRef addressBook, CFDictionaryRef info, void* context)
-{
-    // note that this function is only called when another AddressBook instance modifies
-    // the address book, not the current one. For example, through an OTA MobileMe sync
-    Contacts* contacts = (Contacts*)context;
-    [contacts addressBookDirty];
-    }*/
-
-- (CDVPlugin*)initWithWebView:(UIWebView*)theWebView
-{
-    self = (CDVContacts*)[super initWithWebView:(UIWebView*)theWebView];
-
-    /*if (self) {
-        addressBook = ABAddressBookCreate();
-        ABAddressBookRegisterExternalChangeCallback(addressBook, addressBookChanged, self);
-    }*/
-
-    return self;
-}
-
-// overridden to clean up Contact statics
-- (void)onAppTerminate
-{
-    // NSLog(@"Contacts::onAppTerminate");
-}
-
-// iPhone only method to create a new contact through the GUI
-- (void)newContact:(CDVInvokedUrlCommand*)command
-{
-    NSString* callbackId = command.callbackId;
-
-    CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
-    CDVContacts* __weak weakSelf = self;  // play it safe to avoid retain cycles
-
-    [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errCode) {
-        if (addrBook == NULL) {
-            // permission was denied or other error just return (no error callback)
-            return;
-        }
-        CDVNewContactsController* npController = [[CDVNewContactsController alloc] init];
-        npController.addressBook = addrBook;     // a CF retaining assign
-        CFRelease(addrBook);
-
-        npController.newPersonViewDelegate = self;
-        npController.callbackId = callbackId;
-
-        UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:npController];
-
-        SEL selector = NSSelectorFromString(@"presentViewController:animated:completion:");
-        if ([weakSelf.viewController respondsToSelector:selector]) {
-            [weakSelf.viewController presentViewController:navController animated:YES completion:nil];
-        } else {
-            // deprecated as of iOS >= 6.0
-            [weakSelf.viewController presentModalViewController:navController animated:YES];
-        }
-    }];
-}
-
-- (void)newPersonViewController:(ABNewPersonViewController*)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person
-{
-    ABRecordID recordId = kABRecordInvalidID;
-    CDVNewContactsController* newCP = (CDVNewContactsController*)newPersonViewController;
-    NSString* callbackId = newCP.callbackId;
-
-    if (person != NULL) {
-        // return the contact id
-        recordId = ABRecordGetRecordID(person);
-    }
-
-    if ([newPersonViewController respondsToSelector:@selector(presentingViewController)]) {
-        [[newPersonViewController presentingViewController] dismissViewControllerAnimated:YES completion:nil];
-    } else {
-        [[newPersonViewController parentViewController] dismissModalViewControllerAnimated:YES];
-    }
-
-    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:recordId];
-    [self.commandDelegate sendPluginResult:result callbackId:callbackId];
-}
-
-- (void)displayContact:(CDVInvokedUrlCommand*)command
-{
-    NSString* callbackId = command.callbackId;
-    ABRecordID recordID = [[command.arguments objectAtIndex:0] intValue];
-    NSDictionary* options = [command.arguments objectAtIndex:1 withDefault:[NSNull null]];
-    bool bEdit = [options isKindOfClass:[NSNull class]] ? false : [options existsValue:@"true" forKey:@"allowsEditing"];
-
-    CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
-    CDVContacts* __weak weakSelf = self;  // play it safe to avoid retain cycles
-
-    [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errCode) {
-        if (addrBook == NULL) {
-            // permission was denied or other error - return error
-            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:errCode ? (int)errCode.errorCode:UNKNOWN_ERROR];
-            [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
-            return;
-        }
-        ABRecordRef rec = ABAddressBookGetPersonWithRecordID(addrBook, recordID);
-
-        if (rec) {
-            CDVDisplayContactViewController* personController = [[CDVDisplayContactViewController alloc] init];
-            personController.displayedPerson = rec;
-            personController.personViewDelegate = self;
-            personController.allowsEditing = NO;
-
-            // create this so DisplayContactViewController will have a "back" button.
-            UIViewController* parentController = [[UIViewController alloc] init];
-            UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:parentController];
-
-            [navController pushViewController:personController animated:YES];
-
-            SEL selector = NSSelectorFromString(@"presentViewController:animated:completion:");
-            if ([self.viewController respondsToSelector:selector]) {
-                [self.viewController presentViewController:navController animated:YES completion:nil];
-            } else {
-                // deprecated as of iOS >= 6.0
-                [self.viewController presentModalViewController:navController animated:YES];
-            }
-
-            if (bEdit) {
-                // create the editing controller and push it onto the stack
-                ABPersonViewController* editPersonController = [[ABPersonViewController alloc] init];
-                editPersonController.displayedPerson = rec;
-                editPersonController.personViewDelegate = self;
-                editPersonController.allowsEditing = YES;
-                [navController pushViewController:editPersonController animated:YES];
-            }
-        } else {
-            // no record, return error
-            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:UNKNOWN_ERROR];
-            [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
-        }
-        CFRelease(addrBook);
-    }];
-}
-
-- (BOOL)personViewController:(ABPersonViewController*)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person
-                    property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
-{
-    return YES;
-}
-
-- (void)chooseContact:(CDVInvokedUrlCommand*)command
-{
-    NSString* callbackId = command.callbackId;
-    NSDictionary* options = [command.arguments objectAtIndex:0 withDefault:[NSNull null]];
-
-    CDVContactsPicker* pickerController = [[CDVContactsPicker alloc] init];
-
-    pickerController.peoplePickerDelegate = self;
-    pickerController.callbackId = callbackId;
-    pickerController.options = options;
-    pickerController.pickedContactDictionary = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:kABRecordInvalidID], kW3ContactId, nil];
-    id allowsEditingValue = [options valueForKey:@"allowsEditing"];
-    BOOL allowsEditing = NO;
-    if ([allowsEditingValue isKindOfClass:[NSNumber class]]) {
-        allowsEditing = [(NSNumber*)allowsEditingValue boolValue];
-    }
-    pickerController.allowsEditing = allowsEditing;
-
-    SEL selector = NSSelectorFromString(@"presentViewController:animated:completion:");
-    if ([self.viewController respondsToSelector:selector]) {
-        [self.viewController presentViewController:pickerController animated:YES completion:nil];
-    } else {
-        // deprecated as of iOS >= 6.0
-        [self.viewController presentModalViewController:pickerController animated:YES];
-    }
-}
-
-- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker
-      shouldContinueAfterSelectingPerson:(ABRecordRef)person
-{
-    CDVContactsPicker* picker = (CDVContactsPicker*)peoplePicker;
-    NSNumber* pickedId = [NSNumber numberWithInt:ABRecordGetRecordID(person)];
-
-    if (picker.allowsEditing) {
-        ABPersonViewController* personController = [[ABPersonViewController alloc] init];
-        personController.displayedPerson = person;
-        personController.personViewDelegate = self;
-        personController.allowsEditing = picker.allowsEditing;
-        // store id so can get info in peoplePickerNavigationControllerDidCancel
-        picker.pickedContactDictionary = [NSDictionary dictionaryWithObjectsAndKeys:pickedId, kW3ContactId, nil];
-
-        [peoplePicker pushViewController:personController animated:YES];
-    } else {
-        // Retrieve and return pickedContact information
-        CDVContact* pickedContact = [[CDVContact alloc] initFromABRecord:(ABRecordRef)person];
-        NSArray* fields = [picker.options objectForKey:@"fields"];
-        NSDictionary* returnFields = [[CDVContact class] calcReturnFields:fields];
-        picker.pickedContactDictionary = [pickedContact toDictionary:returnFields];
-
-        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:picker.pickedContactDictionary];
-        [self.commandDelegate sendPluginResult:result callbackId:picker.callbackId];
-
-        if ([picker respondsToSelector:@selector(presentingViewController)]) {
-            [[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];
-        } else {
-            [[picker parentViewController] dismissModalViewControllerAnimated:YES];
-        }
-    }
-    return NO;
-}
-
-- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker
-      shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
-{
-    return YES;
-}
-
-- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController*)peoplePicker
-{
-    // return contactId or invalid if none picked
-    CDVContactsPicker* picker = (CDVContactsPicker*)peoplePicker;
-
-    if (picker.allowsEditing) {
-        // get the info after possible edit
-        // if we got this far, user has already approved/ disapproved addressBook access
-        ABAddressBookRef addrBook = nil;
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
-            if (&ABAddressBookCreateWithOptions != NULL) {
-                addrBook = ABAddressBookCreateWithOptions(NULL, NULL);
-            } else
-#endif
-        {
-            // iOS 4 & 5
-            addrBook = ABAddressBookCreate();
-        }
-        ABRecordRef person = ABAddressBookGetPersonWithRecordID(addrBook, (int)[[picker.pickedContactDictionary objectForKey:kW3ContactId] integerValue]);
-        if (person) {
-            CDVContact* pickedContact = [[CDVContact alloc] initFromABRecord:(ABRecordRef)person];
-            NSArray* fields = [picker.options objectForKey:@"fields"];
-            NSDictionary* returnFields = [[CDVContact class] calcReturnFields:fields];
-            picker.pickedContactDictionary = [pickedContact toDictionary:returnFields];
-        }
-        CFRelease(addrBook);
-    }
-    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:picker.pickedContactDictionary];
-    [self.commandDelegate sendPluginResult:result callbackId:picker.callbackId];
-
-    if ([peoplePicker respondsToSelector:@selector(presentingViewController)]) {
-        [[peoplePicker presentingViewController] dismissViewControllerAnimated:YES completion:nil];
-    } else {
-        [[peoplePicker parentViewController] dismissModalViewControllerAnimated:YES];
-    }
-}
-
-- (void)search:(CDVInvokedUrlCommand*)command
-{
-    NSString* callbackId = command.callbackId;
-    NSArray* fields = [command.arguments objectAtIndex:0];
-    NSDictionary* findOptions = [command.arguments objectAtIndex:1 withDefault:[NSNull null]];
-
-    [self.commandDelegate runInBackground:^{
-        // from Apple:  Important You must ensure that an instance of ABAddressBookRef is used by only one thread.
-        // which is why address book is created within the dispatch queue.
-        // more details here: http: //blog.byadrian.net/2012/05/05/ios-addressbook-framework-and-gcd/
-        CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
-        CDVContacts* __weak weakSelf = self;     // play it safe to avoid retain cycles
-        // it gets uglier, block within block.....
-        [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errCode) {
-            if (addrBook == NULL) {
-                // permission was denied or other error - return error
-                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:errCode ? (int)errCode.errorCode:UNKNOWN_ERROR];
-                [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
-                return;
-            }
-
-            NSArray* foundRecords = nil;
-            // get the findOptions values
-            BOOL multiple = NO;         // default is false
-            NSString* filter = nil;
-            if (![findOptions isKindOfClass:[NSNull class]]) {
-                id value = nil;
-                filter = (NSString*)[findOptions objectForKey:@"filter"];
-                value = [findOptions objectForKey:@"multiple"];
-                if ([value isKindOfClass:[NSNumber class]]) {
-                    // multiple is a boolean that will come through as an NSNumber
-                    multiple = [(NSNumber*)value boolValue];
-                    // NSLog(@"multiple is: %d", multiple);
-                }
-            }
-
-            NSDictionary* returnFields = [[CDVContact class] calcReturnFields:fields];
-
-            NSMutableArray* matches = nil;
-            if (!filter || [filter isEqualToString:@""]) {
-                // get all records
-                foundRecords = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addrBook);
-                if (foundRecords && ([foundRecords count] > 0)) {
-                    // create Contacts and put into matches array
-                    // doesn't make sense to ask for all records when multiple == NO but better check
-                    int xferCount = multiple == YES ? (int)[foundRecords count] : 1;
-                    matches = [NSMutableArray arrayWithCapacity:xferCount];
-
-                    for (int k = 0; k < xferCount; k++) {
-                        CDVContact* xferContact = [[CDVContact alloc] initFromABRecord:(__bridge ABRecordRef)[foundRecords objectAtIndex:k]];
-                        [matches addObject:xferContact];
-                        xferContact = nil;
-                    }
-                }
-            } else {
-                foundRecords = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addrBook);
-                matches = [NSMutableArray arrayWithCapacity:1];
-                BOOL bFound = NO;
-                int testCount = (int)[foundRecords count];
-
-                for (int j = 0; j < testCount; j++) {
-                    CDVContact* testContact = [[CDVContact alloc] initFromABRecord:(__bridge ABRecordRef)[foundRecords objectAtIndex:j]];
-                    if (testContact) {
-                        bFound = [testContact foundValue:filter inFields:returnFields];
-                        if (bFound) {
-                            [matches addObject:testContact];
-                        }
-                        testContact = nil;
-                    }
-                }
-            }
-            NSMutableArray* returnContacts = [NSMutableArray arrayWithCapacity:1];
-
-            if ((matches != nil) && ([matches count] > 0)) {
-                // convert to JS Contacts format and return in callback
-                // - returnFields  determines what properties to return
-                @autoreleasepool {
-                    int count = multiple == YES ? (int)[matches count] : 1;
-
-                    for (int i = 0; i < count; i++) {
-                        CDVContact* newContact = [matches objectAtIndex:i];
-                        NSDictionary* aContact = [newContact toDictionary:returnFields];
-                        [returnContacts addObject:aContact];
-                    }
-                }
-            }
-            // return found contacts (array is empty if no contacts found)
-            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:returnContacts];
-            [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
-            // NSLog(@"findCallback string: %@", jsString);
-
-            if (addrBook) {
-                CFRelease(addrBook);
-            }
-        }];
-    }];     // end of workQueue block
-
-    return;
-}
-
-- (void)save:(CDVInvokedUrlCommand*)command
-{
-    NSString* callbackId = command.callbackId;
-    NSDictionary* contactDict = [command.arguments objectAtIndex:0];
-
-    [self.commandDelegate runInBackground:^{
-        CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
-        CDVContacts* __weak weakSelf = self;     // play it safe to avoid retain cycles
-
-        [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errorCode) {
-            CDVPluginResult* result = nil;
-            if (addrBook == NULL) {
-                // permission was denied or other error - return error
-                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errorCode ? (int)errorCode.errorCode:UNKNOWN_ERROR];
-                [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
-                return;
-            }
-
-            bool bIsError = FALSE, bSuccess = FALSE;
-            BOOL bUpdate = NO;
-            CDVContactError errCode = UNKNOWN_ERROR;
-            CFErrorRef error;
-            NSNumber* cId = [contactDict valueForKey:kW3ContactId];
-            CDVContact* aContact = nil;
-            ABRecordRef rec = nil;
-            if (cId && ![cId isKindOfClass:[NSNull class]]) {
-                rec = ABAddressBookGetPersonWithRecordID(addrBook, [cId intValue]);
-                if (rec) {
-                    aContact = [[CDVContact alloc] initFromABRecord:rec];
-                    bUpdate = YES;
-                }
-            }
-            if (!aContact) {
-                aContact = [[CDVContact alloc] init];
-            }
-
-            bSuccess = [aContact setFromContactDict:contactDict asUpdate:bUpdate];
-            if (bSuccess) {
-                if (!bUpdate) {
-                    bSuccess = ABAddressBookAddRecord(addrBook, [aContact record], &error);
-                }
-                if (bSuccess) {
-                    bSuccess = ABAddressBookSave(addrBook, &error);
-                }
-                if (!bSuccess) {         // need to provide error codes
-                    bIsError = TRUE;
-                    errCode = IO_ERROR;
-                } else {
-                    // give original dictionary back?  If generate dictionary from saved contact, have no returnFields specified
-                    // so would give back all fields (which W3C spec. indicates is not desired)
-                    // for now (while testing) give back saved, full contact
-                    NSDictionary* newContact = [aContact toDictionary:[CDVContact defaultFields]];
-                    // NSString* contactStr = [newContact JSONRepresentation];
-                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newContact];
-                }
-            } else {
-                bIsError = TRUE;
-                errCode = IO_ERROR;
-            }
-            CFRelease(addrBook);
-
-            if (bIsError) {
-                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:(int)errCode];
-            }
-
-            if (result) {
-                [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
-            }
-        }];
-    }];     // end of  queue
-}
-
-- (void)remove:(CDVInvokedUrlCommand*)command
-{
-    NSString* callbackId = command.callbackId;
-    NSNumber* cId = [command.arguments objectAtIndex:0];
-
-    CDVAddressBookHelper* abHelper = [[CDVAddressBookHelper alloc] init];
-    CDVContacts* __weak weakSelf = self;  // play it safe to avoid retain cycles
-
-    [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError* errorCode) {
-        CDVPluginResult* result = nil;
-        if (addrBook == NULL) {
-            // permission was denied or other error - return error
-            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errorCode ? (int)errorCode.errorCode:UNKNOWN_ERROR];
-            [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
-            return;
-        }
-
-        bool bIsError = FALSE, bSuccess = FALSE;
-        CDVContactError errCode = UNKNOWN_ERROR;
-        CFErrorRef error;
-        ABRecordRef rec = nil;
-        if (cId && ![cId isKindOfClass:[NSNull class]] && ([cId intValue] != kABRecordInvalidID)) {
-            rec = ABAddressBookGetPersonWithRecordID(addrBook, [cId intValue]);
-            if (rec) {
-                bSuccess = ABAddressBookRemoveRecord(addrBook, rec, &error);
-                if (!bSuccess) {
-                    bIsError = TRUE;
-                    errCode = IO_ERROR;
-                } else {
-                    bSuccess = ABAddressBookSave(addrBook, &error);
-                    if (!bSuccess) {
-                        bIsError = TRUE;
-                        errCode = IO_ERROR;
-                    } else {
-                        // set id to null
-                        // [contactDict setObject:[NSNull null] forKey:kW3ContactId];
-                        // result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary: contactDict];
-                        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
-                        // NSString* contactStr = [contactDict JSONRepresentation];
-                    }
-                }
-            } else {
-                // no record found return error
-                bIsError = TRUE;
-                errCode = UNKNOWN_ERROR;
-            }
-        } else {
-            // invalid contact id provided
-            bIsError = TRUE;
-            errCode = INVALID_ARGUMENT_ERROR;
-        }
-
-        if (addrBook) {
-            CFRelease(addrBook);
-        }
-        if (bIsError) {
-            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:(int)errCode];
-        }
-        if (result) {
-            [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];
-        }
-    }];
-    return;
-}
-
-@end
-
-/* ABPersonViewController does not have any UI to dismiss.  Adding navigationItems to it does not work properly
- * The navigationItems are lost when the app goes into the background.  The solution was to create an empty
- * NavController in front of the ABPersonViewController. This will cause the ABPersonViewController to have a back button. By subclassing the ABPersonViewController, we can override viewDidDisappear and take down the entire NavigationController.
- */
-@implementation CDVDisplayContactViewController
-@synthesize contactsPlugin;
-
-- (void)viewWillDisappear:(BOOL)animated
-{
-    [super viewWillDisappear:animated];
-
-    if ([self respondsToSelector:@selector(presentingViewController)]) {
-        [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
-    } else {
-        [[self parentViewController] dismissModalViewControllerAnimated:YES];
-    }
-}
-
-@end
-@implementation CDVAddressBookAccessError
-
-@synthesize errorCode;
-
-- (CDVAddressBookAccessError*)initWithCode:(CDVContactError)code
-{
-    self = [super init];
-    if (self) {
-        self.errorCode = code;
-    }
-    return self;
-}
-
-@end
-
-@implementation CDVAddressBookHelper
-
-/**
- * NOTE: workerBlock is responsible for releasing the addressBook that is passed to it
- */
-- (void)createAddressBook:(CDVAddressBookWorkerBlock)workerBlock
-{
-    // TODO: this probably should be reworked - seems like the workerBlock can just create and release its own AddressBook,
-    // and also this important warning from (http://developer.apple.com/library/ios/#documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/BasicObjects.html):
-    // "Important: Instances of ABAddressBookRef cannot be used by multiple threads. Each thread must make its own instance."
-    ABAddressBookRef addressBook;
-
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 60000
-        if (&ABAddressBookCreateWithOptions != NULL) {
-            CFErrorRef error = nil;
-            // CFIndex status = ABAddressBookGetAuthorizationStatus();
-            addressBook = ABAddressBookCreateWithOptions(NULL, &error);
-            // NSLog(@"addressBook access: %lu", status);
-            ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
-                    // callback can occur in background, address book must be accessed on thread it was created on
-                    dispatch_sync(dispatch_get_main_queue(), ^{
-                        if (error) {
-                            workerBlock(NULL, [[CDVAddressBookAccessError alloc] initWithCode:UNKNOWN_ERROR]);
-                        } else if (!granted) {
-                            workerBlock(NULL, [[CDVAddressBookAccessError alloc] initWithCode:PERMISSION_DENIED_ERROR]);
-                        } else {
-                            // access granted
-                            workerBlock(addressBook, [[CDVAddressBookAccessError alloc] initWithCode:UNKNOWN_ERROR]);
-                        }
-                    });
-                });
-        } else
-#endif
-    {
-        // iOS 4 or 5 no checks needed
-        addressBook = ABAddressBookCreate();
-        workerBlock(addressBook, NULL);
-    }
-}
-
-@end

http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/blob/fc255252/src/ubuntu/contacts.cpp
----------------------------------------------------------------------
diff --git a/src/ubuntu/contacts.cpp b/src/ubuntu/contacts.cpp
deleted file mode 100644
index 373a276..0000000
--- a/src/ubuntu/contacts.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-#include "contacts.h"
-
-#if defined QTCONTACTS_USE_NAMESPACE
-QTCONTACTS_USE_NAMESPACE
-#endif
-
-Contacts::Contacts(Cordova *cordova): CPlugin(cordova) {
-    m_fieldNamePairs.clear();
-
-    m_fieldNamePairs["displayName"] = QContactDetail::TypeDisplayLabel;
-    m_fieldNamePairs["name"] = QContactDetail::TypeName;
-    m_fieldNamePairs["nickname"] = QContactDetail::TypeNickname;
-    m_fieldNamePairs["phoneNumbers"] = QContactDetail::TypePhoneNumber;
-    m_fieldNamePairs["emails"] = QContactDetail::TypeEmailAddress;
-    m_fieldNamePairs["addresses"] = QContactDetail::TypeAddress;
-    m_fieldNamePairs["ims"] = QContactDetail::TypeOnlineAccount;
-    m_fieldNamePairs["organizations"] = QContactDetail::TypeOrganization;
-    m_fieldNamePairs["birthday"] = QContactDetail::TypeBirthday;
-    m_fieldNamePairs["note"] = QContactDetail::TypeNote;
-    m_fieldNamePairs["photos"] = QContactDetail::TypeAvatar;
-    m_fieldNamePairs["urls"] = QContactDetail::TypeUrl;
-
-    m_notSupportedFields.clear();
-    m_notSupportedFields << "categories";
-    m_manager.clear();
-    m_manager = QSharedPointer<QContactManager>(new QContactManager());
-}
-
-void Contacts::save(int scId, int ecId, const QVariantMap &params) {
-    QContact result;
-    QList<QContactDetail *> detailsToDelete;
-
-    if (params.find("id") != params.end()) {
-        QString id = params.find("id")->toString();
-        if (!id.isEmpty()) {
-            result = m_manager->contact(QContactId::fromString(id));
-            result.clearDetails();
-        }
-    }
-
-    foreach (QString field, params.keys()) {
-        QContactDetail::DetailType qtDefinition = cordovaFieldNameToQtDefinition(field);
-        if (qtDefinition == QContactDetail::TypeUndefined)
-            continue;
-
-        if (field == "nickname") {
-            QContactNickname *detail = new QContactNickname;
-            detail->setNickname(params[field].toString());
-            detailsToDelete << detail;
-            result.saveDetail(detail);
-        } else if (field == "note") {
-            QContactNote *detail = new QContactNote;
-            detail->setNote(params[field].toString());
-            detailsToDelete << detail;
-            result.saveDetail(detail);
-        } else if (field == "phoneNumbers") {
-            if (params[field].type() != QVariant::List)
-                continue;
-            QVariantList phonesList = params[field].toList();
-            foreach (const QVariant &phoneDesc, phonesList) {
-                if (phoneDesc.type() != QVariant::Map)
-                    continue;
-                QContactPhoneNumber *detail = new QContactPhoneNumber;
-                detail->setNumber(phoneDesc.toMap()["value"].toString());
-                if (!phoneDesc.toMap()["type"].toString().isEmpty() &&
-                        phoneDesc.toMap()["type"].toString() != "phone")
-                    detail->setSubTypes(QList<int>() <<
-                                        subTypePhoneFromString(phoneDesc.toMap()["type"].toString()));
-                detailsToDelete << detail;
-                result.saveDetail(detail);
-            }
-        } else if (field == "emails") {
-            if (params[field].type() != QVariant::List)
-                continue;
-            QVariantList emailsList = params[field].toList();
-            foreach (const QVariant &emailDesc, emailsList) {
-                if (emailDesc.type() != QVariant::Map)
-                    continue;
-                if (emailDesc.toMap()["value"].toString().isEmpty())
-                    continue;
-                QContactEmailAddress *detail = new QContactEmailAddress;
-                detail->setEmailAddress(emailDesc.toMap()["value"].toString());
-                detailsToDelete << detail;
-                result.saveDetail(detail);
-            }
-        } else if (field == "ims") {
-            if (params[field].type() != QVariant::List)
-                continue;
-            QVariantList imsList = params[field].toList();
-            foreach (const QVariant &imDesc, imsList) {
-                if (imDesc.type() != QVariant::Map)
-                    continue;
-                QContactOnlineAccount *detail = new QContactOnlineAccount;
-                detail->setAccountUri(imDesc.toMap()["value"].toString());
-                if (!imDesc.toMap()["type"].toString().isEmpty())
-                    detail->setSubTypes(QList<int>() <<
-                                        subTypeOnlineAccountFromString(imDesc.toMap()["type"].toString()));
-                detailsToDelete << detail;
-                result.saveDetail(detail);
-            }
-        } else if (field == "photos") {
-            if (params[field].type() != QVariant::List)
-                continue;
-            QVariantList photosList = params[field].toList();
-            foreach (const QVariant &photoDesc, photosList) {
-                if (photoDesc.type() != QVariant::Map)
-                    continue;
-                //TODO: we need to decide should we support base64 images or not
-                if (photoDesc.toMap()["type"].toString() != "url")
-                    continue;
-                QContactAvatar *detail = new QContactAvatar;
-                detail->setImageUrl(QUrl(photoDesc.toMap()["value"].toString()));
-                detailsToDelete << detail;
-                result.saveDetail(detail);
-            }
-        } else if (field == "urls") {
-            if (params[field].type() != QVariant::List)
-                continue;
-            QVariantList urlsList = params[field].toList();
-            foreach (const QVariant &urlDesc, urlsList) {
-                if (urlDesc.type() != QVariant::Map)
-                    continue;
-                QContactUrl *detail = new QContactUrl;
-                detail->setUrl(urlDesc.toMap()["value"].toString());
-                if (!urlDesc.toMap()["type"].toString().isEmpty())
-                    detail->setSubType((QContactUrl::SubType) subTypeUrlFromString(urlDesc.toMap()["type"].toString()));
-                detailsToDelete << detail;
-                result.saveDetail(detail);
-            }
-        } else if (field == "birthday") {
-            QDateTime birthday;
-            birthday.setTime_t(params[field].toLongLong() / 1000);
-
-            QContactBirthday *detail = new QContactBirthday;
-            detail->setDateTime(birthday);
-            detailsToDelete << detail;
-            result.saveDetail(detail);
-        } else if (field == "organizations") {
-
-            if (params[field].type() != QVariant::List)
-                continue;
-            QVariantList organizationsList = params[field].toList();
-            foreach (const QVariant &organizationDesc, organizationsList) {
-                if (organizationDesc.type() != QVariant::Map)
-                    continue;
-                QContactOrganization *detail = new QContactOrganization;
-                detail->setName(organizationDesc.toMap()["name"].toString());
-                detail->setDepartment(QStringList() << organizationDesc.toMap()["department"].toString());
-                detail->setRole(organizationDesc.toMap()["title"].toString());
-                detailsToDelete << detail;
-                result.saveDetail(detail);
-            }
-
-        } else if (field == "name") {
-            QContactName *detail = new QContactName;
-            QVariantMap nameMap = params[field].toMap();
-            detail->setLastName(nameMap["familyName"].toString());
-            detail->setFirstName(nameMap["givenName"].toString());
-            detail->setMiddleName(nameMap["middleName"].toString());
-            detail->setPrefix(nameMap["honorificPrefix"].toString());
-            detail->setSuffix(nameMap["honorificSuffix"].toString());
-            detailsToDelete << detail;
-            result.saveDetail(detail);
-        }
-
-    }
-    if (!m_manager->saveContact(&result)) {
-        switch (m_manager->error()) {
-        case QContactManager::DoesNotExistError:
-        case QContactManager::AlreadyExistsError:
-        case QContactManager::InvalidDetailError:
-        case QContactManager::InvalidRelationshipError:
-        case QContactManager::BadArgumentError:
-        case QContactManager::InvalidContactTypeError:
-            callback(ecId, "ContactError.INVALID_ARGUMENT_ERROR");
-            break;
-        case QContactManager::DetailAccessError:
-        case QContactManager::PermissionsError:
-            callback(ecId, "ContactError.PERMISSION_DENIED_ERROR");
-            break;
-        case QContactManager::NotSupportedError:
-            callback(ecId, "ContactError.NOT_SUPPORTED_ERROR");
-            break;
-        case QContactManager::TimeoutError:
-            callback(ecId, "ContactError.TIMEOUT_ERROR");
-            break;
-        case QContactManager::UnspecifiedError:
-        case QContactManager::LockedError:
-        case QContactManager::OutOfMemoryError:
-        case QContactManager::VersionMismatchError:
-        case QContactManager::LimitReachedError:
-        case QContactManager::NoError:
-        default:
-            callback(ecId, "ContactError.UNKNOWN_ERROR");
-            break;
-        }
-    } else {
-        callback(scId, jsonedContact(result));
-    }
-    qDeleteAll(detailsToDelete);
-}
-
-void Contacts::remove(int scId, int ecId, const QString &localId) {
-    QContactId id = QContactId::fromString(localId);
-
-    if (!m_manager->removeContact(id)) {
-        switch (m_manager->error()) {
-        case QContactManager::AlreadyExistsError:
-        case QContactManager::InvalidDetailError:
-        case QContactManager::InvalidRelationshipError:
-        case QContactManager::BadArgumentError:
-        case QContactManager::InvalidContactTypeError:
-            callback(ecId, "ContactError.INVALID_ARGUMENT_ERROR");
-            break;
-        case QContactManager::DetailAccessError:
-        case QContactManager::PermissionsError:
-            callback(ecId, "ContactError.PERMISSION_DENIED_ERROR");
-            break;
-        case QContactManager::NotSupportedError:
-            callback(ecId, "ContactError.NOT_SUPPORTED_ERROR");
-            break;
-        case QContactManager::TimeoutError:
-            callback(ecId, "ContactError.TIMEOUT_ERROR");
-            break;
-        case QContactManager::UnspecifiedError:
-        case QContactManager::LockedError:
-        case QContactManager::OutOfMemoryError:
-        case QContactManager::VersionMismatchError:
-        case QContactManager::LimitReachedError:
-        case QContactManager::NoError:
-        case QContactManager::DoesNotExistError:
-        default:
-            callback(ecId, "ContactError.UNKNOWN_ERROR");
-            break;
-        }
-
-    } else {
-        cb(scId);
-    }
-}
-
-void Contacts::search(int scId, int ecId, const QStringList &fields, const QVariantMap &params) {
-    QString filter;
-    bool multiple = true;
-
-    if (params.find("filter") != params.end()) {
-        filter = params["filter"].toString();
-    }
-    if (params.find("multiple") != params.end()) {
-        multiple = params["multiple"].toBool();
-    }
-
-    findContacts(scId, ecId, fields, filter, multiple);
-}
-
-void Contacts::findContacts(int scId, int ecId, const QStringList &fields, const QString &filter, bool multiple) {
-    if (fields.length() <= 0){
-        callback(ecId, "new ContactError(ContactError.INVALID_ARGUMENT_ERROR)");
-    }
-
-    QContactUnionFilter unionFilter;
-
-    QMap<QContactDetail::DetailType, QList<int> > fieldNames;
-    fieldNames[QContactDetail::TypeDisplayLabel] << QContactDisplayLabel::FieldLabel;
-    fieldNames[QContactDetail::TypeName] << QContactName::FieldFirstName << QContactName::FieldLastName << QContactName::FieldMiddleName << QContactName::FieldPrefix << QContactName::FieldSuffix;
-    fieldNames[QContactDetail::TypeNickname] << QContactNickname::FieldNickname;
-    fieldNames[QContactDetail::TypePhoneNumber] << QContactPhoneNumber::FieldNumber;
-    fieldNames[QContactDetail::TypeEmailAddress] << QContactEmailAddress::FieldEmailAddress;
-    fieldNames[QContactDetail::TypeAddress] << QContactAddress::FieldCountry << QContactAddress::FieldLocality << QContactAddress::FieldPostcode << QContactAddress::FieldPostOfficeBox << QContactAddress::FieldRegion << QContactAddress::FieldStreet;
-    fieldNames[QContactDetail::TypeOnlineAccount] << QContactOnlineAccount::FieldAccountUri;
-    fieldNames[QContactDetail::TypeOrganization] << QContactOrganization::FieldAssistantName << QContactOrganization::FieldDepartment << QContactOrganization::FieldLocation << QContactOrganization::FieldName << QContactOrganization::FieldRole << QContactOrganization::FieldTitle;
-    fieldNames[QContactDetail::TypeBirthday] << QContactBirthday::FieldBirthday;
-    fieldNames[QContactDetail::TypeNote] << QContactNote::FieldNote;
-    fieldNames[QContactDetail::TypeUrl] << QContactUrl::FieldUrl;
-
-    foreach (const QContactDetail::DetailType &defName, fieldNames.keys()) {
-        foreach(int fieldName, fieldNames[defName]) {
-            QContactDetailFilter subFilter;
-            subFilter.setDetailType(defName, fieldName);
-            subFilter.setValue(filter);
-            subFilter.setMatchFlags(QContactFilter::MatchContains);
-            unionFilter.append(subFilter);
-        }
-    }
-
-    QList<QContact> contacts = m_manager->contacts(unionFilter);
-    if (contacts.empty()) {
-        callback(scId, "[]");
-    } else {
-        QStringList stringifiedContacts;
-        foreach (const QContact &contact, contacts) {
-            stringifiedContacts << jsonedContact(contact, fields);
-
-            if (!multiple)
-                break;
-        }
-        callback(scId, QString("[%1]").arg(stringifiedContacts.join(", ")));
-    }
-}
-
-QContactDetail::DetailType Contacts::cordovaFieldNameToQtDefinition(const QString &cordovaFieldName) const {
-    if (m_fieldNamePairs.contains(cordovaFieldName))
-        return m_fieldNamePairs[cordovaFieldName];
-
-    return QContactDetail::TypeUndefined;
-}
-
-int Contacts::subTypePhoneFromString(const QString &cordovaSubType) const
-{
-    QString preparedSubType = cordovaSubType.toLower();
-    if (preparedSubType == "mobile")
-        return QContactPhoneNumber::SubTypeMobile;
-    else if (preparedSubType == "fax")
-        return QContactPhoneNumber::SubTypeFax;
-    else if (preparedSubType == "pager")
-        return QContactPhoneNumber::SubTypePager;
-    else if (preparedSubType == "voice")
-        return QContactPhoneNumber::SubTypeVoice;
-    else if (preparedSubType == "modem")
-        return QContactPhoneNumber::SubTypeModem;
-    else if (preparedSubType == "video")
-        return QContactPhoneNumber::SubTypeVideo;
-    else if (preparedSubType == "car")
-        return QContactPhoneNumber::SubTypeCar;
-    else if (preparedSubType == "assistant")
-        return QContactPhoneNumber::SubTypeAssistant;
-    return QContactPhoneNumber::SubTypeLandline;
-}
-
-int Contacts::subTypeOnlineAccountFromString(const QString &cordovaSubType) const {
-    QString preparedSubType = cordovaSubType.toLower();
-    if (preparedSubType == "aim")
-        return QContactOnlineAccount::ProtocolAim;
-    else if (preparedSubType == "icq")
-        return QContactOnlineAccount::ProtocolIcq;
-    else if (preparedSubType == "irc")
-        return QContactOnlineAccount::ProtocolIrc;
-    else if (preparedSubType == "jabber")
-        return QContactOnlineAccount::ProtocolJabber;
-    else if (preparedSubType == "msn")
-        return QContactOnlineAccount::ProtocolMsn;
-    else if (preparedSubType == "qq")
-        return QContactOnlineAccount::ProtocolQq;
-    else if (preparedSubType == "skype")
-        return QContactOnlineAccount::ProtocolSkype;
-    else if (preparedSubType == "yahoo")
-        return QContactOnlineAccount::ProtocolYahoo;
-    return QContactOnlineAccount::ProtocolUnknown;
-}
-
-int Contacts::subTypeUrlFromString(const QString &cordovaSubType) const {
-    QString preparedSubType = cordovaSubType.toLower();
-    if (preparedSubType == "blog")
-        return QContactUrl::SubTypeBlog;
-    else if (preparedSubType == "favourite")
-        return QContactUrl::SubTypeFavourite;
-    return QContactUrl::SubTypeHomePage;
-}
-
-QString Contacts::subTypePhoneToString(int qtSubType) const {
-    if (qtSubType == QContactPhoneNumber::SubTypeMobile)
-        return "mobile";
-    else if (qtSubType == QContactPhoneNumber::SubTypeFax)
-        return "fax";
-    else if (qtSubType == QContactPhoneNumber::SubTypePager)
-        return "pager";
-    else if (qtSubType == QContactPhoneNumber::SubTypeVoice)
-        return "voice";
-    else if (qtSubType == QContactPhoneNumber::SubTypeModem)
-        return "modem";
-    else if (qtSubType == QContactPhoneNumber::SubTypeVideo)
-        return "video";
-    else if (qtSubType == QContactPhoneNumber::SubTypeCar)
-        return "car";
-    else if (qtSubType == QContactPhoneNumber::SubTypeAssistant)
-        return "assistant";
-    return "home";
-}
-
-QString Contacts::subTypeOnlineAccountToString(int qtSubType) const {
-    if (qtSubType == QContactOnlineAccount::ProtocolAim)
-        return "aim";
-    else if (qtSubType == QContactOnlineAccount::ProtocolIcq)
-        return "icq";
-    else if (qtSubType == QContactOnlineAccount::ProtocolIrc)
-        return "irc";
-    else if (qtSubType == QContactOnlineAccount::ProtocolJabber)
-        return "jabber";
-    else if (qtSubType == QContactOnlineAccount::ProtocolMsn)
-        return "msn";
-    else if (qtSubType == QContactOnlineAccount::ProtocolQq)
-        return "qq";
-    else if (qtSubType == QContactOnlineAccount::ProtocolSkype)
-        return "skype";
-    else if (qtSubType == QContactOnlineAccount::ProtocolYahoo)
-        return "yahoo";
-    return "unknown";
-}
-
-QString Contacts::subTypeUrlToString(int qtSubType) const {
-    if (qtSubType == QContactUrl::SubTypeBlog)
-        return "blog";
-    else if (qtSubType == QContactUrl::SubTypeFavourite)
-        return "favourite";
-    return "homepage";
-}
-
-QString Contacts::jsonedContact(const QContact &contact, const QStringList &fields) const {
-    QStringList resultingFields = fields;
-    if (resultingFields.empty())
-        resultingFields.append(m_fieldNamePairs.keys());
-    if (!resultingFields.contains("id"))
-        resultingFields << "id";
-    QStringList fieldValuesList;
-    foreach (const QString &field, resultingFields) {
-        QContactDetail::DetailType qtDefinitionName = cordovaFieldNameToQtDefinition(field);
-        if (field == "id") {
-            fieldValuesList << QString("%1: \"%2\"")
-                               .arg(field)
-                               .arg(contact.id().toString());
-        } else if (field == "displayName") {
-            QContactDisplayLabel detail = contact.detail(qtDefinitionName);
-            fieldValuesList << QString("%1: \"%2\"")
-                               .arg(field)
-                               .arg(detail.label());
-        } else if (field == "nickname") {
-            QContactNickname detail = contact.detail(qtDefinitionName);
-            fieldValuesList << QString("%1: \"%2\"")
-                               .arg(field)
-                               .arg(detail.nickname());
-        } else if (field == "note") {
-            QContactNote detail = contact.detail(qtDefinitionName);
-            fieldValuesList << QString("%1: \"%2\"")
-                               .arg(field)
-                               .arg(detail.note());
-        } else if (field == "phoneNumbers") {
-            QStringList fieldValues;
-            QList<QContactDetail> details = contact.details(qtDefinitionName);
-            foreach (const QContactDetail &detail, details) {
-                QContactPhoneNumber castedDetail = detail;
-                QStringList subTypes;
-                foreach (int subType, castedDetail.subTypes())
-                    subTypes << subTypePhoneToString(subType);
-
-                if (subTypes.isEmpty())
-                    subTypes << "phone";
-                foreach(const QString &subType, subTypes) {
-                    fieldValues << QString("{type: \"%1\", value: \"%2\", pref: %3}")
-                                   .arg(subType)
-                                   .arg(castedDetail.number())
-                                   .arg("false");
-                }
-            }
-            fieldValuesList << QString("%1: [%2]")
-                               .arg(field)
-                               .arg(fieldValues.join(", "));
-        } else if (field == "emails") {
-            QStringList fieldValues;
-            QList<QContactDetail> details = contact.details(qtDefinitionName);
-            foreach (const QContactDetail &detail, details) {
-                QContactEmailAddress castedDetail = detail;
-                fieldValues << QString("{type: \"%1\", value: \"%2\", pref: %3}")
-                               .arg("email")
-                               .arg(castedDetail.emailAddress())
-                               .arg("false");
-            }
-            fieldValuesList << QString("%1: [%2]")
-                               .arg(field)
-                               .arg(fieldValues.join(", "));
-        } else if (field == "ims") {
-            QStringList fieldValues;
-            QList<QContactDetail> details = contact.details(qtDefinitionName);
-            foreach (const QContactDetail &detail, details) {
-                QContactOnlineAccount castedDetail = detail;
-                QStringList subTypes;
-                foreach (int subType, castedDetail.subTypes())
-                    subTypes << subTypeOnlineAccountToString(subType);
-
-                if (subTypes.isEmpty())
-                    subTypes << "IM";
-                foreach(const QString &subType, subTypes) {
-                    fieldValues << QString("{type: \"%1\", value: \"%2\", pref: %3}")
-                                   .arg(subType)
-                                   .arg(castedDetail.accountUri())
-                                   .arg("false");
-                }
-            }
-            fieldValuesList << QString("%1: [%2]")
-                               .arg(field)
-                               .arg(fieldValues.join(", "));
-        } else if (field == "photos") {
-            QStringList fieldValues;
-            QList<QContactDetail> details = contact.details(qtDefinitionName);
-            foreach (const QContactDetail &detail, details) {
-                QContactAvatar castedDetail = detail;
-                fieldValues << QString("{type: \"%1\", value: \"%2\", pref: %3}")
-                               .arg("url")
-                               .arg(castedDetail.imageUrl().toString())
-                               .arg("false");
-            }
-            fieldValuesList << QString("%1: [%2]")
-                               .arg(field)
-                               .arg(fieldValues.join(", "));
-        } else if (field == "urls") {
-            QStringList fieldValues;
-            QList<QContactDetail> details = contact.details(qtDefinitionName);
-
-            foreach (const QContactDetail &detail, details) {
-                QContactUrl castedDetail = detail;
-                QString subType = subTypeUrlToString(castedDetail.subType());
-
-                fieldValues << QString("{type: \"%1\", value: \"%2\", pref: %3}")
-                               .arg(subType)
-                               .arg(castedDetail.url())
-                               .arg("false");
-            }
-            fieldValuesList << QString("%1: [%2]")
-                               .arg(field)
-                               .arg(fieldValues.join(", "));
-        } else if (field == "birthday") {
-            QContactBirthday detail = contact.detail(qtDefinitionName);
-            fieldValuesList << QString("%1: %2")
-                               .arg(field)
-                               .arg(detail.dateTime().toMSecsSinceEpoch());
-        } else if (field == "organizations") {
-            QStringList fieldValues;
-            QList<QContactDetail> details = contact.details(qtDefinitionName);
-            foreach (const QContactDetail &detail, details) {
-                QContactOrganization castedDetail = detail;
-                fieldValues << QString("{type: \"%1\", name: \"%2\", department: \"%3\", title: \"%4\", pref: %5}")
-                               .arg("organization")
-                               .arg(castedDetail.name())
-                               .arg(castedDetail.department().join(" "))
-                               .arg(castedDetail.role())
-                               .arg("false");
-            }
-            fieldValuesList << QString("%1: [%2]")
-                               .arg(field)
-                               .arg(fieldValues.join(", "));
-        } else if (field == "name") {
-            QContactName detail = contact.detail(qtDefinitionName);
-            fieldValuesList <<  QString("%1: {familyName: \"%2\", givenName: \"%3\", middleName: \"%4\", honorificPrefix: \"%5\", honorificSuffix: \"%6\"}")
-                                .arg(field)
-                                .arg(detail.lastName())
-                                .arg(detail.firstName())
-                                .arg(detail.middleName())
-                                .arg(detail.prefix())
-                                .arg(detail.suffix());
-        }
-
-
-    }
-
-    return QString("{%1}").arg(fieldValuesList.join(", "));
-}

http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/blob/fc255252/src/ubuntu/contacts.h
----------------------------------------------------------------------
diff --git a/src/ubuntu/contacts.h b/src/ubuntu/contacts.h
deleted file mode 100644
index 4c1343b..0000000
--- a/src/ubuntu/contacts.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-#ifndef CONTACTS_H_SSSSSSS
-#define CONTACTS_H_SSSSSSS
-
-#include <cplugin.h>
-
-#include <QtContacts>
-#include <QtCore>
-
-QTCONTACTS_USE_NAMESPACE
-
-class Contacts : public CPlugin {
-    Q_OBJECT
-public:
-    explicit Contacts(Cordova *cordova);
-
-    virtual const QString fullName() override {
-        return Contacts::fullID();
-    }
-
-    virtual const QString shortName() override {
-        return "Contacts";
-    }
-
-    static const QString fullID() {
-        return "Contacts";
-    }
-
-public slots:
-    void save(int scId, int ecId, const QVariantMap &params);
-    void remove(int scId, int ecId, const QString &localId);
-    void search(int scId, int ecId, const QStringList &fields, const QVariantMap &params);
-
-private:
-    void findContacts(int scId, int ecId, const QStringList &fields, const QString &filter, bool multiple);
-    QContactDetail::DetailType cordovaFieldNameToQtDefinition(const QString &cordovaFieldName) const;
-    int subTypePhoneFromString(const QString &cordovaSubType) const;
-    int subTypeOnlineAccountFromString(const QString &cordovaSubType) const;
-    int subTypeUrlFromString(const QString &cordovaSubType) const;
-    QString subTypePhoneToString(int qtSubType) const;
-    QString subTypeOnlineAccountToString(int qtSubType) const;
-    QString subTypeUrlToString(int qtSubType) const;
-    QString jsonedContact(const QContact &contact, const QStringList &fields = QStringList()) const;
-
-    QHash<QString, QContactDetail::DetailType> m_fieldNamePairs;
-    QSet<QString> m_notSupportedFields;
-    QSharedPointer<QContactManager> m_manager;
-};
-
-#endif

http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/blob/fc255252/src/windows8/ContactProxy.js
----------------------------------------------------------------------
diff --git a/src/windows8/ContactProxy.js b/src/windows8/ContactProxy.js
deleted file mode 100644
index 10f9402..0000000
--- a/src/windows8/ContactProxy.js
+++ /dev/null
@@ -1,151 +0,0 @@
-//cordova.define("org.apache.cordova.contacts.ContactProxy", function (require, exports, module) {
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-
-module.exports = {
-    search:function(win,fail,args){
-        var fields = args[0]; // ignored, always returns entire object
-        var options = args[1];
-
-        var filter = options.filter;   // ignored
-        var multiple = true;//options.multiple;
-
-        var picker = new Windows.ApplicationModel.Contacts.ContactPicker();
-        picker.selectionMode = Windows.ApplicationModel.Contacts.ContactSelectionMode.contacts;   // select entire contact
-        if (picker.pickContactAsync) {
-            // TODO: 8.1 has better contact support via the 'Contact' object
-        }
-        else {
-            // 8.0 use the ContactInformation class
-            // decide which function we will call
-            var pickerFunkName = multiple ? 'pickMultipleContactsAsync' : 'pickSingleContactAsync';
-            picker[pickerFunkName]().done(function (res) {
-                if (!res) {
-                    fail && setTimeout(function () {
-                        fail(new Error("User did not pick a contact."));
-                    }, 0);
-                    return;
-                }
-
-                var contactResults = [];
-
-                for (var i = 0; i < res.length; i++) {
-
-
-                    var index,
-                        contactResult = res[i],
-                        contact = {
-                            id: "",
-                            name: { formatted: contactResult.name },  // ContactName
-                            displayName: contactResult.name,          // DOMString
-                            nickname: contactResult.name,             // DOMString
-                            phoneNumbers: contactResult.phoneNumbers, // ContactField[]
-                            addresses: contactResult.locations,       // ContactAddress[]
-                            emails: [],                               // ContactField
-                            ims: contactResult.instantMessages,       // ContactField[]
-                            organizations: [],              // ContactOrganization[]
-                            birthday: null,                 // Date
-                            note: "",                       // DOMString
-                            photos: [],                     // ContactField[]
-                            categories: [],                 // ContactField[]
-                            urls: []                        // ContactField[]
-                        };
-
-                    // Win8-ContactField is {category, name, type, value};
-                    // Cordova ContactField is {type,value, pref:bool };
-                    // Win8 type means 'email' cordova type means 'work|home|...' so we convert them
-                    if (contact.emails && contact.emails.length) {
-                        contact.emails[0].pref = true; // add a preferred prop 
-                        for (index = 0; index < contacts.emails.length; index++) {
-                            contact.emails[index].type = contact.emails[index].category;
-                        }
-                    }
-
-                    if (contact.phoneNumbers && contact.phoneNumbers.length) {
-                        contact.phoneNumbers[0].pref = true; // cordova contact field needs a 'prefered' property on  a contact
-                        // change the meaning of type from 'telephonenumber' to 'work|home|...'
-                        for (index = 0; index < contact.phoneNumbers.length; index++) {
-                            contact.phoneNumbers[index].type = contact.phoneNumbers[index].category;
-                        }
-                    }
-
-                    if (contact.addresses && contact.addresses.length) {
-
-                        // convert addresses/locations to Cordova.ContactAddresses                    
-                        // constr: ContactAddress(pref, type, formatted, streetAddress, locality, region, postalCode, country)
-                        var address, formatted;
-                        for (index = 0; index < contact.addresses.length; index++) {
-                            address = contact.addresses[index];   // make an alias
-                            var formattedArray = [];
-                            // get rid of the empty fields.
-                            var fields = [address.street, address.city, address.region, address.country, address.postalCode];
-                            for (var n = 0; n < fields.length; n++) {
-                                if (fields[n].length > 0) {
-                                    formattedArray.push(fields[n]);
-                                }
-                            }
-                            formattedAddress = formattedArray.join(", ");
-                            console.log(contact.name.formatted + " formatted looks like " + formattedAddress);
-                            contact.addresses[index] = new ContactAddress(false,
-                                                                          address.name,
-                                                                          formattedAddress,
-                                                                          address.street,
-                                                                          address.city,
-                                                                          address.region,
-                                                                          address.postalCode,
-                                                                          address.country);
-                        }
-
-                    }
-
-                    // convert ims to ContactField
-                    if (contact.ims && contact.ims.length) {
-                        // MS ContactInstantMessageField has : displayText, launchUri, service, userName, category, type
-                        contact.ims[0].pref = true;
-                        for (index = 0; index < contact.ims.length; index++) {
-                            contact.ims[index] = new ContactField(contact.ims[index].type, contact.ims[index].value, false);
-                        }
-                    }
-
-                    contactResults.push(contact);
-
-                }
-                // send em back
-                win(contactResults);
-
-            });
-        }
-    },
-
-    save:function(win,fail,args){
-        console && console.error && console.error("Error : Windows 8 does not support creating/saving contacts");
-        fail && setTimeout(function () {
-            fail(new Error("Contact create/save not supported on Windows 8"));
-        }, 0);
-
-    }
-
-
-}
-
-require("cordova/exec/proxy").add("Contacts", module.exports);
-// });