diff --git a/bob/pad/face/config/database/aggregated_db.py b/bob/pad/face/config/database/aggregated_db.py
new file mode 100644
index 0000000000000000000000000000000000000000..375a1751a9346676bda178e95800ac63b508e1f9
--- /dev/null
+++ b/bob/pad/face/config/database/aggregated_db.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+"""Aggregated Db is a database for face PAD experiments.
+
+This database aggregates the data from 3 publicly available data-sets:
+`REPLAYATTACK`_, `REPLAY-MOBILE`_ and `MSU MFSD`_.
+
+You can download the data for the above databases by following the corresponding
+links.
+
+The reference citation for the `REPLAYATTACK`_ is [CAM12]_.
+The reference citation for the `REPLAY-MOBILE`_ is [CBVM16]_.
+The reference citation for the `MSU MFSD`_ is [WHJ15]_.
+
+.. include:: links.rst
+"""
+
+from bob.pad.face.database import AggregatedDbPadDatabase
+
+# Directory where the data files are stored.
+# This directory is given in the .bob_bio_databases.txt file located in your home directory
+original_directory = "[YOUR_AGGREGATED_DB_DIRECTORIES]"
+"""Value of ``~/.bob_bio_databases.txt`` for this database"""
+
+original_extension = ".mov" # extension of the data files
+
+database = AggregatedDbPadDatabase(
+    protocol='grandtest',
+    original_directory=original_directory,
+    original_extension=original_extension,
+    training_depends_on_protocol=True,
+)
+"""The :py:class:`bob.pad.base.database.PadDatabase` derivative with Aggregated Db
+database settings.
+
+.. warning::
+
+   This class only provides a programmatic interface to load data in an orderly
+   manner, respecting usage protocols. It does **not** contain the raw
+   data files. You should procure those yourself.
+
+Notice that ``original_directory`` is set to ``[YOUR_AGGREGATED_DB_DIRECTORIES]``.
+You must make sure to create ``${HOME}/.bob_bio_databases.txt`` file setting this
+value to the places where you actually installed the Replay-Attack, Replay-Mobile
+and MSU MFSD Databases. In particular, the paths pointing to these 3 databases
+must be saparated with a space. For example:
+[YOUR_AGGREGATED_DB_DIRECTORIES] = <PATH_TO_REPLAY_ATTACK> <PATH_TO_REPLAY_MOBILE>
+ <PATH_TO_MSU_MFSD>
+"""
\ No newline at end of file
diff --git a/bob/pad/face/database/__init__.py b/bob/pad/face/database/__init__.py
index abf2f69122cb549489bf3f043f6c66e8c160ed88..bc586be28417c221340e0bf11297282f5cb4e6d6 100644
--- a/bob/pad/face/database/__init__.py
+++ b/bob/pad/face/database/__init__.py
@@ -1,6 +1,8 @@
 from .replay import ReplayPadDatabase
 from .replay_mobile import ReplayMobilePadDatabase
 from .msu_mfsd import MsuMfsdPadDatabase
+from .aggregated_db import AggregatedDbPadDatabase
+
 
 # gets sphinx autodoc done right - don't remove it
 def __appropriate__(*args):
@@ -20,6 +22,7 @@ __appropriate__(
     ReplayPadDatabase,
     ReplayMobilePadDatabase,
     MsuMfsdPadDatabase,
+    AggregatedDbPadDatabase,
     )
 
 __all__ = [_ for _ in dir() if not _.startswith('_')]
diff --git a/bob/pad/face/database/aggregated_db.py b/bob/pad/face/database/aggregated_db.py
new file mode 100644
index 0000000000000000000000000000000000000000..8decbe0e640225f6eb258ba8bc720b7525de9bc1
--- /dev/null
+++ b/bob/pad/face/database/aggregated_db.py
@@ -0,0 +1,266 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+
+#==============================================================================
+from bob.pad.base.database import PadFile # Used in ReplayPadFile class
+
+from bob.pad.base.database import PadDatabase
+
+# Import HLDI for the databases to aggregate:
+from bob.pad.face.database import replay as replay_hldi
+
+from bob.pad.face.database import replay_mobile as replay_mobile_hldi
+
+from bob.pad.face.database import msu_mfsd as msu_mfsd_hldi
+
+#==============================================================================
+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.
+    """
+
+    def __init__(self, f):
+        """
+        **Parameters:**
+
+        ``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,
+            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.
+        """
+
+        self.f = f
+        # this f is actually an instance of the File class that is defined in
+        # bob.db.<database_name>.models and the PadFile class here needs
+        # client_id, path, attack_type, file_id for initialization. We have to
+        # convert information here and provide them to PadFile. attack_type is a
+        # 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():
+            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.
+
+        super(AggregatedDbPadFile, self).__init__(client_id=f.client_id, path=f.path,
+                                            attack_type=attack_type, file_id=f.id)
+
+
+    #==========================================================================
+    def load(self, directory=None, extension='.mov'):
+        """
+        Overridden version of the load method defined in the ``PadFile``.
+
+        **Parameters:**
+
+        ``directory`` : :py:class:`str`
+            String containing the paths to all databases used in this aggregated
+            database. The paths are separated with a space.
+
+        ``extension`` : :py:class:`str`
+            Extension of the video files in the REPLAY-ATTACK and REPLAY-MOBILE
+            databases. The extension of files in MSU MFSD is not taken into account
+            in the HighLevel DB Interface of MSU MFSD. Default: '.mov'.
+
+        **Returns:**
+
+        ``video_data`` : FrameContainer
+            Video data stored in the FrameContainer, see ``bob.bio.video.utils.FrameContainer``
+            for further details.
+        """
+
+        import bob.db.replay
+        import bob.db.replaymobile
+        import bob.db.msu_mfsd_mod
+
+        directories = directory.split(" ")
+
+        if isinstance(self.f, bob.db.replay.models.File): # check if instance of File class of LLDI of Replay-Attack
+
+            db_pad_file = replay_hldi.ReplayPadFile(self.f) # replay_hldi is HLDI of Replay-Attack
+
+            directory = directories[0]
+
+        if isinstance(self.f, bob.db.replaymobile.models.File): # check if instance of File class of LLDI of Replay-Mobile
+
+            db_pad_file = replay_mobile_hldi.ReplayMobilePadFile(self.f) # replay_mobile_hldi is HLDI of Replay-Mobile
+
+            directory = directories[1]
+
+        if isinstance(self.f, bob.db.msu_mfsd_mod.models.File): # check if instance of File class of LLDI of MSU MFSD
+
+            db_pad_file = msu_mfsd_hldi.MsuMfsdPadFile(self.f) # msu_mfsd_hldi is HLDI of MSU MFSD
+
+            directory = directories[2]
+
+        video_data = db_pad_file.load(directory = directory, extension = extension)
+
+        return video_data # video data
+
+
+#==============================================================================
+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.
+    """
+
+    def __init__(
+        self,
+        protocol='grandtest', # grandtest is the default protocol for this database
+        original_directory=None,
+        original_extension=None,
+        **kwargs):
+        """
+        **Parameters:**
+
+        ``protocol`` : :py:class:`str` or ``None``
+            The name of the protocol that defines the default experimental setup
+            for this database. Default: 'grandtest'.
+
+        ``original_directory`` : :py:class:`str`
+            String containing the paths to all databases used in this aggregated
+            database. The paths are separated with a space. Default: None.
+
+        ``original_extension`` : :py:class:`str`
+            Extension of the video files in the REPLAY-ATTACK and REPLAY-MOBILE
+            databases. The extension of files in MSU MFSD is not taken into account
+            in the HighLevel DB Interface of MSU MFSD. Default: None.
+
+        ``kwargs``
+            The arguments of the :py:class:`bob.bio.base.database.BioDatabase` base class constructor.
+        """
+
+        # Import LLDI for all databases:
+        import bob.db.replay
+        import bob.db.replaymobile
+        import bob.db.msu_mfsd_mod
+
+        self.replay_db = bob.db.replay.Database()
+        self.replaymobile_db = bob.db.replaymobile.Database()
+        self.msu_mfsd_db = bob.db.msu_mfsd_mod.Database()
+
+        # Since the high level API expects different group names than what the low
+        # level API offers, you need to convert them when necessary
+        self.low_level_group_names = ('train', 'devel', 'test') # group names in the low-level database interface
+        self.high_level_group_names = ('train', 'dev', 'eval') # names are expected to be like that in objects() function
+
+        # Always use super to call parent class methods.
+        super(AggregatedDbPadDatabase, self).__init__(
+            name = 'aggregated_db',
+            protocol = protocol,
+            original_directory = original_directory,
+            original_extension = original_extension,
+            **kwargs)
+
+
+    #==========================================================================
+    def objects(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs):
+        """
+        This function returns lists of ReplayPadFile objects, which fulfill the given restrictions.
+
+        Keyword parameters:
+
+        ``groups`` : :py:class:`str`
+            OR a list of strings.
+            The groups of which the clients should be returned.
+            Usually, groups are one or more elements of ('train', 'dev', 'eval')
+
+        ``protocol`` : :py:class:`str`
+            The protocol for which the clients should be retrieved.
+            The protocol is dependent on your database.
+            If you do not have protocols defined, just ignore this field.
+
+        ``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'.
+
+        ``model_ids``
+            This parameter is not supported in PAD databases yet
+
+        **Returns:**
+
+        ``files`` : [AggregatedDbPadFile]
+            A list of AggregatedDbPadFile objects.
+        """
+
+        # Convert group names to low-level group names here.
+        groups = self.convert_names_to_lowlevel(groups, self.low_level_group_names, self.high_level_group_names)
+        # Since this database was designed for PAD experiments, nothing special
+        # needs to be done here.
+        replay_files = self.replay_db.objects(protocol=protocol, groups=groups, cls=purposes, **kwargs)
+
+        replaymobile_files = self.replaymobile_db.objects(protocol=protocol, groups=groups, cls=purposes, **kwargs)
+
+        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 = [AggregatedDbPadFile(f) for f in files]
+        return files
+
+
+    #==========================================================================
+    def annotations(self, f):
+        """
+        Return annotations for a given file object ``f``, which is an instance
+        of ``AggregatedDbPadFile`` defined in the HLDI of the Aggregated DB.
+        The ``load()`` method of ``AggregatedDbPadFile`` class (see above)
+        returns a video, therefore this method returns bounding-box annotations
+        for each video frame. The annotations are returned as dictionary of dictionaries.
+
+        **Parameters:**
+
+        ``f`` : :py:class:`object`
+            An instance of ``AggregatedDbPadFile`` defined above.
+
+        **Returns:**
+
+        ``annotations`` : :py:class:`dict`
+            A dictionary containing the annotations for each frame in the video.
+            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
+        import bob.db.replaymobile
+        import bob.db.msu_mfsd_mod
+
+        directories = self.original_directory.split(" ")
+
+        if isinstance(f.f, bob.db.replay.models.File): # check if instance of File class of LLDI of Replay-Attack
+
+            hldi_db = replay_hldi.ReplayPadDatabase(original_directory = directories[0])
+
+        if isinstance(f.f, bob.db.replaymobile.models.File): # check if instance of File class of LLDI of Replay-Mobile
+
+            hldi_db = replay_mobile_hldi.ReplayMobilePadDatabase(original_directory = directories[1])
+
+        if isinstance(f.f, bob.db.msu_mfsd_mod.models.File): # check if instance of File class of LLDI of MSU MFSD
+
+            hldi_db = msu_mfsd_hldi.MsuMfsdPadDatabase(original_directory = directories[2])
+
+        annotations = hldi_db.annotations(f)
+
+        return annotations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bob/pad/face/database/msu_mfsd.py b/bob/pad/face/database/msu_mfsd.py
index 7b183441c2128e222c17725268c6e117328ef8dc..52c7fb8fca9e2ed4594ed465f9d8cba2d353bbd5 100644
--- a/bob/pad/face/database/msu_mfsd.py
+++ b/bob/pad/face/database/msu_mfsd.py
@@ -181,7 +181,7 @@ class MsuMfsdPadDatabase(PadDatabase):
 
         **Returns:**
 
-        ``files`` : :py:class:`str`
+        ``files`` : [MsuMfsdPadFile]
             A list of MsuMfsdPadFile objects.
         """
 
diff --git a/bob/pad/face/database/replay.py b/bob/pad/face/database/replay.py
index 1d1a663548a40e4751f6564e68d55779fd816d41..d9656f3dd0639a73fcf698b1944a2b9687eae252 100644
--- a/bob/pad/face/database/replay.py
+++ b/bob/pad/face/database/replay.py
@@ -148,9 +148,10 @@ class ReplayPadDatabase(PadDatabase):
 
         **Returns:**
 
-        ``files`` : :py:class:`str`
+        ``files`` : [ReplayPadFile]
             A list of ReplayPadFile objects.
         """
+
         # Convert group names to low-level group names here.
         groups = self.convert_names_to_lowlevel(groups, self.low_level_group_names, self.high_level_group_names)
         # Since this database was designed for PAD experiments, nothing special
diff --git a/bob/pad/face/database/replay_mobile.py b/bob/pad/face/database/replay_mobile.py
index 773ca43d469e5341500948c12c2837faa61aa0ea..9745e181a9ef6090f0d9c38f0af8d42208bf9bdd 100644
--- a/bob/pad/face/database/replay_mobile.py
+++ b/bob/pad/face/database/replay_mobile.py
@@ -173,7 +173,7 @@ class ReplayMobilePadDatabase(PadDatabase):
 
         **Returns:**
 
-        ``files`` : :py:class:`str`
+        ``files`` : [ReplayMobilePadFile]
             A list of ReplayMobilePadFile objects.
         """