You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/03/31 19:21:40 UTC

[28/53] [partial] adding bower

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a704d594/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVFileTransfer.m
----------------------------------------------------------------------
diff --git a/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVFileTransfer.m b/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVFileTransfer.m
new file mode 100644
index 0000000..5741aca
--- /dev/null
+++ b/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVFileTransfer.m
@@ -0,0 +1,625 @@
+/*
+ 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 "CDV.h"
+
+#import <AssetsLibrary/ALAsset.h>
+#import <AssetsLibrary/ALAssetRepresentation.h>
+#import <AssetsLibrary/ALAssetsLibrary.h>
+#import <CFNetwork/CFNetwork.h>
+
+@interface CDVFileTransfer ()
+// Sets the requests headers for the request.
+- (void)applyRequestHeaders:(NSDictionary*)headers toRequest:(NSMutableURLRequest*)req;
+// Creates a delegate to handle an upload.
+- (CDVFileTransferDelegate*)delegateForUploadCommand:(CDVInvokedUrlCommand*)command;
+// Creates an NSData* for the file for the given upload arguments.
+- (void)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command;
+@end
+
+// Buffer size to use for streaming uploads.
+static const NSUInteger kStreamBufferSize = 32768;
+// Magic value within the options dict used to set a cookie.
+NSString* const kOptionsKeyCookie = @"__cookie";
+// Form boundary for multi-part requests.
+NSString* const kFormBoundary = @"+++++org.apache.cordova.formBoundary";
+
+// Writes the given data to the stream in a blocking way.
+// If successful, returns bytesToWrite.
+// If the stream was closed on the other end, returns 0.
+// If there was an error, returns -1.
+static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
+{
+    UInt8* bytes = (UInt8*)[data bytes];
+    NSUInteger bytesToWrite = [data length];
+    NSUInteger totalBytesWritten = 0;
+
+    while (totalBytesWritten < bytesToWrite) {
+        CFIndex result = CFWriteStreamWrite(stream,
+                bytes + totalBytesWritten,
+                bytesToWrite - totalBytesWritten);
+        if (result < 0) {
+            CFStreamError error = CFWriteStreamGetError(stream);
+            NSLog(@"WriteStreamError domain: %ld error: %ld", error.domain, error.error);
+            return result;
+        } else if (result == 0) {
+            return result;
+        }
+        totalBytesWritten += result;
+    }
+
+    return totalBytesWritten;
+}
+
+@implementation CDVFileTransfer
+@synthesize activeTransfers;
+
+- (NSString*)escapePathComponentForUrlString:(NSString*)urlString
+{
+    NSRange schemeAndHostRange = [urlString rangeOfString:@"://.*?/" options:NSRegularExpressionSearch];
+
+    if (schemeAndHostRange.length == 0) {
+        return urlString;
+    }
+
+    NSInteger schemeAndHostEndIndex = NSMaxRange(schemeAndHostRange);
+    NSString* schemeAndHost = [urlString substringToIndex:schemeAndHostEndIndex];
+    NSString* pathComponent = [urlString substringFromIndex:schemeAndHostEndIndex];
+    pathComponent = [pathComponent stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+
+    return [schemeAndHost stringByAppendingString:pathComponent];
+}
+
+- (void)applyRequestHeaders:(NSDictionary*)headers toRequest:(NSMutableURLRequest*)req
+{
+    [req setValue:@"XMLHttpRequest" forHTTPHeaderField:@"X-Requested-With"];
+
+    NSString* userAgent = [self.commandDelegate userAgent];
+    if (userAgent) {
+        [req setValue:userAgent forHTTPHeaderField:@"User-Agent"];
+    }
+
+    for (NSString* headerName in headers) {
+        id value = [headers objectForKey:headerName];
+        if (!value || (value == [NSNull null])) {
+            value = @"null";
+        }
+
+        // First, remove an existing header if one exists.
+        [req setValue:nil forHTTPHeaderField:headerName];
+
+        if (![value isKindOfClass:[NSArray class]]) {
+            value = [NSArray arrayWithObject:value];
+        }
+
+        // Then, append all header values.
+        for (id __strong subValue in value) {
+            // Convert from an NSNumber -> NSString.
+            if ([subValue respondsToSelector:@selector(stringValue)]) {
+                subValue = [subValue stringValue];
+            }
+            if ([subValue isKindOfClass:[NSString class]]) {
+                [req addValue:subValue forHTTPHeaderField:headerName];
+            }
+        }
+    }
+}
+
+- (NSURLRequest*)requestForUploadCommand:(CDVInvokedUrlCommand*)command fileData:(NSData*)fileData
+{
+    // arguments order from js: [filePath, server, fileKey, fileName, mimeType, params, debug, chunkedMode]
+    // however, params is a JavaScript object and during marshalling is put into the options dict,
+    // thus debug and chunkedMode are the 6th and 7th arguments
+    NSArray* arguments = command.arguments;
+    NSString* target = (NSString*)[arguments objectAtIndex:0];
+    NSString* server = (NSString*)[arguments objectAtIndex:1];
+    NSString* fileKey = [arguments objectAtIndex:2 withDefault:@"file"];
+    NSString* fileName = [arguments objectAtIndex:3 withDefault:@"no-filename"];
+    NSString* mimeType = [arguments objectAtIndex:4 withDefault:nil];
+    NSDictionary* options = [arguments objectAtIndex:5 withDefault:nil];
+    //    BOOL trustAllHosts = [[arguments objectAtIndex:6 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
+    BOOL chunkedMode = [[arguments objectAtIndex:7 withDefault:[NSNumber numberWithBool:YES]] boolValue];
+    NSDictionary* headers = [arguments objectAtIndex:8 withDefault:nil];
+
+    CDVPluginResult* result = nil;
+    CDVFileTransferError errorCode = 0;
+
+    // NSURL does not accepts URLs with spaces in the path. We escape the path in order
+    // to be more lenient.
+    NSURL* url = [NSURL URLWithString:server];
+
+    if (!url) {
+        errorCode = INVALID_URL_ERR;
+        NSLog(@"File Transfer Error: Invalid server URL %@", server);
+    } else if (!fileData) {
+        errorCode = FILE_NOT_FOUND_ERR;
+    }
+
+    if (errorCode > 0) {
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:errorCode AndSource:target AndTarget:server]];
+        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+        return nil;
+    }
+
+    NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
+    [req setHTTPMethod:@"POST"];
+
+    //    Magic value to set a cookie
+    if ([options objectForKey:kOptionsKeyCookie]) {
+        [req setValue:[options objectForKey:kOptionsKeyCookie] forHTTPHeaderField:@"Cookie"];
+        [req setHTTPShouldHandleCookies:NO];
+    }
+
+    NSString* contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kFormBoundary];
+    [req setValue:contentType forHTTPHeaderField:@"Content-Type"];
+    [self applyRequestHeaders:headers toRequest:req];
+
+    NSData* formBoundaryData = [[NSString stringWithFormat:@"--%@\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
+    NSMutableData* postBodyBeforeFile = [NSMutableData data];
+
+    for (NSString* key in options) {
+        id val = [options objectForKey:key];
+        if (!val || (val == [NSNull null]) || [key isEqualToString:kOptionsKeyCookie]) {
+            continue;
+        }
+        // if it responds to stringValue selector (eg NSNumber) get the NSString
+        if ([val respondsToSelector:@selector(stringValue)]) {
+            val = [val stringValue];
+        }
+        // finally, check whether it is a NSString (for dataUsingEncoding selector below)
+        if (![val isKindOfClass:[NSString class]]) {
+            continue;
+        }
+
+        [postBodyBeforeFile appendData:formBoundaryData];
+        [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
+        [postBodyBeforeFile appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];
+        [postBodyBeforeFile appendData:[@"\r\n" dataUsingEncoding : NSUTF8StringEncoding]];
+    }
+
+    [postBodyBeforeFile appendData:formBoundaryData];
+    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fileKey, fileName] dataUsingEncoding:NSUTF8StringEncoding]];
+    if (mimeType != nil) {
+        [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
+    }
+    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@"Content-Length: %d\r\n\r\n", [fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];
+
+    DLog(@"fileData length: %d", [fileData length]);
+    NSData* postBodyAfterFile = [[NSString stringWithFormat:@"\r\n--%@--\r\n", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];
+
+    NSUInteger totalPayloadLength = [postBodyBeforeFile length] + [fileData length] + [postBodyAfterFile length];
+    [req setValue:[[NSNumber numberWithInteger:totalPayloadLength] stringValue] forHTTPHeaderField:@"Content-Length"];
+
+    if (chunkedMode) {
+        CFReadStreamRef readStream = NULL;
+        CFWriteStreamRef writeStream = NULL;
+        CFStreamCreateBoundPair(NULL, &readStream, &writeStream, kStreamBufferSize);
+        [req setHTTPBodyStream:CFBridgingRelease(readStream)];
+
+        [self.commandDelegate runInBackground:^{
+            if (CFWriteStreamOpen(writeStream)) {
+                NSData* chunks[] = {postBodyBeforeFile, fileData, postBodyAfterFile};
+                int numChunks = sizeof(chunks) / sizeof(chunks[0]);
+
+                for (int i = 0; i < numChunks; ++i) {
+                    CFIndex result = WriteDataToStream(chunks[i], writeStream);
+                    if (result <= 0) {
+                        break;
+                    }
+                }
+            } else {
+                NSLog(@"FileTransfer: Failed to open writeStream");
+            }
+            CFWriteStreamClose(writeStream);
+            CFRelease(writeStream);
+        }];
+    } else {
+        [postBodyBeforeFile appendData:fileData];
+        [postBodyBeforeFile appendData:postBodyAfterFile];
+        [req setHTTPBody:postBodyBeforeFile];
+    }
+    return req;
+}
+
+- (CDVFileTransferDelegate*)delegateForUploadCommand:(CDVInvokedUrlCommand*)command
+{
+    NSString* source = [command.arguments objectAtIndex:0];
+    NSString* server = [command.arguments objectAtIndex:1];
+    BOOL trustAllHosts = [[command.arguments objectAtIndex:6 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
+    NSString* objectId = [command.arguments objectAtIndex:9];
+
+    CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];
+
+    delegate.command = self;
+    delegate.callbackId = command.callbackId;
+    delegate.direction = CDV_TRANSFER_UPLOAD;
+    delegate.objectId = objectId;
+    delegate.source = source;
+    delegate.target = server;
+    delegate.trustAllHosts = trustAllHosts;
+
+    return delegate;
+}
+
+- (void)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command
+{
+    NSString* target = (NSString*)[command.arguments objectAtIndex:0];
+    NSError* __autoreleasing err = nil;
+
+    // return unsupported result for assets-library URLs
+    if ([target hasPrefix:kCDVAssetsLibraryPrefix]) {
+        // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
+        ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
+            if (asset) {
+                // We have the asset!  Get the data and send it off.
+                ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
+                Byte* buffer = (Byte*)malloc([assetRepresentation size]);
+                NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
+                NSData* fileData = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
+                [self uploadData:fileData command:command];
+            } else {
+                // We couldn't find the asset.  Send the appropriate error.
+                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
+                [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+            }
+        };
+        ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
+            // Retrieving the asset failed for some reason.  Send the appropriate error.
+            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
+            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+        };
+
+        ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
+        [assetsLibrary assetForURL:[NSURL URLWithString:target] resultBlock:resultBlock failureBlock:failureBlock];
+        return;
+    } else {
+        // Extract the path part out of a file: URL.
+        NSString* filePath = [target hasPrefix:@"/"] ? [target copy] : [[NSURL URLWithString:target] path];
+        if (filePath == nil) {
+            // We couldn't find the asset.  Send the appropriate error.
+            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
+            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+            return;
+        }
+
+        // Memory map the file so that it can be read efficiently even if it is large.
+        NSData* fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err];
+
+        if (err != nil) {
+            NSLog(@"Error opening file %@: %@", target, err);
+        }
+        [self uploadData:fileData command:command];
+    }
+}
+
+- (void)upload:(CDVInvokedUrlCommand*)command
+{
+    // fileData and req are split into helper functions to ease the unit testing of delegateForUpload.
+    // First, get the file data.  This method will call `uploadData:command`.
+    [self fileDataForUploadCommand:command];
+}
+
+- (void)uploadData:(NSData*)fileData command:(CDVInvokedUrlCommand*)command
+{
+    NSURLRequest* req = [self requestForUploadCommand:command fileData:fileData];
+
+    if (req == nil) {
+        return;
+    }
+    CDVFileTransferDelegate* delegate = [self delegateForUploadCommand:command];
+    [NSURLConnection connectionWithRequest:req delegate:delegate];
+
+    if (activeTransfers == nil) {
+        activeTransfers = [[NSMutableDictionary alloc] init];
+    }
+
+    [activeTransfers setObject:delegate forKey:delegate.objectId];
+}
+
+- (void)abort:(CDVInvokedUrlCommand*)command
+{
+    NSString* objectId = [command.arguments objectAtIndex:0];
+
+    CDVFileTransferDelegate* delegate = [activeTransfers objectForKey:objectId];
+
+    if (delegate != nil) {
+        [delegate.connection cancel];
+        [activeTransfers removeObjectForKey:objectId];
+
+        // delete uncomplete file
+        NSFileManager* fileMgr = [NSFileManager defaultManager];
+        [fileMgr removeItemAtPath:delegate.target error:nil];
+
+        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:CONNECTION_ABORTED AndSource:delegate.source AndTarget:delegate.target]];
+        [self.commandDelegate sendPluginResult:result callbackId:delegate.callbackId];
+    }
+}
+
+- (void)download:(CDVInvokedUrlCommand*)command
+{
+    DLog(@"File Transfer downloading file...");
+    NSString* sourceUrl = [command.arguments objectAtIndex:0];
+    NSString* filePath = [command.arguments objectAtIndex:1];
+    BOOL trustAllHosts = [[command.arguments objectAtIndex:2 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
+    NSString* objectId = [command.arguments objectAtIndex:3];
+    NSDictionary* headers = [command.arguments objectAtIndex:4 withDefault:nil];
+
+    // return unsupported result for assets-library URLs
+    if ([filePath hasPrefix:kCDVAssetsLibraryPrefix]) {
+        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"download not supported for assets-library URLs."];
+        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+        return;
+    }
+
+    CDVPluginResult* result = nil;
+    CDVFileTransferError errorCode = 0;
+
+    NSURL* file;
+
+    if ([filePath hasPrefix:@"/"]) {
+        file = [NSURL fileURLWithPath:filePath];
+    } else {
+        file = [NSURL URLWithString:filePath];
+    }
+
+    NSURL* url = [NSURL URLWithString:sourceUrl];
+
+    if (!url) {
+        errorCode = INVALID_URL_ERR;
+        NSLog(@"File Transfer Error: Invalid server URL %@", sourceUrl);
+    } else if (![file isFileURL]) {
+        errorCode = FILE_NOT_FOUND_ERR;
+        NSLog(@"File Transfer Error: Invalid file path or URL %@", filePath);
+    }
+
+    if (errorCode > 0) {
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:errorCode AndSource:sourceUrl AndTarget:filePath]];
+        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+        return;
+    }
+
+    NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
+    [self applyRequestHeaders:headers toRequest:req];
+
+    CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];
+    delegate.command = self;
+    delegate.direction = CDV_TRANSFER_DOWNLOAD;
+    delegate.callbackId = command.callbackId;
+    delegate.objectId = objectId;
+    delegate.source = sourceUrl;
+    delegate.target = filePath;
+    delegate.trustAllHosts = trustAllHosts;
+
+    delegate.connection = [NSURLConnection connectionWithRequest:req delegate:delegate];
+
+    if (activeTransfers == nil) {
+        activeTransfers = [[NSMutableDictionary alloc] init];
+    }
+
+    [activeTransfers setObject:delegate forKey:delegate.objectId];
+}
+
+- (NSMutableDictionary*)createFileTransferError:(int)code AndSource:(NSString*)source AndTarget:(NSString*)target
+{
+    NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:3];
+
+    [result setObject:[NSNumber numberWithInt:code] forKey:@"code"];
+    [result setObject:source forKey:@"source"];
+    [result setObject:target forKey:@"target"];
+    NSLog(@"FileTransferError %@", result);
+
+    return result;
+}
+
+- (NSMutableDictionary*)createFileTransferError:(int)code
+                                      AndSource:(NSString*)source
+                                      AndTarget:(NSString*)target
+                                  AndHttpStatus:(int)httpStatus
+                                        AndBody:(NSString*)body
+{
+    NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:5];
+
+    [result setObject:[NSNumber numberWithInt:code] forKey:@"code"];
+    [result setObject:source forKey:@"source"];
+    [result setObject:target forKey:@"target"];
+    [result setObject:[NSNumber numberWithInt:httpStatus] forKey:@"http_status"];
+    [result setObject:body forKey:@"body"];
+    NSLog(@"FileTransferError %@", result);
+
+    return result;
+}
+
+- (void)onReset
+{
+    for (CDVFileTransferDelegate* delegate in [activeTransfers allValues]) {
+        [delegate.connection cancel];
+    }
+
+    [activeTransfers removeAllObjects];
+}
+
+@end
+
+@implementation CDVFileTransferDelegate
+
+@synthesize callbackId, connection, source, target, responseData, command, bytesTransfered, bytesExpected, direction, responseCode, objectId;
+
+- (void)connectionDidFinishLoading:(NSURLConnection*)connection
+{
+    NSString* uploadResponse = nil;
+    NSString* downloadResponse = nil;
+    BOOL downloadWriteOK = NO;
+    NSMutableDictionary* uploadResult;
+    CDVPluginResult* result = nil;
+    NSError* __autoreleasing error = nil;
+    NSString* parentPath;
+    BOOL bDirRequest = NO;
+    CDVFile* file;
+
+    NSLog(@"File Transfer Finished with response code %d", self.responseCode);
+
+    if (self.direction == CDV_TRANSFER_UPLOAD) {
+        uploadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+
+        if ((self.responseCode >= 200) && (self.responseCode < 300)) {
+            // create dictionary to return FileUploadResult object
+            uploadResult = [NSMutableDictionary dictionaryWithCapacity:3];
+            if (uploadResponse != nil) {
+                [uploadResult setObject:uploadResponse forKey:@"response"];
+            }
+            [uploadResult setObject:[NSNumber numberWithInt:self.bytesTransfered] forKey:@"bytesSent"];
+            [uploadResult setObject:[NSNumber numberWithInt:self.responseCode] forKey:@"responseCode"];
+            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:uploadResult];
+        } else {
+            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:uploadResponse]];
+        }
+    }
+    if (self.direction == CDV_TRANSFER_DOWNLOAD) {
+        DLog(@"Write file %@", target);
+        // error=[[NSError alloc]init];
+
+        if ((self.responseCode >= 200) && (self.responseCode < 300)) {
+            @try {
+                parentPath = [self.target stringByDeletingLastPathComponent];
+
+                // check if the path exists => create directories if needed
+                if (![[NSFileManager defaultManager] fileExistsAtPath:parentPath]) {
+                    [[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:nil];
+                }
+
+                downloadWriteOK = [self.responseData writeToFile:self.target options:NSDataWritingFileProtectionNone error:&error];
+
+                if (downloadWriteOK == NO) {
+                    // send our results back
+                    downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:INVALID_URL_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
+                } else {
+                    DLog(@"File Transfer Download success");
+
+                    file = [[CDVFile alloc] init];
+
+                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[file getDirectoryEntry:target isDirectory:bDirRequest]];
+                }
+            }
+            @catch(id exception) {
+                // jump back to main thread
+                downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsDictionary:[command createFileTransferError:FILE_NOT_FOUND_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
+            }
+        } else {
+            downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+
+            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
+        }
+    }
+
+    [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];
+
+    // remove connection for activeTransfers
+    [command.activeTransfers removeObjectForKey:objectId];
+}
+
+- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
+{
+    self.mimeType = [response MIMEType];
+
+    // required for iOS 4.3, for some reason; response is
+    // a plain NSURLResponse, not the HTTP subclass
+    if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
+        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
+
+        self.responseCode = [httpResponse statusCode];
+        self.bytesExpected = [response expectedContentLength];
+    } else if ([response.URL isFileURL]) {
+        NSDictionary* attr = [[NSFileManager defaultManager] attributesOfItemAtPath:[response.URL path] error:nil];
+        self.responseCode = 200;
+        self.bytesExpected = [attr[NSFileSize] longLongValue];
+    } else {
+        self.responseCode = 200;
+        self.bytesExpected = NSURLResponseUnknownLength;
+    }
+}
+
+- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
+{
+    NSString* body = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
+    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:body]];
+
+    NSLog(@"File Transfer Error: %@", [error localizedDescription]);
+
+    // remove connection for activeTransfers
+    [command.activeTransfers removeObjectForKey:objectId];
+    [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];
+}
+
+- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
+{
+    self.bytesTransfered += data.length;
+    [self.responseData appendData:data];
+
+    if (self.direction == CDV_TRANSFER_DOWNLOAD) {
+        BOOL lengthComputable = (self.bytesExpected != NSURLResponseUnknownLength);
+        NSMutableDictionary* downloadProgress = [NSMutableDictionary dictionaryWithCapacity:3];
+        [downloadProgress setObject:[NSNumber numberWithBool:lengthComputable] forKey:@"lengthComputable"];
+        [downloadProgress setObject:[NSNumber numberWithInt:self.bytesTransfered] forKey:@"loaded"];
+        [downloadProgress setObject:[NSNumber numberWithInt:self.bytesExpected] forKey:@"total"];
+        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:downloadProgress];
+        [result setKeepCallbackAsBool:true];
+        [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];
+    }
+}
+
+- (void)connection:(NSURLConnection*)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
+{
+    if (self.direction == CDV_TRANSFER_UPLOAD) {
+        NSMutableDictionary* uploadProgress = [NSMutableDictionary dictionaryWithCapacity:3];
+
+        [uploadProgress setObject:[NSNumber numberWithBool:true] forKey:@"lengthComputable"];
+        [uploadProgress setObject:[NSNumber numberWithInt:totalBytesWritten] forKey:@"loaded"];
+        [uploadProgress setObject:[NSNumber numberWithInt:totalBytesExpectedToWrite] forKey:@"total"];
+        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:uploadProgress];
+        [result setKeepCallbackAsBool:true];
+        [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];
+    }
+    self.bytesTransfered = totalBytesWritten;
+}
+
+// for self signed certificates
+- (void)connection:(NSURLConnection*)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge
+{
+    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
+        if (self.trustAllHosts) {
+            NSURLCredential* credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
+            [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
+        }
+        [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
+    } else {
+        [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
+    }
+}
+
+- (id)init
+{
+    if ((self = [super init])) {
+        self.responseData = [NSMutableData data];
+    }
+    return self;
+}
+
+@end;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a704d594/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVGlobalization.h
----------------------------------------------------------------------
diff --git a/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVGlobalization.h b/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVGlobalization.h
new file mode 100644
index 0000000..0384656
--- /dev/null
+++ b/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVGlobalization.h
@@ -0,0 +1,150 @@
+/*
+ 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 <Foundation/Foundation.h>
+#import "CDVPlugin.h"
+
+#define CDV_FORMAT_SHORT 0
+#define CDV_FORMAT_MEDIUM 1
+#define CDV_FORMAT_LONG 2
+#define CDV_FORMAT_FULL 3
+#define CDV_SELECTOR_MONTHS 0
+#define CDV_SELECTOR_DAYS 1
+
+enum CDVGlobalizationError {
+    CDV_UNKNOWN_ERROR = 0,
+    CDV_FORMATTING_ERROR = 1,
+    CDV_PARSING_ERROR = 2,
+    CDV_PATTERN_ERROR = 3,
+};
+typedef NSUInteger CDVGlobalizationError;
+
+@interface CDVGlobalization : CDVPlugin {
+    CFLocaleRef currentLocale;
+}
+
+- (void)getPreferredLanguage:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns the string identifier for the clients current locale setting.
+ * It returns the locale identifier string to the successCB callback with a
+ * properties object as a parameter. If there is an error getting the locale,
+ * then the errorCB callback is invoked.
+ */
+- (void)getLocaleName:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns a date formatted as a string according to the clients user preferences and
+ * calendar using the time zone of the client. It returns the formatted date string to the
+ * successCB callback with a properties object as a parameter. If there is an error
+ * formatting the date, then the errorCB callback is invoked.
+ *
+ * options: "date" contains the number of milliseconds that represents the JavaScript date
+ */
+- (void)dateToString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Parses a date formatted as a string according to the clients user
+ * preferences and calendar using the time zone of the client and returns
+ * the corresponding date object. It returns the date to the successCB
+ * callback with a properties object as a parameter. If there is an error
+ * parsing the date string, then the errorCB callback is invoked.
+ *
+ * options: "dateString" contains the JavaScript string to parse for a date
+ */
+- (void)stringToDate:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns a pattern string for formatting and parsing dates according to the clients
+ * user preferences. It returns the pattern to the successCB callback with a
+ * properties object as a parameter. If there is an error obtaining the pattern,
+ * then the errorCB callback is invoked.
+ *
+ */
+- (void)getDatePattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns an array of either the names of the months or days of the week
+ * according to the clients user preferences and calendar. It returns the array of names to the
+ * successCB callback with a properties object as a parameter. If there is an error obtaining the
+ * names, then the errorCB callback is invoked.
+ *
+ */
+- (void)getDateNames:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns whether daylight savings time is in effect for a given date using the clients
+ * time zone and calendar. It returns whether or not daylight savings time is in effect
+ * to the successCB callback with a properties object as a parameter. If there is an error
+ * reading the date, then the errorCB callback is invoked.
+ *
+ * options: "date" contains the number of milliseconds that represents the JavaScript date
+ *
+ */
+- (void)isDayLightSavingsTime:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns the first day of the week according to the clients user preferences and calendar.
+ * The days of the week are numbered starting from 1 where 1 is considered to be Sunday.
+ * It returns the day to the successCB callback with a properties object as a parameter.
+ * If there is an error obtaining the pattern, then the errorCB callback is invoked.
+ *
+ */
+- (void)getFirstDayOfWeek:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns a number formatted as a string according to the clients user preferences.
+ * It returns the formatted number string to the successCB callback with a properties object as a
+ * parameter. If there is an error formatting the number, then the errorCB callback is invoked.
+ *
+ * options: "number" contains the JavaScript number to format
+ *
+ */
+- (void)numberToString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Parses a number formatted as a string according to the clients user preferences and
+ * returns the corresponding number. It returns the number to the successCB callback with a
+ * properties object as a parameter. If there is an error parsing the number string, then
+ * the errorCB callback is invoked.
+ *
+ * options: "numberString" contains the JavaScript string to parse for a number
+ *
+ */
+- (void)stringToNumber:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns a pattern string for formatting and parsing numbers according to the clients user
+ * preferences. It returns the pattern to the successCB callback with a properties object as a
+ * parameter. If there is an error obtaining the pattern, then the errorCB callback is invoked.
+ *
+ */
+- (void)getNumberPattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+/**
+ * Returns a pattern string for formatting and parsing currency values according to the clients
+ * user preferences and ISO 4217 currency code. It returns the pattern to the successCB callback with a
+ * properties object as a parameter. If there is an error obtaining the pattern, then the errorCB
+ * callback is invoked.
+ *
+ * options: "currencyCode" contains the ISO currency code from JavaScript
+ */
+- (void)getCurrencyPattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a704d594/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVGlobalization.m
----------------------------------------------------------------------
diff --git a/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVGlobalization.m b/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVGlobalization.m
new file mode 100644
index 0000000..9eb9721
--- /dev/null
+++ b/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVGlobalization.m
@@ -0,0 +1,790 @@
+/*
+ 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 "CDVGlobalization.h"
+
+@implementation CDVGlobalization
+
+- (id)initWithWebView:(UIWebView*)theWebView
+{
+    self = (CDVGlobalization*)[super initWithWebView:theWebView];
+    if (self) {
+        currentLocale = CFLocaleCopyCurrent();
+    }
+    return self;
+}
+
+- (void)getPreferredLanguage:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    NSString* callbackId = [arguments objectAtIndex:0];
+    CDVPluginResult* result = nil;
+
+    NSLog(@"log1");
+    // Source: http://stackoverflow.com/questions/3910244/getting-current-device-language-in-ios
+    // (should be OK)
+    NSString* language = [[NSLocale preferredLanguages] objectAtIndex:0];
+
+    if (language) {
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:language forKey:@"value"];
+
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
+                               messageAsDictionary:dictionary];
+    } else {
+        // TBD is this ever expected to happen?
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Unknown error" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+}
+
+- (void)getLocaleName:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CDVPluginResult* result = nil;
+    NSString* callbackId = [arguments objectAtIndex:0];
+    NSDictionary* dictionary = nil;
+
+    NSLocale* locale = [NSLocale currentLocale];
+
+    if (locale) {
+        dictionary = [NSDictionary dictionaryWithObject:[locale localeIdentifier] forKey:@"value"];
+
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    } else {
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Unknown error" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+}
+
+- (void)dateToString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
+    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
+    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
+    NSDate* date = nil;
+    NSString* dateString = nil;
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+
+    id milliseconds = [options valueForKey:@"date"];
+
+    if (milliseconds && [milliseconds isKindOfClass:[NSNumber class]]) {
+        // get the number of seconds since 1970 and create the date object
+        date = [NSDate dateWithTimeIntervalSince1970:[milliseconds doubleValue] / 1000];
+    }
+
+    // see if any options have been specified
+    id items = [options valueForKey:@"options"];
+    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
+        NSEnumerator* enumerator = [items keyEnumerator];
+        id key;
+
+        // iterate through all the options
+        while ((key = [enumerator nextObject])) {
+            id item = [items valueForKey:key];
+
+            // make sure that only string values are present
+            if ([item isKindOfClass:[NSString class]]) {
+                // get the desired format length
+                if ([key isEqualToString:@"formatLength"]) {
+                    if ([item isEqualToString:@"short"]) {
+                        style = kCFDateFormatterShortStyle;
+                    } else if ([item isEqualToString:@"medium"]) {
+                        style = kCFDateFormatterMediumStyle;
+                    } else if ([item isEqualToString:@"long"]) {
+                        style = kCFDateFormatterLongStyle;
+                    } else if ([item isEqualToString:@"full"]) {
+                        style = kCFDateFormatterFullStyle;
+                    }
+                }
+                // get the type of date and time to generate
+                else if ([key isEqualToString:@"selector"]) {
+                    if ([item isEqualToString:@"date"]) {
+                        dateStyle = style;
+                        timeStyle = kCFDateFormatterNoStyle;
+                    } else if ([item isEqualToString:@"time"]) {
+                        dateStyle = kCFDateFormatterNoStyle;
+                        timeStyle = style;
+                    } else if ([item isEqualToString:@"date and time"]) {
+                        dateStyle = style;
+                        timeStyle = style;
+                    }
+                }
+            }
+        }
+    }
+
+    // create the formatter using the user's current default locale and formats for dates and times
+    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
+            currentLocale,
+            dateStyle,
+            timeStyle);
+    // if we have a valid date object then call the formatter
+    if (date) {
+        dateString = (__bridge_transfer NSString*)CFDateFormatterCreateStringWithDate(kCFAllocatorDefault,
+                formatter,
+                (__bridge CFDateRef)date);
+    }
+
+    // if the date was converted to a string successfully then return the result
+    if (dateString) {
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:dateString forKey:@"value"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    }
+    // error
+    else {
+        // DLog(@"GlobalizationCommand dateToString unable to format %@", [date description]);
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_FORMATTING_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Formatting error" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+
+    CFRelease(formatter);
+}
+
+- (void)stringToDate:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
+    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
+    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+    NSString* dateString = nil;
+    NSDateComponents* comps = nil;
+
+    // get the string that is to be parsed for a date
+    id ms = [options valueForKey:@"dateString"];
+
+    if (ms && [ms isKindOfClass:[NSString class]]) {
+        dateString = ms;
+    }
+
+    // see if any options have been specified
+    id items = [options valueForKey:@"options"];
+    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
+        NSEnumerator* enumerator = [items keyEnumerator];
+        id key;
+
+        // iterate through all the options
+        while ((key = [enumerator nextObject])) {
+            id item = [items valueForKey:key];
+
+            // make sure that only string values are present
+            if ([item isKindOfClass:[NSString class]]) {
+                // get the desired format length
+                if ([key isEqualToString:@"formatLength"]) {
+                    if ([item isEqualToString:@"short"]) {
+                        style = kCFDateFormatterShortStyle;
+                    } else if ([item isEqualToString:@"medium"]) {
+                        style = kCFDateFormatterMediumStyle;
+                    } else if ([item isEqualToString:@"long"]) {
+                        style = kCFDateFormatterLongStyle;
+                    } else if ([item isEqualToString:@"full"]) {
+                        style = kCFDateFormatterFullStyle;
+                    }
+                }
+                // get the type of date and time to generate
+                else if ([key isEqualToString:@"selector"]) {
+                    if ([item isEqualToString:@"date"]) {
+                        dateStyle = style;
+                        timeStyle = kCFDateFormatterNoStyle;
+                    } else if ([item isEqualToString:@"time"]) {
+                        dateStyle = kCFDateFormatterNoStyle;
+                        timeStyle = style;
+                    } else if ([item isEqualToString:@"date and time"]) {
+                        dateStyle = style;
+                        timeStyle = style;
+                    }
+                }
+            }
+        }
+    }
+
+    // get the user's default settings for date and time formats
+    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
+            currentLocale,
+            dateStyle,
+            timeStyle);
+
+    // set the parsing to be more lenient
+    CFDateFormatterSetProperty(formatter, kCFDateFormatterIsLenient, kCFBooleanTrue);
+
+    // parse tha date and time string
+    CFDateRef date = CFDateFormatterCreateDateFromString(kCFAllocatorDefault,
+            formatter,
+            (__bridge CFStringRef)dateString,
+            NULL);
+
+    // if we were able to parse the date then get the date and time components
+    if (date != NULL) {
+        NSCalendar* calendar = [NSCalendar currentCalendar];
+
+        unsigned unitFlags = NSYearCalendarUnit |
+            NSMonthCalendarUnit |
+            NSDayCalendarUnit |
+            NSHourCalendarUnit |
+            NSMinuteCalendarUnit |
+            NSSecondCalendarUnit;
+
+        comps = [calendar components:unitFlags fromDate:(__bridge NSDate*)date];
+        CFRelease(date);
+    }
+
+    // put the various elements of the date and time into a dictionary
+    if (comps != nil) {
+        NSArray* keys = [NSArray arrayWithObjects:@"year", @"month", @"day", @"hour", @"minute", @"second", @"millisecond", nil];
+        NSArray* values = [NSArray arrayWithObjects:[NSNumber numberWithInt:[comps year]],
+            [NSNumber numberWithInt:[comps month] - 1],
+            [NSNumber numberWithInt:[comps day]],
+            [NSNumber numberWithInt:[comps hour]],
+            [NSNumber numberWithInt:[comps minute]],
+            [NSNumber numberWithInt:[comps second]],
+            [NSNumber numberWithInt:0],                /* iOS does not provide milliseconds */
+            nil];
+
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    }
+    // error
+    else {
+        // Dlog(@"GlobalizationCommand stringToDate unable to parse %@", dateString);
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_PARSING_ERROR] forKey:@"code"];
+        [dictionary setValue:@"unable to parse" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+
+    CFRelease(formatter);
+}
+
+- (void)getDatePattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CFDateFormatterStyle style = kCFDateFormatterShortStyle;
+    CFDateFormatterStyle dateStyle = kCFDateFormatterShortStyle;
+    CFDateFormatterStyle timeStyle = kCFDateFormatterShortStyle;
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+
+    // see if any options have been specified
+    id items = [options valueForKey:@"options"];
+
+    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
+        NSEnumerator* enumerator = [items keyEnumerator];
+        id key;
+
+        // iterate through all the options
+        while ((key = [enumerator nextObject])) {
+            id item = [items valueForKey:key];
+
+            // make sure that only string values are present
+            if ([item isKindOfClass:[NSString class]]) {
+                // get the desired format length
+                if ([key isEqualToString:@"formatLength"]) {
+                    if ([item isEqualToString:@"short"]) {
+                        style = kCFDateFormatterShortStyle;
+                    } else if ([item isEqualToString:@"medium"]) {
+                        style = kCFDateFormatterMediumStyle;
+                    } else if ([item isEqualToString:@"long"]) {
+                        style = kCFDateFormatterLongStyle;
+                    } else if ([item isEqualToString:@"full"]) {
+                        style = kCFDateFormatterFullStyle;
+                    }
+                }
+                // get the type of date and time to generate
+                else if ([key isEqualToString:@"selector"]) {
+                    if ([item isEqualToString:@"date"]) {
+                        dateStyle = style;
+                        timeStyle = kCFDateFormatterNoStyle;
+                    } else if ([item isEqualToString:@"time"]) {
+                        dateStyle = kCFDateFormatterNoStyle;
+                        timeStyle = style;
+                    } else if ([item isEqualToString:@"date and time"]) {
+                        dateStyle = style;
+                        timeStyle = style;
+                    }
+                }
+            }
+        }
+    }
+
+    // get the user's default settings for date and time formats
+    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
+            currentLocale,
+            dateStyle,
+            timeStyle);
+
+    // get the date pattern to apply when formatting and parsing
+    CFStringRef datePattern = CFDateFormatterGetFormat(formatter);
+    // get the user's current time zone information
+    CFTimeZoneRef timezone = (CFTimeZoneRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterTimeZone);
+
+    // put the pattern and time zone information into the dictionary
+    if ((datePattern != nil) && (timezone != nil)) {
+        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"timezone", @"utc_offset", @"dst_offset", nil];
+        NSArray* values = [NSArray arrayWithObjects:((__bridge NSString*)datePattern),
+            [((__bridge NSTimeZone*)timezone)abbreviation],
+            [NSNumber numberWithLong:[((__bridge NSTimeZone*)timezone)secondsFromGMT]],
+            [NSNumber numberWithDouble:[((__bridge NSTimeZone*)timezone)daylightSavingTimeOffset]],
+            nil];
+
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    }
+    // error
+    else {
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Pattern error" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+
+    if (timezone) {
+        CFRelease(timezone);
+    }
+    CFRelease(formatter);
+}
+
+- (void)getDateNames:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    int style = CDV_FORMAT_LONG;
+    int selector = CDV_SELECTOR_MONTHS;
+    CFStringRef dataStyle = kCFDateFormatterMonthSymbols;
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+
+    // see if any options have been specified
+    id items = [options valueForKey:@"options"];
+
+    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
+        NSEnumerator* enumerator = [items keyEnumerator];
+        id key;
+
+        // iterate through all the options
+        while ((key = [enumerator nextObject])) {
+            id item = [items valueForKey:key];
+
+            // make sure that only string values are present
+            if ([item isKindOfClass:[NSString class]]) {
+                // get the desired type of name
+                if ([key isEqualToString:@"type"]) {
+                    if ([item isEqualToString:@"narrow"]) {
+                        style = CDV_FORMAT_SHORT;
+                    } else if ([item isEqualToString:@"wide"]) {
+                        style = CDV_FORMAT_LONG;
+                    }
+                }
+                // determine if months or days are needed
+                else if ([key isEqualToString:@"item"]) {
+                    if ([item isEqualToString:@"months"]) {
+                        selector = CDV_SELECTOR_MONTHS;
+                    } else if ([item isEqualToString:@"days"]) {
+                        selector = CDV_SELECTOR_DAYS;
+                    }
+                }
+            }
+        }
+    }
+
+    CFDateFormatterRef formatter = CFDateFormatterCreate(kCFAllocatorDefault,
+            currentLocale,
+            kCFDateFormatterFullStyle,
+            kCFDateFormatterFullStyle);
+
+    if ((selector == CDV_SELECTOR_MONTHS) && (style == CDV_FORMAT_LONG)) {
+        dataStyle = kCFDateFormatterMonthSymbols;
+    } else if ((selector == CDV_SELECTOR_MONTHS) && (style == CDV_FORMAT_SHORT)) {
+        dataStyle = kCFDateFormatterShortMonthSymbols;
+    } else if ((selector == CDV_SELECTOR_DAYS) && (style == CDV_FORMAT_LONG)) {
+        dataStyle = kCFDateFormatterWeekdaySymbols;
+    } else if ((selector == CDV_SELECTOR_DAYS) && (style == CDV_FORMAT_SHORT)) {
+        dataStyle = kCFDateFormatterShortWeekdaySymbols;
+    }
+
+    CFArrayRef names = (CFArrayRef)CFDateFormatterCopyProperty(formatter, dataStyle);
+
+    if (names) {
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:((__bridge NSArray*)names) forKey:@"value"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+        CFRelease(names);
+    }
+    // error
+    else {
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Unknown error" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+
+    CFRelease(formatter);
+}
+
+- (void)isDayLightSavingsTime:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    NSDate* date = nil;
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+
+    id milliseconds = [options valueForKey:@"date"];
+
+    if (milliseconds && [milliseconds isKindOfClass:[NSNumber class]]) {
+        // get the number of seconds since 1970 and create the date object
+        date = [NSDate dateWithTimeIntervalSince1970:[milliseconds doubleValue] / 1000];
+    }
+
+    if (date) {
+        // get the current calendar for the user and check if the date is using DST
+        NSCalendar* calendar = [NSCalendar currentCalendar];
+        NSTimeZone* timezone = [calendar timeZone];
+        NSNumber* dst = [NSNumber numberWithBool:[timezone isDaylightSavingTimeForDate:date]];
+
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:dst forKey:@"dst"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    }
+    // error
+    else {
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Unknown error" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+}
+
+- (void)getFirstDayOfWeek:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+
+    NSCalendar* calendar = [NSCalendar autoupdatingCurrentCalendar];
+
+    NSNumber* day = [NSNumber numberWithInt:[calendar firstWeekday]];
+
+    if (day) {
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:day forKey:@"value"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    }
+    // error
+    else {
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_UNKNOWN_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Unknown error" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+}
+
+- (void)numberToString:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
+    NSNumber* number = nil;
+
+    id value = [options valueForKey:@"number"];
+
+    if (value && [value isKindOfClass:[NSNumber class]]) {
+        number = (NSNumber*)value;
+    }
+
+    // see if any options have been specified
+    id items = [options valueForKey:@"options"];
+    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
+        NSEnumerator* enumerator = [items keyEnumerator];
+        id key;
+
+        // iterate through all the options
+        while ((key = [enumerator nextObject])) {
+            id item = [items valueForKey:key];
+
+            // make sure that only string values are present
+            if ([item isKindOfClass:[NSString class]]) {
+                // get the desired style of formatting
+                if ([key isEqualToString:@"type"]) {
+                    if ([item isEqualToString:@"percent"]) {
+                        style = kCFNumberFormatterPercentStyle;
+                    } else if ([item isEqualToString:@"currency"]) {
+                        style = kCFNumberFormatterCurrencyStyle;
+                    } else if ([item isEqualToString:@"decimal"]) {
+                        style = kCFNumberFormatterDecimalStyle;
+                    }
+                }
+            }
+        }
+    }
+
+    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
+            currentLocale,
+            style);
+
+    // get the localized string based upon the locale and user preferences
+    NSString* numberString = (__bridge_transfer NSString*)CFNumberFormatterCreateStringWithNumber(kCFAllocatorDefault,
+            formatter,
+            (__bridge CFNumberRef)number);
+
+    if (numberString) {
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:numberString forKey:@"value"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    }
+    // error
+    else {
+        // DLog(@"GlobalizationCommand numberToString unable to format %@", [number stringValue]);
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_FORMATTING_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Unable to format" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+
+    CFRelease(formatter);
+}
+
+- (void)stringToNumber:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
+    NSString* numberString = nil;
+    double doubleValue;
+
+    id value = [options valueForKey:@"numberString"];
+
+    if (value && [value isKindOfClass:[NSString class]]) {
+        numberString = (NSString*)value;
+    }
+
+    // see if any options have been specified
+    id items = [options valueForKey:@"options"];
+    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
+        NSEnumerator* enumerator = [items keyEnumerator];
+        id key;
+
+        // iterate through all the options
+        while ((key = [enumerator nextObject])) {
+            id item = [items valueForKey:key];
+
+            // make sure that only string values are present
+            if ([item isKindOfClass:[NSString class]]) {
+                // get the desired style of formatting
+                if ([key isEqualToString:@"type"]) {
+                    if ([item isEqualToString:@"percent"]) {
+                        style = kCFNumberFormatterPercentStyle;
+                    } else if ([item isEqualToString:@"currency"]) {
+                        style = kCFNumberFormatterCurrencyStyle;
+                    } else if ([item isEqualToString:@"decimal"]) {
+                        style = kCFNumberFormatterDecimalStyle;
+                    }
+                }
+            }
+        }
+    }
+
+    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
+            currentLocale,
+            style);
+
+    // we need to make this lenient so as to avoid problems with parsing currencies that have non-breaking space characters
+    if (style == kCFNumberFormatterCurrencyStyle) {
+        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterIsLenient, kCFBooleanTrue);
+    }
+
+    // parse againist the largest type to avoid data loss
+    Boolean rc = CFNumberFormatterGetValueFromString(formatter,
+            (__bridge CFStringRef)numberString,
+            NULL,
+            kCFNumberDoubleType,
+            &doubleValue);
+
+    if (rc) {
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:doubleValue] forKey:@"value"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    }
+    // error
+    else {
+        // DLog(@"GlobalizationCommand stringToNumber unable to parse %@", numberString);
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_PARSING_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Unable to parse" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+
+    CFRelease(formatter);
+}
+
+- (void)getNumberPattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+    CFNumberFormatterStyle style = kCFNumberFormatterDecimalStyle;
+    CFStringRef symbolType = NULL;
+    NSString* symbol = @"";
+
+    // see if any options have been specified
+    id items = [options valueForKey:@"options"];
+
+    if (items && [items isKindOfClass:[NSMutableDictionary class]]) {
+        NSEnumerator* enumerator = [items keyEnumerator];
+        id key;
+
+        // iterate through all the options
+        while ((key = [enumerator nextObject])) {
+            id item = [items valueForKey:key];
+
+            // make sure that only string values are present
+            if ([item isKindOfClass:[NSString class]]) {
+                // get the desired style of formatting
+                if ([key isEqualToString:@"type"]) {
+                    if ([item isEqualToString:@"percent"]) {
+                        style = kCFNumberFormatterPercentStyle;
+                    } else if ([item isEqualToString:@"currency"]) {
+                        style = kCFNumberFormatterCurrencyStyle;
+                    } else if ([item isEqualToString:@"decimal"]) {
+                        style = kCFNumberFormatterDecimalStyle;
+                    }
+                }
+            }
+        }
+    }
+
+    CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
+            currentLocale,
+            style);
+
+    NSString* numberPattern = (__bridge NSString*)CFNumberFormatterGetFormat(formatter);
+
+    if (style == kCFNumberFormatterCurrencyStyle) {
+        symbolType = kCFNumberFormatterCurrencySymbol;
+    } else if (style == kCFNumberFormatterPercentStyle) {
+        symbolType = kCFNumberFormatterPercentSymbol;
+    }
+
+    if (symbolType) {
+        symbol = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, symbolType);
+    }
+
+    NSString* decimal = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterDecimalSeparator);
+    NSString* grouping = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterGroupingSeparator);
+    NSString* posSign = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterPlusSign);
+    NSString* negSign = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterMinusSign);
+    NSNumber* fracDigits = (__bridge_transfer NSNumber*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterMinFractionDigits);
+    NSNumber* roundingDigits = (__bridge_transfer NSNumber*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterRoundingIncrement);
+
+    // put the pattern information into the dictionary
+    if (numberPattern != nil) {
+        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"symbol", @"fraction", @"rounding",
+            @"positive", @"negative", @"decimal", @"grouping", nil];
+        NSArray* values = [NSArray arrayWithObjects:numberPattern, symbol, fracDigits, roundingDigits,
+            posSign, negSign, decimal, grouping, nil];
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+    }
+    // error
+    else {
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Pattern error" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+
+    CFRelease(formatter);
+}
+
+- (void)getCurrencyPattern:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
+{
+    CDVPluginResult* result = nil;
+    NSString* callBackId = [arguments objectAtIndex:0];
+    NSString* currencyCode = nil;
+    NSString* numberPattern = nil;
+    NSString* decimal = nil;
+    NSString* grouping = nil;
+    int32_t defaultFractionDigits;
+    double roundingIncrement;
+    Boolean rc;
+
+    id value = [options valueForKey:@"currencyCode"];
+
+    if (value && [value isKindOfClass:[NSString class]]) {
+        currencyCode = (NSString*)value;
+    }
+
+    // first see if there is base currency info available and fill in the currency_info structure
+    rc = CFNumberFormatterGetDecimalInfoForCurrencyCode((__bridge CFStringRef)currencyCode, &defaultFractionDigits, &roundingIncrement);
+
+    // now set the currency code in the formatter
+    if (rc) {
+        CFNumberFormatterRef formatter = CFNumberFormatterCreate(kCFAllocatorDefault,
+                currentLocale,
+                kCFNumberFormatterCurrencyStyle);
+
+        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterCurrencyCode, (__bridge CFStringRef)currencyCode);
+        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterInternationalCurrencySymbol, (__bridge CFStringRef)currencyCode);
+
+        numberPattern = (__bridge NSString*)CFNumberFormatterGetFormat(formatter);
+        decimal = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterCurrencyDecimalSeparator);
+        grouping = (__bridge_transfer NSString*)CFNumberFormatterCopyProperty(formatter, kCFNumberFormatterCurrencyGroupingSeparator);
+
+        NSArray* keys = [NSArray arrayWithObjects:@"pattern", @"code", @"fraction", @"rounding",
+            @"decimal", @"grouping", nil];
+        NSArray* values = [NSArray arrayWithObjects:numberPattern, currencyCode, [NSNumber numberWithInt:defaultFractionDigits],
+            [NSNumber numberWithDouble:roundingIncrement], decimal, grouping, nil];
+        NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
+        CFRelease(formatter);
+    }
+    // error
+    else {
+        // DLog(@"GlobalizationCommand getCurrencyPattern unable to get pattern for %@", currencyCode);
+        NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithCapacity:2];
+        [dictionary setValue:[NSNumber numberWithInt:CDV_PATTERN_ERROR] forKey:@"code"];
+        [dictionary setValue:@"Unable to get pattern" forKey:@"message"];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
+    }
+
+    [self.commandDelegate sendPluginResult:result callbackId:callBackId];
+}
+
+- (void)dealloc
+{
+    if (currentLocale) {
+        CFRelease(currentLocale);
+        currentLocale = nil;
+    }
+}
+
+@end

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a704d594/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVInAppBrowser.h
----------------------------------------------------------------------
diff --git a/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVInAppBrowser.h b/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVInAppBrowser.h
new file mode 100644
index 0000000..f63250a
--- /dev/null
+++ b/portal/dist/appsvc-ui/2.0.2/bower_components/apigee-sdk/samples/push/ios/CordovaLib/Classes/CDVInAppBrowser.h
@@ -0,0 +1,88 @@
+/*
+ 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 "CDVPlugin.h"
+#import "CDVInvokedUrlCommand.h"
+#import "CDVScreenOrientationDelegate.h"
+#import "CDVWebViewDelegate.h"
+
+@class CDVInAppBrowserViewController;
+
+@protocol CDVInAppBrowserNavigationDelegate <NSObject>
+
+- (void)browserLoadStart:(NSURL*)url;
+- (void)browserLoadStop:(NSURL*)url;
+- (void)browserLoadError:(NSError*)error forUrl:(NSURL*)url;
+- (void)browserExit;
+
+@end
+
+@interface CDVInAppBrowser : CDVPlugin <CDVInAppBrowserNavigationDelegate>
+
+@property (nonatomic, retain) CDVInAppBrowserViewController* inAppBrowserViewController;
+@property (nonatomic, copy) NSString* callbackId;
+
+- (void)open:(CDVInvokedUrlCommand*)command;
+- (void)close:(CDVInvokedUrlCommand*)command;
+
+@end
+
+@interface CDVInAppBrowserViewController : UIViewController <UIWebViewDelegate>{
+    @private
+    NSURL* _requestedURL;
+    NSString* _userAgent;
+    NSString* _prevUserAgent;
+    NSInteger _userAgentLockToken;
+    CDVWebViewDelegate* _webViewDelegate;
+}
+
+@property (nonatomic, strong) IBOutlet UIWebView* webView;
+@property (nonatomic, strong) IBOutlet UIBarButtonItem* closeButton;
+@property (nonatomic, strong) IBOutlet UILabel* addressLabel;
+@property (nonatomic, strong) IBOutlet UIBarButtonItem* backButton;
+@property (nonatomic, strong) IBOutlet UIBarButtonItem* forwardButton;
+@property (nonatomic, strong) IBOutlet UIActivityIndicatorView* spinner;
+@property (nonatomic, strong) IBOutlet UIToolbar* toolbar;
+
+@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate;
+@property (nonatomic, weak) id <CDVInAppBrowserNavigationDelegate> navigationDelegate;
+
+- (void)close;
+- (void)navigateTo:(NSURL*)url;
+- (void)showLocationBar:(BOOL)show;
+
+- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent;
+
+@end
+
+@interface CDVInAppBrowserOptions : NSObject {}
+
+@property (nonatomic, assign) BOOL location;
+@property (nonatomic, copy) NSString* presentationstyle;
+@property (nonatomic, copy) NSString* transitionstyle;
+
+@property (nonatomic, assign) BOOL enableviewportscale;
+@property (nonatomic, assign) BOOL mediaplaybackrequiresuseraction;
+@property (nonatomic, assign) BOOL allowinlinemediaplayback;
+@property (nonatomic, assign) BOOL keyboarddisplayrequiresuseraction;
+@property (nonatomic, assign) BOOL suppressesincrementalrendering;
+
++ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options;
+
+@end