diff --git a/openbis-ipad/BisKit/Classes/CISDOBIpadServiceManager.m b/openbis-ipad/BisKit/Classes/CISDOBIpadServiceManager.m
index 2b77122743bb895bb20287ef9ae97ab35161d5fe..57dcfe2672a0f7d65623c38042173d0e6e48419e 100644
--- a/openbis-ipad/BisKit/Classes/CISDOBIpadServiceManager.m
+++ b/openbis-ipad/BisKit/Classes/CISDOBIpadServiceManager.m
@@ -38,14 +38,34 @@
 
 @end
 
-static NSManagedObjectContext* GetDatabaseManagedObjectContext(NSURL* storeUrl, NSError** error)
+// Internal class that synchronizes result data to the managed object context
+@interface CISDOBBackgroundDataSynchronizer : NSObject
+
+@property(readonly, weak) CISDOBIpadServiceManager *serviceManager;
+@property(readonly) CISDOBIpadServiceManagerCall *managerCall;
+@property(readonly) NSArray *rawEntities;
+@property(readonly) NSManagedObjectContext *managedObjectContext;
+@property(readonly) NSError *error;
+
+@property(nonatomic) BOOL prune;
+
+// Initialization
+- (id)initWithServiceManager:(CISDOBIpadServiceManager *)serviceManager managerCall:(CISDOBIpadServiceManagerCall *)call rawEntities:(NSArray *)rawEntities;
+
+// Actions
+- (void)run;
+- (void)notifyCallOfResult:(id)args;
+
+@end
+
+static NSManagedObjectContext* GetMainThreadManagedObjectContext(NSURL* storeUrl, NSError** error)
 {
 	// Explicitly specify which db schema we want to use
 	NSBundle* bundle = [NSBundle bundleForClass: [CISDOBIpadEntity class]];
 	NSString* momPath = [bundle pathForResource: @"persistent-data-model" ofType: @"momd"];
 	NSManagedObjectModel* mom = [[NSManagedObjectModel alloc] initWithContentsOfURL: [NSURL fileURLWithPath: momPath]];
 
-	NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] init];
+	NSManagedObjectContext* moc = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType];
 	NSPersistentStoreCoordinator* coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: mom];
 	[moc setPersistentStoreCoordinator: coordinator];	
 	NSPersistentStore* store = 
@@ -72,7 +92,7 @@ static NSManagedObjectContext* GetDatabaseManagedObjectContext(NSURL* storeUrl,
     CISDOBLiveConnection *connection = [[CISDOBLiveConnection alloc] initWithUrl: openbisUrl trusted: trusted];
     _storeUrl = [storeUrl copy];
     _service = [[CISDOBIpadService alloc] initWithConnection: connection];
-    _managedObjectContext = GetDatabaseManagedObjectContext(self.storeUrl, error);
+    _managedObjectContext = GetMainThreadManagedObjectContext(self.storeUrl, error);
     _persistentStoreCoordinator = _managedObjectContext.persistentStoreCoordinator;
     if (!_managedObjectContext) return nil;
     
@@ -82,45 +102,16 @@ static NSManagedObjectContext* GetDatabaseManagedObjectContext(NSURL* storeUrl,
     return self;
 }
 
-- (BOOL)synchEntity:(CISDOBIpadRawEntity *)rawEntity lastUpdateDate:(NSDate *)date error:(NSError **)error
+- (void)syncEntities:(NSArray *)rawEntities pruning:(BOOL)prune notifying:(CISDOBIpadServiceManagerCall *)managerCall
 {
-    // Create new entities in the moc, and store them.
-    CISDOBIpadEntity *entity;
-    NSArray *matchedEntities = [self entitiesByPermId: [NSArray arrayWithObject: rawEntity.permId] error: error];
-    if (!matchedEntities) return NO;
-    if ([matchedEntities count] > 0) {
-        entity = [matchedEntities objectAtIndex: 0];
-        [entity updateFromRawEntity: rawEntity];
-    } else {
-        entity = [NSEntityDescription insertNewObjectForEntityForName: @"CISDOBIpadEntity" inManagedObjectContext: self.managedObjectContext];
-        [entity initializeFromRawEntity: rawEntity];
-    }
-    entity.lastUpdateDate = date;
-    entity.serverUrlString =  [((CISDOBLiveConnection *)(self.service.connection)).url absoluteString];
-    
-    return YES;
-}
-
-- (BOOL)syncEntities:(NSArray *)rawEntities pruning:(BOOL)prune error:(NSError **)error
-{
-    NSDate *lastUpdateDate = [NSDate date];
-    BOOL success;
-    for (CISDOBIpadRawEntity *rawEntity in rawEntities) {
-        success = [self synchEntity: rawEntity lastUpdateDate: lastUpdateDate error: error];
-        if (!success) return NO;
-    }
-    // If pruning is requested, remove entities that cannot be reached from the server result set.
-    // TODO : we should treat the intial results as a root set and trace out to do a gc, but the simpler implementation is just to remove everything that is not mentioned
-    if (prune) {
-        // Remove all entities that were not mentioned
-        NSArray *entitiesToDelete = [self entitiesNotUpdatedSince: lastUpdateDate error: error];
-        for (CISDOBIpadEntity *entity in entitiesToDelete) {
-            [self.managedObjectContext deleteObject: entity];
-        }
-    }
-    
-    success = [self.managedObjectContext save: error];
-    return success;
+    void (^syncBlock)(void) = ^{
+        CISDOBBackgroundDataSynchronizer *synchronizer = [[CISDOBBackgroundDataSynchronizer alloc] initWithServiceManager: self managerCall: managerCall rawEntities: rawEntities];
+        synchronizer.prune = prune;
+        [synchronizer run];
+        [synchronizer performSelectorOnMainThread: @selector(notifyCallOfResult:) withObject: nil waitUntilDone: NO];
+    };
+    NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:  syncBlock];
+    [blockOp start];
 }
 
 - (CISDOBIpadServiceManagerCall *)managerCallWrappingServiceCall:(CISDOBAsyncCall *)serviceCall pruning:(BOOL)prune
@@ -129,13 +120,7 @@ static NSManagedObjectContext* GetDatabaseManagedObjectContext(NSURL* storeUrl,
     
     serviceCall.success = ^(id result) {
         // Update the cache
-        NSError *error;
-        BOOL didSync = [self syncEntities: result pruning: prune error: &error];
-        if (!didSync) {
-            serviceCall.fail(error);
-        } else if (managerCall.success) {
-            managerCall.success(result);
-        }
+        [self syncEntities: result pruning: prune notifying: managerCall];
     };    
     
     serviceCall.fail = ^(NSError *error) { if (managerCall.fail) managerCall.fail(error); };
@@ -224,3 +209,84 @@ static NSManagedObjectContext* GetDatabaseManagedObjectContext(NSURL* storeUrl,
 }
 
 @end
+
+@implementation CISDOBBackgroundDataSynchronizer
+
+// Initialization
+- (id)initWithServiceManager:(CISDOBIpadServiceManager *)serviceManager managerCall:(CISDOBIpadServiceManagerCall *)call rawEntities:(NSArray *)rawEntities
+{
+    if (!(self = [super init])) return nil;
+    
+    _serviceManager = serviceManager;
+    _managerCall = call;
+    _rawEntities = rawEntities;
+    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSConfinementConcurrencyType];
+    _managedObjectContext.parentContext = _serviceManager.managedObjectContext;
+    _prune = NO;
+    _error = nil;
+    
+    return self;
+}
+
+- (BOOL)synchEntity:(CISDOBIpadRawEntity *)rawEntity lastUpdateDate:(NSDate *)date error:(NSError **)error
+{
+    // Create new entities in the moc, and store them.
+    CISDOBIpadEntity *entity;
+    NSArray *matchedEntities = [self.serviceManager entitiesByPermId: [NSArray arrayWithObject: rawEntity.permId] error: error];
+    if (!matchedEntities) return NO;
+    if ([matchedEntities count] > 0) {
+        entity = [matchedEntities objectAtIndex: 0];
+        [entity updateFromRawEntity: rawEntity];
+    } else {
+        entity = [NSEntityDescription insertNewObjectForEntityForName: @"CISDOBIpadEntity" inManagedObjectContext: self.managedObjectContext];
+        [entity initializeFromRawEntity: rawEntity];
+    }
+    entity.lastUpdateDate = date;
+    entity.serverUrlString =  [((CISDOBLiveConnection *)(self.serviceManager.service.connection)).url absoluteString];
+    
+    return YES;
+}
+
+
+- (void)run
+{
+    NSError *error;
+    NSDate *lastUpdateDate = [NSDate date];
+    BOOL success;
+    for (CISDOBIpadRawEntity *rawEntity in self.rawEntities) {
+        success = [self synchEntity: rawEntity lastUpdateDate: lastUpdateDate error: &error];
+        if (!success) {
+            _error = [error copy];
+            return;
+        }
+    }
+    // If pruning is requested, remove entities that cannot be reached from the server result set.
+    // TODO : we should treat the intial results as a root set and trace out to do a gc, but the simpler implementation is just to remove everything that is not mentioned
+    if (_prune) {
+        // Remove all entities that were not mentioned
+        NSArray *entitiesToDelete = [self.serviceManager entitiesNotUpdatedSince: lastUpdateDate error: &error];
+        for (CISDOBIpadEntity *entity in entitiesToDelete) {
+            [self.managedObjectContext deleteObject: entity];
+        }
+    }
+    
+    success = [self.managedObjectContext save: &error];
+    if (!success) {
+        _error = [error copy];
+        return;
+    }
+    
+    _error = nil;
+}
+
+- (void)notifyCallOfResult:(id)args
+{
+    if (_error) {
+        self.managerCall.serviceCall.fail(self.error);
+    } else if (self.managerCall.success) {
+        self.managerCall.success(self.rawEntities);
+    }
+    
+}
+
+@end