diff --git a/bob/db/cuhk/__init__.py b/bob/db/cuhk/__init__.py
index 7694f5a9ce36ef24203b7fb7203b5e38bc87f3bc..27449873a2bc8219729753a0db10eb3f3027ce59 100644
--- a/bob/db/cuhk/__init__.py
+++ b/bob/db/cuhk/__init__.py
@@ -18,12 +18,10 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 
 """
-Details about the Voxforge database can be found here:
-http://www.voxforge.org/
 """
 
 from .query import Database
-from bob.db.cuhk.models import File, Client, Annotation
+from bob.db.cuhk.models import File, Client, Annotation, Protocol_File_Association
 
 def get_config():
   """Returns a string containing the configuration information.
diff --git a/bob/db/cuhk/create.py b/bob/db/cuhk/create.py
index 56ee27d6fa86400853dcbe28e76ed001e7515f95..1f99c4fe0574d3913c6315beac394382b80ef15d 100644
--- a/bob/db/cuhk/create.py
+++ b/bob/db/cuhk/create.py
@@ -188,6 +188,245 @@ def add_annotations(session, annotation_dir, verbose):
   session.commit()   
 
 
+
+def add_protocols(session, verbose, photo2sketch=True):
+  """
+  There are 9 protocols:
+ 
+  CUHK   - This covers only images from the CUHK student database
+  ARFACE - This covers only images from the ARFACE  database
+  XM2VTS - This covers only images from the XM2VTS student database
+  
+  ALL    - It is a mixture of all databases (the training, dev and eval sets of all)
+
+  CUHK-ARFACE-XM2VTS: Training set of CUHK, dev set of ARFACE and eval set of XM2VTS
+  CUHK-XM2VTS-ARFACE:
+  ARFACE-CUHK-XM2VTS:
+  ARFACE-XM2VTS-CUHK:
+  XM2VTS-CUHK-ARFACE:
+  XM2VTS-ARFACE-CUHK:
+
+  """
+
+  PROTOCOLS = ('cuhk_p2s', 'arface_p2s', 'xm2vts_p2s', 'all-mixed_p2s', 'cuhk-arface-xm2vts_p2s', 'cuhk-xm2vts-arface_p2s',
+  'arface-cuhk-xm2vts_p2s', 'arface-xm2vts-cuhk_p2s', 'xm2vts-cuhk-arface_p2s', 'xm2vts-arface-cuhk_p2s',
+  'cuhk_s2p', 'arface_s2p', 'xm2vts_s2p', 'all-mixed_s2p', 'cuhk-arface-xm2vts_s2p', 'cuhk-xm2vts-arface_s2p',
+  'arface-cuhk-xm2vts_s2p', 'arface-xm2vts-cuhk_s2p', 'xm2vts-cuhk-arface_s2p', 'xm2vts-arface-cuhk_s2p')
+
+  GROUPS    = ('world', 'dev', 'eval')
+
+  PURPOSES   = ('train', 'enrol', 'probe')
+
+  arface = ARFACEWrapper()
+  xm2vts = XM2VTSWrapper()
+  cuhk   = CUHKWrapper()
+
+  if(photo2sketch):
+    suffix = "_p2s"
+  else:
+    suffix = "_s2p"    
+
+  ####### Protocol ARFACE
+
+  if verbose>=1: print('Creating the protocol ARFACE  ...')
+
+  #getting the files
+  world_files = arface.get_files_from_group(group="world")
+  dev_files   = arface.get_files_from_group(group="dev")
+  eval_files  = arface.get_files_from_group(group="eval")
+  
+  #Inserting in the database
+  insert_protocol_data(session, "arface"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "arface"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "arface"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+  
+  ############## Protocol XM2VTS
+  if verbose>=1: print('Creating the protocol XM2VTS  ...')
+
+  #getting the files
+  world_files = xm2vts.get_files_from_group(group="world")
+  dev_files   = xm2vts.get_files_from_group(group="dev")
+  eval_files  = xm2vts.get_files_from_group(group="eval")
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "xm2vts"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "xm2vts"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "xm2vts"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+
+  ############## Protocol CUHK
+
+  if verbose>=1: print('Creating the protocol CUHK  ...')
+
+  #getting the files
+  world_files = cuhk.get_files_from_group(group="world")
+  dev_files   = cuhk.get_files_from_group(group="dev")
+  eval_files  = cuhk.get_files_from_group(group="eval")
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "cuhk"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "cuhk"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "cuhk"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+  ############# Protocol all-mixed
+
+  if verbose>=1: print('Creating the protocol ALL mixed  ...')
+
+  #getting the files
+  world_files = arface.get_files_from_group(group="world") +\
+                xm2vts.get_files_from_group(group="world") +\
+                cuhk.get_files_from_group(group="world")
+
+  dev_files   = arface.get_files_from_group(group="dev") +\
+                xm2vts.get_files_from_group(group="dev") +\
+                cuhk.get_files_from_group(group="dev")
+
+  eval_files  = arface.get_files_from_group(group="eval") +\
+                xm2vts.get_files_from_group(group="eval") +\
+                cuhk.get_files_from_group(group="eval")
+
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "all-mixed"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "all-mixed"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "all-mixed"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+  ############# Protocol cuhk-arface-xm2vts
+
+  if verbose>=1: print('Creating the protocol cuhk-arface-xm2vts  ...')
+
+  #getting the files
+  world_files = cuhk.get_files_from_group(group="world")
+  dev_files   = arface.get_files_from_group(group="dev")
+  eval_files  = xm2vts.get_files_from_group(group="eval")
+
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "cuhk-arface-xm2vts"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "cuhk-arface-xm2vts"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "cuhk-arface-xm2vts"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+  ############# Protocol cuhk-xm2vts-arface
+
+  if verbose>=1: print('Creating the protocol cuhk-xm2vts-arface  ...')
+
+  #getting the files
+  world_files = cuhk.get_files_from_group(group="world")
+  dev_files   = xm2vts.get_files_from_group(group="dev")
+  eval_files  = arface.get_files_from_group(group="eval")
+
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "cuhk-xm2vts-arface"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "cuhk-xm2vts-arface"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "cuhk-xm2vts-arface"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+  ############# Protocol arface-cuhk-xm2vts 
+
+  if verbose>=1: print('Creating the protocol arface-cuhk-xm2vts  ...')
+
+  #getting the files
+  world_files = arface.get_files_from_group(group="world")
+  dev_files   = cuhk.get_files_from_group(group="dev")
+  eval_files  = xm2vts.get_files_from_group(group="eval")
+
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "arface-cuhk-xm2vts"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "arface-cuhk-xm2vts"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "arface-cuhk-xm2vts"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+  ############# Protocol arface-xm2vts-cuhk
+
+  if verbose>=1: print('Creating the protocol arface-xm2vts-cuhk  ...')
+
+  #getting the files
+  world_files = arface.get_files_from_group(group="world")
+  dev_files   = xm2vts.get_files_from_group(group="dev")
+  eval_files  = cuhk.get_files_from_group(group="eval")
+
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "arface-xm2vts-cuhk"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "arface-xm2vts-cuhk"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "arface-xm2vts-cuhk"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+  ############# Protocol xm2vts-cuhk-arface
+
+  if verbose>=1: print('Creating the protocol xm2vts-cuhk-arface  ...')
+
+  #getting the files
+  world_files = xm2vts.get_files_from_group(group="world")
+  dev_files   = cuhk.get_files_from_group(group="dev")
+  eval_files  = arface.get_files_from_group(group="eval")
+
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "xm2vts-cuhk-arface"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "xm2vts-cuhk-arface"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "xm2vts-cuhk-arface"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+
+  ############# Protocol xm2vts-arface-cuhk
+
+  if verbose>=1: print('Creating the protocol xm2vts-arface-cuhk  ...')
+
+  #getting the files
+  world_files = xm2vts.get_files_from_group(group="world")
+  dev_files   = arface.get_files_from_group(group="dev")
+  eval_files  = cuhk.get_files_from_group(group="eval")
+ 
+  #Inserting in the database
+  insert_protocol_data(session, "xm2vts-arface-cuhk"+suffix, "world", "train", world_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "xm2vts-arface-cuhk"+suffix, "dev", "", dev_files, photo2sketch=photo2sketch)
+  insert_protocol_data(session, "xm2vts-arface-cuhk"+suffix, "eval", "", eval_files, photo2sketch=photo2sketch)
+
+  session.commit()
+
+
+
+
+def insert_protocol_data(session, protocol, group, purpose, file_objects, photo2sketch=True):
+
+  for f in file_objects:
+    if purpose!="train":
+      if photo2sketch and f.modality=="photo":
+        purpose = "enrol"
+      else:
+        purpose = "probe"
+     
+    session.add(bob.db.cuhk.Protocol_File_Association(
+       protocol, group, purpose, f.id))
+ 
+
+
 def create_tables(args):
   """Creates all necessary tables (only to be used at the first time)"""
 
@@ -224,8 +463,9 @@ def create(args):
   add_files(s, args.verbose)
   add_annotations(s, args.annotation_dir, args.verbose)
 
-  #add_protocols(s, args.verbose)
-  #add_clientxprotocols(s, args.verbose)
+  add_protocols(s, args.verbose,photo2sketch=True)
+  add_protocols(s, args.verbose,photo2sketch=False)
+
   s.commit()
   s.close()
 
diff --git a/bob/db/cuhk/data/all-cuhk.txt b/bob/db/cuhk/data/all-cuhk.txt
index 310548228faf1b5ef9e7d003c18e0505e10a1b90..6deee2b693cf41739330234162c19355cebb95e4 100644
--- a/bob/db/cuhk/data/all-cuhk.txt
+++ b/bob/db/cuhk/data/all-cuhk.txt
@@ -18,40 +18,40 @@ CUHK-student-dataset/sketch/f1-012-01-sz1 f1-012-01
 CUHK-student-dataset/sketch/f1-013-01-sz1 f1-013-01
 CUHK-student-dataset/sketch/f1-014-01-sz1 f1-014-01
 CUHK-student-dataset/sketch/f1-015-01-sz1 f1-015-01
-CUHK-student-dataset/sketch/f2-005-01-sz1 f2-005-01
-CUHK-student-dataset/sketch/f2-006-01-sz1 f2-006-01
-CUHK-student-dataset/sketch/f2-007-01-sz1 f2-007-01
-CUHK-student-dataset/sketch/f2-008-01-sz1 f2-008-01
-CUHK-student-dataset/sketch/f2-009-01-sz1 f2-009-01
-CUHK-student-dataset/sketch/f2-010-01-sz1 f2-010-01
-CUHK-student-dataset/sketch/f2-011-01-sz1 f2-011-01
-CUHK-student-dataset/sketch/f2-012-01-sz1 f2-012-01
-CUHK-student-dataset/sketch/f2-013-01-sz1 f2-013-01
-CUHK-student-dataset/sketch/f2-014-01-sz1 f2-014-01
-CUHK-student-dataset/sketch/f2-015-01-sz1 f2-015-01
-CUHK-student-dataset/sketch/f2-016-01-sz1 f2-016-01
-CUHK-student-dataset/sketch/f2-017-01-sz1 f2-017-01
-CUHK-student-dataset/sketch/f2-018-01-sz1 f2-018-01
-CUHK-student-dataset/sketch/f2-019-01-sz1 f2-019-01
-CUHK-student-dataset/sketch/f2-020-01-sz1 f2-020-01
-CUHK-student-dataset/sketch/f2-021-01-sz1 f2-021-01
-CUHK-student-dataset/sketch/f2-022-01-sz1 f2-022-01
-CUHK-student-dataset/sketch/f2-023-01-sz1 f2-023-01
-CUHK-student-dataset/sketch/f2-024-01-sz1 f2-024-01
-CUHK-student-dataset/sketch/f2-025-01-sz1 f2-025-01
-CUHK-student-dataset/sketch/f2-026-01-sz1 f2-026-01
-CUHK-student-dataset/sketch/f2-027-01-sz1 f2-027-01
-CUHK-student-dataset/sketch/f2-028-01-sz1 f2-028-01
-CUHK-student-dataset/sketch/f2-029-01-sz1 f2-029-01
-CUHK-student-dataset/sketch/f2-030-01-sz1 f2-030-01
-CUHK-student-dataset/sketch/f2-031-01-sz1 f2-031-01
-CUHK-student-dataset/sketch/f2-032-01-sz1 f2-032-01
-CUHK-student-dataset/sketch/f2-033-01-sz1 f2-033-01
-CUHK-student-dataset/sketch/f2-034-01-sz1 f2-034-01
-CUHK-student-dataset/sketch/f2-035-01-sz1 f2-035-01
-CUHK-student-dataset/sketch/f2-036-01-sz1 f2-036-01
-CUHK-student-dataset/sketch/f2-037-01-sz1 f2-037-01
-CUHK-student-dataset/sketch/f2-038-01-sz1 f2-038-01
+CUHK-student-dataset/sketch/f2-005-01-sz1 f-005-01
+CUHK-student-dataset/sketch/f2-006-01-sz1 f-006-01
+CUHK-student-dataset/sketch/f2-007-01-sz1 f-007-01
+CUHK-student-dataset/sketch/f2-008-01-sz1 f-008-01
+CUHK-student-dataset/sketch/f2-009-01-sz1 f-009-01
+CUHK-student-dataset/sketch/f2-010-01-sz1 f-010-01
+CUHK-student-dataset/sketch/f2-011-01-sz1 f-011-01
+CUHK-student-dataset/sketch/f2-012-01-sz1 f-012-01
+CUHK-student-dataset/sketch/f2-013-01-sz1 f-013-01
+CUHK-student-dataset/sketch/f2-014-01-sz1 f-014-01
+CUHK-student-dataset/sketch/f2-015-01-sz1 f-015-01
+CUHK-student-dataset/sketch/f2-016-01-sz1 f-016-01
+CUHK-student-dataset/sketch/f2-017-01-sz1 f-017-01
+CUHK-student-dataset/sketch/f2-018-01-sz1 f-018-01
+CUHK-student-dataset/sketch/f2-019-01-sz1 f-019-01
+CUHK-student-dataset/sketch/f2-020-01-sz1 f-020-01
+CUHK-student-dataset/sketch/f2-021-01-sz1 f-021-01
+CUHK-student-dataset/sketch/f2-022-01-sz1 f-022-01
+CUHK-student-dataset/sketch/f2-023-01-sz1 f-023-01
+CUHK-student-dataset/sketch/f2-024-01-sz1 f-024-01
+CUHK-student-dataset/sketch/f2-025-01-sz1 f-025-01
+CUHK-student-dataset/sketch/f2-026-01-sz1 f-026-01
+CUHK-student-dataset/sketch/f2-027-01-sz1 f-027-01
+CUHK-student-dataset/sketch/f2-028-01-sz1 f-028-01
+CUHK-student-dataset/sketch/f2-029-01-sz1 f-029-01
+CUHK-student-dataset/sketch/f2-030-01-sz1 f-030-01
+CUHK-student-dataset/sketch/f2-031-01-sz1 f-031-01
+CUHK-student-dataset/sketch/f2-032-01-sz1 f-032-01
+CUHK-student-dataset/sketch/f2-033-01-sz1 f-033-01
+CUHK-student-dataset/sketch/f2-034-01-sz1 f-034-01
+CUHK-student-dataset/sketch/f2-035-01-sz1 f-035-01
+CUHK-student-dataset/sketch/f2-036-01-sz1 f-036-01
+CUHK-student-dataset/sketch/f2-037-01-sz1 f-037-01
+CUHK-student-dataset/sketch/f2-038-01-sz1 f-038-01
 CUHK-student-dataset/sketch/m-063-01-sz1 m-063-01
 CUHK-student-dataset/sketch/m-064-01-sz1 m-064-01
 CUHK-student-dataset/sketch/m-065-01-sz1 m-065-01
@@ -132,60 +132,60 @@ CUHK-student-dataset/sketch/m1-038-01-sz1 m1-038-01
 CUHK-student-dataset/sketch/m1-039-01-sz1 m1-039-01
 CUHK-student-dataset/sketch/m1-040-01-sz1 m1-040-01
 CUHK-student-dataset/sketch/m1-041-01-sz1 m1-041-01
-CUHK-student-dataset/sketch/m2-008-01-sz1 m2-008-01
-CUHK-student-dataset/sketch/m2-009-01-sz1 m2-009-01
-CUHK-student-dataset/sketch/m2-010-01-sz1 m2-010-01
-CUHK-student-dataset/sketch/m2-011-01-sz1 m2-011-01
-CUHK-student-dataset/sketch/m2-012-01-sz1 m2-012-01
-CUHK-student-dataset/sketch/m2-013-01-sz1 m2-013-01
-CUHK-student-dataset/sketch/m2-014-01-sz1 m2-014-01
-CUHK-student-dataset/sketch/m2-015-01-sz1 m2-015-01
-CUHK-student-dataset/sketch/m2-016-01-sz1 m2-016-01
-CUHK-student-dataset/sketch/m2-017-01-sz1 m2-017-01
-CUHK-student-dataset/sketch/m2-018-01-sz1 m2-018-01
-CUHK-student-dataset/sketch/m2-019-01-sz1 m2-019-01
-CUHK-student-dataset/sketch/m2-021-01-sz1 m2-021-01
-CUHK-student-dataset/sketch/m2-022-01-sz1 m2-022-01
-CUHK-student-dataset/sketch/m2-023-01-sz1 m2-023-01
-CUHK-student-dataset/sketch/m2-024-01-sz1 m2-024-01
-CUHK-student-dataset/sketch/m2-025-01-sz1 m2-025-01
-CUHK-student-dataset/sketch/m2-026-01-sz1 m2-026-01
-CUHK-student-dataset/sketch/m2-027-01-sz1 m2-027-01
-CUHK-student-dataset/sketch/m2-028-01-sz1 m2-028-01
-CUHK-student-dataset/sketch/m2-029-01-sz1 m2-029-01
-CUHK-student-dataset/sketch/m2-030-01-sz1 m2-030-01
-CUHK-student-dataset/sketch/m2-031-01-sz1 m2-031-01
-CUHK-student-dataset/sketch/m2-032-01-sz1 m2-032-01
-CUHK-student-dataset/sketch/m2-033-01-sz1 m2-033-01
-CUHK-student-dataset/sketch/m2-034-01-sz1 m2-034-01
-CUHK-student-dataset/sketch/m2-035-01-sz1 m2-035-01
-CUHK-student-dataset/sketch/m2-036-01-sz1 m2-036-01
-CUHK-student-dataset/sketch/m2-037-01-sz1 m2-037-01
-CUHK-student-dataset/sketch/m2-038-01-sz1 m2-038-01
-CUHK-student-dataset/sketch/m2-039-01-sz1 m2-039-01
-CUHK-student-dataset/sketch/m2-040-01-sz1 m2-040-01
-CUHK-student-dataset/sketch/m2-041-01-sz1 m2-041-01
-CUHK-student-dataset/sketch/m2-042-01-sz1 m2-042-01
-CUHK-student-dataset/sketch/m2-043-01-sz1 m2-043-01
-CUHK-student-dataset/sketch/m2-044-01-sz1 m2-044-01
-CUHK-student-dataset/sketch/m2-045-01-sz1 m2-045-01
-CUHK-student-dataset/sketch/m2-046-01-sz1 m2-046-01
-CUHK-student-dataset/sketch/m2-047-01-sz1 m2-047-01
-CUHK-student-dataset/sketch/m2-048-01-sz1 m2-048-01
-CUHK-student-dataset/sketch/m2-049-01-sz1 m2-049-01
-CUHK-student-dataset/sketch/m2-050-01-sz1 m2-050-01
-CUHK-student-dataset/sketch/m2-051-01-sz1 m2-051-01
-CUHK-student-dataset/sketch/m2-052-01-sz1 m2-052-01
-CUHK-student-dataset/sketch/m2-053-01-sz1 m2-053-01
-CUHK-student-dataset/sketch/m2-054-01-sz1 m2-054-01
-CUHK-student-dataset/sketch/m2-055-01-sz1 m2-055-01
-CUHK-student-dataset/sketch/m2-056-01-sz1 m2-056-01
-CUHK-student-dataset/sketch/m2-057-01-sz1 m2-057-01
-CUHK-student-dataset/sketch/m2-058-01-sz1 m2-058-01
-CUHK-student-dataset/sketch/m2-059-01-sz1 m2-059-01
-CUHK-student-dataset/sketch/m2-060-01-sz1 m2-060-01
-CUHK-student-dataset/sketch/m2-061-01-sz1 m2-061-01
-CUHK-student-dataset/sketch/m2-062-01-sz1 m2-062-01
+CUHK-student-dataset/sketch/m2-008-01-sz1 m-008-01
+CUHK-student-dataset/sketch/m2-009-01-sz1 m-009-01
+CUHK-student-dataset/sketch/m2-010-01-sz1 m-010-01
+CUHK-student-dataset/sketch/m2-011-01-sz1 m-011-01
+CUHK-student-dataset/sketch/m2-012-01-sz1 m-012-01
+CUHK-student-dataset/sketch/m2-013-01-sz1 m-013-01
+CUHK-student-dataset/sketch/m2-014-01-sz1 m-014-01
+CUHK-student-dataset/sketch/m2-015-01-sz1 m-015-01
+CUHK-student-dataset/sketch/m2-016-01-sz1 m-016-01
+CUHK-student-dataset/sketch/m2-017-01-sz1 m-017-01
+CUHK-student-dataset/sketch/m2-018-01-sz1 m-018-01
+CUHK-student-dataset/sketch/m2-019-01-sz1 m-019-01
+CUHK-student-dataset/sketch/m2-021-01-sz1 m-021-01
+CUHK-student-dataset/sketch/m2-022-01-sz1 m-022-01
+CUHK-student-dataset/sketch/m2-023-01-sz1 m-023-01
+CUHK-student-dataset/sketch/m2-024-01-sz1 m-024-01
+CUHK-student-dataset/sketch/m2-025-01-sz1 m-025-01
+CUHK-student-dataset/sketch/m2-026-01-sz1 m-026-01
+CUHK-student-dataset/sketch/m2-027-01-sz1 m-027-01
+CUHK-student-dataset/sketch/m2-028-01-sz1 m-028-01
+CUHK-student-dataset/sketch/m2-029-01-sz1 m-029-01
+CUHK-student-dataset/sketch/m2-030-01-sz1 m-030-01
+CUHK-student-dataset/sketch/m2-031-01-sz1 m-031-01
+CUHK-student-dataset/sketch/m2-032-01-sz1 m-032-01
+CUHK-student-dataset/sketch/m2-033-01-sz1 m-033-01
+CUHK-student-dataset/sketch/m2-034-01-sz1 m-034-01
+CUHK-student-dataset/sketch/m2-035-01-sz1 m-035-01
+CUHK-student-dataset/sketch/m2-036-01-sz1 m-036-01
+CUHK-student-dataset/sketch/m2-037-01-sz1 m-037-01
+CUHK-student-dataset/sketch/m2-038-01-sz1 m-038-01
+CUHK-student-dataset/sketch/m2-039-01-sz1 m-039-01
+CUHK-student-dataset/sketch/m2-040-01-sz1 m-040-01
+CUHK-student-dataset/sketch/m2-041-01-sz1 m-041-01
+CUHK-student-dataset/sketch/m2-042-01-sz1 m-042-01
+CUHK-student-dataset/sketch/m2-043-01-sz1 m-043-01
+CUHK-student-dataset/sketch/m2-044-01-sz1 m-044-01
+CUHK-student-dataset/sketch/m2-045-01-sz1 m-045-01
+CUHK-student-dataset/sketch/m2-046-01-sz1 m-046-01
+CUHK-student-dataset/sketch/m2-047-01-sz1 m-047-01
+CUHK-student-dataset/sketch/m2-048-01-sz1 m-048-01
+CUHK-student-dataset/sketch/m2-049-01-sz1 m-049-01
+CUHK-student-dataset/sketch/m2-050-01-sz1 m-050-01
+CUHK-student-dataset/sketch/m2-051-01-sz1 m-051-01
+CUHK-student-dataset/sketch/m2-052-01-sz1 m-052-01
+CUHK-student-dataset/sketch/m2-053-01-sz1 m-053-01
+CUHK-student-dataset/sketch/m2-054-01-sz1 m-054-01
+CUHK-student-dataset/sketch/m2-055-01-sz1 m-055-01
+CUHK-student-dataset/sketch/m2-056-01-sz1 m-056-01
+CUHK-student-dataset/sketch/m2-057-01-sz1 m-057-01
+CUHK-student-dataset/sketch/m2-058-01-sz1 m-058-01
+CUHK-student-dataset/sketch/m2-059-01-sz1 m-059-01
+CUHK-student-dataset/sketch/m2-060-01-sz1 m-060-01
+CUHK-student-dataset/sketch/m2-061-01-sz1 m-061-01
+CUHK-student-dataset/sketch/m2-062-01-sz1 m-062-01
 CUHK-student-dataset/photo/f-005-01 f-005-01  
 CUHK-student-dataset/photo/f-006-01 f-006-01
 CUHK-student-dataset/photo/f-007-01 f-007-01
diff --git a/bob/db/cuhk/models.py b/bob/db/cuhk/models.py
index 2a955734b67f35cc271135f274b34e7c9b84088a..0cc0ad0b9e11360c3e3e87f2f88d2dc79cd3c1a8 100644
--- a/bob/db/cuhk/models.py
+++ b/bob/db/cuhk/models.py
@@ -38,19 +38,35 @@ import os
 Base = declarative_base()
 
 """ Defining protocols. Yes, they are static """
-PROTOCOLS = ('cuhk', 'arface', 'xm2vts', 'all-mixed', 'cuhk-arface-xm2vts', 'cuhk-xm2vts-arface',
-  'arface-cuhk-xm2vts', 'arface-xm2vts-cuhk', 'xm2vts-cuhk-arface', 'xm2vts-arface-cuhk')
+PROTOCOLS = ('cuhk_p2s', 'arface_p2s', 'xm2vts_p2s', 'all-mixed_p2s', 'cuhk-arface-xm2vts_p2s', 'cuhk-xm2vts-arface_p2s',
+  'arface-cuhk-xm2vts_p2s', 'arface-xm2vts-cuhk_p2s', 'xm2vts-cuhk-arface_p2s', 'xm2vts-arface-cuhk_p2s',
+  'cuhk_s2p', 'arface_s2p', 'xm2vts_s2p', 'all-mixed_s2p', 'cuhk-arface-xm2vts_s2p', 'cuhk-xm2vts-arface_s2p',
+  'arface-cuhk-xm2vts_s2p', 'arface-xm2vts-cuhk_s2p', 'xm2vts-cuhk-arface_s2p', 'xm2vts-arface-cuhk_s2p')
+
 
 GROUPS    = ('world', 'dev', 'eval')
 
 PURPOSES   = ('train', 'enrol', 'probe')
 
 
-protocolPurpose_file_association = Table('protocol_file_association', Base.metadata,
-  Column('protocol', Enum(*PROTOCOLS), primary_key=True),
-  Column('group', Enum(*GROUPS), primary_key=True),
-  Column('purpose', Enum(*PURPOSES), primary_key=True),
-  Column('file_id',  Integer, ForeignKey('file.id'), primary_key=True))
+class Protocol_File_Association(Base):
+  """
+  Describe the protocols
+  """
+  __tablename__ = 'protocol_file_association'
+
+  protocol = Column('protocol', Enum(*PROTOCOLS), primary_key=True)
+  group    = Column('group', Enum(*GROUPS), primary_key=True)
+  purpose  = Column('purpose', Enum(*PURPOSES), primary_key=True)
+  file_id  = Column('file_id',  Integer, ForeignKey('file.id'), primary_key=True)
+
+  def __init__(self, protocol, group, purpose, file_id):
+    self.protocol = protocol
+    self.group    = group
+    self.purpose  = purpose
+    self.file_id  = file_id
+
+
 
 class Client(Base):
   """
@@ -95,7 +111,7 @@ class File(Base, bob.db.verification.utils.File):
   modality  = Column(Enum(*modality_choices))
 
   # a back-reference from the client class to a list of files
-  client      = relationship("Client", backref=backref("file", order_by=id))
+  client      = relationship("Client", backref=backref("files", order_by=id))
   all_annotations = relationship("Annotation", backref=backref("file"), uselist=True)
 
   def __init__(self, id, image_name, client_id, modality):
diff --git a/bob/db/cuhk/query.py b/bob/db/cuhk/query.py
index 5407c5ac0bc6a2a9f6fdd0e69631ca10392dca8f..6b2ac236666d4fa5af9fd4bd6d0d630f997b048f 100644
--- a/bob/db/cuhk/query.py
+++ b/bob/db/cuhk/query.py
@@ -21,6 +21,8 @@ import os
 import six
 from bob.db.base import utils
 from .models import *
+from .models import PROTOCOLS, GROUPS, PURPOSES
+
 from .driver import Interface
 
 import bob.db.verification.utils
@@ -40,20 +42,68 @@ class Database(bob.db.verification.utils.SQLiteDatabase, bob.db.verification.uti
 
 
   def objects(self, groups = None, protocol = None, purposes = None, model_ids = None, **kwargs):
-    """This function returns lists of File objects, which fulfill the given restrictions."""
+    """
+      This function returns lists of File objects, which fulfill the given restrictions.
 
+    """
 
-  def model_ids(self, protocol=None, groups=None, gender=None):
-    return []
+    #Checking inputs
+    groups    = self.check_parameters_for_validity(groups, "group", GROUPS)
+    protocols = self.check_parameters_for_validity(protocol, "protocol", PROTOCOLS) 
+    purposes  = self.check_parameters_for_validity(purposes, "purpose", PURPOSES)
+
+    #You need to select only one protocol
+    if (len(protocols) > 1):
+      raise ValueError("Please, select only one of the following protocols {0}".format(protocols))
+ 
+    #Querying
+    query = self.query(bob.db.cuhk.File).join(bob.db.cuhk.Protocol_File_Association).join(bob.db.cuhk.Client)
+
+    #filtering
+    query = query.filter(bob.db.cuhk.Protocol_File_Association.group.in_(groups))
+    query = query.filter(bob.db.cuhk.Protocol_File_Association.protocol.in_(protocols))
+    query = query.filter(bob.db.cuhk.Protocol_File_Association.purpose.in_(purposes))
+
+    if model_ids is not None:     
+     if type(model_ids) is not list and type(model_ids) is not tuple:
+       model_ids = [model_ids]
+
+     query = query.filter(bob.db.cuhk.Client.id.in_(model_ids))
+
+    return query.all()
+    
+
+  def model_ids(self, protocol=None, groups=None):
+
+    #Checking inputs
+    groups    = self.check_parameters_for_validity(groups, "group", GROUPS)
+    protocols = self.check_parameters_for_validity(protocol, "protocol", PROTOCOLS) 
+
+    #You need to select only one protocol
+    if (len(protocols) > 1):
+      raise ValueError("Please, select only one of the following protocols {0}".format(protocols))
+ 
+    #Querying
+    query = self.query(bob.db.cuhk.Client).join(bob.db.cuhk.File).join(bob.db.cuhk.Protocol_File_Association)
+
+    #filtering
+    query = query.filter(bob.db.cuhk.Protocol_File_Association.group.in_(groups))
+    query = query.filter(bob.db.cuhk.Protocol_File_Association.protocol.in_(protocols))
+
+    return query.all()
 
 
   def groups(self, protocol = None, **kwargs):
     """This function returns the list of groups for this database."""
+    return GROUPS
+
 
 
   def tmodel_ids(self, groups = None, protocol = None, **kwargs):
     """This function returns the ids of the T-Norm models of the given groups for the given protocol."""
 
+    return []
+
 
   def tobjects(self, protocol=None, model_ids=None, groups=None):
     #No TObjects    
diff --git a/bob/db/cuhk/utils.py b/bob/db/cuhk/utils.py
index 805c5c818a7e4a537e950b7522ef883f20ae91b8..8144448b1b50f96f49703d59ede6c4d17986342f 100644
--- a/bob/db/cuhk/utils.py
+++ b/bob/db/cuhk/utils.py
@@ -9,6 +9,7 @@ This file has some utilities to deal with the files provided by the database
 """
 
 import os
+import numpy
 import bob.db.arface
 
 def read_annotations(file_name):
@@ -65,6 +66,32 @@ class ARFACEWrapper():
     return 'man' if client_id[0]=='m' else 'woman'
 
 
+  def get_files_from_group(self, group=""):
+    """
+    Get the bob.db.cuhk.File for a given group (world, dev or eval).
+
+    Follow bellow the steps for this selection.
+
+     1 - Select the bob.db.arface.Client for a given group
+     2 - Search the correspondent bob.db.cuhk.File joint with bob.db.cuhk.Client using the original_client_id as a search criteria.
+     3 - Accumulate the result of the search.
+    """
+    arface = bob.db.arface.Database()
+    cuhk   = bob.db.cuhk.Database()
+
+    #Getting the clients from ARFACE
+    clients = arface.query(bob.db.arface.Client).filter(bob.db.arface.Client.sgroup==group)
+    
+    #Getting the correspondent files from bob.db.cuhk
+    files = []    
+    for c in clients:
+      cuhk_files = cuhk.query(bob.db.cuhk.File).join(bob.db.cuhk.Client).filter(bob.db.cuhk.Client.original_id==c.id)
+      for f in cuhk_files:
+        files.append(f)
+
+    return files
+
+
   def get_annotations(self, annotation_dir, annotation_extension='.dat'):
     """
     Get the annotation objects
@@ -72,8 +99,6 @@ class ARFACEWrapper():
 
     db = bob.db.cuhk.Database()
     annotations = []
-
-    #import ipdb; ipdb.set_trace();
  
     for o in db.query(bob.db.cuhk.File).join(bob.db.cuhk.Client).filter(bob.db.cuhk.Client.original_database=="arface"):
       #making the path
@@ -184,6 +209,96 @@ class XM2VTSWrapper():
   def get_gender(self):
     return 'none'
 
+  def get_files_from_group(self, group=""):
+    """
+    This is a hand made protocol since the XM2VTS database is biased.
+
+    For that I shuffled the indexes of the 295 clients and will take:
+      - 40% for training --> 118
+      - 30% for developement --> 88
+      - 30% for testing --> 89
+    """
+    
+    indexes = [273, 241, 285, 256, 173, 193, 107, 55, 53, 143, 163, 63, 13, 113, 258, 271, 134, 17, 20, 227, 203, 96, 66, 112, 77, 237, 42, 61, 272, 161, 209, 206, 195, 140, 150, 294, 152, 136, 188, 232, 21, 75, 141, 25, 249, 269, 70, 217, 251, 29, 153, 83, 185, 94, 116, 265, 177, 38, 156, 191, 118, 121, 204, 100, 255, 286, 78, 260, 282, 33, 242, 200, 91, 224, 137, 180, 65, 12, 3, 151, 154, 1, 290, 198, 167, 212, 72, 133, 144, 57, 0, 211, 48, 292, 213, 277, 52, 223, 115, 230, 49, 4, 291, 214, 18, 71, 146, 289, 250, 268, 201, 170, 11, 178, 2, 155, 264, 64, 287, 14, 110, 30, 19, 149, 68, 183, 44, 60, 181, 283, 86, 139, 81, 126, 202, 120, 10, 9, 164, 218, 43, 148, 105, 186, 225, 93, 184, 50, 257, 132, 254, 27, 108, 106, 69, 252, 138, 122, 196, 175, 228, 7, 168, 135, 15, 231, 182, 280, 147, 54, 261, 79, 281, 125, 142, 101, 259, 41, 187, 16, 275, 248, 179, 169, 89, 245, 26, 73, 199, 90, 128, 236, 40, 166, 262, 84, 32, 97, 92, 174, 284, 37, 36, 111, 82, 104, 58, 98, 235, 215, 220, 130, 85, 216, 205, 274, 22, 244, 129, 247, 6, 240, 279, 5, 109, 31, 74, 127, 95, 117, 210, 165, 80, 59, 114, 194, 238, 207, 239, 267, 159, 243, 131, 171, 67, 222, 8, 47, 45, 99, 123, 229, 293, 270, 253, 46, 162, 263, 102, 76, 88, 28, 158, 278, 62, 246, 176, 124, 234, 276, 87, 24, 157, 119, 197, 190, 35, 34, 160, 56, 266, 172, 39, 233, 221, 192, 288, 23, 226, 219, 189, 208, 145, 103, 51]
+   
+    #Fetching the clients
+    cuhk   = bob.db.cuhk.Database()
+    all_clients = numpy.array(cuhk.query(bob.db.cuhk.Client).filter(bob.db.cuhk.Client.original_database=="xm2vts").order_by(bob.db.cuhk.Client.original_id).all())
+
+    data_training = 118
+    data_dev      = 88
+    data_eval     = 89
+
+    clients = []
+    if(group=="world"):
+      offset = 0      
+      clients = all_clients[indexes[offset:offset+data_training]]
+    elif(group=="dev"):
+      offset = data_training
+      clients = all_clients[indexes[offset:offset+data_dev]]
+    else: 
+      offset  = data_training + data_dev
+      clients = all_clients[indexes[offset:offset+data_eval]]
+       
+ 
+    #Fetching the correspondent files from bob.db.cuhk
+    files = []    
+    for c in clients:
+      cuhk_files = cuhk.query(bob.db.cuhk.File).join(bob.db.cuhk.Client).filter(bob.db.cuhk.Client.id==c.id)
+      for f in cuhk_files:
+        files.append(f)
+
+    return files    
+    
+
+  def get_files_from_group_biased(self, group=""):
+    """
+    TODO: THE BOB.DB.XM2VTS PROTOCOLS ARE BIASED
+
+    Get the bob.db.cuhk.File for a given group (world, dev or eval).
+
+    There is no way to do it using ORM so I did a powerful SQL query in the XM2VTS.
+
+    SELECT client.* FROM client 
+      LEFT JOIN file ON file.client_id = client.id 
+      LEFT JOIN protocolPurpose_file_association ON protocolPurpose_file_association.file_id = file.id 
+      LEFT JOIN protocolPurpose ON protocolPurpose.id = protocolPurpose_file_association.protocolPurpose_id 
+      LEFT JOIN protocol ON protocol.id = protocolPurpose.protocol_id 
+
+      WHERE protocol.name = 'lp1' 
+      AND 
+      protocolPurpose.purpose='<purpose>'
+      AND 
+      protocolPurpose.sgroup='<group>'
+
+    """
+    from sqlalchemy import text
+    xm2vts = bob.db.xm2vts.Database()
+    cuhk   = bob.db.cuhk.Database()
+
+    #Getting the clients from ARFACE
+
+    sql = "SELECT client.* FROM client "\
+          "LEFT JOIN file ON file.client_id = client.id "\
+          "LEFT JOIN protocolPurpose_file_association ON protocolPurpose_file_association.file_id = file.id "\
+          "LEFT JOIN protocolPurpose ON protocolPurpose.id = protocolPurpose_file_association.protocolPurpose_id "\
+          "LEFT JOIN protocol ON protocol.id = protocolPurpose.protocol_id " \
+          "WHERE protocol.name = 'lp1'"\
+          "AND protocolPurpose.sgroup='"+ group +"'"
+ 
+    clients = xm2vts.query(bob.db.xm2vts.Client).from_statement(text(sql)).all()
+
+    #Getting the correspondent files from bob.db.cuhk
+    files = []    
+    for c in clients:
+      cuhk_files = cuhk.query(bob.db.cuhk.File).join(bob.db.cuhk.Client).filter(bob.db.cuhk.Client.original_id==c.id)
+      print "{0} = {1}".format(c.id, cuhk_files.count())
+      for f in cuhk_files:
+        files.append(f)
+
+    return files
+
+
 
 
   def get_annotations(self, annotation_dir, annotation_extension='.dat'):
@@ -335,6 +450,49 @@ class CUHKWrapper():
     return annotations
 
 
+  def get_files_from_group(self, group=""):
+    """
+    This is a hand made protocol since there is no protocol for the CUHK-CUFS database.
+
+    For that I shuffled the indexes of the 188 clients and will take:
+      - 40% for training --> 75
+      - 30% for developement --> 56
+      - 30% for testing --> 57
+    """
+   
+   
+    indexes = [152, 70, 150, 120, 181, 64, 16, 66, 154, 1, 84, 35, 179, 105, 49, 159, 128, 14, 103, 157, 18, 148, 88, 134, 147, 72, 62, 110, 20, 27, 30, 187, 50, 117, 83, 71, 81, 61, 185, 85, 2, 145, 138, 45, 129, 151, 96, 132, 146, 87, 156, 173, 73, 38, 125, 69, 82, 34, 116, 102, 136, 91, 7, 143, 109, 112, 115, 63, 33, 165, 104, 170, 76, 36, 114, 5, 142, 90, 60, 40, 93, 67, 180, 77, 106, 130, 135, 124, 118, 6, 39, 97, 121, 4, 74, 86, 57, 24, 65, 167, 184, 163, 47, 169, 94, 8, 58, 126, 166, 15, 172, 11, 89, 162, 42, 98, 22, 133, 78, 175, 0, 160, 92, 37, 161, 17, 26, 122, 137, 164, 99, 149, 32, 95, 144, 46, 155, 168, 48, 182, 23, 80, 10, 140, 9, 55, 29, 113, 12, 54, 158, 52, 41, 119, 183, 25, 131, 107, 176, 31, 111, 108, 123, 79, 153, 178, 139, 51, 13, 177, 141, 171, 101, 3, 43, 68, 56, 21, 75, 28, 53, 44, 19, 174, 100, 127, 186, 59]
+ 
+    #Fetching the clients
+    cuhk   = bob.db.cuhk.Database()
+    all_clients = numpy.array(cuhk.query(bob.db.cuhk.Client).filter(bob.db.cuhk.Client.original_database=="cuhk").order_by(bob.db.cuhk.Client.id).all())
+
+    data_training = 75
+    data_dev      = 56
+    data_eval     = 57
+
+    clients = []
+    if(group=="world"):
+      offset = 0
+      clients = all_clients[indexes[offset:offset+data_training]]
+    elif(group=="dev"):
+      offset = data_training
+      clients = all_clients[indexes[offset:offset+data_dev]]
+    else: 
+      offset  = data_training + data_dev
+      clients = all_clients[indexes[offset:offset+data_eval]]
+ 
+    #Fetching the correspondent files from bob.db.cuhk
+    files = []    
+    for c in clients:
+      cuhk_files = cuhk.query(bob.db.cuhk.File).join(bob.db.cuhk.Client).filter(bob.db.cuhk.Client.id==c.id)
+      for f in cuhk_files:
+        files.append(f)
+
+    return files    
+ 
+
+
   def get_files(self):
     """
     Get the correct file object from insert