diff --git a/openbis-ipad/BisKit/Classes/CISDOBIpadService.h b/openbis-ipad/BisKit/Classes/CISDOBIpadService.h
index 12a68cc1a1ef36039270327a62f19fd630151c9f..e7406c46185773ccef08c37330f53406dc06c556 100644
--- a/openbis-ipad/BisKit/Classes/CISDOBIpadService.h
+++ b/openbis-ipad/BisKit/Classes/CISDOBIpadService.h
@@ -55,6 +55,9 @@ enum CISOBIpadServiceErrorCode {
 //! Get all root-level entities from the openBIS ipad service, possibly along with some children as well. The success message will be invoked with a collection of CISDOBIpadRawEntity objects.
 - (CISDOBAsyncCall *)listRootLevelEntities;
 
+//! Get drill information from the openBIS ipad service -- this will include information about the children of the entity and possibly their children as well. The success message will be invoked with a collection of CISDOBIpadRawEntity objects.
+- (CISDOBAsyncCall *)drillOnEntityWithPermId:(NSString *)permId refcon:(NSString *)refcon;
+
 @end
 
 
diff --git a/openbis-ipad/BisKit/Classes/CISDOBIpadService.m b/openbis-ipad/BisKit/Classes/CISDOBIpadService.m
index 30114712b1aa15faa9ad91cdf2e3eaeab7f3352a..4e0e25714368a0addcd772e1b1f5a055f352ebe7 100644
--- a/openbis-ipad/BisKit/Classes/CISDOBIpadService.m
+++ b/openbis-ipad/BisKit/Classes/CISDOBIpadService.m
@@ -175,6 +175,34 @@ NSString *const CISDOBIpadServiceErrorDomain = @"CISDOBIpadServiceErrorDomain";
     return iPadCall;
 }
 
+- (CISDOBAsyncCall *)drillOnEntityWithPermId:(NSString *)permId refcon:(NSString *)refcon
+{
+    // A simple version of the method that just request data for one entity.
+    NSDictionary *entity =
+        [NSDictionary dictionaryWithObjectsAndKeys:
+            permId, @"PERM_ID",
+            refcon, @"REFCON", nil];
+    NSArray *entities = [NSArray arrayWithObject: entity];
+    NSDictionary *parameters =
+        [NSDictionary dictionaryWithObjectsAndKeys:
+            @"DRILL", @"requestKey",
+            entities, @"entities", nil];
+    CISDOBAsyncCall *connectionCall =
+        [_connection
+            createReportFromDataStore: [_ipadReadService objectForKey: @"dataStoreCode"]
+            aggregationService: [_ipadReadService objectForKey: @"serviceKey"]
+            parameters: parameters];
+    CISDOBIpadServiceCall *iPadCall = [self iPadCallWrappingConnectionCall: connectionCall];
+    
+    connectionCall.success = ^(id result) {
+        if (iPadCall.success) {
+            iPadCall.success([self rawEntitiesFromResult: result]);
+        }
+    };
+    
+    return iPadCall;
+}
+
 @end
 
 @implementation CISDOBIpadServiceCall
diff --git a/openbis-ipad/BisKit/Tests/CISDOBIpadServiceTest.m b/openbis-ipad/BisKit/Tests/CISDOBIpadServiceTest.m
index 70ccd928b53db4cbffc5f9dd8be7255800c32829..3a318a53850338aa78d1dc9f125ea65f6eb72a44 100644
--- a/openbis-ipad/BisKit/Tests/CISDOBIpadServiceTest.m
+++ b/openbis-ipad/BisKit/Tests/CISDOBIpadServiceTest.m
@@ -52,7 +52,7 @@
     [self waitSeconds: waitTime forCallToComplete: call];
 }
 
-- (void)testListAllEntities
+- (void)testListRootEntities
 {
     CISDOBAsyncCall *call;
     call = [_service loginUser: GetDefaultUserName() password: GetDefaultUserPassword()];
@@ -81,4 +81,35 @@
     }
 }
 
+- (void)testDrill
+{
+    CISDOBAsyncCall *call;
+    call = [_service loginUser: GetDefaultUserName() password: GetDefaultUserPassword()];
+    [self configureAndRunCallSynchronously: call];
+    
+    call = [_service listRootLevelEntities];
+    [self configureAndRunCallSynchronously: call];
+    
+    STAssertNotNil(_callResult, @"The iPad service should have returned some entities.");
+    NSArray *rawEntities = _callResult;
+    STAssertTrue([rawEntities count] > 0, @"The Pad service should have returned some entities.");
+    
+    
+    // Find an entity with children and drill on it
+    CISDOBIpadRawEntity *entityWithChildren = nil;
+    for (CISDOBIpadRawEntity *rawEntity in rawEntities) {
+        if ([rawEntity.children length] > 2) {
+            entityWithChildren = rawEntity;
+            break;
+        }
+    }
+    
+    // Drill
+     call = [_service drillOnEntityWithPermId: entityWithChildren.permId refcon: entityWithChildren.refcon];
+    [self configureAndRunCallSynchronously: call];
+    
+    rawEntities = _callResult;
+    STAssertTrue([rawEntities count] > 0, @"The Pad service should have returned some entities.");
+}
+
 @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 7a0a4a9c2b07ef4de21cc7597e8d050e97adda0b..cc8df0c5208e88bc40f7bac51417227c35f97446 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
diff --git a/openbis-ipad/ipad-example-data/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py b/openbis-ipad/ipad-example-data/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
index c3fbe51da63500e1b14ad9bc542116cc0edeefd5..9f1d5367f5ed3915daef5ac89c2ad09a765c442c 100644
--- a/openbis-ipad/ipad-example-data/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
+++ b/openbis-ipad/ipad-example-data/ipad-ui/1/dss/reporting-plugins/ipad-read-service-v1/ipad_read.py
@@ -11,6 +11,10 @@ def json_encoded_value(coll):
 	"""Utility function for converting a list into a json-encoded list"""
 	return ObjectMapper().writeValueAsString(coll)
 
+def json_string_to_dict(string):
+	"""Utility function for converting a json-encoded dictionary into a Java/Jython dictionary."""
+	return ObjectMapper().readValue(string, dict)
+
 class RequestHandler:
 	"""Abstract superclass for the handlers for concrete requests like ROOT.
 
@@ -200,10 +204,10 @@ def samples_to_dict(samples, material_by_perm_id):
 	result = [sample_to_dict(sample, material_by_perm_id) for sample in samples]
 	return result
 
-def retrieve_samples(sample_perm_id_and_ref_cons):
+def retrieve_samples(sample_perm_ids_and_ref_cons):
 	sc = SearchCriteria()
-	for sample in sample_perm_id_and_ref_con:
-		code = sample['REFCON']['code']	
+	for sample in sample_perm_ids_and_ref_cons:
+		code = json_string_to_dict(sample['REFCON'])['code']	
 		sc.addMatchClause(sc.MatchClause.createAttributeMatch(sc.MatchClauseAttribute.CODE, code))
 	return searchService.searchForSamples(sc)