diff --git a/advanced/databases/avspoof/5.json b/advanced/databases/avspoof/5.json
new file mode 100644
index 0000000000000000000000000000000000000000..7009832e4407d30dfccace1062a2894ded3aa933
--- /dev/null
+++ b/advanced/databases/avspoof/5.json
@@ -0,0 +1,503 @@
+{
+    "description": "The AVspoof Database",
+    "root_folder": "/idiap/resource/database/AVSpoof",
+    "protocols": [
+        {
+            "name": "smalltest_verify_train",
+            "template": "verify_trainset_speech/1",
+            "views": {
+                "train_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "smalltest",
+                        "purpose": "enroll"
+                    }
+                },
+                "train_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "smalltest"
+                    }
+                }
+            }
+        },
+        {
+            "name": "smalltest_verify_train_spoof",
+            "template": "verify_trainset_speech_spoof/1",
+            "views": {
+                "train_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "smalltest"
+                    }
+                }
+            }
+        },
+        {
+            "name": "smalltest_verification",
+            "template": "advanced_speaker_recognition/1",
+            "views": {
+                "train": {
+                    "view": "RecognitionTraining",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "smalltest"
+                    }
+                },
+                "dev_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "group": "devel",
+                        "protocol": "smalltest",
+                        "purpose": "enroll"
+                    }
+                },
+                "dev_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "group": "devel",
+                        "protocol": "smalltest"
+                    }
+                },
+                "test_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "group": "test",
+                        "protocol": "smalltest",
+                        "purpose": "enroll"
+                    }
+                },
+                "test_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "group": "test",
+                        "protocol": "smalltest"
+                    }
+                }
+            }
+        },
+        {
+            "name": "smalltest_verification_spoof",
+            "template": "speaker_recognition_spoof/1",
+            "views": {
+                "dev_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "group": "devel",
+                        "protocol": "smalltest"
+                    }
+                },
+                "test_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "group": "test",
+                        "protocol": "smalltest"
+                    }
+                }
+            }
+        },
+        {
+            "name": "grandtest_verify_train",
+            "template": "verify_trainset_speech/1",
+            "views": {
+                "train_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "grandtest",
+                        "purpose": "enroll"
+                    }
+                },
+                "train_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "grandtest"
+                    }
+                }
+            }
+        },
+        {
+            "name": "grandtest_verify_train_spoof",
+            "template": "verify_trainset_speech_spoof/1",
+            "views": {
+                "train_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "grandtest"
+                    }
+                }
+            }
+        },
+        {
+            "name": "grandtest_verification",
+            "template": "advanced_speaker_recognition/1",
+            "views": {
+                "train": {
+                    "view": "RecognitionTraining",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "group": "train"
+                    }
+                },
+                "dev_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "purpose": "enroll",
+                        "group": "devel"
+                    }
+                },
+                "dev_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "group": "devel"
+                    }
+                },
+                "test_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "purpose": "enroll",
+                        "group": "test"
+                    }
+                },
+                "test_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "group": "test"
+                    }
+                }
+            }
+        },
+        {
+            "name": "grandtest_verification_spoof",
+            "template": "speaker_recognition_spoof/1",
+            "views": {
+                "dev_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "group": "devel"
+                    }
+                },
+                "test_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "group": "test"
+                    }
+                }
+            }
+        },
+        {
+            "name": "physicalaccess_verify_train",
+            "template": "verify_trainset_speech/1",
+            "views": {
+                "train_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "physical_access",
+                        "purpose": "enroll"
+                    }
+                },
+                "train_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "physical_access"
+                    }
+                }
+            }
+        },
+        {
+            "name": "physicalaccess_verify_train_spoof",
+            "template": "verify_trainset_speech_spoof/1",
+            "views": {
+                "train_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "physical_access"
+                    }
+                }
+            }
+        },
+        {
+            "name": "physicalaccess_verification",
+            "template": "advanced_speaker_recognition/1",
+            "views": {
+                "train": {
+                    "view": "RecognitionTraining",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "group": "train"
+                    }
+                },
+                "dev_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "purpose": "enroll",
+                        "group": "devel"
+                    }
+                },
+                "dev_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "group": "devel"
+                    }
+                },
+                "test_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "purpose": "enroll",
+                        "group": "test"
+                    }
+                },
+                "test_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "group": "test"
+                    }
+                }
+            }
+        },
+        {
+            "name": "physicalaccess_verification_spoof",
+            "template": "speaker_recognition_spoof/1",
+            "views": {
+                "dev_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "group": "devel"
+                    }
+                },
+                "test_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "group": "test"
+                    }
+                }
+            }
+        },
+        {
+            "name": "logicalaccess_verify_train",
+            "template": "verify_trainset_speech/1",
+            "views": {
+                "train_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "logical_access",
+                        "purpose": "enroll"
+                    }
+                },
+                "train_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "logical_access"
+                    }
+                }
+            }
+        },
+        {
+            "name": "logicalaccess_verify_train_spoof",
+            "template": "verify_trainset_speech_spoof/1",
+            "views": {
+                "train_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "logical_access"
+                    }
+                }
+            }
+        },
+        {
+            "name": "logicalaccess_verification",
+            "template": "advanced_speaker_recognition/1",
+            "views": {
+                "train": {
+                    "view": "RecognitionTraining",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "group": "train"
+                    }
+                },
+                "dev_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "purpose": "enroll",
+                        "group": "devel"
+                    }
+                },
+                "dev_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "group": "devel"
+                    }
+                },
+                "test_templates": {
+                    "view": "RecognitionTemplates",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "purpose": "enroll",
+                        "group": "test"
+                    }
+                },
+                "test_probes": {
+                    "view": "Probes",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "group": "test"
+                    }
+                }
+            }
+        },
+        {
+            "name": "logicalaccess_verification_spoof",
+            "template": "speaker_recognition_spoof/1",
+            "views": {
+                "dev_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "group": "devel"
+                    }
+                },
+                "test_attacks": {
+                    "view": "Attacks",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "group": "test"
+                    }
+                }
+            }
+        },
+        {
+            "name": "smalltest_antispoofing",
+            "template": "simple_speech_antispoofing/1",
+            "views": {
+                "train": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "group": "train",
+                        "protocol": "smalltest"
+                    }
+                },
+                "dev_probes": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "group": "devel",
+                        "protocol": "smalltest"
+                    }
+                },
+                "eval_probes": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "group": "test",
+                        "protocol": "smalltest"
+                    }
+                }
+            }
+        },
+        {
+            "name": "grandtest_antispoofing",
+            "template": "simple_speech_antispoofing/1",
+            "views": {
+                "train": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "group": "train"
+                    }
+                },
+                "dev_probes": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "group": "devel"
+                    }
+                },
+                "eval_probes": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "grandtest",
+                        "group": "test"
+                    }
+                }
+            }
+        },
+        {
+            "name": "physicalaccess_antispoofing",
+            "template": "simple_speech_antispoofing/1",
+            "views": {
+                "train": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "group": "train"
+                    }
+                },
+                "dev_probes": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "group": "devel"
+                    }
+                },
+                "eval_probes": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "physical_access",
+                        "group": "test"
+                    }
+                }
+            }
+        },
+        {
+            "name": "logicalaccess_antispoofing",
+            "template": "simple_speech_antispoofing/1",
+            "views": {
+                "train": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "group": "train"
+                    }
+                },
+                "dev_probes": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "group": "devel"
+                    }
+                },
+                "eval_probes": {
+                    "view": "SimpleAntispoofing",
+                    "parameters": {
+                        "protocol": "logical_access",
+                        "group": "test"
+                    }
+                }
+            }
+        }
+    ],
+    "schema_version": 2
+}
\ No newline at end of file
diff --git a/advanced/databases/avspoof/5.py b/advanced/databases/avspoof/5.py
new file mode 100644
index 0000000000000000000000000000000000000000..d39daa24ae31bcc21af39204d7083ab9ac38844b
--- /dev/null
+++ b/advanced/databases/avspoof/5.py
@@ -0,0 +1,539 @@
+###############################################################################
+#                                                                             #
+# Copyright (c) 2018 Idiap Research Institute, http://www.idiap.ch/           #
+# Contact: beat.support@idiap.ch                                              #
+#                                                                             #
+# This file is part of the beat.examples module of the BEAT platform.         #
+#                                                                             #
+# Commercial License Usage                                                    #
+# Licensees holding valid commercial BEAT licenses may use this file in       #
+# accordance with the terms contained in a written agreement between you      #
+# and Idiap. For further information contact tto@idiap.ch                     #
+#                                                                             #
+# Alternatively, this file may be used under the terms of the GNU Affero      #
+# Public License version 3 as published by the Free Software and appearing    #
+# in the file LICENSE.AGPL included in the packaging of this file.            #
+# The BEAT platform is distributed in the hope that it will be useful, but    #
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  #
+# or FITNESS FOR A PARTICULAR PURPOSE.                                        #
+#                                                                             #
+# You should have received a copy of the GNU Affero Public License along      #
+# with the BEAT platform. If not, see http://www.gnu.org/licenses/.           #
+#                                                                             #
+###############################################################################
+
+import numpy as np
+from collections import namedtuple
+
+from beat.backend.python.database import View
+
+import bob.io.base
+import bob.db.avspoof
+import scipy.io.wavfile
+
+from bob.db.avspoof.driver import Interface
+
+INFO = Interface()
+SQLITE_FILE = INFO.files()[0]
+
+
+#----------------------------------------------------------
+
+
+class RecognitionTraining(View):
+    """Outputs:
+        - speech: "{{ system_user.username }}/array_1d_floats/1"
+        - file_id: "{{ system_user.username }}/text/1"
+        - client_id: "{{ system_user.username }}/text/1"
+
+    One "file_id" is associated with a given "speech".
+    Several "speech" are associated with a given "client_id".
+
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |    speech   | |    speech   | |    speech   | |    speech   | |    speech   | |    speech   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    ----------------------------------------------- -----------------------------------------------
+    |                   client_id                 | |                   client_id                 |
+    ----------------------------------------------- -----------------------------------------------
+    """
+
+    def index(self, root_folder, parameters):
+        Entry = namedtuple('Entry', ['client_id', 'file_id', 'speech'])
+
+        # Open the database and load the objects to provide via the outputs
+        db = bob.db.avspoof.Database()
+
+        objs = sorted(db.objects(protocol=parameters['protocol'],
+                                 groups=parameters['group'],
+                                 cls=('enroll', 'probe')),
+                      key=lambda x: (x.client_id, x.id))
+
+        return [ Entry(x.client_id, x.id, x.make_path(root_folder, '.wav')) for x in objs ]
+
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == 'client_id':
+            return {
+                'text': str(obj.client_id)
+            }
+
+        elif output == 'file_id':
+            return {
+                'text': str(obj.file_id)
+            }
+
+        elif output == 'speech':
+            rate, audio = scipy.io.wavfile.read(obj.speech)
+
+            return {
+                'value': np.cast['float'](audio)
+            }
+
+
+#----------------------------------------------------------
+
+
+class RecognitionTemplates(View):
+    """Outputs:
+        - speech: "{{ system_user.username }}/array_1d_floats/1"
+        - file_id: "{{ system_user.username }}/text/1"
+        - template_id: "{{ system_user.username }}/text/1"
+        - client_id: "{{ system_user.username }}/text/1"
+
+    One "file_id" is associated with a given "speech".
+    Several "speech" are associated with a given "template_id".
+    Several "template_id" are associated with a given "client_id".
+
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |    speech   | |    speech   | |    speech   | |    speech   | |    speech   | |    speech   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    ----------------------------------------------- -----------------------------------------------
+    |                  template_id                | |                  template_id                |
+    ----------------------------------------------- -----------------------------------------------
+    -----------------------------------------------------------------------------------------------
+    |                                         client_id                                           |
+    -----------------------------------------------------------------------------------------------
+
+    Note: for this particular database, there is only one "template_id"
+    per "client_id".
+    """
+
+    def index(self, root_folder, parameters):
+        Entry = namedtuple('Entry', ['client_id', 'template_id', 'file_id', 'speech'])
+
+        # Open the database and load the objects to provide via the outputs
+        db = bob.db.avspoof.Database()
+
+        if parameters['protocol'] == "smalltest":
+            if parameters['group'] == "train":
+                template_ids = sorted([1, 3])
+            if parameters['group'] == "devel":
+                template_ids = sorted([15, 20])
+            if parameters['group'] == "test":
+                template_ids = sorted([18, 33])
+        else:
+            template_ids = [ client.id for client in db.clients(groups=parameters['group']) ]
+
+        entries = []
+
+        for template_id in template_ids:
+            objs = db.objects(groups=parameters['group'],
+                              protocol=parameters['protocol'],
+                              cls=parameters['purpose'],
+                              clients=(template_id,))
+
+            entries.extend([ Entry(x.client_id, template_id, x.id, x.make_path(root_folder, '.wav'))
+                             for x in objs ])
+
+        return sorted(entries, key=lambda x: (x.client_id, x.template_id, x.file_id))
+
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == 'client_id':
+            return {
+                'text': str(obj.client_id)
+            }
+
+        elif output == 'template_id':
+            return {
+                'text': str(obj.template_id)
+            }
+
+        elif output == 'file_id':
+            return {
+                'text': str(obj.file_id)
+            }
+
+        elif output == 'speech':
+            rate, audio = scipy.io.wavfile.read(obj.speech)
+
+            return {
+                'value': np.cast['float'](audio)
+            }
+
+
+#----------------------------------------------------------
+
+
+class Probes(View):
+    """Outputs:
+        - speech: "{{ system_user.username }}/array_1d_floats/1"
+        - file_id: "{{ system_user.username }}/text/1"
+        - probe_id: "{{ system_user.username }}/text/1",
+        - client_id: "{{ system_user.username }}/text/1"
+        - template_ids: "{{ system_user.username }}/array_1d_text/1",
+
+    One "file_id" is associated with a given "speech".
+    One "probe_id" is associated with a given "speech".
+    Several "speech" are associated with a given "client_id".
+    Several "client_id" are associated with a given "template_ids".
+
+    Each probe must be matched against a number of templates defined by a list of
+    client identifiers.
+
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |    speech   | |    speech   | |    speech   | |    speech   | |    speech   | |    speech   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |   probe_id  | |   probe_id  | |   probe_id  | |   probe_id  | |   probe_id  | |   probe_id  |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    ----------------------------------------------- -----------------------------------------------
+    |                   client_id                 | |                   client_id                 |
+    ----------------------------------------------- -----------------------------------------------
+    -----------------------------------------------------------------------------------------------
+    |                                        template_ids                                         |
+    -----------------------------------------------------------------------------------------------
+    """
+
+    def index(self, root_folder, parameters):
+        Entry = namedtuple('Entry', ['template_ids', 'client_id', 'probe_id', 'file_id', 'speech'])
+
+        # Open the database and load the objects to provide via the outputs
+        db = bob.db.avspoof.Database()
+
+        if parameters['protocol'] == "smalltest":
+            if parameters['group'] == "train":
+                template_ids = sorted([1, 3])
+            if parameters['group'] == "devel":
+                template_ids = sorted([15, 20])
+            if parameters['group'] == "test":
+                template_ids = sorted([18, 33])
+        else:
+            template_ids = sorted([ client.id for client in db.clients(groups=parameters['group']) ])
+
+        objs = sorted(db.objects(protocol=parameters['protocol'],
+                                 groups=parameters['group'],
+                                 cls='probe'),
+                      key=lambda x: (x.client_id, x.id))
+
+        return [ Entry(template_ids, x.client_id, x.id, x.id, x.make_path(root_folder, '.wav')) for x in objs ]
+
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == 'template_ids':
+            return {
+                'text': [ str(x) for x in obj.template_ids ]
+            }
+
+        elif output == 'client_id':
+            return {
+                'text': str(obj.client_id)
+            }
+
+        elif output == 'probe_id':
+            return {
+                'text': str(obj.probe_id)
+            }
+
+        elif output == 'file_id':
+            return {
+                'text': str(obj.file_id)
+            }
+
+        elif output == 'speech':
+            rate, audio = scipy.io.wavfile.read(obj.speech)
+
+            return {
+                'value': np.cast['float'](audio)
+            }
+
+
+#----------------------------------------------------------
+
+
+class Attacks(View):
+    """Outputs:
+        - speech: "{{ system_user.username }}/array_1d_floats/1"
+        - file_id: "{{ system_user.username }}/text/1"
+        - attack_id: "{{ system_user.username }}/text/1",
+        - client_id: "{{ system_user.username }}/text/1"
+        - template_ids: "{{ system_user.username }}/array_1d_text/1",
+
+    One "file_id" is associated with a given "speech".
+    One "probe_id" is associated with a given "speech".
+    Several "speech" are associated with a given "client_id".
+    Several "client_id" are associated with a given "template_ids".
+
+    Each probe must be matched against a number of templates defined by a list of
+    client identifiers.
+
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |    speech   | |    speech   | |    speech   | |    speech   | |    speech   | |    speech   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |  attack_id  | |  attack_id  | |  attack_id  | |  attack_id  | |  attack_id  | |  attack_id  |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    ----------------------------------------------- -----------------------------------------------
+    |                   client_id                 | |                   client_id                 |
+    ----------------------------------------------- -----------------------------------------------
+    -----------------------------------------------------------------------------------------------
+    |                                        template_ids                                         |
+    -----------------------------------------------------------------------------------------------
+    """
+
+    def index(self, root_folder, parameters):
+        Entry = namedtuple('Entry', ['template_ids', 'client_id', 'attack_id', 'file_id', 'speech'])
+
+        # Open the database and load the objects to provide via the outputs
+        db = bob.db.avspoof.Database()
+
+        objs = sorted(db.objects(protocol=parameters['protocol'],
+                                 groups=parameters['group'],
+                                 cls='attack'),
+                      key=lambda x: (x.client_id, x.id))
+
+        return [ Entry([ str(x.client_id) ], x.client_id, x.id, x.id,
+                       x.make_path(root_folder, '.wav')) for x in objs ]
+
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == 'template_ids':
+            return {
+                'text': obj.template_ids
+            }
+
+        elif output == 'client_id':
+            return {
+                'text': str(obj.client_id)
+            }
+
+        elif output == 'attack_id':
+            return {
+                'text': str(obj.attack_id)
+            }
+
+        elif output == 'file_id':
+            return {
+                'text': str(obj.file_id)
+            }
+
+        elif output == 'speech':
+            rate, audio = scipy.io.wavfile.read(obj.speech)
+
+            return {
+                'value': np.cast['float'](audio)
+            }
+
+
+#----------------------------------------------------------
+
+
+class SimpleAntispoofing(View):
+    """Outputs:
+        - speech: "{{ system_user.username }}/array_1d_floats/1"
+        - file_id: "{{ system_user.username }}/text/1"
+        - client_id: "{{ system_user.username }}/text/1"
+        - attack_type: "{{ system_user.username }}/text/1"
+        - class: "{{ system_user.username }}/text/1"
+
+
+    One "file_id" is associated with a given "speech".
+    Several "speech" are associated with a given "client_id".
+    Several "client_id" are associated with a given "template_id".
+
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |    speech   | |    speech   | |    speech   | |    speech   | |    speech   | |    speech   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   | |   file_id   |
+    --------------- --------------- --------------- --------------- --------------- ---------------
+    ------------------------------- ------------------------------- -------------------------------
+    |          attack_type        | |          attack_type        | |          attack_type        |
+    ------------------------------- ------------------------------- -------------------------------
+    --------------------------------------------------------------- -------------------------------
+    |                          client_id                          | |                   client_id
+    --------------------------------------------------------------- -------------------------------
+    -----------------------------------------------------------------------------------------------
+    |                                          class                                              |
+    -----------------------------------------------------------------------------------------------
+
+    Note: for this particular database, there is only one "client_id"
+    per "template_id".
+    """
+
+    def __init__(self):
+        super(SimpleAntispoofing, self)
+        self.output_member_map = {'class': 'cls'}
+
+
+    def index(self, root_folder, parameters):
+        Entry = namedtuple('Entry', ['cls', 'client_id', 'attack_type', 'file_id', 'speech'])
+
+        # Open the database and load the objects to provide via the outputs
+        db = bob.db.avspoof.Database()
+
+        objs_real = sorted(db.objects(protocol=parameters['protocol'],
+                                      groups=parameters['group'],
+                                      cls='real'),
+                           key=lambda x: (x.client_id, x.id))
+
+        objs_attack = sorted(db.objects(protocol=parameters['protocol'],
+                                        groups=parameters['group'],
+                                        cls='attack'),
+                             key=lambda x: (x.client_id, x.get_attack(), x.id))
+
+        return [ Entry('real', x.client_id, 'human', x.id, x.make_path(root_folder, '.wav')) for x in objs_real ] + \
+               [ Entry('attack', x.client_id, x.get_attack(), x.id, x.make_path(root_folder, '.wav')) for x in objs_attack ]
+
+
+    def get(self, output, index):
+        obj = self.objs[index]
+
+        if output == 'class':
+            return {
+                'text': obj.cls
+            }
+
+        elif output == 'client_id':
+            return {
+                'text': str(obj.client_id)
+            }
+
+        elif output == 'attack_type':
+            return {
+                'text': obj.attack_type
+            }
+
+        elif output == 'file_id':
+            return {
+                'text': str(obj.file_id)
+            }
+
+        elif output == 'speech':
+            rate, audio = scipy.io.wavfile.read(obj.speech)
+
+            return {
+                'value': np.cast['float'](audio)
+            }
+
+
+#----------------------------------------------------------
+
+
+def setup_tests():
+    # Install a mock read function for the audio files
+    def mock_read(filename):
+        return 44100, np.ndarray((128,))
+
+    scipy.io.wavfile.read = mock_read
+
+
+#----------------------------------------------------------
+
+
+# Test the behavior of the views (on fake data)
+if __name__ == '__main__':
+
+    setup_tests()
+
+    view = RecognitionTraining()
+    view.objs = view.index(
+        root_folder='',
+        parameters=dict(
+            protocol = 'smalltest',
+            group = 'train',
+        )
+    )
+    view.get('client_id', 0)
+    view.get('file_id', 0)
+    view.get('speech', 0)
+
+
+    view = RecognitionTemplates()
+    view.objs = view.index(
+        root_folder='',
+        parameters=dict(
+            protocol = 'smalltest',
+            group = 'train',
+            purpose = 'enroll',
+        )
+    )
+    view.get('client_id', 0)
+    view.get('template_id', 0)
+    view.get('file_id', 0)
+    view.get('speech', 0)
+
+
+    view = Probes()
+    view.objs = view.index(
+        root_folder='',
+        parameters=dict(
+            protocol = 'smalltest',
+            group = 'train',
+        )
+    )
+    view.get('template_ids', 0)
+    view.get('client_id', 0)
+    view.get('probe_id', 0)
+    view.get('file_id', 0)
+    view.get('speech', 0)
+
+
+    view = Attacks()
+    view.objs = view.index(
+        root_folder='',
+        parameters=dict(
+            protocol = 'smalltest',
+            group = 'train',
+        )
+    )
+    view.get('template_ids', 0)
+    view.get('client_id', 0)
+    view.get('attack_id', 0)
+    view.get('file_id', 0)
+    view.get('speech', 0)
+
+
+    view = SimpleAntispoofing()
+    view.objs = view.index(
+        root_folder='',
+        parameters=dict(
+            protocol = 'smalltest',
+            group = 'train',
+        )
+    )
+    view.get('class', 0)
+    view.get('client_id', 0)
+    view.get('attack_type', 0)
+    view.get('file_id', 0)
+    view.get('speech', 0)
diff --git a/advanced/databases/avspoof/5.rst b/advanced/databases/avspoof/5.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fb8a5f67432d9df6ef19ce758ad46480bc712557
--- /dev/null
+++ b/advanced/databases/avspoof/5.rst
@@ -0,0 +1 @@
+The AVspoof Database
\ No newline at end of file