diff --git a/openbis-ipad/BisKit/Classes/CISDOBIpadService.h b/openbis-ipad/BisKit/Classes/CISDOBIpadService.h
index 66d4f20eadbd573690f4d57eda6d305c99b7a9fd..8a3552c6700a9903dd4c315e0d617603ebb9fcb7 100644
--- a/openbis-ipad/BisKit/Classes/CISDOBIpadService.h
+++ b/openbis-ipad/BisKit/Classes/CISDOBIpadService.h
@@ -42,12 +42,10 @@ enum CISOBIpadServiceErrorCode {
     // Internal State
     BOOL            _isLoggedIn;
     NSDictionary   *_ipadReadService;
-    
-    CISDOBClientPreferences *_clientPreferences;
 }
 
 @property(readonly) CISDOBConnection *connection;
-@property(readonly) CISDOBClientPreferences *clientPreferences;
+@property(strong, nonatomic) CISDOBClientPreferences *clientPreferences;
 
 //! Designated initializer.
 - (id)initWithConnection:(CISDOBConnection *)connection;
diff --git a/openbis-ipad/BisKit/Classes/CISDOBIpadService.m b/openbis-ipad/BisKit/Classes/CISDOBIpadService.m
index 85d10ff5f110c571d5d790d5127e4efc81b6f74d..e62be640eb9728b8078328b3bf40678a21cbc0cb 100644
--- a/openbis-ipad/BisKit/Classes/CISDOBIpadService.m
+++ b/openbis-ipad/BisKit/Classes/CISDOBIpadService.m
@@ -63,60 +63,6 @@ NSString *const CISDOBIpadServiceErrorDomain = @"CISDOBIpadServiceErrorDomain";
 
 - (BOOL)isIpadSupported { return _ipadReadService != nil; }
 
-- (void)rememberClientPreferences:(NSDictionary *)clientPreferences notifying:(CISDOBIpadServiceCall *)iPadCall
-{    
-    _clientPreferences = [[CISDOBClientPreferences alloc] initWithRawPreferences: clientPreferences];
-    if (iPadCall.success) iPadCall.success(_connection.sessionToken);
-    
-}
-
-- (void)retrieveClientPreferences:(CISDOBIpadServiceCall *)iPadCall
-{
-    NSDictionary *parameters = [NSDictionary dictionaryWithObject: @"ROOT" forKey: @"requestKey"];
-    CISDOBAsyncCall *connectionCall =
-        [_connection
-            createReportFromDataStore: [_ipadReadService objectForKey: @"dataStoreCode"]
-            aggregationService: [_ipadReadService objectForKey: @"serviceKey"]
-            parameters: parameters];
-    
-    iPadCall.connectionCall = connectionCall;
-    connectionCall.success = ^(id result) {
-        [self rememberClientPreferences: result notifying: iPadCall];
-    };
-    connectionCall.fail = ^(NSError *error) { if (iPadCall.fail) iPadCall.fail(error); };
-    [connectionCall start];
-}
-
-- (void)rememberIpadService:(NSArray *)services notifying:(CISDOBIpadServiceCall *)iPadCall
-{    
-    for (NSDictionary *service in services) {
-        if ([@"ipad-read-service-v1" isEqualToString: [service objectForKey: @"serviceKey"]]) {
-            _ipadReadService = service;
-            break;
-        }
-    }
-    
-    if (_ipadReadService == nil) {
-        NSString *errorMessage = @"The iPad service is not installed on the selected server";
-        NSDictionary *userInfo =
-            [NSDictionary dictionaryWithObjectsAndKeys: errorMessage, NSLocalizedDescriptionKey, nil];
-        NSError *error = [NSError errorWithDomain: CISDOBIpadServiceErrorDomain code: kCISOBIpadServiceError_NoIpadServiceAvailable userInfo: userInfo];
-        if (iPadCall.fail) iPadCall.fail(error);
-        return;
-    }
-    
-    [self retrieveClientPreferences: iPadCall];
-}
-
-- (void)determineIsIpadSupported:(CISDOBIpadServiceCall *)iPadCall
-{
-    CISDOBAsyncCall *connectionCall = [_connection listAggregationServices];
-    iPadCall.connectionCall = connectionCall;
-    connectionCall.success = ^(id result) { [self rememberIpadService: result notifying: iPadCall]; };
-    connectionCall.fail = ^(NSError *error) { if (iPadCall.fail) iPadCall.fail(error); };
-    [connectionCall start];
-}
-
 - (CISDOBIpadServiceCall *)iPadCallWrappingConnectionCall:(CISDOBAsyncCall *)connectionCall
 {
     CISDOBIpadServiceCall *iPadCall = [[CISDOBIpadServiceCall alloc] initWithService: self connectionCall: connectionCall];
@@ -163,7 +109,8 @@ NSString *const CISDOBIpadServiceErrorDomain = @"CISDOBIpadServiceErrorDomain";
         // Note that we are logged in, but wait until we figure out if the ipad is supported
         // to notify the client.
         _isLoggedIn = YES;
-        [self determineIsIpadSupported: iPadCall];
+        CISDOBIpadServicePostLoginCommand *command = [[CISDOBIpadServicePostLoginCommand alloc] initWithService: self ipadCall: iPadCall];
+        [command run];
     };
     
     return iPadCall;
@@ -335,3 +282,76 @@ NSString *const CISDOBIpadServiceErrorDomain = @"CISDOBIpadServiceErrorDomain";
 }
 
 @end
+
+@implementation CISDOBIpadServicePostLoginCommand
+
+- (id)initWithService:(CISDOBIpadService *)service ipadCall:(CISDOBIpadServiceCall *)call
+{
+    if (!(self = [super init])) return nil;
+    
+    self.service = service;
+    self.ipadCall = call;
+    
+    return self;
+}
+
+- (void)rememberClientPreferences:(NSDictionary *)clientPreferences
+{    
+    self.service.clientPreferences = [[CISDOBClientPreferences alloc] initWithRawPreferences: clientPreferences];
+    if (self.ipadCall.success) self.ipadCall.success(self.service.connection.sessionToken);
+    
+}
+
+- (void)retrieveClientPreferences
+{
+    NSDictionary *parameters = [NSDictionary dictionaryWithObject: @"ROOT" forKey: @"requestKey"];
+    CISDOBAsyncCall *connectionCall =
+        [self.service.connection
+            createReportFromDataStore: [self.service.ipadReadService objectForKey: @"dataStoreCode"]
+            aggregationService: [self.service.ipadReadService objectForKey: @"serviceKey"]
+            parameters: parameters];
+    
+    self.ipadCall.connectionCall = connectionCall;
+    connectionCall.success = ^(id result) {
+        [self rememberClientPreferences: result];
+    };
+    connectionCall.fail = ^(NSError *error) { if (self.ipadCall.fail) self.ipadCall.fail(error); };
+    [connectionCall start];
+}
+
+- (void)rememberIpadService:(NSArray *)services
+{    
+    for (NSDictionary *service in services) {
+        if ([@"ipad-read-service-v1" isEqualToString: [service objectForKey: @"serviceKey"]]) {
+            self.service.ipadReadService = service;
+            break;
+        }
+    }
+    
+    if (self.service.ipadReadService == nil) {
+        NSString *errorMessage = @"The iPad service is not installed on the selected server";
+        NSDictionary *userInfo =
+            [NSDictionary dictionaryWithObjectsAndKeys: errorMessage, NSLocalizedDescriptionKey, nil];
+        NSError *error = [NSError errorWithDomain: CISDOBIpadServiceErrorDomain code: kCISOBIpadServiceError_NoIpadServiceAvailable userInfo: userInfo];
+        if (self.ipadCall.fail) self.ipadCall.fail(error);
+        return;
+    }
+    
+    [self retrieveClientPreferences];
+}
+
+- (void)determineIsIpadSupported
+{
+    CISDOBAsyncCall *connectionCall = [self.service.connection listAggregationServices];
+    self.ipadCall.connectionCall = connectionCall;
+    connectionCall.success = ^(id result) { [self rememberIpadService: result]; };
+    connectionCall.fail = ^(NSError *error) { if (self.ipadCall.fail) self.ipadCall.fail(error); };
+    [connectionCall start];
+}
+
+- (void)run
+{
+    [self determineIsIpadSupported];
+}
+
+@end
diff --git a/openbis-ipad/BisKit/Classes/CISDOBIpadServiceInternal.h b/openbis-ipad/BisKit/Classes/CISDOBIpadServiceInternal.h
index 4c4d9d38d37ee1f90170b75a72fe25155eb0dbde..3ce542b5806ba6c7b02f7630c49b7b25a206f6a0 100644
--- a/openbis-ipad/BisKit/Classes/CISDOBIpadServiceInternal.h
+++ b/openbis-ipad/BisKit/Classes/CISDOBIpadServiceInternal.h
@@ -24,11 +24,8 @@
 #import "CISDOBIpadService.h"
 
 // Internal service call that includes the private state
-@interface CISDOBIpadServiceCall : CISDOBAsyncCall {
-@private
-    // Internal state
-    CISDOBAsyncCall     *_connectionCall;
-}
+@interface CISDOBIpadServiceCall : CISDOBAsyncCall
+
 @property(weak, nonatomic) CISDOBIpadService *service;
 @property(strong, nonatomic) CISDOBAsyncCall *connectionCall;
 
@@ -40,3 +37,23 @@
 
 @end
 
+// An object that carries out all the steps that need to run after the user has logged into the server
+@interface CISDOBIpadServicePostLoginCommand : NSObject
+
+@property(weak, nonatomic) CISDOBIpadService *service;
+@property(weak, nonatomic) CISDOBIpadServiceCall *ipadCall;
+
+// Initialization
+- (id)initWithService:(CISDOBIpadService *)service ipadCall:(CISDOBIpadServiceCall *)call;
+
+// Actions
+- (void)run;
+
+@end
+
+@interface CISDOBIpadService()
+
+@property(strong, nonatomic) NSDictionary *ipadReadService;
+
+@end
+
diff --git a/openbis-ipad/Research/BisMac.xcodeproj/project.xcworkspace/xcuserdata/cramakri.xcuserdatad/UserInterfaceState.xcuserstate b/openbis-ipad/Research/BisMac.xcodeproj/project.xcworkspace/xcuserdata/cramakri.xcuserdatad/UserInterfaceState.xcuserstate
index 91f18b3f11d9e0ec6832f2cb550b90c13b41dd77..ecdd1318264d1844d468b50faed6c4df90e19356 100644
Binary files a/openbis-ipad/Research/BisMac.xcodeproj/project.xcworkspace/xcuserdata/cramakri.xcuserdatad/UserInterfaceState.xcuserstate and b/openbis-ipad/Research/BisMac.xcodeproj/project.xcworkspace/xcuserdata/cramakri.xcuserdatad/UserInterfaceState.xcuserstate differ