Fix bug in sync daemon when deleting locally objects from different containers/accoun...
[pithos-macos] / pithos-macos / PithosSyncDaemon.m
index 841f6f9..442bf7e 100644 (file)
@@ -96,7 +96,7 @@
             resetLocalState:(BOOL)resetLocalState {
     if ((self = [super init])) {
         directoryPath = [aDirectoryPath copy];
-        pithosAccount = [aPithosAccount retain];
+        pithosAccount = aPithosAccount;
         self.accountsDictionary = anAccountsDictionary;
         skipHidden = aSkipHidden;
         self.pithos = pithosAccount.pithos;        
 }
 
 - (void)loadLocalState {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    if ([[NSFileManager defaultManager] fileExistsAtPath:self.pithosStateFilePath])
-        self.storedLocalObjectStates = [NSKeyedUnarchiver unarchiveObjectWithFile:self.pithosStateFilePath];
-    else
-        self.storedLocalObjectStates = [NSMutableDictionary dictionary];
-    if (!storedLocalObjectStates)
-        self.storedLocalObjectStates = [NSMutableDictionary dictionary];
-    for (NSString *accountName in accountsNames) {
-        NSMutableDictionary *accountStoredLocalObjectStates = [storedLocalObjectStates objectForKey:accountName];
-        if (!accountStoredLocalObjectStates) {
-            accountStoredLocalObjectStates = [NSMutableDictionary dictionary];
-            [storedLocalObjectStates setObject:accountStoredLocalObjectStates forKey:accountName];
-        }
-        for (ASIPithosContainer *pithosContainer in [accountsPithosContainers objectForKey:accountName]) {
-            if (![accountStoredLocalObjectStates objectForKey:pithosContainer.name])
-                [accountStoredLocalObjectStates setObject:[NSMutableDictionary dictionary] forKey:pithosContainer.name];
+    @autoreleasepool {
+        if ([[NSFileManager defaultManager] fileExistsAtPath:self.pithosStateFilePath])
+            self.storedLocalObjectStates = [NSKeyedUnarchiver unarchiveObjectWithFile:self.pithosStateFilePath];
+        else
+            self.storedLocalObjectStates = [NSMutableDictionary dictionary];
+        if (!storedLocalObjectStates)
+            self.storedLocalObjectStates = [NSMutableDictionary dictionary];
+        for (NSString *accountName in accountsNames) {
+            NSMutableDictionary *accountStoredLocalObjectStates = [storedLocalObjectStates objectForKey:accountName];
+            if (!accountStoredLocalObjectStates) {
+                accountStoredLocalObjectStates = [NSMutableDictionary dictionary];
+                [storedLocalObjectStates setObject:accountStoredLocalObjectStates forKey:accountName];
+            }
+            for (ASIPithosContainer *pithosContainer in [accountsPithosContainers objectForKey:accountName]) {
+                if (![accountStoredLocalObjectStates objectForKey:pithosContainer.name])
+                    [accountStoredLocalObjectStates setObject:[NSMutableDictionary dictionary] forKey:pithosContainer.name];
+            }
         }
     }
-    [pool drain];
 }
 
 - (void)resetLocalStateWithAll:(BOOL)all {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    self.lastCompletedSync = nil;
-    if (all) {
-        self.storedLocalObjectStates = [NSMutableDictionary dictionary];
-        [self saveLocalState]; // Save an empty dictionary
-        [self loadLocalState]; // Load to populate with containers
-        [self saveLocalState]; // Save again
-        if (self.tempDownloadsDirPath)
-            [PithosUtilities removeContentsAtPath:self.tempDownloadsDirPath];
-    } else {
-        // Remove containers that don't interest us anymore and save
-        if (!storedLocalObjectStates)
-            [self loadLocalState];
-        for (NSString *accountName in storedLocalObjectStates) {
-            NSMutableDictionary *accountStoredLocalObjectStates = [storedLocalObjectStates objectForKey:accountName];
-            NSDictionary *containersDictionary = [accountsDictionary objectForKey:accountName];
-            if (!containersDictionary) {
-                if (self.tempDownloadsDirPath) {
-                    if ([accountName isEqualToString:@""]) {
-                        for (NSString *containerName in accountStoredLocalObjectStates) {
-                            [PithosUtilities removeContentsAtPath:[self.tempDownloadsDirPath stringByAppendingPathComponent:containerName]];
+    @autoreleasepool {
+        self.lastCompletedSync = nil;
+        if (all) {
+            self.storedLocalObjectStates = [NSMutableDictionary dictionary];
+            [self saveLocalState]; // Save an empty dictionary
+            [self loadLocalState]; // Load to populate with containers
+            [self saveLocalState]; // Save again
+            if (self.tempDownloadsDirPath)
+                [PithosUtilities removeContentsAtPath:self.tempDownloadsDirPath];
+        } else {
+            // Remove containers that don't interest us anymore and save
+            if (!storedLocalObjectStates)
+                [self loadLocalState];
+            for (NSString *accountName in storedLocalObjectStates) {
+                NSMutableDictionary *accountStoredLocalObjectStates = [storedLocalObjectStates objectForKey:accountName];
+                NSDictionary *containersDictionary = [accountsDictionary objectForKey:accountName];
+                if (!containersDictionary) {
+                    if (self.tempDownloadsDirPath) {
+                        if ([accountName isEqualToString:@""]) {
+                            for (NSString *containerName in accountStoredLocalObjectStates) {
+                                [PithosUtilities removeContentsAtPath:[self.tempDownloadsDirPath stringByAppendingPathComponent:containerName]];
+                            }
+                        } else {
+                            [PithosUtilities removeContentsAtPath:[[self.tempDownloadsDirPath stringByAppendingPathComponent:@"shared with me"]
+                                                                   stringByAppendingPathComponent:accountName]];
                         }
-                    } else {
-                        [PithosUtilities removeContentsAtPath:[[self.tempDownloadsDirPath stringByAppendingPathComponent:@"shared to me"] 
-                                                               stringByAppendingPathComponent:accountName]];
                     }
-                }
-                [storedLocalObjectStates removeObjectForKey:accountName];
-            } else {
-                // Check the account's containers
-                for (NSString *containerName in accountStoredLocalObjectStates) {
-                    if (![containersDictionary objectForKey:containerName]) {
-                        if ([accountName isEqualToString:@""])
-                            [PithosUtilities removeContentsAtPath:[self.tempDownloadsDirPath stringByAppendingPathComponent:containerName]];
-                        else
-                            [PithosUtilities removeContentsAtPath:[[[self.tempDownloadsDirPath stringByAppendingPathComponent:@"shared to me"] 
-                                                                    stringByAppendingPathComponent:accountName] 
-                                                                   stringByAppendingPathComponent:containerName]];
-                        [accountStoredLocalObjectStates removeObjectForKey:containerName];
+                    [storedLocalObjectStates removeObjectForKey:accountName];
+                } else {
+                    // Check the account's containers
+                    for (NSString *containerName in accountStoredLocalObjectStates) {
+                        if (![containersDictionary objectForKey:containerName]) {
+                            if ([accountName isEqualToString:@""])
+                                [PithosUtilities removeContentsAtPath:[self.tempDownloadsDirPath stringByAppendingPathComponent:containerName]];
+                            else
+                                [PithosUtilities removeContentsAtPath:[[[self.tempDownloadsDirPath stringByAppendingPathComponent:@"shared with me"]
+                                                                        stringByAppendingPathComponent:accountName] 
+                                                                       stringByAppendingPathComponent:containerName]];
+                            [accountStoredLocalObjectStates removeObjectForKey:containerName];
+                        }
                     }
                 }
             }
+            [self saveLocalState];
         }
-        [self saveLocalState];
     }
-    [pool drain];
 }
 
 - (void)saveLocalState {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    [NSKeyedArchiver archiveRootObject:storedLocalObjectStates toFile:self.pithosStateFilePath];
-    [pool drain];
+    @autoreleasepool {
+        [NSKeyedArchiver archiveRootObject:storedLocalObjectStates toFile:self.pithosStateFilePath];
+    }
 }
 
 - (void)resetDaemon {
 - (void)dealloc {
     [[NSNotificationCenter defaultCenter] removeObserver:self];
     [self resetDaemon];
-    [callbackQueue release];
-    [networkQueue release];
-    [tempTrashDirPath release];
-    [tempDownloadsDirPath release];
-    [pithosStateFilePath release];
-    [currentLocalObjectStates release];
-    [storedLocalObjectStates release];
-    [previousRemoteObjects release];
-    [remoteObjects release];
-    [objects release];
-    [lastCompletedSync release];
-    [accountsPithosContainers release];
-    [accountsNames release];
-    [pithos release];
-    [accountsDictionary release];
-    [pithosAccount release];
-    [directoryPath release];
-    [super dealloc];
 }
 
 #pragma mark -
 
 - (NSString *)pithosStateFilePath {
     if (!pithosStateFilePath) {
-        pithosStateFilePath = [[[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
+        pithosStateFilePath = [[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
                                  stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]] 
                                 stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-PithosLocalObjectStates.archive", 
-                                                                pithosAccount.uniqueName]] retain];
+                                                                pithosAccount.uniqueName]];
         NSString *pithosStateFileDirPath = [pithosStateFilePath stringByDeletingLastPathComponent];
         NSFileManager *fileManager = [NSFileManager defaultManager];
         BOOL isDirectory;
         //  pithosStateFilePath = nil;
         // XXX create a dir using mktmps?
     }
-    return [[pithosStateFilePath copy] autorelease];
+    return [pithosStateFilePath copy];
 }
 
 - (NSString *)tempDownloadsDirPath {
     if (!tempDownloadsDirPath) {
-        tempDownloadsDirPath = [[[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
+        tempDownloadsDirPath = [[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
                                   stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]] 
                                  stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-TempDownloads", 
-                                                                 pithosAccount.uniqueName]] retain];
+                                                                 pithosAccount.uniqueName]];
         NSFileManager *fileManager = [NSFileManager defaultManager];
         BOOL isDirectory;
         BOOL fileExists = [fileManager fileExistsAtPath:tempDownloadsDirPath isDirectory:&isDirectory];
 
 - (NSString *)tempTrashDirPath {
     if (!tempTrashDirPath) {
-        tempTrashDirPath = [[[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
+        tempTrashDirPath = [[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] 
                                   stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]] 
                                  stringByAppendingPathComponent:[NSString stringWithFormat:@"%@-TempTrash", 
-                                                                 pithosAccount.uniqueName]] retain];
+                                                                 pithosAccount.uniqueName]];
         NSFileManager *fileManager = [NSFileManager defaultManager];
         BOOL isDirectory;
         BOOL fileExists = [fileManager fileExistsAtPath:tempTrashDirPath isDirectory:&isDirectory];
     if (aDirectoryPath && ![aDirectoryPath isEqualToString:directoryPath]) {
         [self resetDaemon];
         [self resetLocalStateWithAll:YES];
-        [directoryPath release];
         directoryPath = [aDirectoryPath copy];
     }
 }
         if (reset)
             [self resetDaemon];
         
-        [accountsDictionary release];
         accountsDictionary = [anAccountsDictionary copy];
         
         accountsCount = [accountsDictionary count];
 
 - (void)setPithos:(ASIPithos *)aPithos {
     if (!pithos) {
-        pithos = [[ASIPithos pithos] retain];
-        pithos.authUser = [[aPithos.authUser copy] autorelease];
-        pithos.authToken = [[aPithos.authToken copy] autorelease];
-        pithos.storageURLPrefix = [[aPithos.storageURLPrefix copy] autorelease];
-        pithos.authURL = [[aPithos.authURL copy] autorelease];
-        pithos.publicURLPrefix = [[aPithos.publicURLPrefix copy] autorelease];
+        pithos = [ASIPithos pithos];
+        pithos.authUser = [aPithos.authUser copy];
+        pithos.authToken = [aPithos.authToken copy];
+        pithos.storageURLPrefix = [aPithos.storageURLPrefix copy];
+        pithos.authURL = [aPithos.authURL copy];
+        pithos.publicURLPrefix = [aPithos.publicURLPrefix copy];
+        pithos.userCatalogURL = [aPithos.userCatalogURL copy];
     }
     if (aPithos && 
         (![aPithos.authUser isEqualToString:pithos.authUser] || 
         if (![aPithos.authUser isEqualToString:pithos.authUser] || 
             ![aPithos.storageURLPrefix isEqualToString:pithos.storageURLPrefix])
             [self resetLocalStateWithAll:YES];
-        pithos.authUser = [[aPithos.authUser copy] autorelease];
-        pithos.authToken = [[aPithos.authToken copy] autorelease];
-        pithos.storageURLPrefix = [[aPithos.storageURLPrefix copy] autorelease];
-        pithos.authURL = [[aPithos.authURL copy] autorelease];
-        pithos.publicURLPrefix = [[aPithos.publicURLPrefix copy] autorelease];
-    }        
+        pithos.authUser = [aPithos.authUser copy];
+        pithos.authToken = [aPithos.authToken copy];
+        pithos.storageURLPrefix = [aPithos.storageURLPrefix copy];
+        pithos.authURL = [aPithos.authURL copy];
+        pithos.publicURLPrefix = [aPithos.publicURLPrefix copy];
+        pithos.userCatalogURL = [aPithos.userCatalogURL copy];
+    }
 }
 
 #pragma mark -
     if ([accountName isEqualToString:@""])
         return [directoryPath stringByAppendingPathComponent:containerName];
     else
-        return [[[directoryPath stringByAppendingPathComponent:@"shared to me"] 
+        return [[[directoryPath stringByAppendingPathComponent:@"shared with me"]
                  stringByAppendingPathComponent:accountName] 
                 stringByAppendingPathComponent:containerName];
 }
     if ([accountName isEqualToString:@""])
         return containerName;
     else
-        return [[[NSString stringWithString:@"shared to me"] 
-                 stringByAppendingPathComponent:accountName] 
-                stringByAppendingPathComponent:containerName];    
+        return [[@"shared with me" stringByAppendingPathComponent:accountName] stringByAppendingPathComponent:containerName];
 }
 
 #pragma mark -
 }
 
 - (void)emptyTempTrash {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSString *trashDirPath = self.tempTrashDirPath;
-    if (trashDirPath) {
-        NSFileManager *fileManager = [NSFileManager defaultManager];
-        NSError *error = nil;
-//        NSArray *subPaths = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:trashDirPath error:&error];
-        NSArray *subPaths = [fileManager contentsOfDirectoryAtPath:trashDirPath error:&error];
-        if (error) {
-            [PithosUtilities fileActionFailedAlertWithTitle:@"Directory Contents Error" 
-                                                    message:[NSString stringWithFormat:@"Cannot get contents of directory at '%@'", trashDirPath] 
-                                                      error:error];
-            [pool drain];
-            return;
-        }
-        if ([subPaths count]) {
-//            NSMutableArray *subURLs = [NSMutableArray arrayWithCapacity:[subPaths count]];
-//            for (NSString *subPath in subPaths) {
-//                [subURLs addObject:[NSURL fileURLWithPath:[trashDirPath stringByAppendingPathComponent:subPath]]];
-//            }
-//            [self syncOperationStarted];
-//            [[NSWorkspace sharedWorkspace] recycleURLs:subURLs completionHandler:^(NSDictionary *newURLs, NSError *error) {
-//                if (error) {
-//                    [PithosUtilities fileActionFailedAlertWithTitle:@"Move to Trash Error" 
-//                                                            message:@"Cannot move files to Trash" 
-//                                                              error:error];
-//                }
-//                [self syncOperationFinishedWithSuccess:YES];
-//            }];
-            for (NSString *subPath in subPaths) {
-                NSString *subFilePath = [trashDirPath stringByAppendingPathComponent:subPath];
-                error = nil;
-                if (![fileManager removeItemAtPath:subFilePath error:&error] || error)
-                    [PithosUtilities fileActionFailedAlertWithTitle:@"Remove File Error" 
-                                                            message:[NSString stringWithFormat:@"Cannot remove file at '%@'", subFilePath] 
-                                                              error:error];
+    @autoreleasepool {
+        NSString *trashDirPath = self.tempTrashDirPath;
+        if (trashDirPath) {
+            NSFileManager *fileManager = [NSFileManager defaultManager];
+            NSError *error = nil;
+//          NSArray *subPaths = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:trashDirPath error:&error];
+            NSArray *subPaths = [fileManager contentsOfDirectoryAtPath:trashDirPath error:&error];
+            if (error) {
+                [PithosUtilities fileActionFailedAlertWithTitle:@"Directory Contents Error" 
+                                                        message:[NSString stringWithFormat:@"Cannot get contents of directory at '%@'", trashDirPath] 
+                                                          error:error];
+                return;
+            }
+            if ([subPaths count]) {
+//              NSMutableArray *subURLs = [NSMutableArray arrayWithCapacity:[subPaths count]];
+//              for (NSString *subPath in subPaths) {
+//                  [subURLs addObject:[NSURL fileURLWithPath:[trashDirPath stringByAppendingPathComponent:subPath]]];
+//              }
+//              [self syncOperationStarted];
+//              [[NSWorkspace sharedWorkspace] recycleURLs:subURLs completionHandler:^(NSDictionary *newURLs, NSError *error) {
+//                  if (error) {
+//                      [PithosUtilities fileActionFailedAlertWithTitle:@"Move to Trash Error"
+//                                                              message:@"Cannot move files to Trash"
+//                                                                  error:error];
+//                  }
+//                  [self syncOperationFinishedWithSuccess:YES];
+//              }];
+                for (NSString *subPath in subPaths) {
+                    NSString *subFilePath = [trashDirPath stringByAppendingPathComponent:subPath];
+                    error = nil;
+                    if (![fileManager removeItemAtPath:subFilePath error:&error] || error)
+                        [PithosUtilities fileActionFailedAlertWithTitle:@"Remove File Error" 
+                                                                message:[NSString stringWithFormat:@"Cannot remove file at '%@'", subFilePath] 
+                                                                  error:error];
+                }
             }
         }
     }
-    [pool drain];
 }
 
 - (BOOL)moveToTempTrashFile:(NSString *)filePath 
                 accountName:(NSString *)accountName 
             pithosContainer:(ASIPithosContainer *)pithosContainer {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    if (!self.tempTrashDirPath) {
-        [pool drain];
-        return NO;
-    }
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    BOOL isDirectory;
-    BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
-    NSError *error = nil;
-    NSString *containerDirectoryPath = [self dirPathForAccount:accountName container:pithosContainer.name];
-    NSString *newFilePath = [filePath stringByReplacingOccurrencesOfString:containerDirectoryPath withString:self.tempTrashDirPath];
-    NSString *newDirPath = [newFilePath stringByDeletingLastPathComponent];
-    if (fileExists && isDirectory) {
-        NSArray *subPaths = [fileManager subpathsOfDirectoryAtPath:filePath error:&error];
-        if (error) {
-            [PithosUtilities fileActionFailedAlertWithTitle:@"Directory Contents Error" 
-                                                    message:[NSString stringWithFormat:@"Cannot get contents of directory at '%@'", filePath] 
-                                                      error:error];
-            [pool drain];
-            return NO;
-        }
-        if (![fileManager createDirectoryAtPath:newDirPath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
-            [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
-                                                    message:[NSString stringWithFormat:@"Cannot create directory at '%@'", newDirPath] 
-                                                      error:error];
-            [pool drain];
-            return NO;
-        }
-        if (![fileManager moveItemAtPath:filePath toPath:newFilePath error:&error] || error) {
-            [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
-                                                    message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", 
-                                                             filePath, newFilePath] 
-                                                      error:error];
-            [pool drain];
+    @autoreleasepool {
+        if (!self.tempTrashDirPath)
             return NO;
-        }
-        PithosLocalObjectState *currentState = [currentLocalObjectStates objectForKey:filePath];
-        if (currentState) {
-            currentState.filePath = newFilePath;
-            [currentLocalObjectStates setObject:currentState forKey:newFilePath];
-            [currentLocalObjectStates removeObjectForKey:filePath];        
-        } else {
-            [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newFilePath 
-                                                                                       blockHash:pithosContainer.blockHash 
-                                                                                       blockSize:pithosContainer.blockSize] 
-                                         forKey:newFilePath];
-        }
-        for (NSString *subPath in subPaths) {
-            NSString *subFilePath = [filePath stringByAppendingPathComponent:subPath];
-            NSString *newSubFilePath = [subFilePath stringByReplacingOccurrencesOfString:containerDirectoryPath 
-                                                                              withString:self.tempTrashDirPath];
-            currentState = [currentLocalObjectStates objectForKey:subFilePath];
+        NSFileManager *fileManager = [NSFileManager defaultManager];
+        BOOL isDirectory;
+        BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
+        NSError *error = nil;
+        NSString *newFilePath = [filePath stringByReplacingOccurrencesOfString:directoryPath withString:self.tempTrashDirPath];
+        NSString *newDirPath = [newFilePath stringByDeletingLastPathComponent];
+        if (fileExists && isDirectory) {
+            NSArray *subPaths = [fileManager subpathsOfDirectoryAtPath:filePath error:&error];
+            if (error) {
+                [PithosUtilities fileActionFailedAlertWithTitle:@"Directory Contents Error" 
+                                                        message:[NSString stringWithFormat:@"Cannot get contents of directory at '%@'", filePath] 
+                                                          error:error];
+                return NO;
+            }
+            if (![fileManager createDirectoryAtPath:newDirPath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
+                [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
+                                                        message:[NSString stringWithFormat:@"Cannot create directory at '%@'", newDirPath] 
+                                                          error:error];
+                return NO;
+            }
+            if (![fileManager moveItemAtPath:filePath toPath:newFilePath error:&error] || error) {
+                [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
+                                                        message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", 
+                                                                 filePath, newFilePath] 
+                                                          error:error];
+                return NO;
+            }
+            PithosLocalObjectState *currentState = [currentLocalObjectStates objectForKey:filePath];
             if (currentState) {
-                currentState.filePath = newSubFilePath;
-                [currentLocalObjectStates setObject:currentState forKey:newSubFilePath];
-                [currentLocalObjectStates removeObjectForKey:subFilePath];
+                currentState.filePath = newFilePath;
+                [currentLocalObjectStates setObject:currentState forKey:newFilePath];
+                [currentLocalObjectStates removeObjectForKey:filePath];        
             } else {
-                [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newSubFilePath 
+                [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newFilePath 
                                                                                            blockHash:pithosContainer.blockHash 
                                                                                            blockSize:pithosContainer.blockSize] 
-                                             forKey:newSubFilePath];
-            }        
-        }
-    } else if (fileExists && !isDirectory) {
-        if (![fileManager createDirectoryAtPath:newDirPath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
-            [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
-                                                    message:[NSString stringWithFormat:@"Cannot create directory at '%@'", newDirPath] 
-                                                      error:error];
-            [pool drain];
-            return NO;
-        }
-        if (![fileManager moveItemAtPath:filePath toPath:newFilePath error:&error] || error) {
-            [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
-                                                    message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", 
-                                                             filePath, newFilePath] 
-                                                      error:error];
-            [pool drain];
-            return NO;
-        }
-        PithosLocalObjectState *currentState = [currentLocalObjectStates objectForKey:filePath];
-        if (currentState) {
-            currentState.filePath = newFilePath;
-            [currentLocalObjectStates setObject:currentState forKey:newFilePath];
-            [currentLocalObjectStates removeObjectForKey:filePath];        
-        } else {
-            [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newFilePath 
-                                                                                       blockHash:pithosContainer.blockHash 
-                                                                                       blockSize:pithosContainer.blockSize] 
-                                         forKey:newFilePath];
+                                             forKey:newFilePath];
+            }
+            for (NSString *subPath in subPaths) {
+                NSString *subFilePath = [filePath stringByAppendingPathComponent:subPath];
+                NSString *newSubFilePath = [subFilePath stringByReplacingOccurrencesOfString:directoryPath
+                                                                                  withString:self.tempTrashDirPath];
+                currentState = [currentLocalObjectStates objectForKey:subFilePath];
+                if (currentState) {
+                    currentState.filePath = newSubFilePath;
+                    [currentLocalObjectStates setObject:currentState forKey:newSubFilePath];
+                    [currentLocalObjectStates removeObjectForKey:subFilePath];
+                } else {
+                    [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newSubFilePath 
+                                                                                               blockHash:pithosContainer.blockHash 
+                                                                                               blockSize:pithosContainer.blockSize] 
+                                                 forKey:newSubFilePath];
+                }        
+            }
+        } else if (fileExists && !isDirectory) {
+            if (![fileManager createDirectoryAtPath:newDirPath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
+                [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
+                                                        message:[NSString stringWithFormat:@"Cannot create directory at '%@'", newDirPath] 
+                                                          error:error];
+                return NO;
+            }
+            if (![fileManager moveItemAtPath:filePath toPath:newFilePath error:&error] || error) {
+                [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
+                                                        message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", 
+                                                                 filePath, newFilePath] 
+                                                          error:error];
+                return NO;
+            }
+            PithosLocalObjectState *currentState = [currentLocalObjectStates objectForKey:filePath];
+            if (currentState) {
+                currentState.filePath = newFilePath;
+                [currentLocalObjectStates setObject:currentState forKey:newFilePath];
+                [currentLocalObjectStates removeObjectForKey:filePath];        
+            } else {
+                [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:newFilePath 
+                                                                                           blockHash:pithosContainer.blockHash 
+                                                                                           blockSize:pithosContainer.blockSize] 
+                                             forKey:newFilePath];
+            }
         }
     }
-    [pool drain];
     return YES;
 }
 
 - (BOOL)findLocalCopyForObjectWithHash:(NSString *)hash forFile:(NSString *)filePath {
     if ([hash length] != 64)
         return NO;
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    PithosLocalObjectState *localState;
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    BOOL isDirectory;
-    NSError *error = nil;
-    for (NSString *localFilePath in currentLocalObjectStates) {
-        localState = [currentLocalObjectStates objectForKey:localFilePath];
-        if (!localState.isDirectory && [hash isEqualToString:localState.hash] && 
-            [fileManager fileExistsAtPath:localFilePath isDirectory:&isDirectory] && !isDirectory) {
-            if ([localFilePath hasPrefix:directoryPath]) {
-                if (![fileManager copyItemAtPath:localFilePath toPath:filePath error:&error] || error) {
-                    [PithosUtilities fileActionFailedAlertWithTitle:@"Copy File Error" 
-                                                            message:[NSString stringWithFormat:@"Cannot copy file at '%@' to '%@'", 
-                                                                     localFilePath, filePath] 
-                                                              error:error];
-                } else {
-                    [pool drain];
-                    return YES;
-                }
-            } else if (self.tempTrashDirPath && [localFilePath hasPrefix:self.tempTrashDirPath]) {
-                if (![fileManager moveItemAtPath:localFilePath toPath:filePath error:&error] || error) {
-                    [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
-                                                            message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", 
-                                                                     localFilePath, filePath] 
-                                                              error:error];
-                } else {
-                    localState.filePath = filePath;
-                    [currentLocalObjectStates setObject:localState forKey:filePath];
-                    [currentLocalObjectStates removeObjectForKey:localFilePath];
-                    [pool drain];
-                    return YES;
+    @autoreleasepool {
+        PithosLocalObjectState *localState;
+        NSFileManager *fileManager = [NSFileManager defaultManager];
+        BOOL isDirectory;
+        NSError *error = nil;
+        for (NSString *localFilePath in currentLocalObjectStates) {
+            localState = [currentLocalObjectStates objectForKey:localFilePath];
+            if (!localState.isDirectory && [hash isEqualToString:localState.hash] && 
+                [fileManager fileExistsAtPath:localFilePath isDirectory:&isDirectory] && !isDirectory) {
+                if ([localFilePath hasPrefix:directoryPath]) {
+                    if (![fileManager copyItemAtPath:localFilePath toPath:filePath error:&error] || error) {
+                        [PithosUtilities fileActionFailedAlertWithTitle:@"Copy File Error" 
+                                                                message:[NSString stringWithFormat:@"Cannot copy file at '%@' to '%@'", 
+                                                                         localFilePath, filePath] 
+                                                                  error:error];
+                    } else {
+                        return YES;
+                    }
+                } else if (self.tempTrashDirPath && [localFilePath hasPrefix:self.tempTrashDirPath]) {
+                    if (![fileManager moveItemAtPath:localFilePath toPath:filePath error:&error] || error) {
+                        [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
+                                                                message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", 
+                                                                         localFilePath, filePath] 
+                                                                  error:error];
+                    } else {
+                        localState.filePath = filePath;
+                        [currentLocalObjectStates setObject:localState forKey:filePath];
+                        [currentLocalObjectStates removeObjectForKey:localFilePath];
+                        return YES;
+                    }
                 }
             }
         }
     }
-    [pool drain];
     return NO;
 }
 
                      localFilePath:(NSString *)filePath 
                        accountName:(NSString *)accountName 
                    pithosContainer:(ASIPithosContainer *)pithosContainer {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    NSError *error;
-    BOOL isDirectory;
-    BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
-    NSString *fileDirectoryPath = [filePath stringByDeletingLastPathComponent];
-    NSMutableDictionary *containerStoredLocalObjectStates = [[storedLocalObjectStates objectForKey:accountName] 
-                                                             objectForKey:pithosContainer.name];
-    PithosLocalObjectState *storedState = [containerStoredLocalObjectStates objectForKey:object.name];
-    // Remote updated info
-    NSError *remoteError;
-    BOOL remoteIsDirectory;
-    BOOL remoteObjectExists = [PithosUtilities objectExistsAtPithos:pithos 
-                                                      containerName:pithosContainer.name 
-                                                         objectName:object.name 
-                                                              error:&remoteError 
-                                                        isDirectory:&remoteIsDirectory 
-                                                     sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
-    if (!object || !object.objectHash) {
-        // Delete local object
-        if (![accountName isEqualToString:@""]) {
-            // If "shared to me" skip
-            [pool drain];
-            return;
-        }
-        if (remoteObjectExists) {
-            // Remote object created in the meantime, just mark the sync cycle as incomplete, but do delete the local object
-            syncIncomplete = YES;
-        }
-        DLog(@"Sync::delete local object: %@", filePath);
-        if (!fileExists || [self moveToTempTrashFile:filePath accountName:accountName pithosContainer:pithosContainer]) {
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility startAndEndActivityWithType:PithosActivityOther 
-                                                      message:[NSString stringWithFormat:@"Sync: Deleting '%@/%@' locally (finished)", 
-                                                               pithosContainer.name, object.name] 
-                                                pithosAccount:pithosAccount];
-            });
-            [containerStoredLocalObjectStates removeObjectForKey:object.name];
-            [self saveLocalState];
-        }
-    } else if ([PithosUtilities isContentTypeDirectory:object.contentType]) {
-        // Create local directory object
-        if (!remoteObjectExists || !remoteIsDirectory) {
-            // Remote directory object deleted or changed to a file object in the meantime, mark the sync cycle as incomplete and skip
-            syncIncomplete = YES;
-            [pool drain];
-            return;
-        }
-        DLog(@"Sync::create local directory object: %@", filePath);
-        BOOL directoryCreated = NO;
-        if (!fileExists || (!isDirectory && [self moveToTempTrashFile:filePath accountName:accountName pithosContainer:pithosContainer])) {
-            DLog(@"Sync::local directory object doesn't exist: %@", filePath);
-            error = nil;
-            if (![fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
-                [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
-                                                        message:[NSString stringWithFormat:@"Cannot create directory at '%@'", filePath] 
-                                                          error:error];
+    @autoreleasepool {
+        NSFileManager *fileManager = [NSFileManager defaultManager];
+        NSError *error;
+        BOOL isDirectory;
+        BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
+        NSString *fileDirectoryPath = [filePath stringByDeletingLastPathComponent];
+        NSMutableDictionary *containerStoredLocalObjectStates = [[storedLocalObjectStates objectForKey:accountName] 
+                                                                 objectForKey:pithosContainer.name];
+        PithosLocalObjectState *storedState = [containerStoredLocalObjectStates objectForKey:object.name];
+        // Remote updated info
+        NSError *remoteError;
+        BOOL remoteIsDirectory;
+        BOOL remoteObjectExists = [PithosUtilities objectExistsAtPithos:pithos 
+                                                          containerName:pithosContainer.name 
+                                                             objectName:object.name 
+                                                                  error:&remoteError 
+                                                            isDirectory:&remoteIsDirectory 
+                                                         sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
+        if (!object || !object.objectHash) {
+            // Delete local object
+            if (![accountName isEqualToString:@""])
+                // If "shared with me" skip
+                return;
+            if (remoteObjectExists) {
+                // Remote object created in the meantime, just mark the sync cycle as incomplete, but do delete the local object
+                syncIncomplete = YES;
+            }
+            DLog(@"Sync::delete local object: %@", filePath);
+            if (!fileExists || [self moveToTempTrashFile:filePath accountName:accountName pithosContainer:pithosContainer]) {
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility startAndEndActivityWithType:PithosActivityOther 
+                                                          message:[NSString stringWithFormat:@"Sync: Deleting '%@/%@' locally (finished)", 
+                                                                   pithosContainer.name, object.name] 
+                                                    pithosAccount:pithosAccount];
+                });
+                [containerStoredLocalObjectStates removeObjectForKey:object.name];
+                [self saveLocalState];
+            }
+        } else if ([PithosUtilities isContentTypeDirectory:object.contentType]) {
+            // Create local directory object
+            if (!remoteObjectExists || !remoteIsDirectory) {
+                // Remote directory object deleted or changed to a file object in the meantime, mark the sync cycle as incomplete and skip
+                syncIncomplete = YES;
+                return;
+            }
+            DLog(@"Sync::create local directory object: %@", filePath);
+            BOOL directoryCreated = NO;
+            if (!fileExists || (!isDirectory && [self moveToTempTrashFile:filePath accountName:accountName pithosContainer:pithosContainer])) {
+                DLog(@"Sync::local directory object doesn't exist: %@", filePath);
+                error = nil;
+                if (![fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error] || error) {
+                    [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
+                                                            message:[NSString stringWithFormat:@"Cannot create directory at '%@'", filePath] 
+                                                              error:error];
+                } else {
+                    directoryCreated = YES;
+                    storedState.filePath = filePath;
+                    storedState.isDirectory = YES;
+                    [self saveLocalState];
+                }
             } else {
+                DLog(@"Sync::local directory object exists: %@", filePath);
                 directoryCreated = YES;
-                storedState.filePath = filePath;
-                storedState.isDirectory = YES;
-                [self saveLocalState];
             }
-        } else {
-            DLog(@"Sync::local directory object exists: %@", filePath);
-            directoryCreated = YES;
-        }
-        if (directoryCreated)
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility startAndEndActivityWithType:PithosActivityOther 
-                                                      message:[NSString stringWithFormat:@"Sync: Creating directory '%@/%@' locally (finished)", 
-                                                               [self relativeDirPathForAccount:accountName container:pithosContainer.name], 
-                                                               object.name] 
-                                                pithosAccount:pithosAccount];
-            });
-    } else if (object.bytes == 0) {
-        // Create local object with zero length
-        if (!remoteObjectExists || remoteIsDirectory) {
-            // Remote file object deleted or changed to a directory object in the meantime, mark the sync cycle as incomplete and skip
-            syncIncomplete = YES;
-            [pool drain];
-            return;
-        }
-        DLog(@"Sync::create local zero length object: %@", filePath);
-        BOOL fileCreated = NO;
-        if (!fileExists || 
-            ((isDirectory || [PithosUtilities bytesOfFile:filePath]) && 
-             [self moveToTempTrashFile:filePath accountName:accountName pithosContainer:pithosContainer])) {
-            DLog(@"Sync::local zero length object doesn't exist: %@", filePath);
+            if (directoryCreated)
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility startAndEndActivityWithType:PithosActivityOther 
+                                                          message:[NSString stringWithFormat:@"Sync: Creating directory '%@/%@' locally (finished)", 
+                                                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], 
+                                                                   object.name] 
+                                                    pithosAccount:pithosAccount];
+                });
+        } else if (object.bytes == 0) {
+            // Create local object with zero length
+            if (!remoteObjectExists || remoteIsDirectory) {
+                // Remote file object deleted or changed to a directory object in the meantime, mark the sync cycle as incomplete and skip
+                syncIncomplete = YES;
+                return;
+            }
+            DLog(@"Sync::create local zero length object: %@", filePath);
+            BOOL fileCreated = NO;
+            if (!fileExists || 
+                ((isDirectory || [PithosUtilities bytesOfFile:filePath]) && 
+                 [self moveToTempTrashFile:filePath accountName:accountName pithosContainer:pithosContainer])) {
+                DLog(@"Sync::local zero length object doesn't exist: %@", filePath);
+                // Create directory of the file, if it doesn't exist
+                error = nil;
+                if (![PithosUtilities safeCreateDirectory:fileDirectoryPath error:&error]) {
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
+                                                                message:[NSString stringWithFormat:@"Cannot create directory at '%@'", fileDirectoryPath] 
+                                                                  error:error];
+                    });
+                }
+                error = nil;
+                if (![fileManager createFileAtPath:filePath contents:nil attributes:nil]) {
+                    [PithosUtilities fileActionFailedAlertWithTitle:@"Create File Error" 
+                                                            message:[NSString stringWithFormat:@"Cannot create file at '%@'", filePath] 
+                                                              error:error];
+                } else {
+                    fileCreated = YES;
+                    storedState.filePath = filePath;
+                    storedState.hash = object.objectHash;
+                    storedState.tmpFilePath = nil;
+                    [self saveLocalState];
+                }
+            } else {
+                DLog(@"Sync::local zero length object exists: %@", filePath);
+                fileCreated = YES;
+            }
+            if (fileCreated)
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility startAndEndActivityWithType:PithosActivityOther 
+                                                          message:[NSString stringWithFormat:@"Sync: Downloading '%@/%@' (100%%)", 
+                                                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], 
+                                                                   object.name] 
+                                                    pithosAccount:pithosAccount];
+                });
+        } else if (storedState.tmpFilePath == nil) {
+            // Create new local object
+            if (!remoteObjectExists || remoteIsDirectory) {
+                // Remote file object deleted or changed to a directory object in the meantime, mark the sync cycle as incomplete and skip
+                syncIncomplete = YES;
+                return;
+            }
             // Create directory of the file, if it doesn't exist
             error = nil;
             if (![PithosUtilities safeCreateDirectory:fileDirectoryPath error:&error]) {
+                [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
+                                                        message:[NSString stringWithFormat:@"Cannot create directory at '%@'", fileDirectoryPath] 
+                                                          error:error];
+            }
+            // Check first if a local copy exists
+            if ([self findLocalCopyForObjectWithHash:object.objectHash forFile:filePath]) {
+                storedState.filePath = filePath;
+                storedState.hash = object.objectHash;
+                [self saveLocalState];
                 dispatch_async(dispatch_get_main_queue(), ^{
-                    [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
-                                                            message:[NSString stringWithFormat:@"Cannot create directory at '%@'", fileDirectoryPath] 
-                                                              error:error];
+                    [activityFacility startAndEndActivityWithType:PithosActivityOther 
+                                                          message:[NSString stringWithFormat:@"Sync: Downloading '%@/%@' (100%%)", 
+                                                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], 
+                                                                   object.name] 
+                                                    pithosAccount:pithosAccount];
+                });
+            } else {
+                [self syncOperationStarted];
+                __block ASIPithosObjectRequest *objectRequest = [PithosUtilities objectBlockDataRequestWithPithos:pithos 
+                                                                                                    containerName:pithosContainer.name 
+                                                                                                           object:object 
+                                                                                                       blockIndex:0 
+                                                                                                        blockSize:pithosContainer.blockSize];
+                if (![accountName isEqualToString:@""])
+                    [objectRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
+                objectRequest.delegate = self;
+                objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Downloading '%@/%@'", 
+                                           [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
+                PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDownload 
+                                                                           message:[messagePrefix stringByAppendingString:@" (0%%)"] 
+                                                                        totalBytes:object.bytes 
+                                                                      currentBytes:0 
+                                                                     pithosAccount:pithosAccount];
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility updateActivity:activity withMessage:activity.message];
                 });
+                objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                          accountName, @"accountName", 
+                                          pithosContainer, @"pithosContainer", 
+                                          object, @"pithosObject", 
+                                          messagePrefix, @"messagePrefix", 
+                                          [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, (NSUInteger)ceil((object.bytes +0.0)/(pithosContainer.blockSize + 0.0)))], @"missingBlocks", 
+                                          [NSNumber numberWithUnsignedInteger:0], @"missingBlockIndex", 
+                                          filePath, @"filePath", 
+                                          activity, @"activity", 
+                                          [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
+                                          [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
+                                          [messagePrefix stringByAppendingString:@" (100%%)"], @"finishedActivityMessage", 
+                                          [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", 
+                                          [NSNumber numberWithUnsignedInteger:10], @"retries", 
+                                          NSStringFromSelector(@selector(downloadObjectBlockFinished:)), @"didFinishSelector", 
+                                          NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
+                                          nil];
+                [objectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){
+                    [activityFacility updateActivity:activity 
+                                         withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
+                                                      messagePrefix, (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0))] 
+                                          totalBytes:activity.totalBytes 
+                                        currentBytes:(activity.currentBytes + size)];
+                }];
+                [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
             }
+        } else {
+            // Resume local object download
+            if (!remoteObjectExists || remoteIsDirectory) {
+                // Remote file object deleted or changed to a directory object in the meantime, mark the sync cycle as incomplete and skip
+                syncIncomplete = YES;
+                return;
+            }
+            // Create directory of the file, if it doesn't exist
             error = nil;
-            if (![fileManager createFileAtPath:filePath contents:nil attributes:nil]) {
-                [PithosUtilities fileActionFailedAlertWithTitle:@"Create File Error" 
-                                                        message:[NSString stringWithFormat:@"Cannot create file at '%@'", filePath] 
+            if (![PithosUtilities safeCreateDirectory:fileDirectoryPath error:&error]) {
+                [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
+                                                        message:[NSString stringWithFormat:@"Cannot create directory at '%@'", fileDirectoryPath] 
                                                           error:error];
-            } else {
-                fileCreated = YES;
+            }
+            // Check first if a local copy exists
+            if ([self findLocalCopyForObjectWithHash:object.objectHash forFile:filePath]) {
                 storedState.filePath = filePath;
                 storedState.hash = object.objectHash;
+                // Delete incomplete temp download
                 storedState.tmpFilePath = nil;
                 [self saveLocalState];
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility startAndEndActivityWithType:PithosActivityOther 
+                                                          message:[NSString stringWithFormat:@"Sync: Downloading '%@/%@' (100%%)", 
+                                                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], 
+                                                                   object.name] 
+                                                    pithosAccount:pithosAccount];
+                });
+            } else {
+                [self syncOperationStarted];
+                ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectHashmapRequestWithPithos:pithos 
+                                                                                                 containerName:pithosContainer.name 
+                                                                                                    objectName:object.name];
+                if (![accountName isEqualToString:@""])
+                    [objectRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
+                objectRequest.delegate = self;
+                objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Downloading '%@/%@'", 
+                                           [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
+                PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDownload 
+                                                                           message:[messagePrefix stringByAppendingString:@" (0%%)"] 
+                                                                        totalBytes:object.bytes 
+                                                                      currentBytes:0 
+                                                                     pithosAccount:pithosAccount];
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility updateActivity:activity withMessage:activity.message];
+                });
+                objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                          accountName, @"accountName", 
+                                          pithosContainer, @"pithosContainer", 
+                                          object, @"pithosObject", 
+                                          messagePrefix, @"messagePrefix", 
+                                          filePath, @"filePath", 
+                                          activity, @"activity", 
+                                          [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
+                                          [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
+                                          [messagePrefix stringByAppendingString:@" (100%%)"], @"finishedActivityMessage", 
+                                          [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", 
+                                          [NSNumber numberWithUnsignedInteger:10], @"retries", 
+                                          NSStringFromSelector(@selector(downloadObjectHashMapFinished:)), @"didFinishSelector", 
+                                          NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
+                                          nil];
+                [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
             }
-        } else {
-            DLog(@"Sync::local zero length object exists: %@", filePath);
-            fileCreated = YES;
-        }
-        if (fileCreated)
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility startAndEndActivityWithType:PithosActivityOther 
-                                                      message:[NSString stringWithFormat:@"Sync: Downloading '%@/%@' (100%%)", 
-                                                               [self relativeDirPathForAccount:accountName container:pithosContainer.name], 
-                                                               object.name] 
-                                                pithosAccount:pithosAccount];
-            });
-    } else if (storedState.tmpFilePath == nil) {
-        // Create new local object
-        if (!remoteObjectExists || remoteIsDirectory) {
-            // Remote file object deleted or changed to a directory object in the meantime, mark the sync cycle as incomplete and skip
-            syncIncomplete = YES;
-            [pool drain];
-            return;
-        }
-        // Create directory of the file, if it doesn't exist
-        error = nil;
-        if (![PithosUtilities safeCreateDirectory:fileDirectoryPath error:&error]) {
-            [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
-                                                    message:[NSString stringWithFormat:@"Cannot create directory at '%@'", fileDirectoryPath] 
-                                                      error:error];
         }
-        // Check first if a local copy exists
-        if ([self findLocalCopyForObjectWithHash:object.objectHash forFile:filePath]) {
-            storedState.filePath = filePath;
-            storedState.hash = object.objectHash;
-            [self saveLocalState];
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility startAndEndActivityWithType:PithosActivityOther 
-                                                      message:[NSString stringWithFormat:@"Sync: Downloading '%@/%@' (100%%)", 
-                                                               [self relativeDirPathForAccount:accountName container:pithosContainer.name], 
-                                                               object.name] 
-                                                pithosAccount:pithosAccount];
-            });
-        } else {
-            [self syncOperationStarted];
-            __block ASIPithosObjectRequest *objectRequest = [PithosUtilities objectBlockDataRequestWithPithos:pithos 
-                                                                                                containerName:pithosContainer.name 
-                                                                                                       object:object 
-                                                                                                   blockIndex:0 
-                                                                                                    blockSize:pithosContainer.blockSize];
+    }
+}
+
+-(void)updateServerStateWithCurrentState:(PithosLocalObjectState *)currentState 
+                                  object:(ASIPithosObject *)object 
+                           localFilePath:(NSString *)filePath 
+                             accountName:(NSString *)accountName 
+                         pithosContainer:(ASIPithosContainer *)pithosContainer {
+    @autoreleasepool {
+        [self syncOperationStarted];
+        NSFileManager *fileManager = [NSFileManager defaultManager];
+        BOOL isDirectory;
+        BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
+        if (currentState.isDirectory) {
+            // Create remote directory object
+            if (![accountName isEqualToString:@""]) {
+                if (!object.allowedTo) {
+                    NSMutableDictionary *containerRemoteObjects = [[remoteObjects objectForKey:accountName] objectForKey:pithosContainer.name];
+                    NSString *objectAncestorName = [object.name stringByDeletingLastPathComponent];
+                    while ([objectAncestorName length] && !object.allowedTo) {
+                        object.allowedTo = [[containerRemoteObjects objectForKey:objectAncestorName] allowedTo];
+                        objectAncestorName = [objectAncestorName stringByDeletingLastPathComponent];
+                    }
+                }
+                if (![object.allowedTo isEqualToString:@"write"]) {
+                    // If read-only "shared with me" skip
+                    [self syncOperationFinishedWithSuccess:YES];
+                    return;
+                }
+            }
+            if (!fileExists || !isDirectory) {
+                // Local directory object deleted or changed to a file in the meantime, mark the sync cycle as incomplete and skip
+                [self syncOperationFinishedWithSuccess:NO];
+                return;
+            }
+            ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos 
+                                                                                               containerName:pithosContainer.name 
+                                                                                                  objectName:object.name 
+                                                                                                        eTag:nil 
+                                                                                                 contentType:@"application/directory" 
+                                                                                             contentEncoding:nil 
+                                                                                          contentDisposition:nil 
+                                                                                                    manifest:nil 
+                                                                                                     sharing:nil 
+                                                                                                    isPublic:ASIPithosObjectRequestPublicIgnore 
+                                                                                                    metadata:nil 
+                                                                                                        data:[NSData data]];
             if (![accountName isEqualToString:@""])
                 [objectRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
             objectRequest.delegate = self;
             objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
             objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-            NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Downloading '%@/%@'", 
+            NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Creating directory '%@/%@'", 
                                        [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
-            PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDownload 
-                                                                       message:[messagePrefix stringByAppendingString:@" (0%%)"] 
-                                                                    totalBytes:object.bytes 
-                                                                  currentBytes:0 
+            PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityCreateDirectory 
+                                                                       message:messagePrefix 
                                                                  pithosAccount:pithosAccount];
             dispatch_async(dispatch_get_main_queue(), ^{
                 [activityFacility updateActivity:activity withMessage:activity.message];
                                       pithosContainer, @"pithosContainer", 
                                       object, @"pithosObject", 
                                       messagePrefix, @"messagePrefix", 
-                                      [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, (NSUInteger)ceil((object.bytes +0.0)/(pithosContainer.blockSize + 0.0)))], @"missingBlocks", 
-                                      [NSNumber numberWithUnsignedInteger:0], @"missingBlockIndex", 
-                                      filePath, @"filePath", 
                                       activity, @"activity", 
                                       [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
                                       [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
-                                      [messagePrefix stringByAppendingString:@" (100%%)"], @"finishedActivityMessage", 
-                                      [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", 
+                                      [messagePrefix stringByAppendingString:@" (finished)"], @"finishedActivityMessage", 
+                                      [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
                                       [NSNumber numberWithUnsignedInteger:10], @"retries", 
-                                      NSStringFromSelector(@selector(downloadObjectBlockFinished:)), @"didFinishSelector", 
+                                      NSStringFromSelector(@selector(uploadDirectoryObjectFinished:)), @"didFinishSelector", 
                                       NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
                                       nil];
-            [objectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){
-                [activityFacility updateActivity:activity 
-                                     withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
-                                                  messagePrefix, (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0))] 
-                                      totalBytes:activity.totalBytes 
-                                    currentBytes:(activity.currentBytes + size)];
-            }];
-            [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
-        }
-    } else {
-        // Resume local object download
-        if (!remoteObjectExists || remoteIsDirectory) {
-            // Remote file object deleted or changed to a directory object in the meantime, mark the sync cycle as incomplete and skip
-            syncIncomplete = YES;
-            [pool drain];
-            return;
-        }
-        // Create directory of the file, if it doesn't exist
-        error = nil;
-        if (![PithosUtilities safeCreateDirectory:fileDirectoryPath error:&error]) {
-            [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
-                                                    message:[NSString stringWithFormat:@"Cannot create directory at '%@'", fileDirectoryPath] 
-                                                      error:error];
-        }
-        // Check first if a local copy exists
-        if ([self findLocalCopyForObjectWithHash:object.objectHash forFile:filePath]) {
-            storedState.filePath = filePath;
-            storedState.hash = object.objectHash;
-            // Delete incomplete temp download
-            storedState.tmpFilePath = nil;
-            [self saveLocalState];
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility startAndEndActivityWithType:PithosActivityOther 
-                                                      message:[NSString stringWithFormat:@"Sync: Downloading '%@/%@' (100%%)", 
-                                                               [self relativeDirPathForAccount:accountName container:pithosContainer.name], 
-                                                               object.name] 
-                                                pithosAccount:pithosAccount];
-            });
-        } else {
-            [self syncOperationStarted];
-            ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectHashmapRequestWithPithos:pithos 
-                                                                                             containerName:pithosContainer.name 
-                                                                                                objectName:object.name];
-            if (![accountName isEqualToString:@""])
-                [objectRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
-            objectRequest.delegate = self;
-            objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-            objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-            NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Downloading '%@/%@'", 
-                                       [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
-            PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDownload 
-                                                                       message:[messagePrefix stringByAppendingString:@" (0%%)"] 
-                                                                    totalBytes:object.bytes 
-                                                                  currentBytes:0 
-                                                                 pithosAccount:pithosAccount];
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility updateActivity:activity withMessage:activity.message];
-            });
-            objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-                                      accountName, @"accountName", 
-                                      pithosContainer, @"pithosContainer", 
-                                      object, @"pithosObject", 
-                                      messagePrefix, @"messagePrefix", 
-                                      filePath, @"filePath", 
-                                      activity, @"activity", 
-                                      [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
-                                      [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
-                                      [messagePrefix stringByAppendingString:@" (100%%)"], @"finishedActivityMessage", 
-                                      [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", 
-                                      [NSNumber numberWithUnsignedInteger:10], @"retries", 
-                                      NSStringFromSelector(@selector(downloadObjectHashMapFinished:)), @"didFinishSelector", 
-                                      NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
-                                      nil];
-            [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
-        }
-    }
-    [pool drain];
-}
-
--(void)updateServerStateWithCurrentState:(PithosLocalObjectState *)currentState 
-                                  object:(ASIPithosObject *)object 
-                           localFilePath:(NSString *)filePath 
-                             accountName:(NSString *)accountName 
-                         pithosContainer:(ASIPithosContainer *)pithosContainer {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    [self syncOperationStarted];
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    BOOL isDirectory;
-    BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
-    if (currentState.isDirectory) {
-        // Create remote directory object
-        if (![accountName isEqualToString:@""]) {
-            if (!object.allowedTo) {
-                NSMutableDictionary *containerRemoteObjects = [[remoteObjects objectForKey:accountName] objectForKey:pithosContainer.name];
-                NSString *objectAncestorName = [object.name stringByDeletingLastPathComponent];
-                while ([objectAncestorName length] && !object.allowedTo) {
-                    object.allowedTo = [[containerRemoteObjects objectForKey:objectAncestorName] allowedTo];
-                    objectAncestorName = [objectAncestorName stringByDeletingLastPathComponent];
-                }
-            }
-            if (![object.allowedTo isEqualToString:@"write"]) {
-                // If read-only "shared to me" skip
+            [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
+        } else if (![currentState exists]) {
+            // Delete remote object
+            if (![accountName isEqualToString:@""]) {
+                // If "shared with me" skip
                 [self syncOperationFinishedWithSuccess:YES];
-                [pool drain];
                 return;
             }
-        }
-        if (!fileExists || !isDirectory) {
-            // Local directory object deleted or changed to a file in the meantime, mark the sync cycle as incomplete and skip
-            [self syncOperationFinishedWithSuccess:NO];
-            [pool drain];
-            return;
-        }
-        ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithPithos:pithos 
+            if (fileExists) {
+                // Local object created in the meantime, just mark the sync cycle as incomplete, but do delete the server object
+                syncIncomplete = YES;
+            }
+            if ([pithosContainer.name isEqualToString:@"trash"]) {
+                // Delete
+                ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest deleteObjectRequestWithPithos:pithos 
+                                                                                                containerName:pithosContainer.name 
+                                                                                                   objectName:object.name];
+                objectRequest.delegate = self;
+                objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Deleting '%@/%@'", 
+                                           [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
+                PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDelete 
+                                                                           message:messagePrefix 
+                                                                     pithosAccount:pithosAccount];
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility updateActivity:activity withMessage:activity.message];
+                });
+                objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                          accountName, @"accountName", 
+                                          pithosContainer, @"pithosContainer", 
+                                          object, @"pithosObject", 
+                                          messagePrefix, @"messagePrefix", 
+                                          activity, @"activity", 
+                                          [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
+                                          [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
+                                          [messagePrefix stringByAppendingString:@" (finished)"], @"finishedActivityMessage", 
+                                          [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
+                                          [NSNumber numberWithUnsignedInteger:10], @"retries", 
+                                          NSStringFromSelector(@selector(deleteObjectFinished:)), @"didFinishSelector", 
+                                          NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
+                                          nil];
+                [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
+            } else {
+                // Move to container trash
+                NSString *safeName;
+                if ([PithosUtilities isContentTypeDirectory:object.contentType])
+                    safeName = [PithosUtilities safeSubdirNameForPithos:pithos containerName:@"trash" subdirName:object.name];
+                else
+                    safeName = [PithosUtilities safeObjectNameForPithos:pithos containerName:@"trash" objectName:object.name];
+                if (safeName) {
+                    ASIPithosObjectRequest *objectRequest = [PithosUtilities moveObjectRequestWithPithos:pithos 
                                                                                            containerName:pithosContainer.name 
                                                                                               objectName:object.name 
-                                                                                                    eTag:nil 
-                                                                                             contentType:@"application/directory" 
-                                                                                         contentEncoding:nil 
-                                                                                      contentDisposition:nil 
-                                                                                                manifest:nil 
-                                                                                                 sharing:nil 
-                                                                                                isPublic:ASIPithosObjectRequestPublicIgnore 
-                                                                                                metadata:nil 
-                                                                                                    data:[NSData data]];
-        if (![accountName isEqualToString:@""])
-            [objectRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
-        objectRequest.delegate = self;
-        objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-        objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-        NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Creating directory '%@/%@'", 
-                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
-        PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityCreateDirectory 
-                                                                   message:messagePrefix 
-                                                             pithosAccount:pithosAccount];
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility updateActivity:activity withMessage:activity.message];
-        });
-        objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-                                  accountName, @"accountName", 
-                                  pithosContainer, @"pithosContainer", 
-                                  object, @"pithosObject", 
-                                  messagePrefix, @"messagePrefix", 
-                                  activity, @"activity", 
-                                  [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
-                                  [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
-                                  [messagePrefix stringByAppendingString:@" (finished)"], @"finishedActivityMessage", 
-                                  [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
-                                  [NSNumber numberWithUnsignedInteger:10], @"retries", 
-                                  NSStringFromSelector(@selector(uploadDirectoryObjectFinished:)), @"didFinishSelector", 
-                                  NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
-                                  nil];
-        [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
-    } else if (![currentState exists]) {
-        // Delete remote object
-        if (![accountName isEqualToString:@""]) {
-            // If "shared to me" skip
-            [self syncOperationFinishedWithSuccess:YES];
-            [pool drain];
-            return;
-        }
-        if (fileExists) {
-            // Local object created in the meantime, just mark the sync cycle as incomplete, but do delete the server object
-            syncIncomplete = YES;
-        }
-        if ([pithosContainer.name isEqualToString:@"trash"]) {
-            // Delete
-            ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest deleteObjectRequestWithPithos:pithos 
-                                                                                            containerName:pithosContainer.name 
-                                                                                               objectName:object.name];
-            objectRequest.delegate = self;
-            objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-            objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-            NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Deleting '%@/%@'", 
-                                       [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
-            PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDelete 
-                                                                       message:messagePrefix 
-                                                                 pithosAccount:pithosAccount];
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility updateActivity:activity withMessage:activity.message];
-            });
-            objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-                                      accountName, @"accountName", 
-                                      pithosContainer, @"pithosContainer", 
-                                      object, @"pithosObject", 
-                                      messagePrefix, @"messagePrefix", 
-                                      activity, @"activity", 
-                                      [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
-                                      [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
-                                      [messagePrefix stringByAppendingString:@" (finished)"], @"finishedActivityMessage", 
-                                      [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
-                                      [NSNumber numberWithUnsignedInteger:10], @"retries", 
-                                      NSStringFromSelector(@selector(deleteObjectFinished:)), @"didFinishSelector", 
-                                      NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
-                                      nil];
-            [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
-        } else {
-            // Move to container trash
-            NSString *safeName;
-            if ([PithosUtilities isContentTypeDirectory:object.contentType])
-                safeName = [PithosUtilities safeSubdirNameForPithos:pithos containerName:@"trash" subdirName:object.name];
-            else
-                safeName = [PithosUtilities safeObjectNameForPithos:pithos containerName:@"trash" objectName:object.name];
-            if (safeName) {
-                ASIPithosObjectRequest *objectRequest = [PithosUtilities moveObjectRequestWithPithos:pithos 
-                                                                                       containerName:pithosContainer.name 
-                                                                                          objectName:object.name 
-                                                                            destinationContainerName:@"trash" 
-                                                                               destinationObjectName:safeName 
-                                                                                       checkIfExists:NO];
-                if (objectRequest) {
-                    objectRequest.delegate = self;
-                    objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-                    objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-                    NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Moving to trash '%@/%@'", 
-                                               [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
-                    PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDelete 
-                                                                               message:messagePrefix 
-                                                                         pithosAccount:pithosAccount];
-                    dispatch_async(dispatch_get_main_queue(), ^{
-                        [activityFacility updateActivity:activity withMessage:activity.message];
-                    });
-                    objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
-                                              accountName, @"accountName", 
-                                              pithosContainer, @"pithosContainer", 
-                                              object, @"pithosObject", 
-                                              messagePrefix, @"messagePrefix", 
-                                              activity, @"activity", 
-                                              [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
-                                              [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
-                                              [messagePrefix stringByAppendingString:@" (finished)"], @"finishedActivityMessage", 
-                                              [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
-                                              [NSNumber numberWithUnsignedInteger:10], @"retries", 
-                                              NSStringFromSelector(@selector(moveObjectToTrashFinished:)), @"didFinishSelector", 
-                                              NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
-                                              nil];
-                    [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
+                                                                                destinationContainerName:@"trash" 
+                                                                                   destinationObjectName:safeName 
+                                                                                           checkIfExists:NO];
+                    if (objectRequest) {
+                        objectRequest.delegate = self;
+                        objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                        objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                        NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Moving to trash '%@/%@'", 
+                                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
+                        PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDelete 
+                                                                                   message:messagePrefix 
+                                                                             pithosAccount:pithosAccount];
+                        dispatch_async(dispatch_get_main_queue(), ^{
+                            [activityFacility updateActivity:activity withMessage:activity.message];
+                        });
+                        objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                                  accountName, @"accountName", 
+                                                  pithosContainer, @"pithosContainer", 
+                                                  object, @"pithosObject", 
+                                                  messagePrefix, @"messagePrefix", 
+                                                  activity, @"activity", 
+                                                  [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
+                                                  [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
+                                                  [messagePrefix stringByAppendingString:@" (finished)"], @"finishedActivityMessage", 
+                                                  [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
+                                                  [NSNumber numberWithUnsignedInteger:10], @"retries", 
+                                                  NSStringFromSelector(@selector(moveObjectToTrashFinished:)), @"didFinishSelector", 
+                                                  NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
+                                                  nil];
+                        [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
+                    } else {
+                        [self syncOperationFinishedWithSuccess:NO];
+                    }
                 } else {
                     [self syncOperationFinishedWithSuccess:NO];
                 }
-            } else {
-                [self syncOperationFinishedWithSuccess:NO];
             }
-        }
-    } else {
-        // Upload file to remote object
-        if (![accountName isEqualToString:@""]) {
-            if (!object.allowedTo) {
-                NSMutableDictionary *containerRemoteObjects = [[remoteObjects objectForKey:accountName] objectForKey:pithosContainer.name];
-                NSString *objectAncestorName = [object.name stringByDeletingLastPathComponent];
-                while ([objectAncestorName length] && !object.allowedTo) {
-                    object.allowedTo = [[containerRemoteObjects objectForKey:objectAncestorName] allowedTo];
-                    objectAncestorName = [objectAncestorName stringByDeletingLastPathComponent];
+        } else {
+            // Upload file to remote object
+            if (![accountName isEqualToString:@""]) {
+                if (!object.allowedTo) {
+                    NSMutableDictionary *containerRemoteObjects = [[remoteObjects objectForKey:accountName] objectForKey:pithosContainer.name];
+                    NSString *objectAncestorName = [object.name stringByDeletingLastPathComponent];
+                    while ([objectAncestorName length] && !object.allowedTo) {
+                        object.allowedTo = [[containerRemoteObjects objectForKey:objectAncestorName] allowedTo];
+                        objectAncestorName = [objectAncestorName stringByDeletingLastPathComponent];
+                    }
+                }
+                if (![object.allowedTo isEqualToString:@"write"]) {
+                    // If read-only "shared with me" skip
+                    [self syncOperationFinishedWithSuccess:YES];
+                    return;
                 }
             }
-            if (![object.allowedTo isEqualToString:@"write"]) {
-                // If read-only "shared to me" skip
-                [self syncOperationFinishedWithSuccess:YES];
-                [pool drain];
+            if (!fileExists || isDirectory) {
+                // Local file object deleted or changed to a directory in the meantime, mark the sync cycle as incomplete and skip
+                [self syncOperationFinishedWithSuccess:NO];
                 return;
             }
-        }
-        if (!fileExists || isDirectory) {
-            // Local file object deleted or changed to a directory in the meantime, mark the sync cycle as incomplete and skip
-            [self syncOperationFinishedWithSuccess:NO];
-            [pool drain];
-            return;
-        }
-        NSError *error = nil;
-        object.contentType = [PithosUtilities contentTypeOfFile:filePath error:&error];
-        if (object.contentType == nil)
-            object.contentType = @"application/octet-stream";
-        #if DEBUG_PITHOS
-        if (error)
-            DLog(@"contentType detection error: %@", error);
-        #endif
-        NSArray *hashes = nil;
-        ASIPithosObjectRequest *objectRequest = [PithosUtilities writeObjectDataRequestWithPithos:pithos 
-                                                                                    containerName:pithosContainer.name 
-                                                                                       objectName:object.name 
-                                                                                      contentType:object.contentType 
-                                                                                        blockSize:pithosContainer.blockSize 
-                                                                                        blockHash:pithosContainer.blockHash 
-                                                                                          forFile:filePath 
-                                                                                    checkIfExists:NO 
-                                                                                           hashes:&hashes 
-                                                                                   sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
-        if (objectRequest) {
-            objectRequest.delegate = self;
-            objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-            objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-            NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Uploading '%@/%@'", 
-                                       [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
-            PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityUpload 
-                                                                       message:[messagePrefix stringByAppendingString:@" (0%%)"] 
-                                                                    totalBytes:[[objectRequest.userInfo objectForKey:@"bytes"] unsignedIntegerValue]
-                                                                  currentBytes:0 
-                                                                 pithosAccount:pithosAccount];
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility updateActivity:activity withMessage:activity.message];
-            });
-            [(NSMutableDictionary *)objectRequest.userInfo addEntriesFromDictionary:
-             [NSDictionary dictionaryWithObjectsAndKeys:
-              accountName, @"accountName", 
-              pithosContainer, @"pithosContainer", 
-              object, @"pithosObject", 
-              messagePrefix, @"messagePrefix", 
-              filePath, @"filePath", 
-              hashes, @"hashes", 
-              [NSNumber numberWithUnsignedInteger:10], @"iteration", 
-              activity, @"activity", 
-              [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
-              [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
-              [messagePrefix stringByAppendingString:@" (100%%)"], @"finishedActivityMessage", 
-              [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", 
-              [NSNumber numberWithUnsignedInteger:10], @"retries", 
-              NSStringFromSelector(@selector(uploadObjectUsingHashMapFinished:)), @"didFinishSelector", 
-              NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
-              nil]];
-            [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
-        } else {
-            [self syncOperationFinishedWithSuccess:NO];
+            NSError *error = nil;
+            object.contentType = [PithosUtilities contentTypeOfFile:filePath error:&error];
+            if (object.contentType == nil)
+                object.contentType = @"application/octet-stream";
+            #if DEBUG_PITHOS
+            if (error)
+                DLog(@"contentType detection error: %@", error);
+            #endif
+            NSArray *hashes = nil;
+            ASIPithosObjectRequest *objectRequest = [PithosUtilities writeObjectDataRequestWithPithos:pithos 
+                                                                                        containerName:pithosContainer.name 
+                                                                                           objectName:object.name 
+                                                                                          contentType:object.contentType 
+                                                                                            blockSize:pithosContainer.blockSize 
+                                                                                            blockHash:pithosContainer.blockHash 
+                                                                                              forFile:filePath 
+                                                                                        checkIfExists:NO 
+                                                                                               hashes:&hashes 
+                                                                                       sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
+            if (objectRequest) {
+                objectRequest.delegate = self;
+                objectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                objectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                NSString *messagePrefix = [NSString stringWithFormat:@"Sync: Uploading '%@/%@'", 
+                                           [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
+                PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityUpload 
+                                                                           message:[messagePrefix stringByAppendingString:@" (0%%)"] 
+                                                                        totalBytes:[[objectRequest.userInfo objectForKey:@"bytes"] unsignedIntegerValue]
+                                                                      currentBytes:0 
+                                                                     pithosAccount:pithosAccount];
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility updateActivity:activity withMessage:activity.message];
+                });
+                [(NSMutableDictionary *)objectRequest.userInfo addEntriesFromDictionary:
+                 [NSDictionary dictionaryWithObjectsAndKeys:
+                  accountName, @"accountName", 
+                  pithosContainer, @"pithosContainer", 
+                  object, @"pithosObject", 
+                  messagePrefix, @"messagePrefix", 
+                  filePath, @"filePath", 
+                  hashes, @"hashes", 
+                  [NSNumber numberWithUnsignedInteger:10], @"iteration", 
+                  activity, @"activity", 
+                  [messagePrefix stringByAppendingString:@" (stopped)"], @"stoppedActivityMessage", 
+                  [messagePrefix stringByAppendingString:@" (failed)"], @"failedActivityMessage", 
+                  [messagePrefix stringByAppendingString:@" (100%%)"], @"finishedActivityMessage", 
+                  [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority", 
+                  [NSNumber numberWithUnsignedInteger:10], @"retries", 
+                  NSStringFromSelector(@selector(uploadObjectUsingHashMapFinished:)), @"didFinishSelector", 
+                  NSStringFromSelector(@selector(requestFailed:)), @"didFailSelector", 
+                  nil]];
+                [networkQueue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
+            } else {
+                [self syncOperationFinishedWithSuccess:NO];
+            }
         }
     }
-    [pool drain];
 }
 
 #pragma mark -
 
 - (void)performRequestFinishedDelegateInBackground:(ASIPithosRequest *)request {
     // Add an operation to the callbackQueue with a completionBlock for the case of cancellation
-    NSInvocationOperation *operation = [[[NSInvocationOperation alloc] initWithTarget:self 
+    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self 
                                                                              selector:NSSelectorFromString([request.userInfo objectForKey:@"didFinishSelector"]) 
-                                                                               object:request] autorelease];
+                                                                               object:request];
     operation.completionBlock = ^{
-        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-        if ([[request.userInfo objectForKey:@"operation"] isCancelled]) {
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility endActivity:[request.userInfo objectForKey:@"activity"] 
-                                  withMessage:[request.userInfo objectForKey:@"stoppedActivityMessage"]];
-            });
-            [self syncOperationFinishedWithSuccess:NO];
+        @autoreleasepool {
+            if ([[request.userInfo objectForKey:@"operation"] isCancelled]) {
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility endActivity:[request.userInfo objectForKey:@"activity"] 
+                                      withMessage:[request.userInfo objectForKey:@"stoppedActivityMessage"]];
+                });
+                [self syncOperationFinishedWithSuccess:NO];
+            }
         }
-        [pool drain];
     };
     [(NSMutableDictionary *)request.userInfo setObject:operation forKey:@"operation"];
     [callbackQueue addOperation:operation];
                    withObject:request];
     } else {
         // Add an operation to the callbackQueue with a completionBlock for the case of cancellation
-        NSInvocationOperation *operation = [[[NSInvocationOperation alloc] initWithTarget:self 
+        NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self 
                                                                                  selector:NSSelectorFromString([request.userInfo objectForKey:@"didFailSelector"]) 
-                                                                                   object:request] autorelease];
+                                                                                   object:request];
         operation.completionBlock = ^{
-            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-            if ([[request.userInfo objectForKey:@"operation"] isCancelled]) {
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    [activityFacility endActivity:[request.userInfo objectForKey:@"activity"] 
-                                      withMessage:[request.userInfo objectForKey:@"stoppedActivityMessage"]];
-                });
-                [self syncOperationFinishedWithSuccess:NO];
+            @autoreleasepool {
+                if ([[request.userInfo objectForKey:@"operation"] isCancelled]) {
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        [activityFacility endActivity:[request.userInfo objectForKey:@"activity"] 
+                                          withMessage:[request.userInfo objectForKey:@"stoppedActivityMessage"]];
+                    });
+                    [self syncOperationFinishedWithSuccess:NO];
+                }
             }
-            [pool drain];
         };
         [(NSMutableDictionary *)request.userInfo setObject:operation forKey:@"operation"];
         [callbackQueue addOperation:operation];
 }
 
 - (void)listRequestFinished:(ASIPithosContainerRequest *)containerRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [containerRequest.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::list request finished: %@", containerRequest.url);
-    if (operation.isCancelled) {
-        [self listRequestFailed:containerRequest];
-    } else if ((containerRequest.responseStatusCode == 200) || 
-               (containerRequest.responseStatusCode == 304) || 
-               (containerRequest.responseStatusCode == 403)) {
-        NSString *accountName = [accountsNames objectAtIndex:accountsIndex];
-        ASIPithosContainer *pithosContainer = [[accountsPithosContainers objectForKey:accountName] objectAtIndex:containersIndex];
-        if (containerRequest.responseStatusCode == 200) {
-            NSArray *someObjects = [containerRequest objects];
-            if (objects == nil) {
-                objects = [[NSMutableArray alloc] initWithArray:someObjects];
-            } else {
-                [objects addObjectsFromArray:someObjects];
-            }
-            if ([someObjects count] < 10000) {
-                pithosContainer.blockHash = [containerRequest blockHash];
-                pithosContainer.blockSize = [containerRequest blockSize];
-                pithosContainer.lastModified = [containerRequest lastModified];
-                NSMutableDictionary *containerRemoteObjects = [NSMutableDictionary dictionaryWithCapacity:[objects count]];
-                for (ASIPithosObject *object in objects) {
-                    [containerRemoteObjects setObject:object forKey:object.name];
+    @autoreleasepool {
+        NSOperation *operation = [containerRequest.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::list request finished: %@", containerRequest.url);
+        if (operation.isCancelled) {
+            [self listRequestFailed:containerRequest];
+        } else if ((containerRequest.responseStatusCode == 200) || 
+                   (containerRequest.responseStatusCode == 304) || 
+                   (containerRequest.responseStatusCode == 403)) {
+            NSString *accountName = [accountsNames objectAtIndex:accountsIndex];
+            ASIPithosContainer *pithosContainer = [[accountsPithosContainers objectForKey:accountName] objectAtIndex:containersIndex];
+            if (containerRequest.responseStatusCode == 200) {
+                NSArray *someObjects = [containerRequest objects];
+                if (objects == nil) {
+                    objects = [[NSMutableArray alloc] initWithArray:someObjects];
+                } else {
+                    [objects addObjectsFromArray:someObjects];
                 }
-                [[remoteObjects objectForKey:accountName] setObject:containerRemoteObjects forKey:pithosContainer.name];
-                [objects release];
-                objects = nil;
-            } else {
-                // Do an additional request to fetch more objects
+                if ([someObjects count] < 10000) {
+                    pithosContainer.blockHash = [containerRequest blockHash];
+                    pithosContainer.blockSize = [containerRequest blockSize];
+                    pithosContainer.lastModified = [containerRequest lastModified];
+                    NSMutableDictionary *containerRemoteObjects = [NSMutableDictionary dictionaryWithCapacity:[objects count]];
+                    for (ASIPithosObject *object in objects) {
+                        [containerRemoteObjects setObject:object forKey:object.name];
+                    }
+                    [[remoteObjects objectForKey:accountName] setObject:containerRemoteObjects forKey:pithosContainer.name];
+                    objects = nil;
+                } else {
+                    // Do an additional request to fetch more objects
+                    ASIPithosContainerRequest *newContainerRequest = [ASIPithosContainerRequest listObjectsRequestWithPithos:pithos 
+                                                                                                               containerName:pithosContainer.name 
+                                                                                                                       limit:0 
+                                                                                                                      marker:[[someObjects lastObject] name] 
+                                                                                                                      prefix:nil 
+                                                                                                                   delimiter:nil 
+                                                                                                                        path:nil 
+                                                                                                                        meta:nil 
+                                                                                                                      shared:NO 
+                                                                                                                       until:nil 
+                                                                                                             ifModifiedSince:pithosContainer.lastModified];
+                    if (![accountName isEqualToString:@""])
+                        [newContainerRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
+                    newContainerRequest.delegate = self;
+                    newContainerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                    newContainerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                    newContainerRequest.userInfo = containerRequest.userInfo;
+                    [(NSMutableDictionary *)newContainerRequest.userInfo setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
+                    [networkQueue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
+                    return;
+                }
+            } else if (containerRequest.responseStatusCode == 304) {
+                NSMutableDictionary *containerRemoteObjects = [[previousRemoteObjects objectForKey:accountName] 
+                                                               objectForKey:pithosContainer.name];
+                if (containerRemoteObjects) 
+                    [[remoteObjects objectForKey:accountName] setObject:containerRemoteObjects forKey:pithosContainer.name];
+            } else if (containerRequest.responseStatusCode == 403) {
+                [[remoteObjects objectForKey:accountName] setObject:[NSMutableDictionary dictionary] forKey:pithosContainer.name];
+            }
+            
+            containersIndex++;
+            if (containersIndex == [[accountsPithosContainers objectForKey:accountName] count]) {
+                accountsIndex++;
+                containersIndex = 0;
+            }
+            if (accountsIndex < accountsCount) {
+                accountName = [accountsNames objectAtIndex:accountsIndex];
+                pithosContainer = [[accountsPithosContainers objectForKey:accountName] objectAtIndex:containersIndex];
+                // Do a request for the next container
                 ASIPithosContainerRequest *newContainerRequest = [ASIPithosContainerRequest listObjectsRequestWithPithos:pithos 
                                                                                                            containerName:pithosContainer.name 
                                                                                                                    limit:0 
-                                                                                                                  marker:[[someObjects lastObject] name] 
+                                                                                                                  marker:nil 
                                                                                                                   prefix:nil 
                                                                                                                delimiter:nil 
                                                                                                                     path:nil 
                 newContainerRequest.userInfo = containerRequest.userInfo;
                 [(NSMutableDictionary *)newContainerRequest.userInfo setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
                 [networkQueue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
-                [pool drain];
                 return;
             }
-        } else if (containerRequest.responseStatusCode == 304) {
-            NSMutableDictionary *containerRemoteObjects = [[previousRemoteObjects objectForKey:accountName] 
-                                                           objectForKey:pithosContainer.name];
-            if (containerRemoteObjects) 
-                [[remoteObjects objectForKey:accountName] setObject:containerRemoteObjects forKey:pithosContainer.name];
-        } else if (containerRequest.responseStatusCode == 403) {
-            [[remoteObjects objectForKey:accountName] setObject:[NSMutableDictionary dictionary] forKey:pithosContainer.name];
-        }
-        
-        containersIndex++;
-        if (containersIndex == [[accountsPithosContainers objectForKey:accountName] count]) {
-            accountsIndex++;
-            containersIndex = 0;
-        }
-        if (accountsIndex < accountsCount) {
-            accountName = [accountsNames objectAtIndex:accountsIndex];
-            pithosContainer = [[accountsPithosContainers objectForKey:accountName] objectAtIndex:containersIndex];
-            // Do a request for the next container
-            ASIPithosContainerRequest *newContainerRequest = [ASIPithosContainerRequest listObjectsRequestWithPithos:pithos 
-                                                                                                       containerName:pithosContainer.name 
-                                                                                                               limit:0 
-                                                                                                              marker:nil 
-                                                                                                              prefix:nil 
-                                                                                                           delimiter:nil 
-                                                                                                                path:nil 
-                                                                                                                meta:nil 
-                                                                                                              shared:NO 
-                                                                                                               until:nil 
-                                                                                                     ifModifiedSince:pithosContainer.lastModified];
-            if (![accountName isEqualToString:@""])
-                [newContainerRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
-            newContainerRequest.delegate = self;
-            newContainerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-            newContainerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-            newContainerRequest.userInfo = containerRequest.userInfo;
-            [(NSMutableDictionary *)newContainerRequest.userInfo setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
-            [networkQueue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
-            [pool drain];
-            return;
-        }
-        self.previousRemoteObjects = remoteObjects;
-        // remoteObjects contains all remote objects for the legal containers, without enforcing directory exclusions
-        
-        if (operation.isCancelled) {
-            [self listRequestFailed:containerRequest];
-            [pool drain];
-            return;
-        }
+            self.previousRemoteObjects = remoteObjects;
+            // remoteObjects contains all remote objects for the legal containers, without enforcing directory exclusions
+            
+            if (operation.isCancelled) {
+                [self listRequestFailed:containerRequest];
+                return;
+            }
 
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"] 
-                              withMessage:[containerRequest.userInfo objectForKey:@"finishedActivityMessage"]];
-        });
-        NSFileManager *fileManager = [NSFileManager defaultManager];
-        
-        // Compute current state of legal existing local objects 
-        // and add an empty stored state for legal new local objects since last sync
-        self.currentLocalObjectStates = [NSMutableDictionary dictionary];
-        for (NSString *accountName in accountsNames) {
-            for (ASIPithosContainer *pithosContainer in [accountsPithosContainers objectForKey:accountName]) {
-                NSString *containerDirectoryPath = [self dirPathForAccount:accountName container:pithosContainer.name];
-                NSSet *containerExcludedDirectories = [[accountsDictionary objectForKey:accountName] objectForKey:pithosContainer.name];
-                BOOL containerExcludeRootFiles = [containerExcludedDirectories containsObject:@""];
-                NSMutableDictionary *containerStoredLocalObjectStates = [[storedLocalObjectStates objectForKey:accountName] 
-                                                                         objectForKey:pithosContainer.name];
-                NSDirectoryEnumerator *dirEnumerator = [fileManager enumeratorAtPath:containerDirectoryPath];
-                for (NSString *objectName in dirEnumerator) {
-                    objectName = [objectName precomposedStringWithCanonicalMapping];
-                    if (operation.isCancelled) {
-                        operation.completionBlock = nil;
-                        [self saveLocalState];
-                        [self syncOperationFinishedWithSuccess:NO];
-                        [pool drain];
-                        return;
-                    }
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"] 
+                                  withMessage:[containerRequest.userInfo objectForKey:@"finishedActivityMessage"]];
+            });
+            NSFileManager *fileManager = [NSFileManager defaultManager];
+            
+            // Compute current state of legal existing local objects 
+            // and add an empty stored state for legal new local objects since last sync
+            self.currentLocalObjectStates = [NSMutableDictionary dictionary];
+            for (NSString *accountName in accountsNames) {
+                for (ASIPithosContainer *pithosContainer in [accountsPithosContainers objectForKey:accountName]) {
+                    NSString *containerDirectoryPath = [self dirPathForAccount:accountName container:pithosContainer.name];
+                    NSSet *containerExcludedDirectories = [[accountsDictionary objectForKey:accountName] objectForKey:pithosContainer.name];
+                    BOOL containerExcludeRootFiles = [containerExcludedDirectories containsObject:@""];
+                    NSMutableDictionary *containerStoredLocalObjectStates = [[storedLocalObjectStates objectForKey:accountName] 
+                                                                             objectForKey:pithosContainer.name];
+                    NSDirectoryEnumerator *dirEnumerator = [fileManager enumeratorAtPath:containerDirectoryPath];
+                    for (__strong NSString *objectName in dirEnumerator) {
+                        objectName = [objectName precomposedStringWithCanonicalMapping];
+                        if (operation.isCancelled) {
+                            operation.completionBlock = nil;
+                            [self saveLocalState];
+                            [self syncOperationFinishedWithSuccess:NO];
+                            return;
+                        }
 
-                    NSString *filePath = [containerDirectoryPath stringByAppendingPathComponent:objectName];
-                    NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
-                    BOOL isDirectory;
-                    BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
-                    if ([[attributes fileType] isEqualToString:NSFileTypeSymbolicLink]) {
-                        [PithosUtilities fileActionFailedAlertWithTitle:@"Sync Error" 
-                                                                message:[NSString stringWithFormat:@"Sync directory at '%@' contains symbolic links. Remove them and re-activate sync for account '%@'.", 
-                                                                         containerDirectoryPath, pithosAccount.name] 
-                                                                  error:nil];
-                        pithosAccount.syncActive = NO;
-                        return;
-                    } else if (fileExists) {
-                        if (skipHidden && [[objectName lastPathComponent] hasPrefix:@"."]) {
-                            // Skip hidden directory and its descendants, or hidden file
-                            if (isDirectory)
-                                [dirEnumerator skipDescendants];
-                            // Remove stored state if any
-                            [containerStoredLocalObjectStates removeObjectForKey:objectName];
-                            continue;
-                        } else if ([[objectName pathComponents] count] == 1) {
-                            if ([containerExcludedDirectories containsObject:[objectName lowercaseString]]) {
-                                // Skip excluded directory and its descendants, or root file with same name
+                        NSString *filePath = [containerDirectoryPath stringByAppendingPathComponent:objectName];
+                        NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
+                        BOOL isDirectory;
+                        BOOL fileExists = [fileManager fileExistsAtPath:filePath isDirectory:&isDirectory];
+                        if ([[attributes fileType] isEqualToString:NSFileTypeSymbolicLink]) {
+                            [PithosUtilities fileActionFailedAlertWithTitle:@"Sync Error" 
+                                                                    message:[NSString stringWithFormat:@"Sync directory at '%@' contains symbolic links. Remove them and re-activate sync for account '%@'.", 
+                                                                             containerDirectoryPath, pithosAccount.name] 
+                                                                      error:nil];
+                            pithosAccount.syncActive = NO;
+                            return;
+                        } else if (fileExists) {
+                            if (skipHidden && [[objectName lastPathComponent] hasPrefix:@"."]) {
+                                // Skip hidden directory and its descendants, or hidden file
                                 if (isDirectory)
                                     [dirEnumerator skipDescendants];
                                 // Remove stored state if any
                                 [containerStoredLocalObjectStates removeObjectForKey:objectName];
                                 continue;
-                            } else if (!isDirectory && containerExcludeRootFiles) {
-                                // Skip excluded root file
-                                // Remove stored state if any
-                                [containerStoredLocalObjectStates removeObjectForKey:objectName];
-                                continue;
+                            } else if ([[objectName pathComponents] count] == 1) {
+                                if ([containerExcludedDirectories containsObject:[objectName lowercaseString]]) {
+                                    // Skip excluded directory and its descendants, or root file with same name
+                                    if (isDirectory)
+                                        [dirEnumerator skipDescendants];
+                                    // Remove stored state if any
+                                    [containerStoredLocalObjectStates removeObjectForKey:objectName];
+                                    continue;
+                                } else if (!isDirectory && containerExcludeRootFiles) {
+                                    // Skip excluded root file
+                                    // Remove stored state if any
+                                    [containerStoredLocalObjectStates removeObjectForKey:objectName];
+                                    continue;
+                                }
+                            }
+                            // Include local object
+                            PithosLocalObjectState *storedLocalObjectState = [containerStoredLocalObjectStates objectForKey:objectName];
+                            if (!storedLocalObjectState || [storedLocalObjectState isModified]) {
+                                // New or modified existing local object, compute current state
+                                if (!storedLocalObjectState)
+                                    // For new local object, also create empty stored state
+                                    [containerStoredLocalObjectStates setObject:[PithosLocalObjectState localObjectState] forKey:objectName];
+                                [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:filePath 
+                                                                                                           blockHash:pithosContainer.blockHash 
+                                                                                                           blockSize:pithosContainer.blockSize] 
+                                                             forKey:filePath];
+                            } else {
+                                // Local object hasn't changed, set stored state also to current
+                                [currentLocalObjectStates setObject:storedLocalObjectState forKey:filePath];
                             }
-                        }
-                        // Include local object
-                        PithosLocalObjectState *storedLocalObjectState = [containerStoredLocalObjectStates objectForKey:objectName];
-                        if (!storedLocalObjectState || [storedLocalObjectState isModified]) {
-                            // New or modified existing local object, compute current state
-                            if (!storedLocalObjectState)
-                                // For new local object, also create empty stored state
-                                [containerStoredLocalObjectStates setObject:[PithosLocalObjectState localObjectState] forKey:objectName];
-                            [currentLocalObjectStates setObject:[PithosLocalObjectState localObjectStateWithFile:filePath 
-                                                                                                       blockHash:pithosContainer.blockHash 
-                                                                                                       blockSize:pithosContainer.blockSize] 
-                                                         forKey:filePath];
-                        } else {
-                            // Local object hasn't changed, set stored state also to current
-                            [currentLocalObjectStates setObject:storedLocalObjectState forKey:filePath];
                         }
                     }
+                    [self saveLocalState];
                 }
-                [self saveLocalState];
             }
-        }
-        
-        if (operation.isCancelled) {
-            operation.completionBlock = nil;
-            [self syncOperationFinishedWithSuccess:NO];
-            [pool drain];
-            return;
-        }
+            
+            if (operation.isCancelled) {
+                operation.completionBlock = nil;
+                [self syncOperationFinishedWithSuccess:NO];
+                return;
+            }
 
-        // Add an empty stored state for legal new remote objects since last sync
-        for (NSString *accountName in accountsNames) {
-            for (ASIPithosContainer *pithosContainer in [accountsPithosContainers objectForKey:accountName]) {
-                NSSet *containerExcludedDirectories = [[accountsDictionary objectForKey:accountName] objectForKey:pithosContainer.name];
-                BOOL containerExcludeRootFiles = [containerExcludedDirectories containsObject:@""];
-                NSMutableDictionary *containerStoredLocalObjectStates = [[storedLocalObjectStates objectForKey:accountName] 
-                                                                         objectForKey:pithosContainer.name];
-                NSMutableDictionary *containerRemoteObjects = [[remoteObjects objectForKey:accountName] objectForKey:pithosContainer.name];
-                for (NSString *objectName in containerRemoteObjects) {
-                    if (operation.isCancelled) {
-                        operation.completionBlock = nil;
-                        [self saveLocalState];
-                        [self syncOperationFinishedWithSuccess:NO];
-                        [pool drain];
-                        return;
-                    }
+            // Add an empty stored state for legal new remote objects since last sync
+            for (NSString *accountName in accountsNames) {
+                for (ASIPithosContainer *pithosContainer in [accountsPithosContainers objectForKey:accountName]) {
+                    NSSet *containerExcludedDirectories = [[accountsDictionary objectForKey:accountName] objectForKey:pithosContainer.name];
+                    BOOL containerExcludeRootFiles = [containerExcludedDirectories containsObject:@""];
+                    NSMutableDictionary *containerStoredLocalObjectStates = [[storedLocalObjectStates objectForKey:accountName] 
+                                                                             objectForKey:pithosContainer.name];
+                    NSMutableDictionary *containerRemoteObjects = [[remoteObjects objectForKey:accountName] objectForKey:pithosContainer.name];
+                    for (NSString *objectName in containerRemoteObjects) {
+                        if (operation.isCancelled) {
+                            operation.completionBlock = nil;
+                            [self saveLocalState];
+                            [self syncOperationFinishedWithSuccess:NO];
+                            return;
+                        }
 
-                    ASIPithosObject *object = [containerRemoteObjects objectForKey:objectName];
-                    NSString *localObjectName;
-                    if ([object.name hasSuffix:@"/"])
-                        localObjectName = [NSString stringWithFormat:@"%@:", [object.name substringToIndex:([object.name length] -1)]];
-                    else
-                        localObjectName = [NSString stringWithString:object.name];
-                    NSArray *pathComponents = [localObjectName pathComponents];
-                    if (skipHidden) {
-                        BOOL skipObject = NO;
-                        for (NSString *pathComponent in pathComponents) {
-                            if ([pathComponent hasPrefix:@"."]) {
-                                // Skip hidden directory and its descendants, or hidden file
-                                // Remove stored state if any
-                                [containerStoredLocalObjectStates removeObjectForKey:objectName];
-                                skipObject = YES;
-                                break;
+                        ASIPithosObject *object = [containerRemoteObjects objectForKey:objectName];
+                        NSString *localObjectName;
+                        if ([object.name hasSuffix:@"/"])
+                            localObjectName = [NSString stringWithFormat:@"%@:", [object.name substringToIndex:([object.name length] -1)]];
+                        else
+                            localObjectName = [NSString stringWithString:object.name];
+                        NSArray *pathComponents = [localObjectName pathComponents];
+                        if (skipHidden) {
+                            BOOL skipObject = NO;
+                            for (NSString *pathComponent in pathComponents) {
+                                if ([pathComponent hasPrefix:@"."]) {
+                                    // Skip hidden directory and its descendants, or hidden file
+                                    // Remove stored state if any
+                                    [containerStoredLocalObjectStates removeObjectForKey:objectName];
+                                    skipObject = YES;
+                                    break;
+                                }
                             }
+                            if (skipObject)
+                                continue;
                         }
-                        if (skipObject)
+                        if ([containerExcludedDirectories containsObject:[[pathComponents objectAtIndex:0] lowercaseString]]) {
+                            // Skip excluded directory object and its descendants, or root file object with same name
+                            // Remove stored state if any
+                            [containerStoredLocalObjectStates removeObjectForKey:object.name];
                             continue;
+                        } else if (containerExcludeRootFiles && 
+                                   ([pathComponents count] == 1) && 
+                                   ![PithosUtilities isContentTypeDirectory:object.contentType]) {
+                            // Skip root file object
+                            // Remove stored state if any
+                            [containerStoredLocalObjectStates removeObjectForKey:object.name];                    
+                            continue;
+                        }
+                        if (![containerStoredLocalObjectStates objectForKey:object.name])
+                            [containerStoredLocalObjectStates setObject:[PithosLocalObjectState localObjectState] forKey:object.name];
                     }
-                    if ([containerExcludedDirectories containsObject:[[pathComponents objectAtIndex:0] lowercaseString]]) {
-                        // Skip excluded directory object and its descendants, or root file object with same name
-                        // Remove stored state if any
-                        [containerStoredLocalObjectStates removeObjectForKey:object.name];
-                        continue;
-                    } else if (containerExcludeRootFiles && 
-                               ([pathComponents count] == 1) && 
-                               ![PithosUtilities isContentTypeDirectory:object.contentType]) {
-                        // Skip root file object
-                        // Remove stored state if any
-                        [containerStoredLocalObjectStates removeObjectForKey:object.name];                    
-                        continue;
-                    }
-                    if (![containerStoredLocalObjectStates objectForKey:object.name])
-                        [containerStoredLocalObjectStates setObject:[PithosLocalObjectState localObjectState] forKey:object.name];
+                    [self saveLocalState];
                 }
-                [self saveLocalState];
             }
-        }
 
-        if (operation.isCancelled) {
-            operation.completionBlock = nil;
-            [self syncOperationFinishedWithSuccess:NO];
-            [pool drain];
-            return;
-        }
+            if (operation.isCancelled) {
+                operation.completionBlock = nil;
+                [self syncOperationFinishedWithSuccess:NO];
+                return;
+            }
 
-        // For each stored state compare with current and remote state
-        // Stored states of local objects that have been deleted, 
-        // haven't been checked for legality (only existing local remote objects)
-        // These should be identified and skipped
-        for (NSString *accountName in accountsNames) {
-            for (ASIPithosContainer *pithosContainer in [accountsPithosContainers objectForKey:accountName]) {
-                NSString *containerDirectoryPath = [self dirPathForAccount:accountName container:pithosContainer.name];
-                NSSet *containerExcludedDirectories = [[accountsDictionary objectForKey:accountName] objectForKey:pithosContainer.name];
-                BOOL containerExcludeRootFiles = [containerExcludedDirectories containsObject:@""];
-                NSMutableDictionary *containerStoredLocalObjectStates = [[storedLocalObjectStates objectForKey:accountName] 
-                                                                         objectForKey:pithosContainer.name];
-                NSMutableDictionary *containerRemoteObjects = [[remoteObjects objectForKey:accountName] objectForKey:pithosContainer.name];
-                for (NSString *objectName in [[containerStoredLocalObjectStates allKeys] sortedArrayUsingSelector:@selector(compare:)]) {
-                    if (operation.isCancelled) {
-                        operation.completionBlock = nil;
-                        [self syncOperationFinishedWithSuccess:NO];
-                        [pool drain];
-                        return;
-                    }
+            // For each stored state compare with current and remote state
+            // Stored states of local objects that have been deleted, 
+            // haven't been checked for legality (only existing local remote objects)
+            // These should be identified and skipped
+            for (NSString *accountName in accountsNames) {
+                for (ASIPithosContainer *pithosContainer in [accountsPithosContainers objectForKey:accountName]) {
+                    NSString *containerDirectoryPath = [self dirPathForAccount:accountName container:pithosContainer.name];
+                    NSSet *containerExcludedDirectories = [[accountsDictionary objectForKey:accountName] objectForKey:pithosContainer.name];
+                    BOOL containerExcludeRootFiles = [containerExcludedDirectories containsObject:@""];
+                    NSMutableDictionary *containerStoredLocalObjectStates = [[storedLocalObjectStates objectForKey:accountName] 
+                                                                             objectForKey:pithosContainer.name];
+                    NSMutableDictionary *containerRemoteObjects = [[remoteObjects objectForKey:accountName] objectForKey:pithosContainer.name];
+                    for (NSString *objectName in [[containerStoredLocalObjectStates allKeys] sortedArrayUsingSelector:@selector(compare:)]) {
+                        if (operation.isCancelled) {
+                            operation.completionBlock = nil;
+                            [self syncOperationFinishedWithSuccess:NO];
+                            return;
+                        }
 
-                    NSString *filePath = [containerDirectoryPath stringByAppendingPathComponent:objectName];
-                    if ([objectName hasSuffix:@"/"])
-                        filePath = [filePath stringByAppendingString:@":"];
-                    ASIPithosObject *object = [ASIPithosObject object];
-                    object.name = objectName;
-                    DLog(@"Sync::object name: %@", object.name);
-
-                    PithosLocalObjectState *storedLocalObjectState = [containerStoredLocalObjectStates objectForKey:object.name];
-                    PithosLocalObjectState *currentLocalObjectState = [currentLocalObjectStates objectForKey:filePath];
-                    if (!currentLocalObjectState) {
-                        // The stored state corresponds to a remote or deleted local object, that's why there is no current state
-                        // In the latter case it must be checked for legality, which can be determined by its stored state
-                        // If it existed locally, but was deleted, state.exists is true, 
-                        // else if the stored state is an empty state that was created due to the server object, state.exists is false
-                        if (storedLocalObjectState.exists) {
-                            NSString *localObjectName;
-                            if ([object.name hasSuffix:@"/"])
-                                localObjectName = [NSString stringWithFormat:@"%@:", [object.name substringToIndex:([object.name length] -1)]];
-                            else
-                                localObjectName = [NSString stringWithString:object.name];
-                            NSArray *pathComponents = [localObjectName pathComponents];
-                            if (skipHidden) {
-                                BOOL skipObject = NO;
-                                for (NSString *pathComponent in pathComponents) {
-                                    if ([pathComponent hasPrefix:@"."]) {
-                                        // Skip hidden directory and its descendants, or hidden file
-                                        // Remove stored state if any
-                                        [containerStoredLocalObjectStates removeObjectForKey:objectName];
-                                        [self saveLocalState];
-                                        skipObject = YES;
-                                        break;
+                        NSString *filePath = [containerDirectoryPath stringByAppendingPathComponent:objectName];
+                        if ([objectName hasSuffix:@"/"])
+                            filePath = [filePath stringByAppendingString:@":"];
+                        ASIPithosObject *object = [ASIPithosObject object];
+                        object.name = objectName;
+                        DLog(@"Sync::object name: %@", object.name);
+
+                        PithosLocalObjectState *storedLocalObjectState = [containerStoredLocalObjectStates objectForKey:object.name];
+                        PithosLocalObjectState *currentLocalObjectState = [currentLocalObjectStates objectForKey:filePath];
+                        if (!currentLocalObjectState) {
+                            // The stored state corresponds to a remote or deleted local object, that's why there is no current state
+                            // In the latter case it must be checked for legality, which can be determined by its stored state
+                            // If it existed locally, but was deleted, state.exists is true, 
+                            // else if the stored state is an empty state that was created due to the server object, state.exists is false
+                            if (storedLocalObjectState.exists) {
+                                NSString *localObjectName;
+                                if ([object.name hasSuffix:@"/"])
+                                    localObjectName = [NSString stringWithFormat:@"%@:", [object.name substringToIndex:([object.name length] -1)]];
+                                else
+                                    localObjectName = [NSString stringWithString:object.name];
+                                NSArray *pathComponents = [localObjectName pathComponents];
+                                if (skipHidden) {
+                                    BOOL skipObject = NO;
+                                    for (NSString *pathComponent in pathComponents) {
+                                        if ([pathComponent hasPrefix:@"."]) {
+                                            // Skip hidden directory and its descendants, or hidden file
+                                            // Remove stored state if any
+                                            [containerStoredLocalObjectStates removeObjectForKey:objectName];
+                                            [self saveLocalState];
+                                            skipObject = YES;
+                                            break;
+                                        }
                                     }
+                                    if (skipObject)
+                                        continue;
                                 }
-                                if (skipObject)
+                                if ([containerExcludedDirectories containsObject:[[pathComponents objectAtIndex:0] lowercaseString]]) {
+                                    // Skip excluded directory object and its descendants, or root file object with same name
+                                    // Remove stored state
+                                    [containerStoredLocalObjectStates removeObjectForKey:object.name];
+                                    [self saveLocalState];
                                     continue;
+                                } else if (containerExcludeRootFiles && ([pathComponents count] == 1) && !storedLocalObjectState.isDirectory) {
+                                    // Skip root file object
+                                    // Remove stored state
+                                    [containerStoredLocalObjectStates removeObjectForKey:object.name];                    
+                                    [self saveLocalState];
+                                    continue;
+                                }
                             }
-                            if ([containerExcludedDirectories containsObject:[[pathComponents objectAtIndex:0] lowercaseString]]) {
-                                // Skip excluded directory object and its descendants, or root file object with same name
-                                // Remove stored state
-                                [containerStoredLocalObjectStates removeObjectForKey:object.name];
-                                [self saveLocalState];
-                                continue;
-                            } else if (containerExcludeRootFiles && ([pathComponents count] == 1) && !storedLocalObjectState.isDirectory) {
-                                // Skip root file object
-                                // Remove stored state
-                                [containerStoredLocalObjectStates removeObjectForKey:object.name];                    
-                                [self saveLocalState];
-                                continue;
-                            }
+                            // There is also the off case that a local object has been created in the meantime
+                            // This call works in any case, existent or non-existent local object 
+                            currentLocalObjectState = [PithosLocalObjectState localObjectStateWithFile:filePath 
+                                                                                             blockHash:pithosContainer.blockHash 
+                                                                                             blockSize:pithosContainer.blockSize];
                         }
-                        // There is also the off case that a local object has been created in the meantime
-                        // This call works in any case, existent or non-existent local object 
-                        currentLocalObjectState = [PithosLocalObjectState localObjectStateWithFile:filePath 
-                                                                                         blockHash:pithosContainer.blockHash 
-                                                                                         blockSize:pithosContainer.blockSize];
-                    }
-            
-                    PithosLocalObjectState *remoteObjectState = [PithosLocalObjectState localObjectState];
-                    ASIPithosObject *remoteObject = [containerRemoteObjects objectForKey:object.name];
-                    if (remoteObject) {
-                        if ([PithosUtilities isContentTypeDirectory:remoteObject.contentType]) {
-                            remoteObjectState.isDirectory = YES;
-                        } else {
-                            remoteObjectState.hash = remoteObject.objectHash;
+                
+                        PithosLocalObjectState *remoteObjectState = [PithosLocalObjectState localObjectState];
+                        ASIPithosObject *remoteObject = [containerRemoteObjects objectForKey:object.name];
+                        if (remoteObject) {
+                            if ([PithosUtilities isContentTypeDirectory:remoteObject.contentType]) {
+                                remoteObjectState.isDirectory = YES;
+                            } else {
+                                remoteObjectState.hash = remoteObject.objectHash;
+                            }
                         }
-                    }
 
-                    BOOL localStateHasChanged = ![currentLocalObjectState isEqualToState:storedLocalObjectState];
-                    BOOL serverStateHasChanged = ![remoteObjectState isEqualToState:storedLocalObjectState];
-                    DLog(@"Sync::localStateHasChanged: %d, serverStateHasChanged: %d", localStateHasChanged, serverStateHasChanged);
-                    if (!localStateHasChanged) {
-                        // Local state hasn't changed
-                        if (serverStateHasChanged) {
-                            // Server state has changed
-                            // Update local state to match that of the server 
-                            object.bytes = remoteObject.bytes;
-                            object.version = remoteObject.version;
-                            object.contentType = remoteObject.contentType;
-                            object.objectHash = remoteObject.objectHash;
-                            [self updateLocalStateWithObject:object localFilePath:filePath 
-                                                 accountName:accountName pithosContainer:pithosContainer];
-                        } else if (!remoteObject && ![currentLocalObjectState exists]) {
-                            // Server state hasn't changed
-                            // If the object doesn't exist neither in the server or locally, it should be removed from the stored local objects
-                            [containerStoredLocalObjectStates removeObjectForKey:objectName];
-                            [self saveLocalState];
-                        }
-                } else {
-                    // Local state has changed
-                    if (!serverStateHasChanged) {
-                        // Server state hasn't changed
-                        if (currentLocalObjectState.isDirectory)
-                            object.contentType = @"application/directory";
-                        else
-                            object.objectHash = currentLocalObjectState.hash;
-                        [self updateServerStateWithCurrentState:currentLocalObjectState object:object localFilePath:filePath 
-                                                    accountName:accountName pithosContainer:pithosContainer];
-                    } else {
-                        // Server state has also changed
-                        if (remoteObjectState.isDirectory && currentLocalObjectState.isDirectory) {
-                            // Both did the same change (directory)
-                            storedLocalObjectState.filePath = filePath;
-                            storedLocalObjectState.isDirectory = YES;
-                            [self saveLocalState];
-                        } else if ([remoteObjectState isEqualToState:currentLocalObjectState]) {
-                            // Both did the same change (object edit or delete)
-                            if (![remoteObjectState exists]) {
-                                [containerStoredLocalObjectStates removeObjectForKey:object.name];
-                            } else {
-                                storedLocalObjectState.filePath = filePath;
-                                storedLocalObjectState.hash = remoteObjectState.hash;
+                        BOOL localStateHasChanged = ![currentLocalObjectState isEqualToState:storedLocalObjectState];
+                        BOOL serverStateHasChanged = ![remoteObjectState isEqualToState:storedLocalObjectState];
+                        DLog(@"Sync::localStateHasChanged: %d, serverStateHasChanged: %d", localStateHasChanged, serverStateHasChanged);
+                        if (!localStateHasChanged) {
+                            // Local state hasn't changed
+                            if (serverStateHasChanged) {
+                                // Server state has changed
+                                // Update local state to match that of the server 
+                                object.bytes = remoteObject.bytes;
+                                object.version = remoteObject.version;
+                                object.contentType = remoteObject.contentType;
+                                object.objectHash = remoteObject.objectHash;
+                                [self updateLocalStateWithObject:object localFilePath:filePath 
+                                                     accountName:accountName pithosContainer:pithosContainer];
+                            } else if (!remoteObject && ![currentLocalObjectState exists]) {
+                                // Server state hasn't changed
+                                // If the object doesn't exist neither in the server or locally, it should be removed from the stored local objects
+                                [containerStoredLocalObjectStates removeObjectForKey:objectName];
+                                [self saveLocalState];
                             }
-                            [self saveLocalState];
+                    } else {
+                        // Local state has changed
+                        if (!serverStateHasChanged) {
+                            // Server state hasn't changed
+                            if (currentLocalObjectState.isDirectory)
+                                object.contentType = @"application/directory";
+                            else
+                                object.objectHash = currentLocalObjectState.hash;
+                            [self updateServerStateWithCurrentState:currentLocalObjectState object:object localFilePath:filePath 
+                                                        accountName:accountName pithosContainer:pithosContainer];
                         } else {
-                            // Conflict, we ask the user which change to keep
-                            NSString *informativeText;
-                            NSString *firstButtonText;
-                            NSString *secondButtonText;
-                            
-                            if (![remoteObjectState exists]) {
-                                // Remote object has been deleted
-                                informativeText = [NSString stringWithFormat:@"'%@/%@' has been modified locally, while it has been deleted from server.", 
-                                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name ];
-                                firstButtonText = @"Delete local file";
-                                secondButtonText = @"Upload file to server";
-                            } else if (![currentLocalObjectState exists]) {
-                                informativeText = [NSString stringWithFormat:@"'%@/%@' has been modified on the server, while it has been deleted locally.", 
-                                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
-                                firstButtonText = @"Download file from server";
-                                secondButtonText = @"Delete file on server";
+                            // Server state has also changed
+                            if (remoteObjectState.isDirectory && currentLocalObjectState.isDirectory) {
+                                // Both did the same change (directory)
+                                storedLocalObjectState.filePath = filePath;
+                                storedLocalObjectState.isDirectory = YES;
+                                [self saveLocalState];
+                            } else if ([remoteObjectState isEqualToState:currentLocalObjectState]) {
+                                // Both did the same change (object edit or delete)
+                                if (![remoteObjectState exists]) {
+                                    [containerStoredLocalObjectStates removeObjectForKey:object.name];
+                                } else {
+                                    storedLocalObjectState.filePath = filePath;
+                                    storedLocalObjectState.hash = remoteObjectState.hash;
+                                }
+                                [self saveLocalState];
                             } else {
-                                informativeText = [NSString stringWithFormat:@"'%@/%@' has been modified both locally and on the server.", 
-                                                   [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
-                                firstButtonText = @"Keep server version";
-                                secondButtonText = @"Keep local version";
-                            }
-                            __block NSInteger choice;
-                            dispatch_sync(dispatch_get_main_queue(), ^{
-                                NSAlert *alert = [[[NSAlert alloc] init] autorelease];
-                                [alert setMessageText:@"Conflict"];
-                                [alert setInformativeText:informativeText];
-                                [alert addButtonWithTitle:firstButtonText];
-                                [alert addButtonWithTitle:secondButtonText];
-                                [alert addButtonWithTitle:@"Do nothing"];
-                                choice = [alert runModal];
-                            });
-                            if (choice == NSAlertFirstButtonReturn) {
-                                object.bytes = remoteObject.bytes;
-                                object.version = remoteObject.version;
-                                object.contentType = remoteObject.contentType;
-                                object.objectHash = remoteObject.objectHash;
-                                [self updateLocalStateWithObject:object localFilePath:filePath 
-                                                 accountName:accountName pithosContainer:pithosContainer];
-                            } if (choice == NSAlertSecondButtonReturn) {
-                                if (currentLocalObjectState.isDirectory)
-                                    object.contentType = @"application/directory";
-                                else
-                                    object.objectHash = currentLocalObjectState.hash;
-                                [self updateServerStateWithCurrentState:currentLocalObjectState object:object localFilePath:filePath 
-                                                            accountName:accountName pithosContainer:pithosContainer];
+                                // Conflict, we ask the user which change to keep
+                                NSString *informativeText;
+                                NSString *firstButtonText;
+                                NSString *secondButtonText;
+                                
+                                if (![remoteObjectState exists]) {
+                                    // Remote object has been deleted
+                                    informativeText = [NSString stringWithFormat:@"'%@/%@' has been modified locally, while it has been deleted from server.", 
+                                                       [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name ];
+                                    firstButtonText = @"Delete local file";
+                                    secondButtonText = @"Upload file to server";
+                                } else if (![currentLocalObjectState exists]) {
+                                    informativeText = [NSString stringWithFormat:@"'%@/%@' has been modified on the server, while it has been deleted locally.", 
+                                                       [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
+                                    firstButtonText = @"Download file from server";
+                                    secondButtonText = @"Delete file on server";
+                                } else {
+                                    informativeText = [NSString stringWithFormat:@"'%@/%@' has been modified both locally and on the server.", 
+                                                       [self relativeDirPathForAccount:accountName container:pithosContainer.name], object.name];
+                                    firstButtonText = @"Keep server version";
+                                    secondButtonText = @"Keep local version";
+                                }
+                                __block NSInteger choice;
+                                dispatch_sync(dispatch_get_main_queue(), ^{
+                                    NSAlert *alert = [[NSAlert alloc] init];
+                                    [alert setMessageText:@"Conflict"];
+                                    [alert setInformativeText:informativeText];
+                                    [alert addButtonWithTitle:firstButtonText];
+                                    [alert addButtonWithTitle:secondButtonText];
+                                    [alert addButtonWithTitle:@"Do nothing"];
+                                    choice = [alert runModal];
+                                });
+                                if (choice == NSAlertFirstButtonReturn) {
+                                    object.bytes = remoteObject.bytes;
+                                    object.version = remoteObject.version;
+                                    object.contentType = remoteObject.contentType;
+                                    object.objectHash = remoteObject.objectHash;
+                                    [self updateLocalStateWithObject:object localFilePath:filePath 
+                                                     accountName:accountName pithosContainer:pithosContainer];
+                                } if (choice == NSAlertSecondButtonReturn) {
+                                    if (currentLocalObjectState.isDirectory)
+                                        object.contentType = @"application/directory";
+                                    else
+                                        object.objectHash = currentLocalObjectState.hash;
+                                    [self updateServerStateWithCurrentState:currentLocalObjectState object:object localFilePath:filePath 
+                                                                accountName:accountName pithosContainer:pithosContainer];
+                                }
                             }
                         }
                     }
                 }
             }
+            }
+            [self syncOperationFinishedWithSuccess:YES];
+        } else {
+            [self listRequestFailed:containerRequest];
         }
-        }
-        [self syncOperationFinishedWithSuccess:YES];
-    } else {
-        [self listRequestFailed:containerRequest];
     }
-    [pool drain];
 }
 
 - (void)listRequestFailed:(ASIPithosContainerRequest *)containerRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [containerRequest.userInfo objectForKey:@"operation"];
-    if (operation.isCancelled) {
-        [objects release];
-        objects = nil;
-        [pool drain];
-        return;        
-    }
-    if (containerRequest.isCancelled) {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"] 
-                              withMessage:[containerRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
-        });
-        [objects release];
-        objects = nil;
-        [self syncOperationFinishedWithSuccess:NO];
-        [pool drain];
-        return;
-    }
-    // If the server listing fails, the sync should start over, so just retrying is enough
-    NSUInteger retries = [[containerRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue];
-    if (retries > 0) {
-        ASIPithosContainerRequest *newContainerRequest = (ASIPithosContainerRequest *)[[PithosUtilities copyRequest:containerRequest] autorelease];
-        [(NSMutableDictionary *)(newContainerRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
-        [networkQueue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
-    } else {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"] 
-                              withMessage:[containerRequest.userInfo objectForKey:@"failedActivityMessage"]];
-        });
-        [objects release];
-        objects = nil;
-        // Since the server listing failed in all retries, the operation finished and the sync cycle is completeted unsuccesfully
-        [self syncOperationFinishedWithSuccess:NO];
-    }
-    [pool drain];
-}
-
-- (void)downloadObjectBlockFinished:(ASIPithosObjectRequest *)objectRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::download object block finished: %@", objectRequest.url);
-    if (operation.isCancelled) {
-        [self requestFailed:objectRequest];
-    } else if (objectRequest.responseStatusCode == 206) {
-        NSString *accountName = [objectRequest.userInfo objectForKey:@"accountName"];
-        ASIPithosContainer *pithosContainer = [objectRequest.userInfo objectForKey:@"pithosContainer"];
-        ASIPithosObject *object = [objectRequest.userInfo objectForKey:@"pithosObject"];
-        NSFileManager *fileManager = [NSFileManager defaultManager];
-        NSError *error;
-        PithosActivity *activity = [objectRequest.userInfo objectForKey:@"activity"];
-        
-        NSString *downloadsDirPath = self.tempDownloadsDirPath;
-        if (!downloadsDirPath) {
+    @autoreleasepool {
+        NSOperation *operation = [containerRequest.userInfo objectForKey:@"operation"];
+        if (operation.isCancelled) {
+            objects = nil;
+            return;        
+        }
+        if (containerRequest.isCancelled) {
             dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility endActivity:activity 
-                                  withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
+                [activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"] 
+                                  withMessage:[containerRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
             });
+            objects = nil;
             [self syncOperationFinishedWithSuccess:NO];
-            [pool drain];
             return;
         }
-        
-        PithosLocalObjectState *storedState = [[[storedLocalObjectStates objectForKey:accountName] 
-                                                objectForKey:pithosContainer.name] 
-                                               objectForKey:object.name];
-        if ((storedState.tmpFilePath == nil) || ![fileManager fileExistsAtPath:storedState.tmpFilePath]) {
-            NSString *tempFileTemplate = [downloadsDirPath stringByAppendingPathComponent:@"download.XXXXXX"];
-            const char *tempFileTemplateCString = [tempFileTemplate fileSystemRepresentation];
-            char *tempFileNameCString = (char *)malloc(strlen(tempFileTemplateCString) + 1);
-            strcpy(tempFileNameCString, tempFileTemplateCString);
-            int fileDescriptor = mkstemp(tempFileNameCString);
-            NSString *tempFilePath = [fileManager stringWithFileSystemRepresentation:tempFileNameCString length:strlen(tempFileNameCString)];
-            free(tempFileNameCString);
-            if (fileDescriptor == -1) {
-                [PithosUtilities fileActionFailedAlertWithTitle:@"Create Temporary File Error" 
-                                                        message:[NSString stringWithFormat:@"Cannot create temporary file at '%@'", tempFilePath] 
-                                                          error:nil];
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    [activityFacility endActivity:activity 
-                                      withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
-                });
-                [self syncOperationFinishedWithSuccess:NO];
-                [pool drain];
-                return;
-            }
-            close(fileDescriptor);
-            storedState.tmpFilePath = tempFilePath;
-            [self saveLocalState];
+        // If the server listing fails, the sync should start over, so just retrying is enough
+        NSUInteger retries = [[containerRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue];
+        if (retries > 0) {
+            ASIPithosContainerRequest *newContainerRequest = (ASIPithosContainerRequest *)[PithosUtilities copyRequest:containerRequest];
+            [(NSMutableDictionary *)(newContainerRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+            [networkQueue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
+        } else {
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"] 
+                                  withMessage:[containerRequest.userInfo objectForKey:@"failedActivityMessage"]];
+            });
+            objects = nil;
+            // Since the server listing failed in all retries, the operation finished and the sync cycle is completeted unsuccesfully
+            [self syncOperationFinishedWithSuccess:NO];
         }
+    }
+}
 
-        NSUInteger missingBlockIndex = [[objectRequest.userInfo objectForKey:@"missingBlockIndex"] unsignedIntegerValue];
-        NSFileHandle *tempFileHandle = [NSFileHandle fileHandleForWritingAtPath:storedState.tmpFilePath];
-        [tempFileHandle seekToFileOffset:missingBlockIndex*pithosContainer.blockSize];
-        [tempFileHandle writeData:[objectRequest responseData]];
-        [tempFileHandle closeFile];
-
-        NSIndexSet *missingBlocks = [objectRequest.userInfo objectForKey:@"missingBlocks"];
-        missingBlockIndex = [missingBlocks indexGreaterThanIndex:missingBlockIndex];
-        if (missingBlockIndex == NSNotFound) {
-            NSString *filePath = [objectRequest.userInfo objectForKey:@"filePath"];
-            NSString *dirPath = [filePath stringByDeletingLastPathComponent];
-            if ([fileManager fileExistsAtPath:filePath] && ![self moveToTempTrashFile:filePath 
-                                                                          accountName:accountName 
-                                                                      pithosContainer:pithosContainer]) {
+- (void)downloadObjectBlockFinished:(ASIPithosObjectRequest *)objectRequest {
+    @autoreleasepool {
+        NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::download object block finished: %@", objectRequest.url);
+        if (operation.isCancelled) {
+            [self requestFailed:objectRequest];
+        } else if (objectRequest.responseStatusCode == 206) {
+            NSString *accountName = [objectRequest.userInfo objectForKey:@"accountName"];
+            ASIPithosContainer *pithosContainer = [objectRequest.userInfo objectForKey:@"pithosContainer"];
+            ASIPithosObject *object = [objectRequest.userInfo objectForKey:@"pithosObject"];
+            NSFileManager *fileManager = [NSFileManager defaultManager];
+            NSError *error;
+            PithosActivity *activity = [objectRequest.userInfo objectForKey:@"activity"];
+            
+            NSString *downloadsDirPath = self.tempDownloadsDirPath;
+            if (!downloadsDirPath) {
                 dispatch_async(dispatch_get_main_queue(), ^{
                     [activityFacility endActivity:activity 
                                       withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
                 });
                 [self syncOperationFinishedWithSuccess:NO];
-                [pool drain];
                 return;
-            } else if (![fileManager fileExistsAtPath:dirPath]) {
-                // File doesn't exist but also the containing directory doesn't exist
-                // In most cases this should have been resolved as an update of the corresponding local object,
-                // but it never hurts to check
+            }
+            
+            PithosLocalObjectState *storedState = [[[storedLocalObjectStates objectForKey:accountName] 
+                                                    objectForKey:pithosContainer.name] 
+                                                   objectForKey:object.name];
+            if ((storedState.tmpFilePath == nil) || ![fileManager fileExistsAtPath:storedState.tmpFilePath]) {
+                NSString *tempFileTemplate = [downloadsDirPath stringByAppendingPathComponent:@"download.XXXXXX"];
+                const char *tempFileTemplateCString = [tempFileTemplate fileSystemRepresentation];
+                char *tempFileNameCString = (char *)malloc(strlen(tempFileTemplateCString) + 1);
+                strcpy(tempFileNameCString, tempFileTemplateCString);
+                int fileDescriptor = mkstemp(tempFileNameCString);
+                NSString *tempFilePath = [fileManager stringWithFileSystemRepresentation:tempFileNameCString length:strlen(tempFileNameCString)];
+                free(tempFileNameCString);
+                if (fileDescriptor == -1) {
+                    [PithosUtilities fileActionFailedAlertWithTitle:@"Create Temporary File Error" 
+                                                            message:[NSString stringWithFormat:@"Cannot create temporary file at '%@'", tempFilePath] 
+                                                              error:nil];
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        [activityFacility endActivity:activity 
+                                          withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
+                    });
+                    [self syncOperationFinishedWithSuccess:NO];
+                    return;
+                }
+                close(fileDescriptor);
+                storedState.tmpFilePath = tempFilePath;
+                [self saveLocalState];
+            }
+
+            NSUInteger missingBlockIndex = [[objectRequest.userInfo objectForKey:@"missingBlockIndex"] unsignedIntegerValue];
+            NSFileHandle *tempFileHandle = [NSFileHandle fileHandleForWritingAtPath:storedState.tmpFilePath];
+            [tempFileHandle seekToFileOffset:missingBlockIndex*pithosContainer.blockSize];
+            [tempFileHandle writeData:[objectRequest responseData]];
+            [tempFileHandle closeFile];
+
+            NSIndexSet *missingBlocks = [objectRequest.userInfo objectForKey:@"missingBlocks"];
+            missingBlockIndex = [missingBlocks indexGreaterThanIndex:missingBlockIndex];
+            if (missingBlockIndex == NSNotFound) {
+                NSString *filePath = [objectRequest.userInfo objectForKey:@"filePath"];
+                NSString *dirPath = [filePath stringByDeletingLastPathComponent];
+                if ([fileManager fileExistsAtPath:filePath] && ![self moveToTempTrashFile:filePath 
+                                                                              accountName:accountName 
+                                                                          pithosContainer:pithosContainer]) {
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        [activityFacility endActivity:activity 
+                                          withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
+                    });
+                    [self syncOperationFinishedWithSuccess:NO];
+                    return;
+                } else if (![fileManager fileExistsAtPath:dirPath]) {
+                    // File doesn't exist but also the containing directory doesn't exist
+                    // In most cases this should have been resolved as an update of the corresponding local object,
+                    // but it never hurts to check
+                    error = nil;
+                    [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];
+                    if (error != nil) {
+                        [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
+                                                                message:[NSString stringWithFormat:@"Cannot create directory at '%@'", dirPath] 
+                                                                  error:error];
+                        dispatch_async(dispatch_get_main_queue(), ^{
+                            [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
+                                              withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
+                        });
+                        [self syncOperationFinishedWithSuccess:NO];
+                        return;
+                    }
+                }
+                // Move file from tmp download
                 error = nil;
-                [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];
+                [fileManager moveItemAtPath:storedState.tmpFilePath toPath:filePath error:&error];
                 if (error != nil) {
-                    [PithosUtilities fileActionFailedAlertWithTitle:@"Create Directory Error" 
-                                                            message:[NSString stringWithFormat:@"Cannot create directory at '%@'", dirPath] 
+                    [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
+                                                            message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", storedState.tmpFilePath, filePath] 
                                                               error:error];
                     dispatch_async(dispatch_get_main_queue(), ^{
-                        [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
+                        [activityFacility endActivity:activity 
                                           withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
                     });
                     [self syncOperationFinishedWithSuccess:NO];
-                    [pool drain];
                     return;
                 }
-            }
-            // Move file from tmp download
-            error = nil;
-            [fileManager moveItemAtPath:storedState.tmpFilePath toPath:filePath error:&error];
-            if (error != nil) {
-                [PithosUtilities fileActionFailedAlertWithTitle:@"Move File Error" 
-                                                        message:[NSString stringWithFormat:@"Cannot move file at '%@' to '%@'", storedState.tmpFilePath, filePath] 
-                                                          error:error];
                 dispatch_async(dispatch_get_main_queue(), ^{
                     [activityFacility endActivity:activity 
-                                      withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
+                                      withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"] 
+                                       totalBytes:activity.totalBytes 
+                                     currentBytes:activity.totalBytes];
                 });
-                [self syncOperationFinishedWithSuccess:NO];
-                [pool drain];
+
+                storedState.filePath = filePath;
+                storedState.hash = object.objectHash;
+                storedState.tmpFilePath = nil;
+                [self saveLocalState];
+                [self syncOperationFinishedWithSuccess:YES];
                 return;
+            } else {
+                if (newSyncRequested || syncLate || operation.isCancelled) {
+                    [self requestFailed:objectRequest];
+                } else {
+                    __block ASIPithosObjectRequest *newObjectRequest = [PithosUtilities objectBlockDataRequestWithPithos:pithos
+                                                                                                           containerName:pithosContainer.name 
+                                                                                                                  object:object 
+                                                                                                              blockIndex:missingBlockIndex 
+                                                                                                               blockSize:pithosContainer.blockSize];
+                    if (![accountName isEqualToString:@""])
+                        [newObjectRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
+                    newObjectRequest.delegate = self;
+                    newObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                    newObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                    newObjectRequest.userInfo = objectRequest.userInfo;
+                    [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:missingBlockIndex] forKey:@"missingBlockIndex"];
+                    [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
+                    [newObjectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){
+                        [activityFacility updateActivity:activity 
+                                             withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
+                                                          [newObjectRequest.userInfo objectForKey:@"messagePrefix"], 
+                                                          (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0))] 
+                                              totalBytes:activity.totalBytes 
+                                            currentBytes:(activity.currentBytes + size)];
+                    }];
+                    [networkQueue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]]];
+                }
             }
+        } else if (objectRequest.responseStatusCode == 412) {
+            // The object has changed on the server
             dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility endActivity:activity 
-                                  withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"] 
-                                   totalBytes:activity.totalBytes 
-                                 currentBytes:activity.totalBytes];
+                [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
+                                  withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
             });
-
-            storedState.filePath = filePath;
-            storedState.hash = object.objectHash;
-            storedState.tmpFilePath = nil;
-            [self saveLocalState];
-            [self syncOperationFinishedWithSuccess:YES];
-            [pool drain];
-            return;
+            [self syncOperationFinishedWithSuccess:NO];
         } else {
+            [self requestFailed:objectRequest];
+        }
+    }
+}
+
+- (void)downloadObjectHashMapFinished:(ASIPithosObjectRequest *)objectRequest {
+    @autoreleasepool {
+        NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::download object hashmap finished: %@", objectRequest.url);
+        if (operation.isCancelled) {
+            [self requestFailed:objectRequest];
+        } else if (objectRequest.responseStatusCode == 200) {
             if (newSyncRequested || syncLate || operation.isCancelled) {
                 [self requestFailed:objectRequest];
             } else {
-                __block ASIPithosObjectRequest *newObjectRequest = [PithosUtilities objectBlockDataRequestWithPithos:pithos 
+                NSString *accountName = [objectRequest.userInfo objectForKey:@"accountName"];
+                ASIPithosContainer *pithosContainer = [objectRequest.userInfo objectForKey:@"pithosContainer"];
+                ASIPithosObject *object = [objectRequest.userInfo objectForKey:@"pithosObject"];
+                PithosLocalObjectState *storedState = [[[storedLocalObjectStates objectForKey:accountName] 
+                                                        objectForKey:pithosContainer.name] 
+                                                       objectForKey:object.name];
+                if ([PithosUtilities bytesOfFile:storedState.tmpFilePath] > object.bytes)
+                    [[NSFileHandle fileHandleForWritingAtPath:storedState.tmpFilePath] truncateFileAtOffset:object.bytes];
+                PithosActivity *activity = [objectRequest.userInfo objectForKey:@"activity"];
+                NSIndexSet *missingBlocks = [PithosUtilities missingBlocksForFile:storedState.tmpFilePath 
+                                                                        blockSize:pithosContainer.blockSize 
+                                                                        blockHash:pithosContainer.blockHash 
+                                                                       withHashes:[objectRequest hashes]];
+                NSUInteger missingBlockIndex = [missingBlocks firstIndex];
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility updateActivity:activity 
+                                         withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
+                                                      [objectRequest.userInfo objectForKey:@"messagePrefix"], 
+                                                      (100*(activity.totalBytes - [missingBlocks count]*pithosContainer.blockSize + 0.0)/(activity.totalBytes + 0.0))] 
+                                          totalBytes:activity.totalBytes 
+                                        currentBytes:(activity.totalBytes - [missingBlocks count]*pithosContainer.blockSize)];
+                });
+
+                __block ASIPithosObjectRequest *newObjectRequest = [PithosUtilities objectBlockDataRequestWithPithos:pithos
                                                                                                        containerName:pithosContainer.name 
                                                                                                               object:object 
                                                                                                           blockIndex:missingBlockIndex 
                 newObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
                 newObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
                 newObjectRequest.userInfo = objectRequest.userInfo;
+                [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:missingBlocks forKey:@"missingBlocks"];
                 [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:missingBlockIndex] forKey:@"missingBlockIndex"];
                 [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
+                [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:NSStringFromSelector(@selector(downloadObjectBlockFinished:)) forKey:@"didFinishSelector"];
                 [newObjectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){
                     [activityFacility updateActivity:activity 
                                          withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
                 }];
                 [networkQueue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]]];
             }
+        } else {
+            [self requestFailed:objectRequest];
         }
-    } else if (objectRequest.responseStatusCode == 412) {
-        // The object has changed on the server
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
-                              withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
-        });
-        [self syncOperationFinishedWithSuccess:NO];
-    } else {
-        [self requestFailed:objectRequest];
     }
-    [pool drain];
 }
 
-- (void)downloadObjectHashMapFinished:(ASIPithosObjectRequest *)objectRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::download object hashmap finished: %@", objectRequest.url);
-    if (operation.isCancelled) {
-        [self requestFailed:objectRequest];
-    } else if (objectRequest.responseStatusCode == 200) {
-        if (newSyncRequested || syncLate || operation.isCancelled) {
+- (void)uploadDirectoryObjectFinished:(ASIPithosObjectRequest *)objectRequest {
+    @autoreleasepool {
+        NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::upload directory object finished: %@", objectRequest.url);
+        if (operation.isCancelled) {
             [self requestFailed:objectRequest];
-        } else {
-            NSString *accountName = [objectRequest.userInfo objectForKey:@"accountName"];
-            ASIPithosContainer *pithosContainer = [objectRequest.userInfo objectForKey:@"pithosContainer"];
-            ASIPithosObject *object = [objectRequest.userInfo objectForKey:@"pithosObject"];
-            PithosLocalObjectState *storedState = [[[storedLocalObjectStates objectForKey:accountName] 
-                                                    objectForKey:pithosContainer.name] 
-                                                   objectForKey:object.name];
-            if ([PithosUtilities bytesOfFile:storedState.tmpFilePath] > object.bytes)
-                [[NSFileHandle fileHandleForWritingAtPath:storedState.tmpFilePath] truncateFileAtOffset:object.bytes];
-            PithosActivity *activity = [objectRequest.userInfo objectForKey:@"activity"];
-            NSIndexSet *missingBlocks = [PithosUtilities missingBlocksForFile:storedState.tmpFilePath 
-                                                                    blockSize:pithosContainer.blockSize 
-                                                                    blockHash:pithosContainer.blockHash 
-                                                                   withHashes:[objectRequest hashes]];
-            NSUInteger missingBlockIndex = [missingBlocks firstIndex];
+        } else if (objectRequest.responseStatusCode == 201) {
+            PithosLocalObjectState *storedState = [[[storedLocalObjectStates objectForKey:[objectRequest.userInfo objectForKey:@"accountName"]] 
+                                                    objectForKey:[[objectRequest.userInfo objectForKey:@"pithosContainer"] name]] 
+                                                   objectForKey:[[objectRequest.userInfo objectForKey:@"pithosObject"] name]];
+            storedState.isDirectory = YES;
+            [self saveLocalState];
             dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility updateActivity:activity 
-                                     withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
-                                                  [objectRequest.userInfo objectForKey:@"messagePrefix"], 
-                                                  (100*(activity.totalBytes - [missingBlocks count]*pithosContainer.blockSize + 0.0)/(activity.totalBytes + 0.0))] 
-                                      totalBytes:activity.totalBytes 
-                                    currentBytes:(activity.totalBytes - [missingBlocks count]*pithosContainer.blockSize)];
+                [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
+                                  withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"]];
             });
-
-            __block ASIPithosObjectRequest *newObjectRequest = [PithosUtilities objectBlockDataRequestWithPithos:pithos 
-                                                                                                   containerName:pithosContainer.name 
-                                                                                                          object:object 
-                                                                                                      blockIndex:missingBlockIndex 
-                                                                                                       blockSize:pithosContainer.blockSize];
-            if (![accountName isEqualToString:@""])
-                [newObjectRequest setRequestUserFromDefaultTo:accountName withPithos:pithos];
-            newObjectRequest.delegate = self;
-            newObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-            newObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-            newObjectRequest.userInfo = objectRequest.userInfo;
-            [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:missingBlocks forKey:@"missingBlocks"];
-            [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:missingBlockIndex] forKey:@"missingBlockIndex"];
-            [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
-            [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:NSStringFromSelector(@selector(downloadObjectBlockFinished:)) forKey:@"didFinishSelector"];
-            [newObjectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){
-                [activityFacility updateActivity:activity 
-                                     withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
-                                                  [newObjectRequest.userInfo objectForKey:@"messagePrefix"], 
-                                                  (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0))] 
-                                      totalBytes:activity.totalBytes 
-                                    currentBytes:(activity.currentBytes + size)];
-            }];
-            [networkQueue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]]];
+            [self syncOperationFinishedWithSuccess:YES];
+        } else {
+            [self requestFailed:objectRequest];
         }
-    } else {
-        [self requestFailed:objectRequest];
-    }
-    [pool drain];
-}
-
-- (void)uploadDirectoryObjectFinished:(ASIPithosObjectRequest *)objectRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::upload directory object finished: %@", objectRequest.url);
-    if (operation.isCancelled) {
-        [self requestFailed:objectRequest];
-    } else if (objectRequest.responseStatusCode == 201) {
-        PithosLocalObjectState *storedState = [[[storedLocalObjectStates objectForKey:[objectRequest.userInfo objectForKey:@"accountName"]] 
-                                                objectForKey:[[objectRequest.userInfo objectForKey:@"pithosContainer"] name]] 
-                                               objectForKey:[[objectRequest.userInfo objectForKey:@"pithosObject"] name]];
-        storedState.isDirectory = YES;
-        [self saveLocalState];
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
-                              withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"]];
-        });
-        [self syncOperationFinishedWithSuccess:YES];
-    } else {
-        [self requestFailed:objectRequest];
     }
-    [pool drain];
 }
 
 - (void)moveObjectToTrashFinished:(ASIPithosObjectRequest *)objectRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::move object to trash finished: %@", objectRequest.url);
-    if (operation.isCancelled) {
-        [self requestFailed:objectRequest];
-    } else if (objectRequest.responseStatusCode == 201) {
-        [[[storedLocalObjectStates objectForKey:[objectRequest.userInfo objectForKey:@"accountName"]] 
-          objectForKey:[[objectRequest.userInfo objectForKey:@"pithosContainer"] name]] 
-         removeObjectForKey:[[objectRequest.userInfo objectForKey:@"pithosObject"] name]];
-        [self saveLocalState];
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
-                              withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"]];
-        });
-        [self syncOperationFinishedWithSuccess:YES];
-    } else {
-        [self requestFailed:objectRequest];
+    @autoreleasepool {
+        NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::move object to trash finished: %@", objectRequest.url);
+        if (operation.isCancelled) {
+            [self requestFailed:objectRequest];
+        } else if (objectRequest.responseStatusCode == 201) {
+            [[[storedLocalObjectStates objectForKey:[objectRequest.userInfo objectForKey:@"accountName"]] 
+              objectForKey:[[objectRequest.userInfo objectForKey:@"pithosContainer"] name]] 
+             removeObjectForKey:[[objectRequest.userInfo objectForKey:@"pithosObject"] name]];
+            [self saveLocalState];
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
+                                  withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"]];
+            });
+            [self syncOperationFinishedWithSuccess:YES];
+        } else {
+            [self requestFailed:objectRequest];
+        }
     }
-    [pool drain];
 }
 
 - (void)deleteObjectFinished:(ASIPithosObjectRequest *)objectRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::delete object finished: %@", objectRequest.url);
-    if (operation.isCancelled) {
-        [self requestFailed:objectRequest];
-    } else if (objectRequest.responseStatusCode == 204) {
-        [[[storedLocalObjectStates objectForKey:[objectRequest.userInfo objectForKey:@"accountName"]] 
-          objectForKey:[[objectRequest.userInfo objectForKey:@"pithosContainer"] name]] 
-         removeObjectForKey:[[objectRequest.userInfo objectForKey:@"pithosObject"] name]];
-        [self saveLocalState];
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
-                              withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"]];
-        });
-        [self syncOperationFinishedWithSuccess:YES];
-    } else {
-        [self requestFailed:objectRequest];
-    }
-    [pool drain];
-}
-
-- (void)uploadObjectUsingHashMapFinished:(ASIPithosObjectRequest *)objectRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::upload using hashmap finished: %@", objectRequest.url);
-    NSString *accountName = [objectRequest.userInfo objectForKey:@"accountName"];
-    ASIPithosContainer *pithosContainer = [objectRequest.userInfo objectForKey:@"pithosContainer"];
-    ASIPithosObject *object = [objectRequest.userInfo objectForKey:@"pithosObject"];
-    PithosLocalObjectState *storedState = [[[storedLocalObjectStates objectForKey:accountName] 
-                                            objectForKey:pithosContainer.name] 
-                                           objectForKey:object.name];
-    PithosActivity *activity = [objectRequest.userInfo objectForKey:@"activity"];
-    NSUInteger totalBytes = activity.totalBytes;
-    NSUInteger currentBytes = activity.currentBytes;
-    if (operation.isCancelled) {
-        [self requestFailed:objectRequest];
-    } else if (objectRequest.responseStatusCode == 201) {
-        DLog(@"Sync::object created: %@", objectRequest.url);
-        storedState.filePath = [objectRequest.userInfo objectForKey:@"filePath"];
-        storedState.hash = object.objectHash;
-        [self saveLocalState];
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:activity 
-                              withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"] 
-                               totalBytes:totalBytes 
-                             currentBytes:totalBytes];
-        });
-        [self syncOperationFinishedWithSuccess:YES];
-    } else if (objectRequest.responseStatusCode == 409) {
-        if (newSyncRequested || syncLate || operation.isCancelled) {
+    @autoreleasepool {
+        NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::delete object finished: %@", objectRequest.url);
+        if (operation.isCancelled) {
             [self requestFailed:objectRequest];
-        } else {
-            NSUInteger iteration = [[objectRequest.userInfo objectForKey:@"iteration"] unsignedIntegerValue];
-            if (iteration == 0) {
-                DLog(@"Sync::upload iteration limit reached: %@", objectRequest.url);
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    [activityFacility endActivity:activity withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
-                });
-                [self syncOperationFinishedWithSuccess:NO];
-                [pool drain];
-                return;
-            }
-            DLog(@"Sync::object is missing hashes: %@", objectRequest.url);
-            NSIndexSet *missingBlocks = [PithosUtilities missingBlocksForHashes:[objectRequest.userInfo objectForKey:@"hashes"]
-                                                              withMissingHashes:[objectRequest hashes]];
-            if (totalBytes >= [missingBlocks count]*pithosContainer.blockSize)
-                currentBytes = totalBytes - [missingBlocks count]*pithosContainer.blockSize;
+        } else if (objectRequest.responseStatusCode == 204) {
+            [[[storedLocalObjectStates objectForKey:[objectRequest.userInfo objectForKey:@"accountName"]] 
+              objectForKey:[[objectRequest.userInfo objectForKey:@"pithosContainer"] name]] 
+             removeObjectForKey:[[objectRequest.userInfo objectForKey:@"pithosObject"] name]];
+            [self saveLocalState];
             dispatch_async(dispatch_get_main_queue(), ^{
-                [activityFacility updateActivity:activity 
-                                     withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
-                                                  [objectRequest.userInfo objectForKey:@"messagePrefix"], 
-                                                  (100*(currentBytes + 0.0)/(totalBytes + 0.0))] 
-                                      totalBytes:totalBytes 
-                                    currentBytes:currentBytes];
+                [activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"] 
+                                  withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"]];
             });
-            NSUInteger missingBlockIndex = [missingBlocks firstIndex];
-            __block ASIPithosContainerRequest *newContainerRequest = [PithosUtilities updateContainerDataRequestWithPithos:pithos 
-                                                                                                             containerName:pithosContainer.name 
-                                                                                                                 blockSize:pithosContainer.blockSize 
-                                                                                                                   forFile:[objectRequest.userInfo objectForKey:@"filePath"] 
-                                                                                                         missingBlockIndex:missingBlockIndex 
-                                                                                                            sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
-            newContainerRequest.delegate = self;
-            newContainerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-            newContainerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-            newContainerRequest.userInfo = objectRequest.userInfo;
-            [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:(--iteration)] forKey:@"iteration"];
-            [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
-            [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:missingBlocks forKey:@"missingBlocks"];
-            [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:missingBlockIndex] forKey:@"missingBlockIndex"];
-            [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:NSStringFromSelector(@selector(uploadMissingBlockFinished:)) forKey:@"didFinishSelector"];
-            [newContainerRequest setBytesSentBlock:^(unsigned long long size, unsigned long long total){
-                [activityFacility updateActivity:activity 
-                                     withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
-                                                  [newContainerRequest.userInfo objectForKey:@"messagePrefix"], 
-                                                  (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0))] 
-                                      totalBytes:activity.totalBytes 
-                                    currentBytes:(activity.currentBytes + size)];
-            }];
-            [networkQueue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
+            [self syncOperationFinishedWithSuccess:YES];
+        } else {
+            [self requestFailed:objectRequest];
         }
-    } else {
-        [self requestFailed:objectRequest];
     }
-    [pool drain];
 }
 
-- (void)uploadMissingBlockFinished:(ASIPithosContainerRequest *)containerRequest {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [containerRequest.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::upload of missing block finished: %@", containerRequest.url);
-    if (operation.isCancelled) {
-        [self requestFailed:containerRequest];
-    } else if (containerRequest.responseStatusCode == 202) {
-        NSString *accountName = [containerRequest.userInfo objectForKey:@"accountName"];
-        ASIPithosContainer *pithosContainer = [containerRequest.userInfo objectForKey:@"pithosContainer"];
-        ASIPithosObject *object = [containerRequest.userInfo objectForKey:@"pithosObject"];
-        PithosActivity *activity = [containerRequest.userInfo objectForKey:@"activity"];
-        NSIndexSet *missingBlocks = [containerRequest.userInfo objectForKey:@"missingBlocks"];
-        NSUInteger missingBlockIndex = [[containerRequest.userInfo objectForKey:@"missingBlockIndex"] unsignedIntegerValue];
-        missingBlockIndex = [missingBlocks indexGreaterThanIndex:missingBlockIndex];
+- (void)uploadObjectUsingHashMapFinished:(ASIPithosObjectRequest *)objectRequest {
+    @autoreleasepool {
+        NSOperation *operation = [objectRequest.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::upload using hashmap finished: %@", objectRequest.url);
+        NSString *accountName = [objectRequest.userInfo objectForKey:@"accountName"];
+        ASIPithosContainer *pithosContainer = [objectRequest.userInfo objectForKey:@"pithosContainer"];
+        ASIPithosObject *object = [objectRequest.userInfo objectForKey:@"pithosObject"];
+        PithosLocalObjectState *storedState = [[[storedLocalObjectStates objectForKey:accountName] 
+                                                objectForKey:pithosContainer.name] 
+                                               objectForKey:object.name];
+        PithosActivity *activity = [objectRequest.userInfo objectForKey:@"activity"];
+        NSUInteger totalBytes = activity.totalBytes;
+        NSUInteger currentBytes = activity.currentBytes;
         if (operation.isCancelled) {
-            [self requestFailed:containerRequest];
-        } else if (missingBlockIndex == NSNotFound) {
-            NSArray *hashes = [containerRequest.userInfo objectForKey:@"hashes"];
-            ASIPithosObjectRequest *newObjectRequest = [PithosUtilities writeObjectDataRequestWithPithos:pithos 
-                                                                                           containerName:pithosContainer.name 
-                                                                                              objectName:object.name 
-                                                                                             contentType:object.contentType 
-                                                                                               blockSize:pithosContainer.blockSize 
-                                                                                               blockHash:pithosContainer.blockHash
-                                                                                                 forFile:[containerRequest.userInfo objectForKey:@"filePath"] 
-                                                                                           checkIfExists:NO 
-                                                                                                  hashes:&hashes 
-                                                                                          sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
-            newObjectRequest.delegate = self;
-            newObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
-            newObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-            newObjectRequest.userInfo = containerRequest.userInfo;
-            [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
-            [(NSMutableDictionary *)(newObjectRequest.userInfo) removeObjectForKey:@"missingBlocks"];
-            [(NSMutableDictionary *)(newObjectRequest.userInfo) removeObjectForKey:@"missingBlockIndex"];
-            [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:NSStringFromSelector(@selector(uploadObjectUsingHashMapFinished:)) forKey:@"didFinishSelector"];
-            [networkQueue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]]];
-        } else {
+            [self requestFailed:objectRequest];
+        } else if (objectRequest.responseStatusCode == 201) {
+            DLog(@"Sync::object created: %@", objectRequest.url);
+            storedState.filePath = [objectRequest.userInfo objectForKey:@"filePath"];
+            storedState.hash = object.objectHash;
+            [self saveLocalState];
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [activityFacility endActivity:activity 
+                                  withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"] 
+                                   totalBytes:totalBytes 
+                                 currentBytes:totalBytes];
+            });
+            [self syncOperationFinishedWithSuccess:YES];
+        } else if (objectRequest.responseStatusCode == 409) {
             if (newSyncRequested || syncLate || operation.isCancelled) {
-                [self requestFailed:containerRequest];
+                [self requestFailed:objectRequest];
             } else {
-                __block ASIPithosContainerRequest *newContainerRequest = [PithosUtilities updateContainerDataRequestWithPithos:pithos 
-                                                                                                                 containerName:pithosContainer.name
-                                                                                                                     blockSize:pithosContainer.blockSize
-                                                                                                                       forFile:[containerRequest.userInfo objectForKey:@"filePath"] 
+                NSUInteger iteration = [[objectRequest.userInfo objectForKey:@"iteration"] unsignedIntegerValue];
+                if (iteration == 0) {
+                    DLog(@"Sync::upload iteration limit reached: %@", objectRequest.url);
+                    dispatch_async(dispatch_get_main_queue(), ^{
+                        [activityFacility endActivity:activity withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
+                    });
+                    [self syncOperationFinishedWithSuccess:NO];
+                    return;
+                }
+                DLog(@"Sync::object is missing hashes: %@", objectRequest.url);
+                NSIndexSet *missingBlocks = [PithosUtilities missingBlocksForHashes:[objectRequest.userInfo objectForKey:@"hashes"]
+                                                                  withMissingHashes:[objectRequest hashes]];
+                if (totalBytes >= [missingBlocks count]*pithosContainer.blockSize)
+                    currentBytes = totalBytes - [missingBlocks count]*pithosContainer.blockSize;
+                dispatch_async(dispatch_get_main_queue(), ^{
+                    [activityFacility updateActivity:activity 
+                                         withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
+                                                      [objectRequest.userInfo objectForKey:@"messagePrefix"], 
+                                                      (100*(currentBytes + 0.0)/(totalBytes + 0.0))] 
+                                          totalBytes:totalBytes 
+                                        currentBytes:currentBytes];
+                });
+                NSUInteger missingBlockIndex = [missingBlocks firstIndex];
+                __block ASIPithosContainerRequest *newContainerRequest = [PithosUtilities updateContainerDataRequestWithPithos:pithos
+                                                                                                                 containerName:pithosContainer.name 
+                                                                                                                     blockSize:pithosContainer.blockSize 
+                                                                                                                       forFile:[objectRequest.userInfo objectForKey:@"filePath"] 
                                                                                                              missingBlockIndex:missingBlockIndex 
                                                                                                                 sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
                 newContainerRequest.delegate = self;
                 newContainerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
                 newContainerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
-                newContainerRequest.userInfo = containerRequest.userInfo;
+                newContainerRequest.userInfo = objectRequest.userInfo;
+                [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:(--iteration)] forKey:@"iteration"];
                 [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
+                [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:missingBlocks forKey:@"missingBlocks"];
                 [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:missingBlockIndex] forKey:@"missingBlockIndex"];
+                [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:NSStringFromSelector(@selector(uploadMissingBlockFinished:)) forKey:@"didFinishSelector"];
                 [newContainerRequest setBytesSentBlock:^(unsigned long long size, unsigned long long total){
                     [activityFacility updateActivity:activity 
                                          withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
                 }];
                 [networkQueue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
             }
+        } else {
+            [self requestFailed:objectRequest];
         }
-    } else {
-        [self requestFailed:containerRequest];
     }
-    [pool drain];
 }
 
-- (void)requestFailed:(ASIPithosRequest *)request {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSOperation *operation = [request.userInfo objectForKey:@"operation"];
-    DLog(@"Sync::request failed: %@", request.url);
-    if (operation.isCancelled) {
-        [pool drain];
-        return;        
-    }
-    if (request.isCancelled || newSyncRequested || syncLate) {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[request.userInfo objectForKey:@"activity"] 
-                              withMessage:[request.userInfo objectForKey:@"stoppedActivityMessage"]];
-        });
-        [self syncOperationFinishedWithSuccess:NO];
-        [pool drain];
-        return;
+- (void)uploadMissingBlockFinished:(ASIPithosContainerRequest *)containerRequest {
+    @autoreleasepool {
+        NSOperation *operation = [containerRequest.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::upload of missing block finished: %@", containerRequest.url);
+        if (operation.isCancelled) {
+            [self requestFailed:containerRequest];
+        } else if (containerRequest.responseStatusCode == 202) {
+            NSString *accountName = [containerRequest.userInfo objectForKey:@"accountName"];
+            ASIPithosContainer *pithosContainer = [containerRequest.userInfo objectForKey:@"pithosContainer"];
+            ASIPithosObject *object = [containerRequest.userInfo objectForKey:@"pithosObject"];
+            PithosActivity *activity = [containerRequest.userInfo objectForKey:@"activity"];
+            NSIndexSet *missingBlocks = [containerRequest.userInfo objectForKey:@"missingBlocks"];
+            NSUInteger missingBlockIndex = [[containerRequest.userInfo objectForKey:@"missingBlockIndex"] unsignedIntegerValue];
+            missingBlockIndex = [missingBlocks indexGreaterThanIndex:missingBlockIndex];
+            if (operation.isCancelled) {
+                [self requestFailed:containerRequest];
+            } else if (missingBlockIndex == NSNotFound) {
+                NSArray *hashes = [containerRequest.userInfo objectForKey:@"hashes"];
+                ASIPithosObjectRequest *newObjectRequest = [PithosUtilities writeObjectDataRequestWithPithos:pithos 
+                                                                                               containerName:pithosContainer.name 
+                                                                                                  objectName:object.name 
+                                                                                                 contentType:object.contentType 
+                                                                                                   blockSize:pithosContainer.blockSize 
+                                                                                                   blockHash:pithosContainer.blockHash
+                                                                                                     forFile:[containerRequest.userInfo objectForKey:@"filePath"] 
+                                                                                               checkIfExists:NO 
+                                                                                                      hashes:&hashes 
+                                                                                              sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
+                newObjectRequest.delegate = self;
+                newObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                newObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                newObjectRequest.userInfo = containerRequest.userInfo;
+                [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
+                [(NSMutableDictionary *)(newObjectRequest.userInfo) removeObjectForKey:@"missingBlocks"];
+                [(NSMutableDictionary *)(newObjectRequest.userInfo) removeObjectForKey:@"missingBlockIndex"];
+                [(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:NSStringFromSelector(@selector(uploadObjectUsingHashMapFinished:)) forKey:@"didFinishSelector"];
+                [networkQueue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]]];
+            } else {
+                if (newSyncRequested || syncLate || operation.isCancelled) {
+                    [self requestFailed:containerRequest];
+                } else {
+                    __block ASIPithosContainerRequest *newContainerRequest = [PithosUtilities updateContainerDataRequestWithPithos:pithos 
+                                                                                                                     containerName:pithosContainer.name
+                                                                                                                         blockSize:pithosContainer.blockSize
+                                                                                                                           forFile:[containerRequest.userInfo objectForKey:@"filePath"] 
+                                                                                                                 missingBlockIndex:missingBlockIndex 
+                                                                                                                    sharingAccount:([accountName isEqualToString:@""] ? nil : accountName)];
+                    newContainerRequest.delegate = self;
+                    newContainerRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                    newContainerRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                    newContainerRequest.userInfo = containerRequest.userInfo;
+                    [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
+                    [(NSMutableDictionary *)(newContainerRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:missingBlockIndex] forKey:@"missingBlockIndex"];
+                    [newContainerRequest setBytesSentBlock:^(unsigned long long size, unsigned long long total){
+                        [activityFacility updateActivity:activity 
+                                             withMessage:[NSString stringWithFormat:@"%@ (%.0f%%)", 
+                                                          [newContainerRequest.userInfo objectForKey:@"messagePrefix"], 
+                                                          (100*(activity.currentBytes + size + 0.0)/(activity.totalBytes + 0.0))] 
+                                              totalBytes:activity.totalBytes 
+                                            currentBytes:(activity.currentBytes + size)];
+                    }];
+                    [networkQueue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
+                }
+            }
+        } else {
+            [self requestFailed:containerRequest];
+        }
     }
-    NSUInteger retries = [[request.userInfo objectForKey:@"retries"] unsignedIntegerValue];
-    if (retries > 0) {
-        ASIPithosRequest *newRequest = (ASIPithosRequest *)[[PithosUtilities copyRequest:request] autorelease];
-        [(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
-        [networkQueue addOperation:[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]]];
-    } else {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            [activityFacility endActivity:[request.userInfo objectForKey:@"activity"] 
-                              withMessage:[request.userInfo objectForKey:@"failedActivityMessage"]];
-        });
-        [self syncOperationFinishedWithSuccess:NO];
+}
+
+- (void)requestFailed:(ASIPithosRequest *)request {
+    @autoreleasepool {
+        NSOperation *operation = [request.userInfo objectForKey:@"operation"];
+        DLog(@"Sync::request failed: %@", request.url);
+        if (operation.isCancelled)
+            return;
+        if (request.isCancelled || newSyncRequested || syncLate) {
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [activityFacility endActivity:[request.userInfo objectForKey:@"activity"] 
+                                  withMessage:[request.userInfo objectForKey:@"stoppedActivityMessage"]];
+            });
+            [self syncOperationFinishedWithSuccess:NO];
+            return;
+        }
+        NSUInteger retries = [[request.userInfo objectForKey:@"retries"] unsignedIntegerValue];
+        if (retries > 0) {
+            ASIPithosRequest *newRequest = (ASIPithosRequest *)[PithosUtilities copyRequest:request];
+            [(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+            [networkQueue addOperation:[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]]];
+        } else {
+            dispatch_async(dispatch_get_main_queue(), ^{
+                [activityFacility endActivity:[request.userInfo objectForKey:@"activity"] 
+                                  withMessage:[request.userInfo objectForKey:@"failedActivityMessage"]];
+            });
+            [self syncOperationFinishedWithSuccess:NO];
+        }
     }
-    [pool drain];
 }
 
 @end