diff --git a/Module.php b/Module.php
index be8d4a9ce948c07eec2a902abf61b66488b39fd5..eb11981b995d8db53b2ddf77bec33c3ecbc56e2c 100644
--- a/Module.php
+++ b/Module.php
@@ -17,7 +17,7 @@ use Zend\ServiceManager\ServiceLocatorInterface;
 use Zend\View\Renderer\PhpRenderer;
 
 /**
- * OaiPmhRepository plugin class.
+ * OaiPmhRepository module class.
  */
 class Module extends AbstractModule
 {
@@ -85,63 +85,7 @@ SQL;
 
     public function upgrade($oldVersion, $newVersion, ServiceLocatorInterface $serviceLocator)
     {
-        $config = require __DIR__ . '/config/module.config.php';
-        $defaultSettings = $config[strtolower(__NAMESPACE__)]['config'];
-        $settings = $serviceLocator->get('Omeka\Settings');
-
-        if (version_compare($oldVersion, '0.3', '<')) {
-            $connection = $serviceLocator->get('Omeka\Connection');
-            $sql = <<<'SQL'
-ALTER TABLE oai_pmh_repository_token CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE verb verb VARCHAR(190) NOT NULL, CHANGE metadata_prefix metadata_prefix VARCHAR(190) NOT NULL, CHANGE `cursor` `cursor` INT NOT NULL, CHANGE `set` `set` INT DEFAULT NULL;
-DROP INDEX expiration ON oai_pmh_repository_token;
-CREATE INDEX IDX_E9AC4F9524CD504D ON oai_pmh_repository_token (expiration);
-SQL;
-            $connection->exec($sql);
-
-            $settings->set('oaipmhrepository_name', $settings->get('oaipmh_repository_name',
-                $settings->get('installation_title')));
-            $settings->set('oaipmhrepository_namespace_id', $settings->get('oaipmhrepository_namespace_id',
-                $this->getServerNameWithoutProtocol($serviceLocator)));
-            $settings->set('oaipmhrepository_expose_media', $settings->get('oaipmh_repository_namespace_expose_files',
-                $defaultSettings['oaipmhrepository_expose_media']));
-            $settings->set('oaipmhrepository_list_limit',
-                $defaultSettings['oaipmhrepository_list_limit']);
-            $settings->set('oaipmhrepository_token_expiration_time',
-                $defaultSettings['oaipmhrepository_token_expiration_time']);
-
-            $settings->delete('oaipmh_repository_name');
-            $settings->delete('oaipmh_repository_namespace_id');
-            $settings->delete('oaipmh_repository_namespace_expose_files');
-            $settings->delete('oaipmh_repository_record_limit');
-            $settings->delete('oaipmh_repository_list_limit');
-            $settings->delete('oaipmh_repository_expiration_time');
-            $settings->delete('oaipmh_repository_token_expiration_time');
-        }
-
-        if (version_compare($oldVersion, '0.3.1', '<')) {
-            $settings->set('oaipmhrepository_global_repository',
-                $defaultSettings['oaipmhrepository_global_repository']);
-            $settings->set('oaipmhrepository_by_site_repository', 'item_set');
-            $settings->set('oaipmhrepository_oai_set_format',
-                $defaultSettings['oaipmhrepository_oai_set_format']);
-            $settings->set('oaipmhrepository_human_interface',
-                $defaultSettings['oaipmhrepository_human_interface']);
-            $settings->set('oaipmhrepository_hide_empty_sets',
-                $defaultSettings['oaipmhrepository_hide_empty_sets']);
-        }
-
-        if (version_compare($oldVersion, '3.2.2', '<')) {
-            $connection = $serviceLocator->get('Omeka\Connection');
-            $sql = <<<'SQL'
-ALTER TABLE oai_pmh_repository_token CHANGE `set` `set` VARCHAR(190) DEFAULT NULL;
-SQL;
-            $connection->exec($sql);
-
-            $settings->set('oaipmhrepository_append_identifier_global',
-                $defaultSettings['oaipmhrepository_append_identifier_global']);
-            $settings->set('oaipmhrepository_append_identifier_site',
-                $defaultSettings['oaipmhrepository_append_identifier_site']);
-        }
+        require_once 'data/scripts/upgrade.php';
     }
 
     protected function manageSettings($settings, $process, $key = 'config')
diff --git a/README.md b/README.md
index c47f850c05f19ede3eecf208438974c0454fb5c9..0947d3507e22597355430afa0a20ee0b16c95d9c 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,10 @@
 OAI-PMH Repository (module for Omeka S)
 =======================================
 
-[OAI-PMH Repository] is a module for [Omeka S] that implements an Open Archives Initiative Protocol for Metadata Harvesting ([OAI-PMH]) repository for Omeka S, allowing
-Omeka S items, item sets, and media to be harvested by OAI-PMH harvesters. The
-module implements version 2.0 of the protocol.
+[OAI-PMH Repository] is a module for [Omeka S] that implements an Open Archives
+Initiative Protocol for Metadata Harvesting ([OAI-PMH]) repository for Omeka S,
+allowing Omeka S items, item sets, and media to be harvested by OAI-PMH
+harvesters. The module implements version 2.0 of the protocol.
 
 This [Omeka S] module is a rewrite of the [OAI-PMH Repository plugin] for [Omeka]
 by [BibLibre] and intends to provide the same features as the original plugin.
@@ -51,6 +52,10 @@ breaks the assumption that each identifier is globally unique. Best practice is
 to set this value to the domain name the Omeka server is published at, possibly
 with a prefix like "oai."
 
+### Metadata formats
+
+Select the formats that will be available. Only `oai_dc` is required.
+
 ### Expose media
 
 Whether the repository should expose direct URLs to all the files associated
@@ -94,6 +99,11 @@ with "dc:description". For other merges, the event `oaipmhrepository.values` can
 be used. For a quick hack, the file `data/mapping/generic_dcterms.php` can be
 used.
 
+### Metadata for mets (item and media)
+
+Mets can use any format to describe the item and the files. The formats that are
+commonly used are `dc` and `mods` (currently unavailable).
+
 ### Human interface
 
 The OAI-PMH pages can be displayed and browsed with a themable responsive human
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000000000000000000000000000000000000..83603a7c7598c6d835f1ee47bc7f0ad6485074ea
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,55 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+        "This file is @generated automatically"
+    ],
+    "content-hash": "964a0fdaa3ef915638fa856319b2c385",
+    "packages": [],
+    "packages-dev": [
+        {
+            "name": "biblibre/omeka-s-test-helper",
+            "version": "dev-master",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/biblibre/omeka-s-test-helper.git",
+                "reference": "a02c8dc4259365f7de1d09626a97347ba19cbf6e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/biblibre/omeka-s-test-helper/zipball/a02c8dc4259365f7de1d09626a97347ba19cbf6e",
+                "reference": "a02c8dc4259365f7de1d09626a97347ba19cbf6e",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "OmekaTestHelper\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Test helpers for Omeka S",
+            "homepage": "https://github.com/biblibre/omeka-s-test-helper",
+            "keywords": [
+                "omeka",
+                "test"
+            ],
+            "time": "2016-09-22T16:40:26+00:00"
+        }
+    ],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": {
+        "biblibre/omeka-s-test-helper": 20
+    },
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": []
+}
diff --git a/config/module.ini b/config/module.ini
index 355004c94cfaa1b571a78b6175afd7c505695e01..7c5fdd9f044c2bff930eb73faf4d1092c5ab4424 100644
--- a/config/module.ini
+++ b/config/module.ini
@@ -1,12 +1,12 @@
 [info]
 name         = "OAI-PMH Repository"
 description  = "Exposes Omeka items as an OAI-PMH repository."
-tags         = "share, open data, library protocol"
+tags         = "share, open data, library protocol, dublin core, mets, mods, cdwalite"
 license      = "GPL-3.0"
 author       = "BibLibre (port from Omeka Classic plugin of John Flatness), improved by Daniel Berthereau"
-author_link  = "https://github.com/biblibre"
-module_link  = "https://github.com/biblibre/omeka-s-module-OaiPmhRepository"
-support_link = "https://github.com/biblibre/omeka-s-module-OaiPmhRepository/issues"
+author_link  = "https://github.com/Daniel-KM"
+module_link  = "https://github.com/Daniel-KM/omeka-s-module-OaiPmhRepository"
+support_link = "https://github.com/Daniel-KM/omeka-s-module-OaiPmhRepository/issues"
 configurable = true
-version      = "3.2.2"
+version      = "3.3.0"
 omeka_version_constraint = "^1.0.0"
diff --git a/data/scripts/upgrade.php b/data/scripts/upgrade.php
new file mode 100644
index 0000000000000000000000000000000000000000..5670770653bb867ec63500420b523a89407aeffa
--- /dev/null
+++ b/data/scripts/upgrade.php
@@ -0,0 +1,73 @@
+<?php
+namespace OaiPmhRepository;
+
+$services = $serviceLocator;
+$settings = $services->get('Omeka\Settings');
+$connection = $services->get('Omeka\Connection');
+$config = require dirname(dirname(__DIR__)) . '/config/module.config.php';
+$defaultSettings = $config[strtolower(__NAMESPACE__)]['config'];
+
+if (version_compare($oldVersion, '0.3', '<')) {
+    $connection = $serviceLocator->get('Omeka\Connection');
+    $sql = <<<'SQL'
+ALTER TABLE oai_pmh_repository_token CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE verb verb VARCHAR(190) NOT NULL, CHANGE metadata_prefix metadata_prefix VARCHAR(190) NOT NULL, CHANGE `cursor` `cursor` INT NOT NULL, CHANGE `set` `set` INT DEFAULT NULL;
+DROP INDEX expiration ON oai_pmh_repository_token;
+CREATE INDEX IDX_E9AC4F9524CD504D ON oai_pmh_repository_token (expiration);
+SQL;
+    $connection->exec($sql);
+
+    $settings->set('oaipmhrepository_name', $settings->get('oaipmh_repository_name',
+        $settings->get('installation_title')));
+    $settings->set('oaipmhrepository_namespace_id', $settings->get('oaipmhrepository_namespace_id',
+        $this->getServerNameWithoutProtocol($serviceLocator)));
+    $settings->set('oaipmhrepository_expose_media', $settings->get('oaipmh_repository_namespace_expose_files',
+        $defaultSettings['oaipmhrepository_expose_media']));
+    $settings->set('oaipmhrepository_list_limit',
+        $defaultSettings['oaipmhrepository_list_limit']);
+    $settings->set('oaipmhrepository_token_expiration_time',
+        $defaultSettings['oaipmhrepository_token_expiration_time']);
+
+    $settings->delete('oaipmh_repository_name');
+    $settings->delete('oaipmh_repository_namespace_id');
+    $settings->delete('oaipmh_repository_namespace_expose_files');
+    $settings->delete('oaipmh_repository_record_limit');
+    $settings->delete('oaipmh_repository_list_limit');
+    $settings->delete('oaipmh_repository_expiration_time');
+    $settings->delete('oaipmh_repository_token_expiration_time');
+}
+
+if (version_compare($oldVersion, '0.3.1', '<')) {
+    $settings->set('oaipmhrepository_global_repository',
+        $defaultSettings['oaipmhrepository_global_repository']);
+    $settings->set('oaipmhrepository_by_site_repository', 'item_set');
+    $settings->set('oaipmhrepository_oai_set_format',
+        $defaultSettings['oaipmhrepository_oai_set_format']);
+    $settings->set('oaipmhrepository_human_interface',
+        $defaultSettings['oaipmhrepository_human_interface']);
+    $settings->set('oaipmhrepository_hide_empty_sets',
+        $defaultSettings['oaipmhrepository_hide_empty_sets']);
+}
+
+if (version_compare($oldVersion, '3.2.2', '<')) {
+    $connection = $serviceLocator->get('Omeka\Connection');
+    $sql = <<<'SQL'
+ALTER TABLE oai_pmh_repository_token CHANGE `set` `set` VARCHAR(190) DEFAULT NULL;
+SQL;
+    $connection->exec($sql);
+
+    $settings->set('oaipmhrepository_append_identifier_global',
+        $defaultSettings['oaipmhrepository_append_identifier_global']);
+    $settings->set('oaipmhrepository_append_identifier_site',
+        $defaultSettings['oaipmhrepository_append_identifier_site']);
+}
+
+if (version_compare($oldVersion, '3.3.0', '<')) {
+    $settings->set('oaipmhrepository_metadata_formats',
+        $defaultSettings['oaipmhrepository_metadata_formats']);
+    $settings->set('oaipmhrepository_generic_dcterms',
+        $defaultSettings['oaipmhrepository_generic_dcterms']);
+    $settings->set('oaipmhrepository_mets_data_item',
+        $defaultSettings['oaipmhrepository_mets_data_item']);
+    $settings->set('oaipmhrepository_mets_data_media',
+        $defaultSettings['oaipmhrepository_mets_data_media']);
+}