Sync with "shared to me" selected accounts.
[pithos-macos] / pithos-macos / PithosUtilities.m
index 8fecb7b..af97bb2 100644 (file)
@@ -2,7 +2,7 @@
 //  PithosUtilities.m
 //  pithos-macos
 //
-// Copyright 2011 GRNET S.A. All rights reserved.
+// Copyright 2011-2012 GRNET S.A. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or
 // without modification, are permitted provided that the following
@@ -36,6 +36,8 @@
 // or implied, of GRNET S.A.
 
 #import "PithosUtilities.h"
+#import "ASINetworkQueue.h"
+#import "ASIPithos.h"
 #import "ASIPithosContainerRequest.h"
 #import "ASIPithosObjectRequest.h"
 #import "ASIPithosObject.h"
 #pragma mark -
 #pragma mark Download
 
-+ (ASIPithosObjectRequest *)objectDataRequestWithContainerName:(NSString *)containerName 
-                                                    objectName:(NSString *)objectName 
-                                                   toDirectory:(NSString *)directoryPath 
-                                                 checkIfExists:(BOOL)ifExists 
-                                                sharingAccount:(NSString *)sharingAccount {
-    NSString *fileName = [objectName lastPathComponent];
-    if([objectName hasSuffix:@"/"])
-        fileName = [fileName stringByAppendingString:@"/"];    
++ (ASIPithosObjectRequest *)objectDataRequestWithPithos:(ASIPithos *)pithos 
+                                          containerName:(NSString *)containerName 
+                                             objectName:(NSString *)objectName 
+                                                version:(NSString *)version 
+                                            toDirectory:(NSString *)directoryPath 
+                                        withNewFileName:(NSString *)newFileName 
+                                          checkIfExists:(BOOL)ifExists 
+                                         sharingAccount:(NSString *)sharingAccount {
+    NSString *fileName;
+    if (newFileName) {
+        fileName = [NSString stringWithString:newFileName];
+    } else {
+        fileName = [objectName lastPathComponent];
+        if ([objectName hasSuffix:@"/"])
+            fileName = [fileName stringByAppendingString:@"/"];    
+    }
     fileName = [fileName stringByReplacingOccurrencesOfString:@"/" withString:@":"];
     
     NSFileManager *fileManager = [NSFileManager defaultManager];
         return nil;
     }
 
-    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectDataRequestWithContainerName:containerName 
-                                                                                            objectName:objectName];
+    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectDataRequestWithPithos:pithos 
+                                                                                  containerName:containerName 
+                                                                                     objectName:objectName 
+                                                                                        version:version];
     if (sharingAccount)
-        [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+        [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
     objectRequest.downloadDestinationPath = destinationPath;
     objectRequest.allowResumeForFileDownloads = YES;
     objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
     return objectRequest;
 }
 
-+ (NSArray *)objectDataRequestsForSubdirWithContainerName:(NSString *)containerName 
-                                               objectName:(NSString *)objectName 
-                                              toDirectory:(NSString *)directoryPath 
-                                            checkIfExists:(BOOL)ifExists 
-                                           sharingAccount:(NSString *)sharingAccount {
++ (NSArray *)objectDataRequestsForSubdirWithPithos:(ASIPithos *)pithos 
+                                     containerName:(NSString *)containerName 
+                                        objectName:(NSString *)objectName 
+                                       toDirectory:(NSString *)directoryPath 
+                                     checkIfExists:(BOOL)ifExists 
+                                    sharingAccount:(NSString *)sharingAccount {
     NSString *subdirName = [objectName lastPathComponent];
     NSString *destinationPath = [directoryPath stringByAppendingPathComponent:subdirName];
     if (ifExists && [[NSFileManager defaultManager] fileExistsAtPath:destinationPath]) {
             return nil;
     }
     
-    NSArray *objects = [self objectsForSubdirWithContainerName:containerName objectName:objectName 
-                                                     delimiter:nil sharingAccount:sharingAccount];
+    NSArray *objects = [self objectsForSubdirWithPithos:pithos containerName:containerName objectName:objectName 
+                                              delimiter:nil sharingAccount:sharingAccount];
     if (objects == nil)
         return nil;
     
     }
     
     for (ASIPithosObject *object in objects) {
-        if ([object.contentType isEqualToString:@"application/directory"]) {
+        if ([self isContentTypeDirectory:object.contentType]) {
             NSString *subdirDirectoryPath = [directoryPath stringByAppendingPathComponent:subdirName];
             subdirDirectoryPath = [subdirDirectoryPath stringByAppendingPathComponent:[object.name substringFromIndex:subdirPrefixLength]];
             
             NSString *objectDirectoryPath = [directoryPath stringByAppendingPathComponent:subdirName];
             objectDirectoryPath = [objectDirectoryPath stringByAppendingPathComponent:[object.name substringWithRange:NSMakeRange(subdirPrefixLength, [object.name length] - subdirPrefixLength - [fileName length])]];
             
-            ASIPithosObjectRequest *objectRequest = [self objectDataRequestWithContainerName:containerName 
-                                                                                  objectName:object.name 
-                                                                                 toDirectory:objectDirectoryPath 
-                                                                               checkIfExists:NO 
-                                                                              sharingAccount:sharingAccount];
+            ASIPithosObjectRequest *objectRequest = [self objectDataRequestWithPithos:pithos 
+                                                                        containerName:containerName 
+                                                                           objectName:object.name 
+                                                                              version:nil 
+                                                                          toDirectory:objectDirectoryPath 
+                                                                      withNewFileName:nil 
+                                                                        checkIfExists:NO 
+                                                                       sharingAccount:sharingAccount];
             [(NSMutableDictionary *)objectRequest.userInfo setObject:[NSNumber numberWithUnsignedInteger:object.bytes] forKey:@"bytes"];
             [objectRequests addObject:objectRequest];
         }
 #pragma mark -
 #pragma mark Download Block
 
-+ (ASIPithosObjectRequest *)objectBlockDataRequestWithContainerName:(NSString *)containerName 
-                                                             object:(ASIPithosObject *)object 
-                                                         blockIndex:(NSUInteger)blockIndex 
-                                                          blockSize:(NSUInteger)blockSize {
++ (ASIPithosObjectRequest *)objectBlockDataRequestWithPithos:(ASIPithos *)pithos 
+                                               containerName:(NSString *)containerName 
+                                                      object:(ASIPithosObject *)object 
+                                                  blockIndex:(NSUInteger)blockIndex 
+                                                   blockSize:(NSUInteger)blockSize {
     NSUInteger rangeStart = blockIndex * blockSize;
     NSUInteger rangeEnd = (rangeStart + blockSize <= object.bytes) ? (rangeStart + blockSize - 1) : (object.bytes - 1);
-    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectDataRequestWithContainerName:containerName
-                                                                                            objectName:object.name
-                                                                                               version:nil
-                                                                                                 range:[NSString stringWithFormat:@"bytes=%lu-%lu", rangeStart, rangeEnd]
-                                                                                               ifMatch:object.hash];
+    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectDataRequestWithPithos:pithos 
+                                                                                  containerName:containerName
+                                                                                     objectName:object.name
+                                                                                        version:nil
+                                                                                          range:[NSString stringWithFormat:@"bytes=%lu-%lu", rangeStart, rangeEnd]
+                                                                                        ifMatch:object.hash];
     return objectRequest;
 }
 
 #pragma mark -
 #pragma mark Upload
 
-+ (ASIPithosObjectRequest *)writeObjectDataRequestWithContainerName:(NSString *)containerName
-                                                         objectName:(NSString *)objectName
-                                                        contentType:(NSString *)contentType 
-                                                          blockSize:(NSUInteger)blockSize 
-                                                          blockHash:(NSString *)blockHash 
-                                                            forFile:(NSString *)filePath 
-                                                      checkIfExists:(BOOL)ifExists 
-                                                             hashes:(NSArray **)hashes 
-                                                     sharingAccount:(NSString *)sharingAccount {
-    if (ifExists && ![self proceedIfObjectExistsAtContainerName:containerName objectName:objectName 
-                                                 sharingAccount:(NSString *)sharingAccount])
++ (ASIPithosObjectRequest *)writeObjectDataRequestWithPithos:(ASIPithos *)pithos 
+                                               containerName:(NSString *)containerName
+                                                  objectName:(NSString *)objectName
+                                                 contentType:(NSString *)contentType 
+                                                   blockSize:(NSUInteger)blockSize 
+                                                   blockHash:(NSString *)blockHash 
+                                                     forFile:(NSString *)filePath 
+                                               checkIfExists:(BOOL)ifExists 
+                                                      hashes:(NSArray **)hashes 
+                                              sharingAccount:(NSString *)sharingAccount {
+    if (ifExists && ![self proceedIfObjectExistsAtPithos:pithos containerName:containerName objectName:objectName 
+                                          sharingAccount:(NSString *)sharingAccount])
         return nil;
     
     if (*hashes == nil)
     if ([filePath hasSuffix:@"/"])
         fileName = [fileName stringByAppendingString:@"/"];
     NSUInteger bytes = [self bytesOfFile:filePath];
-    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithContainerName:containerName 
-                                                                                                 objectName:objectName 
-                                                                                                contentType:contentType 
-                                                                                            contentEncoding:nil 
-                                                                                         contentDisposition:nil 
-                                                                                                   manifest:nil 
-                                                                                                    sharing:nil 
-                                                                                                   isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                                   metadata:nil
-                                                                                                  blockSize:blockSize
-                                                                                                  blockHash:blockHash 
-                                                                                                     hashes:*hashes 
-                                                                                                      bytes:bytes];
+    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos 
+                                                                                       containerName:containerName 
+                                                                                          objectName:objectName 
+                                                                                         contentType:contentType 
+                                                                                     contentEncoding:nil 
+                                                                                  contentDisposition:nil 
+                                                                                            manifest:nil 
+                                                                                             sharing:nil 
+                                                                                            isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                                            metadata:nil
+                                                                                           blockSize:blockSize
+                                                                                           blockHash:blockHash 
+                                                                                              hashes:*hashes 
+                                                                                               bytes:bytes];
     if (sharingAccount) 
-        [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+        [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
     objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                               fileName, @"fileName", 
                               [NSNumber numberWithUnsignedInteger:bytes], @"bytes", 
     return objectRequest;
 }
 
-+ (NSIndexSet *)missingBlocksForHashes:(NSArray *)hashes withMissingHashesResponse:(NSString *)missingHashesResponse {
-    NSArray *responseLines = [missingHashesResponse componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
++ (NSIndexSet *)missingBlocksForHashes:(NSArray *)hashes withMissingHashes:(NSArray *)missingHashes {
     NSMutableIndexSet *missingBlocks = [NSMutableIndexSet indexSet];
-    for (NSString *line in responseLines) {
-        if (![line length])
+    for (NSString *missingHash in missingHashes) {
+        if (![missingHash length])
             break;
-        NSUInteger missingBlock = [hashes indexOfObject:line];
+        NSUInteger missingBlock = [hashes indexOfObject:missingHash];
         if (missingBlock != NSNotFound)
             [missingBlocks addIndex:missingBlock];
     }
     return missingBlocks;
 }
 
-+ (ASIPithosContainerRequest *)updateContainerDataRequestWithContainerName:(NSString *)containerName 
-                                                                 blockSize:(NSUInteger)blockSize 
-                                                                   forFile:(NSString *)filePath 
-                                                                    hashes:(NSArray *)hashes 
-                                                     missingHashesResponse:(NSString *)missingHashesResponse 
-                                                            sharingAccount:(NSString *)sharingAccount {
-    NSIndexSet *missingBlocks = [self missingBlocksForHashes:hashes withMissingHashesResponse:missingHashesResponse];
++ (ASIPithosContainerRequest *)updateContainerDataRequestWithPithos:(ASIPithos *)pithos 
+                                                      containerName:(NSString *)containerName 
+                                                          blockSize:(NSUInteger)blockSize 
+                                                            forFile:(NSString *)filePath 
+                                                             hashes:(NSArray *)hashes 
+                                                      missingHashes:(NSArray *)missingHashes 
+                                                     sharingAccount:(NSString *)sharingAccount {
+    NSIndexSet *missingBlocks = [self missingBlocksForHashes:hashes withMissingHashes:missingHashes];
     
     NSFileManager *fileManager = [NSFileManager defaultManager];
     NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
     [tempFileHandle closeFile];
     [fileHandle closeFile];
 
-    ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest updateContainerDataRequestWithContainerName:containerName 
-                                                                                                                  policy:nil 
-                                                                                                                metadata:nil 
-                                                                                                                  update:YES 
-                                                                                                                    file:tempFilePath];
+    ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest updateContainerDataRequestWithPithos:pithos 
+                                                                                                    containerName:containerName 
+                                                                                                           policy:nil 
+                                                                                                         metadata:nil 
+                                                                                                           update:YES 
+                                                                                                             file:tempFilePath];
     if (sharingAccount)
-        [containerRequest setRequestUserFromDefaultTo:sharingAccount];
+        [containerRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
     return containerRequest;
 }
 
-+ (ASIPithosContainerRequest *)updateContainerDataRequestWithContainerName:(NSString *)containerName 
-                                                                 blockSize:(NSUInteger)blockSize 
-                                                                   forFile:(NSString *)filePath 
-                                                         missingBlockIndex:(NSUInteger)missingBlockIndex 
-                                                            sharingAccount:(NSString *)sharingAccount {
++ (ASIPithosContainerRequest *)updateContainerDataRequestWithPithos:(ASIPithos *)pithos 
+                                                      containerName:(NSString *)containerName 
+                                                          blockSize:(NSUInteger)blockSize 
+                                                            forFile:(NSString *)filePath 
+                                                  missingBlockIndex:(NSUInteger)missingBlockIndex 
+                                                     sharingAccount:(NSString *)sharingAccount {
     NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
     [fileHandle seekToFileOffset:(missingBlockIndex *blockSize)];
     NSData *blockData = [fileHandle readDataOfLength:blockSize];
     [fileHandle closeFile];
-    ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest updateContainerDataRequestWithContainerName:containerName 
-                                                                                                                  policy:nil 
-                                                                                                                metadata:nil 
-                                                                                                                  update:YES 
-                                                                                                                    data:blockData];
+    ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest updateContainerDataRequestWithPithos:pithos 
+                                                                                                    containerName:containerName 
+                                                                                                           policy:nil 
+                                                                                                         metadata:nil 
+                                                                                                           update:YES 
+                                                                                                             data:blockData];
     if (sharingAccount)
-        [containerRequest setRequestUserFromDefaultTo:sharingAccount];
+        [containerRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
     return containerRequest;
 }
 
-+ (NSArray *)writeObjectDataRequestsWithContainerName:(NSString *)containerName
-                                           objectName:(NSString *)objectName
-                                            blockSize:(NSUInteger)blockSize 
-                                            blockHash:(NSString *)blockHash 
-                                         forDirectory:(NSString *)directoryPath 
-                                        checkIfExists:(BOOL)ifExists 
-                                          objectNames:(NSMutableArray **)objectNames
-                                         contentTypes:(NSMutableArray **)contentTypes
-                                            filePaths:(NSMutableArray **)filePaths 
-                                         hashesArrays:(NSMutableArray **)hashesArrays 
-                              directoryObjectRequests:(NSMutableArray **) directoryObjectRequests 
-                                       sharingAccount:(NSString *)sharingAccount {
-    if (ifExists && ![self proceedIfObjectExistsAtContainerName:containerName objectName:objectName sharingAccount:sharingAccount])
++ (NSArray *)writeObjectDataRequestsWithPithos:(ASIPithos *)pithos 
+                                 containerName:(NSString *)containerName
+                                    objectName:(NSString *)objectName
+                                     blockSize:(NSUInteger)blockSize 
+                                     blockHash:(NSString *)blockHash 
+                                  forDirectory:(NSString *)directoryPath 
+                                 checkIfExists:(BOOL)ifExists 
+                                   objectNames:(NSMutableArray **)objectNames
+                                  contentTypes:(NSMutableArray **)contentTypes
+                                     filePaths:(NSMutableArray **)filePaths 
+                                  hashesArrays:(NSMutableArray **)hashesArrays 
+                       directoryObjectRequests:(NSMutableArray **) directoryObjectRequests 
+                                sharingAccount:(NSString *)sharingAccount {
+    if (ifExists && ![self proceedIfObjectExistsAtPithos:pithos containerName:containerName objectName:objectName 
+                                          sharingAccount:sharingAccount])
         return nil;
 
     NSFileManager *fileManager = [NSFileManager defaultManager];
     }
     
     *directoryObjectRequests = [NSMutableArray arrayWithCapacity:[subPaths count]];
-    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithContainerName:containerName 
-                                                                                                 objectName:objectName 
-                                                                                                       eTag:nil 
-                                                                                                contentType:@"application/directory" 
-                                                                                            contentEncoding:nil 
-                                                                                         contentDisposition:nil 
-                                                                                                   manifest:nil 
-                                                                                                    sharing:nil 
-                                                                                                   isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                                   metadata:nil 
-                                                                                                       data:[NSData data]];
+    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos 
+                                                                                       containerName:containerName 
+                                                                                          objectName:objectName 
+                                                                                                eTag:nil 
+                                                                                         contentType:@"application/directory" 
+                                                                                     contentEncoding:nil 
+                                                                                  contentDisposition:nil 
+                                                                                            manifest:nil 
+                                                                                             sharing:nil 
+                                                                                            isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                                            metadata:nil 
+                                                                                                data:[NSData data]];
     if (sharingAccount)
-        [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+        [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
     objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                               [directoryPath lastPathComponent], @"fileName", 
                               nil];
                         contentType = @"application/octet-stream";
                     if (error)
                         NSLog(@"contentType detection error: %@", error);
-                    objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithContainerName:containerName 
-                                                                                         objectName:subObjectName 
-                                                                                        contentType:contentType 
-                                                                                    contentEncoding:nil 
-                                                                                 contentDisposition:nil 
-                                                                                           manifest:nil 
-                                                                                            sharing:nil 
-                                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                           metadata:nil
-                                                                                          blockSize:blockSize
-                                                                                          blockHash:blockHash 
-                                                                                             hashes:hashes 
-                                                                                              bytes:bytes];
+                    objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos 
+                                                                               containerName:containerName 
+                                                                                  objectName:subObjectName 
+                                                                                 contentType:contentType 
+                                                                             contentEncoding:nil 
+                                                                          contentDisposition:nil 
+                                                                                    manifest:nil 
+                                                                                     sharing:nil 
+                                                                                    isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                                    metadata:nil
+                                                                                   blockSize:blockSize
+                                                                                   blockHash:blockHash 
+                                                                                      hashes:hashes 
+                                                                                       bytes:bytes];
                     if (sharingAccount)
-                        [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+                        [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
                     objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                               fileName, @"fileName", 
                                               [NSNumber numberWithUnsignedInteger:bytes], @"bytes", 
             } else {
                 subObjectName = [objectName stringByAppendingPathComponent:objectNameSuffix];
                 fileName = [filePath lastPathComponent];
-                objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithContainerName:containerName 
-                                                                                     objectName:subObjectName 
-                                                                                           eTag:nil 
-                                                                                    contentType:@"application/directory" 
-                                                                                contentEncoding:nil 
-                                                                             contentDisposition:nil 
-                                                                                       manifest:nil 
-                                                                                        sharing:nil 
-                                                                                       isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                       metadata:nil 
-                                                                                           data:[NSData data]];
+                objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos 
+                                                                           containerName:containerName 
+                                                                              objectName:subObjectName 
+                                                                                    eTag:nil 
+                                                                             contentType:@"application/directory" 
+                                                                         contentEncoding:nil 
+                                                                      contentDisposition:nil 
+                                                                                manifest:nil 
+                                                                                 sharing:nil 
+                                                                                isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                                metadata:nil 
+                                                                                    data:[NSData data]];
                 if (sharingAccount)
-                    [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+                    [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
                 objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                           fileName, @"fileName", 
                                           nil];
 #pragma mark -
 #pragma mark Delete
 
-+ (NSArray *)deleteObjectRequestsForSubdirWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
-    NSArray *objects = [self objectsForSubdirWithContainerName:containerName objectName:objectName delimiter:nil sharingAccount:nil];
++ (NSArray *)deleteObjectRequestsForSubdirWithPithos:(ASIPithos *)pithos 
+                                       containerName:(NSString *)containerName 
+                                          objectName:(NSString *)objectName {
+    NSArray *objects = [self objectsForSubdirWithPithos:pithos containerName:containerName objectName:objectName delimiter:nil 
+                                         sharingAccount:nil];
     if (objects == nil)
         return nil;
 
     NSMutableArray *objectRequests = [NSMutableArray arrayWithCapacity:([objects count] + 1)];
     ASIPithosObjectRequest *objectRequest;
     if (![objectName hasSuffix:@"/"]) {
-        objectRequest = [ASIPithosObjectRequest deleteObjectRequestWithContainerName:containerName objectName:objectName];
+        objectRequest = [ASIPithosObjectRequest deleteObjectRequestWithPithos:pithos containerName:containerName objectName:objectName];
         objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   [objectName lastPathComponent], @"fileName", 
                                   nil];
         fileName = [object.name lastPathComponent];
         if ([object.name hasSuffix:@"/"])
             fileName = [fileName stringByAppendingString:@"/"];
-        objectRequest = [ASIPithosObjectRequest deleteObjectRequestWithContainerName:containerName objectName:object.name];
+        objectRequest = [ASIPithosObjectRequest deleteObjectRequestWithPithos:pithos containerName:containerName objectName:object.name];
         objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                   fileName, @"fileName", 
                                   nil];
 #pragma mark -
 #pragma mark Copy
 
-+ (ASIPithosObjectRequest *)copyObjectRequestWithContainerName:(NSString *)containerName 
-                                                    objectName:(NSString *)objectName 
-                                      destinationContainerName:(NSString *)destinationContainerName 
-                                         destinationObjectName:(NSString *)destinationObjectName 
-                                                 checkIfExists:(BOOL)ifExists 
-                                                sharingAccount:(NSString *)sharingAccount {
-    if (ifExists && ![self proceedIfObjectExistsAtContainerName:destinationContainerName objectName:destinationObjectName sharingAccount:nil])
++ (ASIPithosObjectRequest *)copyObjectRequestWithPithos:(ASIPithos *)pithos 
+                                          containerName:(NSString *)containerName 
+                                             objectName:(NSString *)objectName 
+                               destinationContainerName:(NSString *)destinationContainerName 
+                                  destinationObjectName:(NSString *)destinationObjectName 
+                                          checkIfExists:(BOOL)ifExists 
+                                         sharingAccount:(NSString *)sharingAccount {
+    if (ifExists && ![self proceedIfObjectExistsAtPithos:pithos containerName:destinationContainerName objectName:destinationObjectName 
+                                          sharingAccount:nil])
         return nil;
     
-    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithContainerName:containerName 
-                                                                                                objectName:objectName 
-                                                                                               contentType:nil 
-                                                                                           contentEncoding:nil 
-                                                                                        contentDisposition:nil 
-                                                                                                  manifest:nil 
-                                                                                                   sharing:nil 
-                                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                                  metadata:nil 
-                                                                                  destinationContainerName:destinationContainerName 
-                                                                                     destinationObjectName:destinationObjectName 
-                                                                                        destinationAccount:nil
-                                                                                             sourceVersion:nil];
+    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos 
+                                                                                      containerName:containerName 
+                                                                                         objectName:objectName 
+                                                                                        contentType:nil 
+                                                                                    contentEncoding:nil 
+                                                                                 contentDisposition:nil 
+                                                                                           manifest:nil 
+                                                                                            sharing:nil 
+                                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                                           metadata:nil 
+                                                                           destinationContainerName:destinationContainerName 
+                                                                              destinationObjectName:destinationObjectName 
+                                                                                 destinationAccount:nil
+                                                                                      sourceVersion:nil];
     objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                               containerName, @"sourceContainerName", 
                               objectName, @"sourceObjectName", 
                               destinationObjectName, @"destinationObjectName", 
                               nil];
     if (sharingAccount) 
-        [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+        [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
     return objectRequest;
 }
 
-+ (NSArray *)copyObjectRequestsForSubdirWithContainerName:(NSString *)containerName 
-                                               objectName:(NSString *)objectName 
-                                 destinationContainerName:(NSString *)destinationContainerName 
-                                    destinationObjectName:(NSString *)destinationObjectName 
-                                            checkIfExists:(BOOL)ifExists 
-                                           sharingAccount:(NSString *)sharingAccount {
-    if (ifExists && ![self proceedIfObjectExistsAtContainerName:destinationContainerName objectName:destinationObjectName sharingAccount:nil])
++ (NSArray *)copyObjectRequestsForSubdirWithPithos:(ASIPithos *)pithos 
+                                     containerName:(NSString *)containerName 
+                                        objectName:(NSString *)objectName 
+                          destinationContainerName:(NSString *)destinationContainerName 
+                             destinationObjectName:(NSString *)destinationObjectName 
+                                     checkIfExists:(BOOL)ifExists 
+                                    sharingAccount:(NSString *)sharingAccount {
+    if (ifExists && ![self proceedIfObjectExistsAtPithos:pithos containerName:destinationContainerName objectName:destinationObjectName 
+                                          sharingAccount:nil])
         return nil;
     
-    NSArray *objects = [self objectsForSubdirWithContainerName:containerName objectName:objectName 
-                                                     delimiter:nil sharingAccount:sharingAccount];
+    NSArray *objects = [self objectsForSubdirWithPithos:pithos containerName:containerName objectName:objectName 
+                                              delimiter:nil sharingAccount:sharingAccount];
     if (objects == nil)
         return nil;
     
     ASIPithosObjectRequest *objectRequest;
     if ([objectName isEqualToString:destinationObjectName]) {
         if (![objectName hasSuffix:@"/"]) {
-            objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithContainerName:containerName 
-                                                                                objectName:objectName 
-                                                                               contentType:nil 
-                                                                           contentEncoding:nil 
-                                                                        contentDisposition:nil 
-                                                                                  manifest:nil 
-                                                                                   sharing:nil 
-                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                  metadata:nil 
-                                                                  destinationContainerName:destinationContainerName 
-                                                                     destinationObjectName:objectName 
-                                                                        destinationAccount:nil 
-                                                                             sourceVersion:nil];
+            objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos 
+                                                                      containerName:containerName 
+                                                                         objectName:objectName 
+                                                                        contentType:nil 
+                                                                    contentEncoding:nil 
+                                                                 contentDisposition:nil 
+                                                                           manifest:nil 
+                                                                            sharing:nil 
+                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                           metadata:nil 
+                                                           destinationContainerName:destinationContainerName 
+                                                              destinationObjectName:objectName 
+                                                                 destinationAccount:nil 
+                                                                      sourceVersion:nil];
             objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       containerName, @"sourceContainerName", 
                                       objectName, @"sourceObjectName", 
                                       objectName, @"destinationObjectName", 
                                       nil];
             if (sharingAccount)
-                [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+                [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
             [objectRequests addObject:objectRequest];
         }
         for (ASIPithosObject *object in objects) {
-            objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithContainerName:containerName 
-                                                                                objectName:object.name 
-                                                                               contentType:nil 
-                                                                           contentEncoding:nil 
-                                                                        contentDisposition:nil 
-                                                                                  manifest:nil 
-                                                                                   sharing:nil 
-                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                  metadata:nil 
-                                                                  destinationContainerName:destinationContainerName 
-                                                                     destinationObjectName:object.name 
-                                                                        destinationAccount:nil 
-                                                                             sourceVersion:nil];
+            objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos 
+                                                                      containerName:containerName 
+                                                                         objectName:object.name 
+                                                                        contentType:nil 
+                                                                    contentEncoding:nil 
+                                                                 contentDisposition:nil 
+                                                                           manifest:nil 
+                                                                            sharing:nil 
+                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                           metadata:nil 
+                                                           destinationContainerName:destinationContainerName 
+                                                              destinationObjectName:object.name 
+                                                                 destinationAccount:nil 
+                                                                      sourceVersion:nil];
             objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       containerName, @"sourceContainerName", 
                                       object.name, @"sourceObjectName", 
                                       object.name, @"destinationObjectName", 
                                       nil];
             if (sharingAccount)
-                [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+                [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
             [objectRequests addObject:objectRequest];
         }
     } else {
         if (![objectName hasSuffix:@"/"]) {
-            objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithContainerName:containerName 
-                                                                                objectName:objectName 
-                                                                               contentType:nil 
-                                                                           contentEncoding:nil 
-                                                                        contentDisposition:nil 
-                                                                                  manifest:nil 
-                                                                                   sharing:nil 
-                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                  metadata:nil 
-                                                                  destinationContainerName:destinationContainerName 
-                                                                     destinationObjectName:destinationObjectName 
-                                                                        destinationAccount:nil 
-                                                                             sourceVersion:nil];
+            objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos 
+                                                                      containerName:containerName 
+                                                                         objectName:objectName 
+                                                                        contentType:nil 
+                                                                    contentEncoding:nil 
+                                                                 contentDisposition:nil 
+                                                                           manifest:nil 
+                                                                            sharing:nil 
+                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                           metadata:nil 
+                                                           destinationContainerName:destinationContainerName 
+                                                              destinationObjectName:destinationObjectName 
+                                                                 destinationAccount:nil 
+                                                                      sourceVersion:nil];
             objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       containerName, @"sourceContainerName", 
                                       objectName, @"sourceObjectName", 
                                       destinationObjectName, @"destinationObjectName", 
                                       nil];
             if (sharingAccount)
-                [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+                [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
             [objectRequests addObject:objectRequest];
         }
         NSRange prefixRange = NSMakeRange(0, [objectName length]);
                                                                    withString:destinationObjectName
                                                                       options:NSAnchoredSearch
                                                                         range:prefixRange];
-            objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithContainerName:containerName 
-                                                                                objectName:object.name 
-                                                                               contentType:nil 
-                                                                           contentEncoding:nil 
-                                                                        contentDisposition:nil 
-                                                                                  manifest:nil 
-                                                                                   sharing:nil 
-                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                  metadata:nil 
-                                                                  destinationContainerName:destinationContainerName 
-                                                                     destinationObjectName:newObjectName 
-                                                                        destinationAccount:nil 
-                                                                             sourceVersion:nil];
+            objectRequest = [ASIPithosObjectRequest copyObjectDataRequestWithPithos:pithos 
+                                                                      containerName:containerName 
+                                                                         objectName:object.name 
+                                                                        contentType:nil 
+                                                                    contentEncoding:nil 
+                                                                 contentDisposition:nil 
+                                                                           manifest:nil 
+                                                                            sharing:nil 
+                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                           metadata:nil 
+                                                           destinationContainerName:destinationContainerName 
+                                                              destinationObjectName:newObjectName 
+                                                                 destinationAccount:nil 
+                                                                      sourceVersion:nil];
             objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       containerName, @"sourceContainerName", 
                                       object.name, @"sourceObjectName", 
                                       newObjectName, @"destinationObjectName", 
                                       nil];
             if (sharingAccount)
-                [objectRequest setRequestUserFromDefaultTo:sharingAccount];
+                [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
             [objectRequests addObject:objectRequest];
         }
     }
 #pragma mark -
 #pragma mark Move
 
-+ (ASIPithosObjectRequest *)moveObjectRequestWithContainerName:(NSString *)containerName 
-                                     objectName:(NSString *)objectName 
-                       destinationContainerName:(NSString *)destinationContainerName 
-                          destinationObjectName:(NSString *)destinationObjectName 
-                                  checkIfExists:(BOOL)ifExists {
-    if (ifExists && ![self proceedIfObjectExistsAtContainerName:destinationContainerName objectName:destinationObjectName sharingAccount:nil])
++ (ASIPithosObjectRequest *)moveObjectRequestWithPithos:(ASIPithos *)pithos 
+                                          containerName:(NSString *)containerName 
+                                             objectName:(NSString *)objectName 
+                               destinationContainerName:(NSString *)destinationContainerName 
+                                  destinationObjectName:(NSString *)destinationObjectName 
+                                          checkIfExists:(BOOL)ifExists {
+    if (ifExists && ![self proceedIfObjectExistsAtPithos:pithos containerName:destinationContainerName objectName:destinationObjectName 
+                                          sharingAccount:nil])
         return nil;
     
-    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithContainerName:containerName 
-                                                                                                objectName:objectName 
-                                                                                               contentType:nil 
-                                                                                           contentEncoding:nil 
-                                                                                        contentDisposition:nil 
-                                                                                                  manifest:nil 
-                                                                                                   sharing:nil 
-                                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                                  metadata:nil 
-                                                                                  destinationContainerName:destinationContainerName 
-                                                                                     destinationObjectName:destinationObjectName 
-                                                                                        destinationAccount:nil];
+    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithPithos:pithos 
+                                                                                      containerName:containerName 
+                                                                                         objectName:objectName 
+                                                                                        contentType:nil 
+                                                                                    contentEncoding:nil 
+                                                                                 contentDisposition:nil 
+                                                                                           manifest:nil 
+                                                                                            sharing:nil 
+                                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                                           metadata:nil 
+                                                                           destinationContainerName:destinationContainerName 
+                                                                              destinationObjectName:destinationObjectName 
+                                                                                 destinationAccount:nil];
     objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                               containerName, @"sourceContainerName", 
                               objectName, @"sourceObjectName", 
     return objectRequest;
 }
 
-+ (NSArray *)moveObjectRequestsForSubdirWithContainerName:(NSString *)containerName 
-                                               objectName:(NSString *)objectName 
-                                 destinationContainerName:(NSString *)destinationContainerName 
-                                    destinationObjectName:(NSString *)destinationObjectName 
-                                            checkIfExists:(BOOL)ifExists {
-    if (ifExists && ![self proceedIfObjectExistsAtContainerName:destinationContainerName objectName:destinationObjectName sharingAccount:nil])
++ (NSArray *)moveObjectRequestsForSubdirWithPithos:(ASIPithos *)pithos 
+                                     containerName:(NSString *)containerName 
+                                        objectName:(NSString *)objectName 
+                          destinationContainerName:(NSString *)destinationContainerName 
+                             destinationObjectName:(NSString *)destinationObjectName 
+                                     checkIfExists:(BOOL)ifExists {
+    if (ifExists && ![self proceedIfObjectExistsAtPithos:pithos containerName:destinationContainerName objectName:destinationObjectName 
+                                          sharingAccount:nil])
         return nil;
     
-    NSArray *objects = [self objectsForSubdirWithContainerName:containerName objectName:objectName delimiter:nil sharingAccount:nil];
+    NSArray *objects = [self objectsForSubdirWithPithos:pithos containerName:containerName objectName:objectName 
+                                              delimiter:nil sharingAccount:nil];
     if (objects == nil)
         return nil;
     
     NSMutableArray *objectRequests = [NSMutableArray arrayWithCapacity:([objects count] + 1)];
     if ([objectName isEqualToString:destinationObjectName]) {
         if (![objectName hasSuffix:@"/"]) {
-            objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithContainerName:containerName 
-                                                                                objectName:objectName 
-                                                                               contentType:nil 
-                                                                           contentEncoding:nil 
-                                                                        contentDisposition:nil 
-                                                                                  manifest:nil 
-                                                                                   sharing:nil 
-                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                  metadata:nil 
-                                                                  destinationContainerName:destinationContainerName 
-                                                                     destinationObjectName:objectName 
-                                                                        destinationAccount:nil];
+            objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithPithos:pithos 
+                                                                      containerName:containerName 
+                                                                         objectName:objectName 
+                                                                        contentType:nil 
+                                                                    contentEncoding:nil 
+                                                                 contentDisposition:nil 
+                                                                           manifest:nil 
+                                                                            sharing:nil 
+                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                           metadata:nil 
+                                                           destinationContainerName:destinationContainerName 
+                                                              destinationObjectName:objectName 
+                                                                 destinationAccount:nil];
             objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       containerName, @"sourceContainerName", 
                                       objectName, @"sourceObjectName", 
             [objectRequests addObject:objectRequest];
         }
         for (ASIPithosObject *object in objects) {
-            objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithContainerName:containerName 
-                                                                                objectName:object.name 
-                                                                               contentType:nil 
-                                                                           contentEncoding:nil 
-                                                                        contentDisposition:nil 
-                                                                                  manifest:nil 
-                                                                                   sharing:nil 
-                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                  metadata:nil 
-                                                                  destinationContainerName:destinationContainerName 
-                                                                     destinationObjectName:object.name 
-                                                                        destinationAccount:nil];
+            objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithPithos:pithos 
+                                                                      containerName:containerName 
+                                                                         objectName:object.name 
+                                                                        contentType:nil 
+                                                                    contentEncoding:nil 
+                                                                 contentDisposition:nil 
+                                                                           manifest:nil 
+                                                                            sharing:nil 
+                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                           metadata:nil 
+                                                           destinationContainerName:destinationContainerName 
+                                                              destinationObjectName:object.name 
+                                                                 destinationAccount:nil];
             objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       containerName, @"sourceContainerName", 
                                       object.name, @"sourceObjectName", 
         }
     } else {
         if (![objectName hasSuffix:@"/"]) {
-            objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithContainerName:containerName 
-                                                                                objectName:objectName 
-                                                                               contentType:nil 
-                                                                           contentEncoding:nil 
-                                                                        contentDisposition:nil 
-                                                                                  manifest:nil 
-                                                                                   sharing:nil 
-                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                  metadata:nil 
-                                                                  destinationContainerName:destinationContainerName 
-                                                                     destinationObjectName:destinationObjectName 
-                                                                        destinationAccount:nil];
+            objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithPithos:pithos 
+                                                                      containerName:containerName 
+                                                                         objectName:objectName 
+                                                                        contentType:nil 
+                                                                    contentEncoding:nil 
+                                                                 contentDisposition:nil 
+                                                                           manifest:nil 
+                                                                            sharing:nil 
+                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                           metadata:nil 
+                                                           destinationContainerName:destinationContainerName 
+                                                              destinationObjectName:destinationObjectName 
+                                                                 destinationAccount:nil];
             objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       containerName, @"sourceContainerName", 
                                       objectName, @"sourceObjectName", 
                                                                    withString:destinationObjectName
                                                                       options:NSAnchoredSearch
                                                                         range:prefixRange];
-            objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithContainerName:containerName 
-                                                                                objectName:object.name
-                                                                               contentType:nil 
-                                                                           contentEncoding:nil 
-                                                                        contentDisposition:nil 
-                                                                                  manifest:nil 
-                                                                                   sharing:nil 
-                                                                                  isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                  metadata:nil 
-                                                                  destinationContainerName:destinationContainerName 
-                                                                     destinationObjectName:newObjectName 
-                                                                        destinationAccount:nil];
+            objectRequest = [ASIPithosObjectRequest moveObjectDataRequestWithPithos:pithos 
+                                                                      containerName:containerName 
+                                                                         objectName:object.name
+                                                                        contentType:nil 
+                                                                    contentEncoding:nil 
+                                                                 contentDisposition:nil 
+                                                                           manifest:nil 
+                                                                            sharing:nil 
+                                                                           isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                           metadata:nil 
+                                                           destinationContainerName:destinationContainerName 
+                                                              destinationObjectName:newObjectName 
+                                                                 destinationAccount:nil];
             objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       containerName, @"sourceContainerName", 
                                       object.name, @"sourceObjectName", 
 + (NSUInteger)bytesOfFile:(NSString *)filePath {
     NSFileManager *fileManager = [NSFileManager defaultManager];
     NSDictionary *attributes = [fileManager attributesOfItemAtPath:filePath error:nil];
-    return [[attributes objectForKey:NSFileSize] intValue];
+    return [[attributes objectForKey:NSFileSize] unsignedIntegerValue];
 }
 
 // Content type of the file or nil if it cannot be determined
     return [response MIMEType];
 }
 
+// Creates a directory if it doesn't exist and returns if successful
++ (BOOL)safeCreateDirectory:(NSString *)directoryPath error:(NSError **)error {
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    BOOL isDirectory;
+    BOOL fileExists = [fileManager fileExistsAtPath:directoryPath isDirectory:&isDirectory];
+    if (fileExists)
+        return isDirectory;
+    if (![fileManager createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:error] || *error)
+        return NO;
+    return YES;
+}
+
+// Removes contents of a directory
++ (void)removeContentsAtPath:(NSString *)dirPath {
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    NSError *error = nil;
+    BOOL isDirectory;
+    if (![fileManager fileExistsAtPath:dirPath isDirectory:&isDirectory])
+        return;
+    if (isDirectory) {
+        for (NSString *subPath in [fileManager contentsOfDirectoryAtPath:dirPath error:&error]) {
+            if (error) {
+                [self fileActionFailedAlertWithTitle:@"Directory Contents Error" 
+                                             message:[NSString stringWithFormat:@"Cannot get contents of directory at '%@'", dirPath] 
+                                               error:error];
+                break;
+            }
+            NSString *subFilePath = [dirPath stringByAppendingPathComponent:subPath];
+            if (![fileManager removeItemAtPath:subFilePath error:&error] || error) {
+                [self fileActionFailedAlertWithTitle:@"Remove File Error" 
+                                             message:[NSString stringWithFormat:@"Cannot remove file at '%@'", subFilePath] 
+                                               error:error];
+            }
+            error = nil;
+        }
+    } else if (![fileManager removeItemAtPath:dirPath error:&error] || error) {
+        [self fileActionFailedAlertWithTitle:@"Remove File Error" 
+                                     message:[NSString stringWithFormat:@"Cannot remove file at '%@'", dirPath] 
+                                       error:error];
+    }
+}
+
+// Returns if an object is a directory based on its content type
++ (BOOL)isContentTypeDirectory:(NSString *)contentType {
+    return ([contentType isEqualToString:@"application/directory"] ||
+            [contentType hasPrefix:@"application/directory;"] ||
+            [contentType isEqualToString:@"application/folder"] ||
+            [contentType hasPrefix:@"application/folder;"]);
+}
+
 // Returns if an object exists at the given container/object path and if this object is an application/directory
 // If an error occured an alert is shown and it is returned so the caller won't proceed
-+ (BOOL)objectExistsAtContainerName:(NSString *)containerName objectName:(NSString *)objectName 
-                              error:(NSError **)error isDirectory:(BOOL *)isDirectory 
-                     sharingAccount:(NSString *)sharingAccount {
-    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectMetadataRequestWithContainerName:containerName 
-                                                                                                objectName:objectName];
++ (BOOL)objectExistsAtPithos:(ASIPithos *)pithos containerName:(NSString *)containerName objectName:(NSString *)objectName 
+                       error:(NSError **)error isDirectory:(BOOL *)isDirectory sharingAccount:(NSString *)sharingAccount {
+    ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectMetadataRequestWithPithos:pithos 
+                                                                                      containerName:containerName 
+                                                                                         objectName:objectName];
     if (sharingAccount)
-        [objectRequest setRequestUserFromDefaultTo:sharingAccount];
-    [[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
-    while (![objectRequest isFinished]) {
-        sleep(1);
-    }
+        [objectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
+    ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
+    [networkQueue go];
+    [networkQueue addOperations:[NSArray arrayWithObject:[self prepareRequest:objectRequest]] waitUntilFinished:YES];
     *error = [objectRequest error];
     if (*error) {
         [self httpRequestErrorAlertWithRequest:objectRequest];
         return NO;
     } else if (objectRequest.responseStatusCode == 200) {
-        *isDirectory = [[objectRequest contentType] isEqualToString:@"application/directory"];
+        *isDirectory = [self isContentTypeDirectory:[objectRequest contentType]];
         return YES;
     }
     return NO;
 }
 
-// Returns if the called should proceed, after an interactive check if an object exists 
+// Returns if the caller should proceed, after an interactive check if an object exists 
 // at the given container/object path is performed
-+ (BOOL)proceedIfObjectExistsAtContainerName:(NSString *)containerName objectName:(NSString *)objectName 
-                              sharingAccount:(NSString *)sharingAccount {
++ (BOOL)proceedIfObjectExistsAtPithos:(ASIPithos *)pithos containerName:(NSString *)containerName objectName:(NSString *)objectName 
+                       sharingAccount:(NSString *)sharingAccount {
     NSError *error = nil;
     BOOL isDirectory;
-    BOOL objectExists = [self objectExistsAtContainerName:containerName 
-                                               objectName:objectName
-                                                    error:&error 
-                                              isDirectory:&isDirectory 
-                                           sharingAccount:sharingAccount];
+    BOOL objectExists = [self objectExistsAtPithos:pithos containerName:containerName objectName:objectName 
+                                             error:&error isDirectory:&isDirectory sharingAccount:sharingAccount];
     if (error) {
         return NO;
     } else if (objectExists) {
     return YES;
 }
 
-
 // List of objects at the given container/object path, with prefix and or delimiter
-+ (NSArray *)objectsWithContainerName:(NSString *)containerName objectNamePrefix:(NSString *)objectNamePrefix 
-                            delimiter:(NSString *)delimiter sharingAccount:(NSString *)sharingAccount {
++ (NSArray *)objectsWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName objectNamePrefix:(NSString *)objectNamePrefix 
+                     delimiter:(NSString *)delimiter sharingAccount:(NSString *)sharingAccount {
     NSMutableArray *objects = [NSMutableArray array];
     NSString *marker = nil;
     do {
-        ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest listObjectsRequestWithContainerName:containerName 
-                                                                                                               limit:0 
-                                                                                                              marker:marker 
-                                                                                                              prefix:objectNamePrefix 
-                                                                                                           delimiter:delimiter 
-                                                                                                                path:nil 
-                                                                                                                meta:nil 
-                                                                                                              shared:NO 
-                                                                                                               until:nil];
+        ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest listObjectsRequestWithPithos:pithos 
+                                                                                                containerName:containerName 
+                                                                                                        limit:0 
+                                                                                                       marker:marker 
+                                                                                                       prefix:objectNamePrefix 
+                                                                                                    delimiter:delimiter 
+                                                                                                         path:nil 
+                                                                                                         meta:nil 
+                                                                                                       shared:NO 
+                                                                                                        until:nil];
         if (sharingAccount)
-            [containerRequest setRequestUserFromDefaultTo:sharingAccount];
-        [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
-        while (![containerRequest isFinished]) {
-            sleep(1);
-        }
+            [containerRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
+        ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
+        [networkQueue go];
+        [networkQueue addOperations:[NSArray arrayWithObject:[self prepareRequest:containerRequest]] waitUntilFinished:YES];
         if ([containerRequest error]) {
             [self httpRequestErrorAlertWithRequest:containerRequest];
             return nil;
 
 // List of objects at the given container/object path, that may be a subdir or an application/directory, 
 // with prefix and or delimiter
-+ (NSArray *)objectsForSubdirWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
-                                     delimiter:(NSString *)delimiter sharingAccount:(NSString *)sharingAccount {
++ (NSArray *)objectsForSubdirWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName objectName:(NSString *)objectName 
+                              delimiter:(NSString *)delimiter sharingAccount:(NSString *)sharingAccount {
     NSString *subdirNamePrefix = [NSString stringWithString:objectName];
     if (![subdirNamePrefix hasSuffix:@"/"])
         subdirNamePrefix = [subdirNamePrefix stringByAppendingString:@"/"];
-    return [self objectsWithContainerName:containerName objectNamePrefix:subdirNamePrefix 
-                                delimiter:delimiter sharingAccount:sharingAccount];
+    return [self objectsWithPithos:pithos containerName:containerName objectNamePrefix:subdirNamePrefix 
+                         delimiter:delimiter sharingAccount:sharingAccount];
 }
 
 // A safe object name at the given container/object path
 // The original name has " %d" appended to it before any ".*" suffix, for the first integer that produces a name that is free to use
 // If the original name hasn't got a "." but has a "/" suffix, then it is replaced with " %d/" instead
 // Subdirs are taken into consideration
-+ (NSString *)safeObjectNameForContainerName:(NSString *)containerName objectName:(NSString *)objectName {
++ (NSString *)safeObjectNameForPithos:(ASIPithos *)pithos containerName:(NSString *)containerName objectName:(NSString *)objectName {
     NSString *objectNamePrefix;
     NSString *objectNameExtraSuffix;
     NSRange lastDotRange = [objectName rangeOfString:@"." options:NSBackwardsSearch];
         objectNamePrefix = [NSString stringWithString:objectName];
         objectNameExtraSuffix = [NSString string];
     }
-    NSArray *objects = [self objectsWithContainerName:containerName 
-                                     objectNamePrefix:[objectNamePrefix stringByDeletingLastPathComponent] 
-                                            delimiter:@"/" 
-                                       sharingAccount:nil];
+    NSArray *objects = [self objectsWithPithos:pithos containerName:containerName 
+                              objectNamePrefix:[objectNamePrefix stringByDeletingLastPathComponent] 
+                                     delimiter:@"/" sharingAccount:nil];
     if (objects == nil)
         return nil;
     if ([objects count] == 0)
 // The original name has " %d" appended to it, for the first integer that produces a name that is free to use
 // If the original name has a "/" suffix, then it is replaced with " %d/" instead
 // Subdirs are taken into consideration
-+ (NSString *)safeSubdirNameForContainerName:(NSString *)containerName subdirName:(NSString *)subdirName {
++ (NSString *)safeSubdirNameForPithos:(ASIPithos *)pithos containerName:(NSString *)containerName subdirName:(NSString *)subdirName {
     NSString *subdirNamePrefix;
     NSString *subdirNameExtraSuffix;
     if ([subdirName hasSuffix:@"/"]) {
         subdirNamePrefix = [NSString stringWithString:subdirName];
         subdirNameExtraSuffix = [NSString string];
     }
-    NSArray *objects = [self objectsWithContainerName:containerName 
-                                     objectNamePrefix:[subdirNamePrefix stringByDeletingLastPathComponent] 
-                                            delimiter:@"/" 
-                                       sharingAccount:nil];
+    NSArray *objects = [self objectsWithPithos:pithos containerName:containerName 
+                              objectNamePrefix:[subdirNamePrefix stringByDeletingLastPathComponent] 
+                                     delimiter:@"/" sharingAccount:nil];
     if (objects == nil)
         return nil;
     if ([objects count] == 0)
 }
 
 + (ASIPithosRequest *)copyRequest:(ASIPithosRequest *)request {
-    NSMutableDictionary *userInfo = [[request.userInfo retain] autorelease];
+    NSMutableDictionary *userInfo = (NSMutableDictionary *)[[request.userInfo retain] autorelease];
     request.userInfo = nil;
     ASIPithosRequest *newRequest = [request copy];
     newRequest.userInfo = userInfo;