diff --git a/bob/pad/face/database/aggregated_db.py b/bob/pad/face/database/aggregated_db.py
index 9087f3e747db1c3a21f6a5ede62883e843bd92d9..3669aee750dd26ae2b8b7ae865089e71516c9258 100644
--- a/bob/pad/face/database/aggregated_db.py
+++ b/bob/pad/face/database/aggregated_db.py
@@ -13,13 +13,17 @@ from bob.pad.face.database import replay_mobile as replay_mobile_hldi
 
 from bob.pad.face.database import msu_mfsd as msu_mfsd_hldi
 
+from bob.bio.video.database.mobio import MobioBioFile
+
+from bob.bio.video import FrameSelector
+
 import numpy as np
 
 #==============================================================================
 class AggregatedDbPadFile(PadFile):
     """
     A high level implementation of the File class for the Aggregated Database
-    uniting 3 databases: REPLAY-ATTACK, REPLAY-MOBILE and MSU MFSD.
+    uniting 4 databases: REPLAY-ATTACK, REPLAY-MOBILE, MSU MFSD and Mobio.
     """
 
     def __init__(self, f):
@@ -28,10 +32,12 @@ class AggregatedDbPadFile(PadFile):
 
         ``f`` : :py:class:`object`
             An instance of the File class defined in the low level db interface
-            of the Replay-Attack or Replay-Mobile or MSU MFSD database, respectively
+            of Replay-Attack, or Replay-Mobile, or MSU MFSD, or Mobio database,
+            respectively:
             in the bob.db.replay.models.py       file or
             in the bob.db.replaymobile.models.py file or
-            in the bob.db.msu_mfsd_mod.models.py file.
+            in the bob.db.msu_mfsd_mod.models.py file or
+            in the bob.db.mobio.models.py file.
         """
 
         self.f = f
@@ -42,10 +48,19 @@ class AggregatedDbPadFile(PadFile):
         # little tricky to get here. Based on the documentation of PadFile:
         # In cased of a spoofed data, this parameter should indicate what kind of spoofed attack it is.
         # The default None value is interpreted that the PadFile is a genuine or real sample.
-        if f.is_real():
+
+        import bob.db.mobio
+
+        if isinstance(f, bob.db.mobio.models.File): # MOBIO files doen't have is_real() method
+
             attack_type = None
+
         else:
-            attack_type = 'attack'
+
+            if f.is_real():
+                attack_type = None
+            else:
+                attack_type = 'attack'
         # attack_type is a string and I decided to make it like this for this
         # particular database. You can do whatever you want for your own database.
 
@@ -67,10 +82,12 @@ class AggregatedDbPadFile(PadFile):
 
         ``f`` : :py:class:`object`
             An instance of the File class defined in the low level db interface
-            of the Replay-Attack or Replay-Mobile or MSU MFSD database, respectively
+            of Replay-Attack, or Replay-Mobile, or MSU MFSD, or Mobio database,
+            respectively:
             in the bob.db.replay.models.py       file or
             in the bob.db.replaymobile.models.py file or
-            in the bob.db.msu_mfsd_mod.models.py file.
+            in the bob.db.msu_mfsd_mod.models.py file or
+            in the bob.db.mobio.models.py file.
 
         ``n`` : :py:class:`int`
             An offset to be added to the file id for different databases is defined
@@ -87,6 +104,7 @@ class AggregatedDbPadFile(PadFile):
         import bob.db.replay
         import bob.db.replaymobile
         import bob.db.msu_mfsd_mod
+        import bob.db.mobio
 
         if isinstance(f, bob.db.replay.models.File): # check if instance of File class of LLDI of Replay-Attack
 
@@ -100,6 +118,10 @@ class AggregatedDbPadFile(PadFile):
 
             file_id = np.int(f.id + 2*n)
 
+        if isinstance(f, bob.db.mobio.models.File): # check if instance of File class of LLDI of Mobio
+
+            file_id = np.int(f.id + 3*n)
+
         return file_id
 
 
@@ -113,10 +135,12 @@ class AggregatedDbPadFile(PadFile):
 
         ``f`` : :py:class:`object`
             An instance of the File class defined in the low level db interface
-            of the Replay-Attack or Replay-Mobile or MSU MFSD database, respectively
+            of Replay-Attack, or Replay-Mobile, or MSU MFSD, or Mobio database,
+            respectively:
             in the bob.db.replay.models.py       file or
             in the bob.db.replaymobile.models.py file or
-            in the bob.db.msu_mfsd_mod.models.py file.
+            in the bob.db.msu_mfsd_mod.models.py file or
+            in the bob.db.mobio.models.py file.
 
         **Returns:**
 
@@ -128,6 +152,7 @@ class AggregatedDbPadFile(PadFile):
         import bob.db.replay
         import bob.db.replaymobile
         import bob.db.msu_mfsd_mod
+        import bob.db.mobio
 
         if isinstance(f, bob.db.replay.models.File): # check if instance of File class of LLDI of Replay-Attack
 
@@ -141,6 +166,10 @@ class AggregatedDbPadFile(PadFile):
 
             file_path = '_'.join([f.path, 'msu_mfsd_mod'])
 
+        if isinstance(f, bob.db.mobio.models.File): # check if instance of File class of LLDI of Mobio
+
+            file_path = '_'.join([f.path, 'mobio'])
+
         return file_path
 
 
@@ -170,6 +199,7 @@ class AggregatedDbPadFile(PadFile):
         import bob.db.replay
         import bob.db.replaymobile
         import bob.db.msu_mfsd_mod
+        import bob.db.mobio
 
         directories = directory.split(" ")
 
@@ -191,7 +221,21 @@ class AggregatedDbPadFile(PadFile):
 
             directory = directories[2]
 
-        video_data = db_pad_file.load(directory = directory, extension = extension)
+        if isinstance(self.f, bob.db.mobio.models.File): # check if instance of File class of LLDI of Mobio
+
+            db_pad_file = MobioBioFile(self.f) # msu_mfsd_hldi is HLDI of MSU MFSD
+
+            directory = directories[3]
+
+        if isinstance(db_pad_file, bob.bio.video.database.mobio.MobioBioFile):
+
+            frame_selector = FrameSelector(selection_style='all') # select all frames of the file
+
+            video_data = db_pad_file.load(directory = directory, extension = '.mp4', frame_selector = frame_selector)
+
+        else:
+
+            video_data = db_pad_file.load(directory = directory, extension = extension)
 
         return video_data # video data
 
@@ -201,7 +245,7 @@ class AggregatedDbPadDatabase(PadDatabase):
     """
     A high level implementation of the Database class for the Aggregated Database
     uniting 3 databases: REPLAY-ATTACK, REPLAY-MOBILE and MSU MFSD. Currently this
-    database supports 3 protocols, which are listed in the ``available_protocols``
+    database supports 5 protocols, which are listed in the ``available_protocols``
     argument of this class.
 
     Available protocols are:
@@ -226,6 +270,16 @@ class AggregatedDbPadDatabase(PadDatabase):
        'eval' set  - only **photo** attacks are used in final evaluation.
        In this case the final performance is estimated on previously
        unseen **photo** attacks.
+
+    4. "grandtest-mobio" - this protocol is using all the data available in the
+       databases Replay-Attack, Replay-Mobile, MSU MFSD plus some additional data
+       from MOBIO dataset is used in the training set.
+
+    5. "grandtest-train-eval" - - this protocol is using all the data available
+       in the databases Replay-Attack, Replay-Mobile, MSU MFSD. Only two gropus
+       'train' and 'eval' are available in this protocol. The 'dev' set is
+       concatenated to the training data. When requesting 'dev' set, the
+       data of the 'eval' set is returned.
     """
 
     def __init__(
@@ -258,10 +312,12 @@ class AggregatedDbPadDatabase(PadDatabase):
         import bob.db.replay
         import bob.db.replaymobile
         import bob.db.msu_mfsd_mod
+        import bob.db.mobio
 
         self.replay_db = bob.db.replay.Database()
         self.replaymobile_db = bob.db.replaymobile.Database()
         self.msu_mfsd_db = bob.db.msu_mfsd_mod.Database()
+        self.mobio = bob.db.mobio.Database()
 
         # Since the high level API expects different group names than what the low
         # level API offers, you need to convert them when necessary
@@ -269,7 +325,7 @@ class AggregatedDbPadDatabase(PadDatabase):
         self.high_level_group_names = ('train', 'dev', 'eval') # names are expected to be like that in objects() function
 
         # A list of available protocols:
-        self.available_protocols = ['grandtest', 'photo-photo-video', 'video-video-photo']
+        self.available_protocols = ['grandtest', 'photo-photo-video', 'video-video-photo', 'grandtest-mobio', 'grandtest-train-eval']
 
         # Always use super to call parent class methods.
         super(AggregatedDbPadDatabase, self).__init__(
@@ -280,16 +336,73 @@ class AggregatedDbPadDatabase(PadDatabase):
             **kwargs)
 
 
+    #==========================================================================
+    def get_mobio_files_given_single_group(self, groups=None, purposes=None):
+        """
+        Get a list of files for the MOBIO database. All files are bona-fide
+        samples and used only for training. Thus, a non-empty list is returned
+        only when groups='train' and purposes='real'.
+        Only one file per client is selected. The files collected in Idiap are
+        excluded from training set to make sure identities in 'train' set don't
+        overlap with 'devel' and 'test' sets.
+
+        **Parameters:**
+
+        ``groups`` : :py:class:`str`
+            The group of which the clients should be returned.
+            One element of ('train', 'devel', 'test').
+
+        ``purposes`` : :py:class:`str`
+            OR a list of strings.
+            The purposes for which File objects should be retrieved.
+            Usually it is either 'real' or 'attack'.
+
+        **Returns:**
+
+        ``mobio_files`` : [File]
+            A list of files, as defined in the low level interface of the MOBIO
+            database.
+        """
+
+        mobio_files = []
+
+        if (groups is not None) and ('train' in groups) and (purposes is not None) and ('real' in purposes):
+
+            files_mobio = self.mobio.all_files()
+
+            metadata = []
+
+            for f in files_mobio:
+
+                metadata.append((f.client_id))
+
+            metadata_set = list(set(metadata)) # metadata_set is a list of unique client ids
+
+            for f in files_mobio:
+
+                metadata = (f.client_id)
+
+                if metadata in metadata_set: # only one video per client id is selected
+
+                    metadata_set.remove(metadata)
+
+                    if "idiap" not in f.path:
+                        # videos collected at idiap are excluded to make sure identities in train set dont overlap with dev and test sets.
+                        mobio_files.append(f)
+
+        return mobio_files
+
+
     #==========================================================================
     def get_files_given_single_group(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs):
         """
-        This function returns 3 lists of files for Raplay-Attack, Replay-Mobile
-        and MSU MFSD databases, which fulfill the given restrictions. This
+        This function returns 4 lists of files for Raplay-Attack, Replay-Mobile,
+        MSU MFSD and MOBIO databases, which fulfill the given restrictions. This
         function for the groups parameter accepts a single string ONLY, which
         determines the low level name of the group, see ``low_level_group_names``
         argument of this class for available options.
 
-        Keyword parameters:
+        **Parameters:**
 
         ``groups`` : :py:class:`str`
             The group of which the clients should be returned.
@@ -321,6 +434,16 @@ class AggregatedDbPadDatabase(PadDatabase):
                In this case the final performance is estimated on previously
                unseen **photo** attacks.
 
+            4. "grandtest-mobio" - this protocol is using all the data available in the
+               databases Replay-Attack, Replay-Mobile, MSU MFSD plus some additional data
+               from MOBIO dataset is used in the training set.
+
+            5. "grandtest-train-eval" - - this protocol is using all the data available
+               in the databases Replay-Attack, Replay-Mobile, MSU MFSD. Only two gropus
+               'train' and 'test' are available in this protocol. The 'devel' set is
+               concatenated to the training data. When requesting 'devel' set, the
+               data of the 'test' set is returned.
+
         ``purposes`` : :py:class:`str`
             OR a list of strings.
             The purposes for which File objects should be retrieved.
@@ -339,9 +462,11 @@ class AggregatedDbPadDatabase(PadDatabase):
 
         ``msu_mfsd_files`` : [File]
             A list of files corresponding to MSU MFSD database.
+
+        ``mobio_files`` : [File]
+            A list of files corresponding to MOBIO database or an empty list.
         """
 
-        # with grandtest protocol
         if protocol == 'grandtest' or protocol is None or groups is None:
 
             replay_files = self.replay_db.objects(protocol=protocol, groups=groups, cls=purposes, **kwargs)
@@ -386,14 +511,44 @@ class AggregatedDbPadDatabase(PadDatabase):
 
                 msu_mfsd_files = self.msu_mfsd_db.objects(group=groups, cls=purposes, instrument = ('print', ''), **kwargs)
 
-        return replay_files, replaymobile_files, msu_mfsd_files
+        mobio_files = []
+
+        if protocol == 'grandtest-mobio':
+
+            replay_files = self.replay_db.objects(protocol='grandtest', groups=groups, cls=purposes, **kwargs)
+
+            replaymobile_files = self.replaymobile_db.objects(protocol='grandtest', groups=groups, cls=purposes, **kwargs)
+
+            msu_mfsd_files = self.msu_mfsd_db.objects(group=groups, cls=purposes, **kwargs)
+
+            mobio_files = self.get_mobio_files_given_single_group(groups=groups, purposes=purposes)
+
+        if protocol == 'grandtest-train-eval':
+
+            if groups == 'train':
+
+                replay_files = self.replay_db.objects(protocol='grandtest', groups=['train', 'devel'], cls=purposes, **kwargs)
+
+                replaymobile_files = self.replaymobile_db.objects(protocol='grandtest', groups=['train', 'devel'], cls=purposes, **kwargs)
+
+                msu_mfsd_files = self.msu_mfsd_db.objects(group=['train', 'devel'], cls=purposes, **kwargs)
+
+            if groups in ['devel', 'test']:
+
+                replay_files = self.replay_db.objects(protocol='grandtest', groups='test', cls=purposes, **kwargs)
+
+                replaymobile_files = self.replaymobile_db.objects(protocol='grandtest', groups='test', cls=purposes, **kwargs)
+
+                msu_mfsd_files = self.msu_mfsd_db.objects(group='test', cls=purposes, **kwargs)
+
+        return replay_files, replaymobile_files, msu_mfsd_files, mobio_files
 
 
     #==========================================================================
     def get_files_given_groups(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs):
         """
-        This function returns 3 lists of files for Raplay-Attack, Replay-Mobile
-        and MSU MFSD databases, which fulfill the given restrictions. This
+        This function returns 4 lists of files for Raplay-Attack, Replay-Mobile,
+        MSU MFSD and MOBIO databases, which fulfill the given restrictions. This
         function for the groups parameter accepts a single string OR a list
         of strings with multiple groups. Group names are low level, see
         ``low_level_group_names`` argument of the class for available options.
@@ -431,6 +586,16 @@ class AggregatedDbPadDatabase(PadDatabase):
                In this case the final performance is estimated on previously
                unseen **photo** attacks.
 
+            4. "grandtest-mobio" - this protocol is using all the data available in the
+               databases Replay-Attack, Replay-Mobile, MSU MFSD plus some additional data
+               from MOBIO dataset is used in the training set.
+
+            5. "grandtest-train-eval" - - this protocol is using all the data available
+               in the databases Replay-Attack, Replay-Mobile, MSU MFSD. Only two gropus
+               'train' and 'test' are available in this protocol. The 'devel' set is
+               concatenated to the training data. When requesting 'devel' set, the
+               data of the 'test' set is returned.
+
         ``purposes`` : :py:class:`str`
             OR a list of strings.
             The purposes for which File objects should be retrieved.
@@ -449,6 +614,9 @@ class AggregatedDbPadDatabase(PadDatabase):
 
         ``msu_mfsd_files`` : [File]
             A list of files corresponding to MSU MFSD database.
+
+        ``mobio_files`` : [File]
+            A list of files corresponding to MOBIO database or an empty list.
         """
 
         if isinstance(groups, str) or groups is None: # if a single group is given
@@ -461,6 +629,8 @@ class AggregatedDbPadDatabase(PadDatabase):
 
         msu_mfsd_files = []
 
+        mobio_files = []
+
         for group in groups:
 
             files = self.get_files_given_single_group(groups = group, protocol = protocol, purposes = purposes, model_ids = model_ids, **kwargs)
@@ -471,7 +641,9 @@ class AggregatedDbPadDatabase(PadDatabase):
 
             msu_mfsd_files += files[2]
 
-        return replay_files, replaymobile_files, msu_mfsd_files
+            mobio_files += files[3]
+
+        return replay_files, replaymobile_files, msu_mfsd_files, mobio_files
 
 
     #==========================================================================
@@ -512,6 +684,10 @@ class AggregatedDbPadDatabase(PadDatabase):
                In this case the final performance is estimated on previously
                unseen **photo** attacks.
 
+            4. "grandtest-mobio" - this protocol is using all the data available in the
+               databases Replay-Attack, Replay-Mobile, MSU MFSD plus some additional data
+               from MOBIO dataset is used in the training set.
+
         ``purposes`` : :py:class:`str`
             OR a list of strings.
             The purposes for which File objects should be retrieved.
@@ -531,11 +707,11 @@ class AggregatedDbPadDatabase(PadDatabase):
         # Since this database was designed for PAD experiments, nothing special
         # needs to be done here.
 
-        replay_files, replaymobile_files, msu_mfsd_files = self.get_files_given_groups(groups = groups,
-                                                                                       protocol = protocol,
-                                                                                       purposes = purposes,
-                                                                                       model_ids = model_ids,
-                                                                                       **kwargs)
+        replay_files, replaymobile_files, msu_mfsd_files, mobio_files = self.get_files_given_groups(groups = groups,
+                                                                                                    protocol = protocol,
+                                                                                                    purposes = purposes,
+                                                                                                    model_ids = model_ids,
+                                                                                                    **kwargs)
 
 #            replay_files = self.replay_db.objects(protocol=protocol, groups=groups, cls=purposes, **kwargs)
 #
@@ -543,7 +719,7 @@ class AggregatedDbPadDatabase(PadDatabase):
 #
 #            msu_mfsd_files = self.msu_mfsd_db.objects(group=groups, cls=purposes, **kwargs)
 
-        files = replay_files + replaymobile_files + msu_mfsd_files # append all files to a single list
+        files = replay_files + replaymobile_files + msu_mfsd_files + mobio_files # append all files to a single list
 
         files = [AggregatedDbPadFile(f) for f in files]
 
@@ -571,6 +747,7 @@ class AggregatedDbPadDatabase(PadDatabase):
             Dictionary structure: ``annotations = {'1': frame1_dict, '2': frame1_dict, ...}``.
             Where ``frameN_dict = {'topleft': (row, col), 'bottomright': (row, col)}``
             is the dictionary defining the coordinates of the face bounding box in frame N.
+
         """
 
         import bob.db.replay
@@ -591,6 +768,19 @@ class AggregatedDbPadDatabase(PadDatabase):
 
             hldi_db = msu_mfsd_hldi.MsuMfsdPadDatabase(original_directory = directories[2])
 
-        annotations = hldi_db.annotations(f)
+        if self.protocol == "grandtest-mobio" or isinstance(f.f, bob.db.mobio.models.File): # annotations are not available for this protocol
+
+            annotations = {}
+
+        else:
+
+            annotations = hldi_db.annotations(f)
 
         return annotations
+
+
+
+
+
+
+
diff --git a/test-requirements.txt b/test-requirements.txt
index 9c59832182371a73802a46b035a5fbbb852980e5..306a471cc175f084f79b51a77535a02ff7b7f44c 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,4 +1,5 @@
 nose
 bob.db.replay
 bob.db.replaymobile
-bob.db.msu_mfsd_mod
\ No newline at end of file
+bob.db.msu_mfsd_mod
+bob.db.mobio