diff --git a/src/UnicaenAuth/Authentication/Storage/Chain.php b/src/UnicaenAuth/Authentication/Storage/Chain.php
index da7f42af4ccc1931e3875821ecc7bb1da18c2939..21a8cfa3e54d94686496e1198e1dd819eefbdab7 100644
--- a/src/UnicaenAuth/Authentication/Storage/Chain.php
+++ b/src/UnicaenAuth/Authentication/Storage/Chain.php
@@ -3,8 +3,6 @@
 namespace UnicaenAuth\Authentication\Storage;
 
 use Zend\Authentication\Storage\StorageInterface;
-use Zend\ServiceManager\ServiceLocatorInterface;
-use Zend\ServiceManager\ServiceLocatorAwareInterface;
 use Zend\EventManager\EventManagerInterface;
 use Zend\EventManager\EventManagerAwareInterface;
 use Zend\EventManager\EventManager;
@@ -16,8 +14,6 @@ use Zend\EventManager\EventManager;
  * Exemples de sources disponibles :
  *  - Ldap (annuaire LDAP)
  *  - Db (table des utilisateurs en base de données)
- * 
- * 
  *
  * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
  * @see ChainEvent
@@ -25,18 +21,13 @@ use Zend\EventManager\EventManager;
  * @see Ldap
  * @see Db
  */
-class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventManagerAwareInterface
+class Chain implements StorageInterface, EventManagerAwareInterface
 {
     /**
      * @var StorageInterface
      */
     protected $storage;
     
-    /**
-     * @var ServiceLocatorInterface
-     */
-    protected $serviceLocator;
-    
     /**
      * @var EventManagerInterface 
      */
@@ -47,6 +38,11 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana
      */
     protected $event;
     
+    /**
+     * @var array
+     */
+    protected $resolvedIdentity;
+    
     /**
      * Returns true if and only if storage is empty
      *
@@ -68,12 +64,23 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana
      */
     public function read()
     {
+        if (null !== $this->resolvedIdentity) {
+            return $this->resolvedIdentity;
+        }
+        
         $e = $this->getEvent();
         $this->getEventManager()->trigger('read', $e);
         
         $identity = $e->getContents();
         
-        return $identity;
+        if ($identity) {
+            $this->resolvedIdentity = $identity;
+        }
+        else {
+            $this->resolvedIdentity = null;
+        }
+        
+        return $this->resolvedIdentity;
     }
 
     /**
@@ -131,28 +138,6 @@ class Chain implements StorageInterface, ServiceLocatorAwareInterface, EventMana
         return $this;
     }
     
-    /**
-     * Set service locator
-     *
-     * @param ServiceLocatorInterface $serviceLocator
-     * @return self
-     */
-    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
-    {
-        $this->serviceLocator = $serviceLocator;
-        return $this;
-    }
-
-    /**
-     * Get service locator
-     *
-     * @return ServiceLocatorInterface
-     */
-    public function getServiceLocator()
-    {
-        return $this->serviceLocator;
-    }
-    
     /**
      * Inject an EventManager instance
      *
diff --git a/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php b/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php
index b8124ee2b1a5e19ee312bc41cdefab30e964cc77..4a31033073aa6c0ca350b0e798fabff7814577a1 100644
--- a/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php
+++ b/src/UnicaenAuth/Authentication/Storage/ChainServiceFactory.php
@@ -25,7 +25,6 @@ class ChainServiceFactory implements FactoryInterface
         );
         
         $chain = new Chain();
-        $chain->setServiceLocator($serviceLocator);
         
         foreach ($storages as $priority => $name) {
             $storage = $serviceLocator->get($name);
diff --git a/src/UnicaenAuth/Authentication/Storage/Db.php b/src/UnicaenAuth/Authentication/Storage/Db.php
index 14c96da2aa38e9957924488e9504e8ad317b7a54..d677d2986c44449844a85f9275914b8478873804 100644
--- a/src/UnicaenAuth/Authentication/Storage/Db.php
+++ b/src/UnicaenAuth/Authentication/Storage/Db.php
@@ -7,7 +7,9 @@ use Zend\ServiceManager\ServiceManager;
 use Zend\ServiceManager\ServiceManagerAwareInterface;
 use Zend\ServiceManager\Exception\ServiceNotFoundException;
 use Zend\Authentication\Exception\InvalidArgumentException;
-use ZfcUser\Authentication\Storage\Db as DbStorage;
+use Zend\Authentication\Storage\Session;
+use Zend\Authentication\Storage\StorageInterface;
+use ZfcUser\Mapper\UserInterface as UserMapper;
 
 /**
  * Db authentication storage.
@@ -17,9 +19,14 @@ use ZfcUser\Authentication\Storage\Db as DbStorage;
 class Db implements ChainableStorage, ServiceManagerAwareInterface
 {
     /**
-     * @var DbStorage 
+     * @var StorageInterface
      */
-    protected $delegate;
+    protected $storage;
+
+    /**
+     * @var UserMapper
+     */
+    protected $mapper;
 
     /**
      * @var mixed
@@ -27,47 +34,60 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
     protected $resolvedIdentity;
 
     /**
-     * Writes $contents to storage
-     *
-     * @param  mixed $contents
-     * @throws \Zend\Authentication\Exception\InvalidArgumentException If writing $contents to storage is impossible
-     * @return void
+     * @var ServiceManager
      */
-    public function write(ChainEvent $e)
-    {
-        $contents = $e->getParam('contents');
-        
-        $this->resolvedIdentity = null;
-        $this->getDelegate()->write($contents);
-    }
+    protected $serviceManager;
     
     /**
      * Returns the contents of storage
      *
      * Behavior is undefined when storage is empty.
      *
+     * @params ChainEvent $e
      * @throws InvalidArgumentException If reading contents from storage is impossible
-     * @return \ZfcUser\Entity\UserInterface
+     * @return void
      */
     public function read(ChainEvent $e)
     {
-        $identity = $this->findIdentity();
+        if (!$this->resolvedIdentity) {
+            $identity = $this->findIdentity();
+            if ($identity) {
+                $this->resolvedIdentity = $identity;
+            } 
+            else {
+                $this->resolvedIdentity = null;
+            }
+        }
         
-        $e->addContents('db', $identity);
+        $e->addContents('db', $this->resolvedIdentity);
+    }
+
+    /**
+     * Writes $contents to storage
+     *
+     * @params ChainEvent $e
+     * @throws \Zend\Authentication\Exception\InvalidArgumentException If writing $contents to storage is impossible
+     * @return void
+     */
+    public function write(ChainEvent $e)
+    {
+        $contents = $e->getParam('contents');
         
-        return $identity;
+        $this->resolvedIdentity = null;
+        $this->getStorage()->write($contents);
     }
 
     /**
      * Clears contents from storage
      *
+     * @params ChainEvent $e
      * @throws \Zend\Authentication\Exception\InvalidArgumentException If clearing contents from storage is impossible
      * @return void
      */
     public function clear(ChainEvent $e)
     {
         $this->resolvedIdentity = null;
-        $this->getDelegate()->getStorage()->clear();
+        $this->getStorage()->clear();
     }
     
     /**
@@ -76,8 +96,16 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
      */
     protected function findIdentity()
     {
+        $id = $this->getStorage()->read();
+        
+        // si on obtient autre chose qu'un scalaire, l'utilisateur a déjà été 
+        // recherché/trouvé dans la base de données
+        if ($id && !is_scalar($id)) {
+            return $id;
+        }
+            
         /**
-         * 1ere tentative (mécanisme standard du module ZfcUser) :
+         * 1ere tentative :
          * 
          * Recherche dans la base de données de l'utilisateur dont l'id correspond à ce qui
          * est stoqué en session.
@@ -85,19 +113,16 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
          * NB: En cas de problème de connexion ou de service 'zfcuser_user_mapper' introuvable,
          * cela signifie sans doute que l'application n'utilise pas de table des utilisateurs.
          */
-        try {
-            $identity = $this->getDelegate()->read();
-        }
-        catch (PDOException $pdoe) {
-            $identity = null;
-        }
-        catch (ServiceNotFoundException $e) {
-            $identity = null;
-        }
-        // si on obtient autre chose qu'un scalaire, l'utilisateur a déjà été 
-        // recherché/trouvé dans la base de données
-        if ($identity && !is_scalar($identity)) {
-            return $identity;
+        if (is_int($id) || is_scalar($id)) {
+            try {
+                $identity = $this->getMapper()->findById($id);
+            }
+            catch (PDOException $pdoe) {
+                $identity = null;
+            }
+            catch (ServiceNotFoundException $e) {
+                $identity = null;
+            }
         }
         
         /**
@@ -109,10 +134,9 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
          * NB: En cas de problème de connexion ou de service 'zfcuser_user_mapper' introuvable,
          * cela signifie sans doute que l'application n'utilise pas de table des utilisateurs.
          */
-        $username = $this->getDelegate()->getStorage()->read();
-        if (is_string($username)) {
+        if (is_string($id)) {
             try {
-                $identity = $this->getDelegate()->getMapper()->findByUsername($username);
+                $identity = $this->getMapper()->findByUsername($id);
             }
             catch (PDOException $pdoe) {
                 $identity = null;
@@ -122,14 +146,58 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
             }
         }
         
-        if ($identity) {
-            $this->resolvedIdentity = $identity;
-        } 
-        else {
-            $this->resolvedIdentity = null;
+        return $identity;
+    }
+
+    /**
+     * getStorage
+     *
+     * @return StorageInterface
+     */
+    public function getStorage()
+    {
+        if (null === $this->storage) {
+            $this->setStorage(new Session());
         }
-        
-        return $this->resolvedIdentity;
+        return $this->storage;
+    }
+
+    /**
+     * setStorage
+     *
+     * @param StorageInterface $storage
+     * @access public
+     * @return Db
+     */
+    public function setStorage(StorageInterface $storage)
+    {
+        $this->storage = $storage;
+        return $this;
+    }
+
+    /**
+     * getMapper
+     *
+     * @return UserMapper
+     */
+    public function getMapper()
+    {
+        if (null === $this->mapper) {
+            $this->mapper = $this->getServiceManager()->get('zfcuser_user_mapper');
+        }
+        return $this->mapper;
+    }
+
+    /**
+     * setMapper
+     *
+     * @param UserMapper $mapper
+     * @return Db
+     */
+    public function setMapper(UserMapper $mapper = null)
+    {
+        $this->mapper = $mapper;
+        return $this;
     }
 
     /**
@@ -146,21 +214,11 @@ class Db implements ChainableStorage, ServiceManagerAwareInterface
      * Set service manager instance
      *
      * @param ServiceManager $locator
-     * @return void
+     * @return self
      */
     public function setServiceManager(ServiceManager $serviceManager)
     {
         $this->serviceManager = $serviceManager;
-    }
-    
-    /**
-     * @return DbStorage
-     */
-    protected function getDelegate()
-    {
-        if (null === $this->delegate) {
-            $this->delegate = $this->getServiceManager()->get('ZfcUser\Authentication\Storage\Db');
-        }
-        return $this->delegate;
+        return $this;
     }
 }
\ No newline at end of file
diff --git a/src/UnicaenAuth/Authentication/Storage/Ldap.php b/src/UnicaenAuth/Authentication/Storage/Ldap.php
index 7f7dc6ef6a521ecaeb0ef003a25ab5c45ac60a7d..c3140f7fa417d86f47b473296e2a5432bfd5295c 100644
--- a/src/UnicaenAuth/Authentication/Storage/Ldap.php
+++ b/src/UnicaenAuth/Authentication/Storage/Ldap.php
@@ -43,17 +43,6 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
      */
     protected $serviceManager;
 
-    /**
-     * Returns true if and only if storage is empty
-     *
-     * @throws InvalidArgumentException If it is impossible to determine whether storage is empty
-     * @return boolean
-     */
-    public function isEmpty()
-    {
-        return $this->getStorage()->isEmpty();
-    }
-
     /**
      * Returns the contents of storage
      *
@@ -84,7 +73,15 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
         $identity = $this->getStorage()->read();
 
         if (is_scalar($identity)) {
-            $identity = $this->getMapper()->findOneByUsername($identity);
+            try {
+                $identity = $this->getMapper()->findOneByUsername($identity);
+            }
+            catch (\Zend\Ldap\Exception\LdapException $exc) {
+                $identity = null;
+            }
+            catch (\UnicaenApp\Exception $exc) {
+                $identity = null;
+            }
         }
 
         if ($identity) {
@@ -168,7 +165,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
      * @param LdapPeopleMapper $mapper
      * @return Ldap
      */
-    public function setMapper(LdapPeopleMapper $mapper)
+    public function setMapper(LdapPeopleMapper $mapper = null)
     {
         $this->mapper = $mapper;
         return $this;
@@ -188,7 +185,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
      * Set service manager instance
      *
      * @param ServiceManager $locator
-     * @return void
+     * @return self
      */
     public function setServiceManager(ServiceManager $serviceManager)
     {
@@ -199,7 +196,7 @@ class Ldap implements ChainableStorage, ServiceManagerAwareInterface
     /**
      * @param ModuleOptions $options
      */
-    public function setOptions(ModuleOptions $options)
+    public function setOptions(ModuleOptions $options = null)
     {
         $this->options = $options;
         return $this;
diff --git a/src/UnicaenAuth/Authentication/Storage/LdapDb.php b/src/UnicaenAuth/Authentication/Storage/LdapDb.php
deleted file mode 100644
index 4afd4f70a0ed76a579359ba04240950781d40f58..0000000000000000000000000000000000000000
--- a/src/UnicaenAuth/Authentication/Storage/LdapDb.php
+++ /dev/null
@@ -1,200 +0,0 @@
-<?php
-namespace UnicaenAuth\Authentication\Storage;
-
-use UnicaenAuth\Entity\Ldap\PeopleAdapter;
-use UnicaenAuth\Options\ModuleOptions;
-use Zend\Authentication\Exception\InvalidArgumentException;
-use Zend\Authentication\Storage;
-use Zend\ServiceManager\ServiceManager;
-use Zend\ServiceManager\ServiceManagerAwareInterface;
-use ZfcUser\Entity\UserInterface;
-
-/**
- * Ldap/Db mixin authentification storage.
- *
- * @see Ldap
- * @see Db
- * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
- */
-class LdapDb implements Storage\StorageInterface, ServiceManagerAwareInterface
-{
-    /**
-     * @var ServiceManager
-     */
-    protected $serviceManager;
-    
-    /**
-     * @var Ldap
-     */
-    protected $ldapStorage;
-    
-    /**
-     * @var Db
-     */
-    protected $dbStorage;
-
-    /**
-     * @var ModuleOptions
-     */
-    protected $options;
-
-    /**
-     * Returns true if and only if storage is empty
-     *
-     * @throws InvalidArgumentException If it is impossible to determine whether storage is empty
-     * @return boolean
-     */
-    public function isEmpty()
-    {
-        if ($this->getLdapStorage()->isEmpty() && $this->getDbStorage()->isEmpty()) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns the contents of storage
-     *
-     * Behavior is undefined when storage is empty.
-     *
-     * @throws InvalidArgumentException If reading contents from storage is impossible
-     * @return UserInterface
-     */
-    public function read()
-    {
-        $identity = null;
-        $userId = null;
-        if (($dbIdentity = $this->getDbStorage()->read())) {
-            $userId = $dbIdentity->getId();
-            $identity = $dbIdentity;
-        }
-        
-        $userExistsInDb   = (bool) $dbIdentity;
-        $userExistsInLdap = $dbIdentity && $dbIdentity->getPassword() === 'ldap';
-        // NB: si le mot de passe est 'ldap', alors l'utilisateur a été créé à partir de l'annuaire LDAP
-
-        if (!$userExistsInDb || $userExistsInLdap) {
-            // on s'attend à ce que les données en session soient l'entité LDAP correspondant à l'utilisateur connecté
-            $ldapIdentity = $this->getLdapStorage()->read();
-            if ($ldapIdentity) {
-                $identity = new PeopleAdapter($ldapIdentity->getData(), $userId);
-            }
-        }
-        
-        return $identity;
-    }
-
-    /**
-     * Writes $contents to storage
-     *
-     * @param  mixed $contents
-     * @throws InvalidArgumentException If writing $contents to storage is impossible
-     * @return void
-     */
-    public function write($contents)
-    {
-        $this->getLdapStorage()->write($contents);
-        $this->getDbStorage()->write($contents);
-    }
-
-    /**
-     * Clears contents from storage
-     *
-     * @throws InvalidArgumentException If clearing contents from storage is impossible
-     * @return void
-     */
-    public function clear()
-    {
-        $this->getLdapStorage()->clear();
-        $this->getDbStorage()->clear();
-    }
-
-    /**
-     * Retrieve service manager instance
-     *
-     * @return ServiceManager
-     */
-    public function getServiceManager()
-    {
-        return $this->serviceManager;
-    }
-
-    /**
-     * Set service manager
-     *
-     * @param ServiceManager $serviceManager
-     * @return LdapDb
-     */
-    public function setServiceManager(ServiceManager $serviceManager)
-    {
-        $this->serviceManager = $serviceManager;
-        return $this;
-    }
-
-    /**
-     * get db Storage
-     *
-     * @return Db
-     */
-    public function getDbStorage()
-    {
-        return $this->dbStorage;
-    }
-
-    /**
-     * set db Storage
-     *
-     * @param Db $storage
-     * @access public
-     * @return LdapDb
-     */
-    public function setDbStorage(Db $storage)
-    {
-        $this->dbStorage = $storage;
-        return $this;
-    }
-
-    /**
-     * get ldap Storage
-     *
-     * @return Ldap
-     */
-    public function getLdapStorage()
-    {
-        return $this->ldapStorage;
-    }
-
-    /**
-     * set ldap Storage
-     *
-     * @param Ldap $storage
-     * @access public
-     * @return LdapDb
-     */
-    public function setLdapStorage(Ldap $storage)
-    {
-        $this->ldapStorage = $storage;
-        return $this;
-    }
-
-    /**
-     * @param ModuleOptions $options
-     * @return LdapDb
-     */
-    public function setOptions(ModuleOptions $options)
-    {
-        $this->options = $options;
-        return $this;
-    }
-
-    /**
-     * @return ModuleOptions
-     */
-    public function getOptions()
-    {
-        if (null === $this->options) {
-            $this->setOptions($this->getServiceManager()->get('unicaen-auth_module_options'));
-        }
-        return $this->options;
-    }
-}
\ No newline at end of file
diff --git a/src/UnicaenAuth/Entity/Ldap/People.php b/src/UnicaenAuth/Entity/Ldap/People.php
index 746e7602b4013f6e75ece801aa8a59d2899530eb..19ee96f76edc35c8aa8694f6c44e7a05bedb7ed2 100644
--- a/src/UnicaenAuth/Entity/Ldap/People.php
+++ b/src/UnicaenAuth/Entity/Ldap/People.php
@@ -2,7 +2,6 @@
 namespace UnicaenAuth\Entity\Ldap;
 
 use UnicaenApp\Entity\Ldap\People as BasePeople;
-use UnicaenAuth\Acl\NamedRole;
 use BjyAuthorize\Provider\Role\ProviderInterface;
 use ZfcUser\Entity\UserInterface;
 
@@ -16,31 +15,17 @@ use ZfcUser\Entity\UserInterface;
  */
 class People extends BasePeople implements UserInterface, ProviderInterface
 {
-    /**
-     * @var int
-     */
-//    protected $id;
-//
-//    /**
-//     * Constructeur.
-//     * 
-//     * @param array $data Valeurs des attributs brutes
-//     * @param int $userId Id éventuel de l'utilisateur dans la base de données de l'appli
-//     */
-//    public function __construct(array $data = array(), $userId = null)
-//    {
-//        parent::__construct($data);
-//        $this->setId($userId);
-//    }
-    
     /**
      * Constructeur.
      * 
-     * @param BasePeople $people 
+     * @param array|BasePeople $people 
      */
-    public function __construct(BasePeople $people)
+    public function __construct($data = null)
     {
-        parent::__construct($people->getData());
+        if ($data instanceof BasePeople) {
+            $data = $data->getData();
+        }
+        parent::__construct($data);
     }
 
     /**
@@ -64,7 +49,7 @@ class People extends BasePeople implements UserInterface, ProviderInterface
      */
     public function getId()
     {
-        return /*$this->id ?: */$this->uid;
+        return $this->uid;
     }
 
     /**
@@ -106,8 +91,6 @@ class People extends BasePeople implements UserInterface, ProviderInterface
      */
     public function setId($id)
     {
-//        $this->id = $id;
-//        return $this;
         throw new \BadMethodCallException("Forbidden!");
     }
 
diff --git a/src/UnicaenAuth/Provider/Identity/ChainServiceFactory.php b/src/UnicaenAuth/Provider/Identity/ChainServiceFactory.php
index f085277a7c65bd3a47eceaef5e3f5c7dc116c445..6f5ba726303037a622d3ee90eb9c6a5d733718d5 100644
--- a/src/UnicaenAuth/Provider/Identity/ChainServiceFactory.php
+++ b/src/UnicaenAuth/Provider/Identity/ChainServiceFactory.php
@@ -19,16 +19,6 @@ class ChainServiceFactory implements FactoryInterface
      */
     public function createService(ServiceLocatorInterface $serviceLocator)
     {
-//        $config = $serviceLocator->get('BjyAuthorize\Config');
-//        
-//        if (!isset($config['identity_provider']) ||
-//            'UnicaenAuth\Provider\Identity\Chain' !== $config['identity_provider']) {
-//            throw new InvalidArgumentException(
-//                'Config for "UnicaenAuth\Provider\Identity\Chain" not set'
-//            );
-//        }
-//        $providers = (array) $config['identity_provider']['UnicaenAuth\Provider\Identity\Chain'];
-        
         $providers = array(
             200 => 'UnicaenAuth\Provider\Identity\Db',
             100 => 'UnicaenAuth\Provider\Identity\Ldap',
diff --git a/src/UnicaenAuth/Provider/Identity/Db.php b/src/UnicaenAuth/Provider/Identity/Db.php
index 467b8cbccd46ec735ca62651344e2ff23baa8c40..65f1912a3bdf574535f085d46c0f34ec61fe145a 100644
--- a/src/UnicaenAuth/Provider/Identity/Db.php
+++ b/src/UnicaenAuth/Provider/Identity/Db.php
@@ -29,11 +29,10 @@ class Db extends AuthenticationIdentityProvider implements ChainableProvider
      */
     public function getIdentityRoles()
     {
-        if (! $identity = $this->authService->getIdentity()) {
+        if (!($identity = $this->authService->getIdentity())) {
             return array($this->defaultRole);
         }
         
-        $identity = $this->authService->getIdentity();
         if (is_array($identity) && isset($identity['db'])) {
             $identity = $identity['db'];
         }
diff --git a/src/UnicaenAuth/Provider/Identity/DbServiceFactory.php b/src/UnicaenAuth/Provider/Identity/DbServiceFactory.php
index dc3208745b8d283c1115da44883bf4682c9a4e58..afd4eb349c62402a65569d15e400a1cceabb20bb 100644
--- a/src/UnicaenAuth/Provider/Identity/DbServiceFactory.php
+++ b/src/UnicaenAuth/Provider/Identity/DbServiceFactory.php
@@ -4,7 +4,6 @@ namespace UnicaenAuth\Provider\Identity;
 
 use Zend\ServiceManager\FactoryInterface;
 use Zend\ServiceManager\ServiceLocatorInterface;
-use UnicaenAuth\Acl\NamedRole;
 
 /**
  * Db identity provider factory
diff --git a/src/UnicaenAuth/Provider/Identity/Ldap.php b/src/UnicaenAuth/Provider/Identity/Ldap.php
index c2e2f6f1e38bbafc678d2b87036ab62f8c18a0e4..39b1f2f4e5b98e238c648fadf3a8c64baa3d6bbd 100644
--- a/src/UnicaenAuth/Provider/Identity/Ldap.php
+++ b/src/UnicaenAuth/Provider/Identity/Ldap.php
@@ -37,7 +37,7 @@ class Ldap extends AuthenticationIdentityProvider implements ChainableProvider,
      */
     public function getIdentityRoles()
     {
-        if (!$identity = $this->authService->getIdentity()) {
+        if (!($identity = $this->authService->getIdentity())) {
             return array($this->defaultRole);
         }
         
diff --git a/src/UnicaenAuth/Provider/Role/Config.php b/src/UnicaenAuth/Provider/Role/Config.php
index d105477ca034da2f7edccef7506c3d338bc37d82..ab0a10ce60078f6b1c5c004689c5b78e5a84f0fe 100644
--- a/src/UnicaenAuth/Provider/Role/Config.php
+++ b/src/UnicaenAuth/Provider/Role/Config.php
@@ -43,17 +43,20 @@ class Config extends \BjyAuthorize\Provider\Role\Config
      */
     protected function loadRole($name, $options = array(), $parent = null)
     {
-        if (isset($options['name']) && !is_array($options['name'])) {
+        if (isset($options['name'])) {
             $roleName = $options['name'];
-        } elseif (ldap_explode_dn($name, 1) !== false && ($group = $this->mapper->findOneByDn($name))) {
+        } 
+        elseif (ldap_explode_dn($name, 1) !== false && ($group = $this->mapper->findOneByDn($name))) {
             $roleName = $group->getDescription();
-        } else {
+        } 
+        else {
             $roleName = null;
         }
         
         if (isset($options['children']) && count($options['children']) > 0) {
             $children = $options['children'];
-        } else {
+        } 
+        else {
             $children = array();
         }
 
@@ -64,7 +67,8 @@ class Config extends \BjyAuthorize\Provider\Role\Config
         foreach ($children as $key => $value) {
             if (is_numeric($key)) {
                 $roles = array_merge($roles, $this->loadRole($value, array(), $role));
-            } else {
+            } 
+            else {
                 $roles = array_merge($roles, $this->loadRole($key, $value, $role));
             }
         }
diff --git a/src/UnicaenAuth/Provider/Role/ConfigServiceFactory.php b/src/UnicaenAuth/Provider/Role/ConfigServiceFactory.php
index 8547159e9d3bb643207051e17108b099e72b338d..158b1e3a6776d0a6af4478e280f30e4eb6442145 100644
--- a/src/UnicaenAuth/Provider/Role/ConfigServiceFactory.php
+++ b/src/UnicaenAuth/Provider/Role/ConfigServiceFactory.php
@@ -2,6 +2,7 @@
 
 namespace UnicaenAuth\Provider\Role;
 
+use BjyAuthorize\Exception\InvalidArgumentException;
 use Zend\ServiceManager\FactoryInterface;
 use Zend\ServiceManager\ServiceLocatorInterface;
 
diff --git a/src/UnicaenAuth/Provider/Role/Db.php b/src/UnicaenAuth/Provider/Role/Db.php
index afab30a28f3afe61c367988fe17c3b14edce2e5d..4010be32948984b537434233d4171bd5049b86d2 100644
--- a/src/UnicaenAuth/Provider/Role/Db.php
+++ b/src/UnicaenAuth/Provider/Role/Db.php
@@ -19,39 +19,40 @@ class Db extends ObjectRepositoryProvider
     public function getRoles()
     {
         try {
-            $result = $this->objectRepository->findAll();
+//            $result = $this->objectRepository->findAll();
+            return parent::getRoles();
         }
         catch (PDOException $exc) {
             return array();
         }
         
-        $roles  = array();
-
-        // Pass One: Build each object
-        foreach ($result as $role) { /* @var $role \UnicaenAuth\Entity\Db\Role */
-            if (!$role instanceof RoleInterface) {
-                continue;
-            }
-            
-            $roleId = $role->getRoleId();
-            $parent = null;
-
-            if ($role instanceof HierarchicalRoleInterface && $parent = $role->getParent()) {
-                $parent = $parent->getRoleId();
-            }
-
-            $roles[$roleId] = new NamedRole($roleId, $parent, $role->getName());
-        }
-
-        // Pass Two: Re-inject parent objects to preserve hierarchy
-        /* @var $roleObj NamedRole */
-        foreach ($roles as $roleObj) {
-            $parentRoleObj = $roleObj->getParent();
-
-            if ($parentRoleObj && $parentRoleObj->getRoleId()) {
-                $roleObj->setParent($roles[$parentRoleObj->getRoleId()]);
-            }
-        }
+//        $roles  = array();
+//
+//        // Pass One: Build each object
+//        foreach ($result as $role) { /* @var $role \UnicaenAuth\Entity\Db\Role */
+//            if (!$role instanceof RoleInterface) {
+//                continue;
+//            }
+//            
+//            $roleId = $role->getRoleId();
+//            $parent = null;
+//
+//            if ($role instanceof HierarchicalRoleInterface && $parent = $role->getParent()) {
+//                $parent = $parent->getRoleId();
+//            }
+//
+//            $roles[$roleId] = new NamedRole($roleId, $parent, $role->getName());
+//        }
+//
+//        // Pass Two: Re-inject parent objects to preserve hierarchy
+//        /* @var $roleObj NamedRole */
+//        foreach ($roles as $roleObj) {
+//            $parentRoleObj = $roleObj->getParent();
+//
+//            if ($parentRoleObj && $parentRoleObj->getRoleId()) {
+//                $roleObj->setParent($roles[$parentRoleObj->getRoleId()]);
+//            }
+//        }
 
         return array_values($roles);
     }
diff --git a/tests/UnicaenAuthTest/Acl/NamedRoleTest.php b/tests/UnicaenAuthTest/Acl/NamedRoleTest.php
index 78229f2cee84351724da7bdc231efab07001af04..be8e2e973982634d2de138ed937787a11797c9f0 100644
--- a/tests/UnicaenAuthTest/Acl/NamedRoleTest.php
+++ b/tests/UnicaenAuthTest/Acl/NamedRoleTest.php
@@ -29,4 +29,11 @@ class NamedRoleTest extends PHPUnit_Framework_TestCase
         $role->setRoleName($name = "New role name");
         $this->assertEquals($name, $role->getRoleName());
     }
+    
+    public function testCanSetDescription()
+    {
+        $role = new NamedRole('role-id', null, null, "Role description");
+        $role->setRoleDescription($desc = "New role description");
+        $this->assertEquals($desc, $role->getRoleDescription());
+    }
 }
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Authentication/Adapter/CasTest.php b/tests/UnicaenAuthTest/Authentication/Adapter/CasTest.php
index 223cb8f4fc3d843b47b8119486a29c8eed96200b..88a18ca77df593dbb6b1078ea270e50024d9727d 100644
--- a/tests/UnicaenAuthTest/Authentication/Adapter/CasTest.php
+++ b/tests/UnicaenAuthTest/Authentication/Adapter/CasTest.php
@@ -11,7 +11,7 @@ use Zend\Authentication\Result;
 
 define ('__VENDOR_DIR__', __DIR__ . '/../../../../vendor');
 
-require_once __VENDOR_DIR__ . '/gorg/phpcas/CAS.php';
+require_once __VENDOR_DIR__ . '/intouch/phpcas/CAS.php';
         
 /**
  * Description of CasTest
@@ -134,7 +134,7 @@ class CasTest extends PHPUnit_Framework_TestCase
         $result = ob_get_clean();
         
         $expected = <<<EOS
-<html><head><title>CAS Authentication wanted!</title></head><body><h1>CAS Authentication wanted!</h1><p>You should already have been redirected to the CAS server. Click <a href="https://cas.unicaen.fr/login?service=http%3A%2F%2F%3A">here</a> to continue.</p><hr><address>phpCAS 1.3.1+ using server <a href="https://cas.unicaen.fr/">https://cas.unicaen.fr/</a> (CAS 2.0)</a></address></body></html>
+<html><head><title>CAS Authentication wanted!</title></head><body><h1>CAS Authentication wanted!</h1><p>You should already have been redirected to the CAS server. Click <a href="https://cas.unicaen.fr/login?service=http%3A%2F%2F%3A">here</a> to continue.</p><hr><address>phpCAS 1.3.2+ using server <a href="https://cas.unicaen.fr/">https://cas.unicaen.fr/</a> (CAS 2.0)</a></address></body></html>
 EOS;
         $this->assertEquals($expected, $result);
     }
diff --git a/tests/UnicaenAuthTest/Authentication/Storage/ChainEventTest.php b/tests/UnicaenAuthTest/Authentication/Storage/ChainEventTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..05f1f72c1816639489125f8a87f2c3f98403d0fa
--- /dev/null
+++ b/tests/UnicaenAuthTest/Authentication/Storage/ChainEventTest.php
@@ -0,0 +1,51 @@
+<?php
+namespace UnicaenAuthTest\Authentication\Storage;
+
+use PDOException;
+use PHPUnit_Framework_TestCase;
+use UnicaenAuth\Authentication\Storage\Db;
+use Zend\ServiceManager\Exception\ServiceNotFoundException;
+use ZfcUser\Entity\User;
+use UnicaenAuth\Authentication\Storage\ChainEvent;
+
+/**
+ * Description of ChainEventTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class ChainEventTest extends PHPUnit_Framework_TestCase
+{
+    protected $event;
+    
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->event = new ChainEvent();
+    }
+    
+    public function testContentsIsEmptyAtConstruction()
+    {
+        $this->assertEquals(array(), $this->event->getContents());
+    }
+    
+    public function testCanAddContents()
+    {
+        $this->event->addContents('key 1', 'content 1');
+        $this->event->addContents('key 2', 'content 2');
+        $expected = array(
+            'key 1' => 'content 1', 
+            'key 2' => 'content 2',
+        );
+        $this->assertEquals($expected, $this->event->getContents());
+    }
+    
+    public function testCanClearContents()
+    {
+        $this->event->addContents('key 1', 'content 1.1');
+        $this->event->clearContents();
+        $this->assertEquals(array(), $this->event->getContents());
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Authentication/Storage/ChainServiceFactoryTest.php b/tests/UnicaenAuthTest/Authentication/Storage/ChainServiceFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3738b6ea2757af14088d9e0d4d96c16b756efede
--- /dev/null
+++ b/tests/UnicaenAuthTest/Authentication/Storage/ChainServiceFactoryTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace UnicaenAuthTest\Authentication\Storage;
+
+use UnicaenAuth\Authentication\Storage\ChainServiceFactory;
+
+/**
+ * Description of ChainServiceFactory
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class ChainServiceFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    protected $serviceLocator;
+    protected $eventManager;
+    protected $factory;
+    protected $events = array('read', 'write', 'clear');
+            
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->factory        = new ChainServiceFactory();
+        $this->serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface', array());
+        $this->ldapStorage    = $this->getMock('UnicaenAuth\Authentication\Storage\Ldap', $this->events);
+        $this->dbStorage      = $this->getMock('UnicaenAuth\Authentication\Storage\Db', $this->events);
+    }
+    
+    public function testCanCreateService()
+    {
+        $this->serviceLocator->expects($this->exactly(2))
+                ->method('get')
+                ->will($this->onConsecutiveCalls($this->ldapStorage, $this->dbStorage));
+        
+        $service = $this->factory->createService($this->serviceLocator);
+        
+        $this->assertInstanceOf('UnicaenAuth\Authentication\Storage\Chain', $service);
+        
+        foreach ($this->events as $event) {
+            $listeners = $service->getEventManager()->getListeners($event); /* @var $listeners \Zend\Stdlib\SplPriorityQueue */
+            $this->assertCount(2, $listeners);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Authentication/Storage/ChainTest.php b/tests/UnicaenAuthTest/Authentication/Storage/ChainTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..854a6ccd72c9b53050b3e799da922ee6a35e8512
--- /dev/null
+++ b/tests/UnicaenAuthTest/Authentication/Storage/ChainTest.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace UnicaenAuthTest\Authentication\Storage;
+
+use UnicaenAuth\Authentication\Storage\Chain;
+
+/**
+ * Description of ChainTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class ChainTest extends \PHPUnit_Framework_TestCase
+{
+    protected $storage;
+    protected $innerStorage;
+    protected $eventManager;
+    protected $event;
+            
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->storage      = new Chain();
+        $this->innerStorage = $this->getMock('Zend\Authentication\Storage\Session', array('isEmpty', 'read', 'write', 'clear'));
+        $this->eventManager = $this->getMock('Zend\EventManager\EventManager', array('trigger'));
+        $this->event        = $this->getMock('UnicaenAuth\Authentication\Storage\ChainEvent', array('getContents'));
+        
+        $this->storage->setStorage($this->innerStorage)
+                ->setEventManager($this->eventManager)
+                ->setEvent($this->event);
+    }
+    
+    public function testCanRetrieveDefaultInnerStorage()
+    {
+        $storage = new Chain();
+        $this->assertInstanceOf('Zend\Authentication\Storage\StorageInterface', $storage->getStorage());
+    }
+    
+    public function testCanSetInnerStorage()
+    {
+        $storage = new Chain();
+        $storage->setStorage($inner = new \Zend\Authentication\Storage\Session());
+        $this->assertSame($inner, $storage->getStorage());
+    }
+    
+    public function testCanRetrieveDefaultEventManager()
+    {
+        $storage = new Chain();
+        $this->assertInstanceOf('Zend\EventManager\EventManagerInterface', $storage->getEventManager());
+    }
+    
+    public function testCanSetEventManager()
+    {
+        $storage = new Chain();
+        $storage->setEventManager($em = new \Zend\EventManager\EventManager());
+        $this->assertSame($em, $storage->getEventManager());
+    }
+    
+    public function testCanRetrieveDefaultEvent()
+    {
+        $storage = new Chain();
+        $this->assertInstanceOf('UnicaenAuth\Authentication\Storage\ChainEvent', $storage->getEvent());
+    }
+    
+    public function testCanSetEvent()
+    {
+        $storage = new Chain();
+        $storage->setEvent($e = new \UnicaenAuth\Authentication\Storage\ChainEvent());
+        $this->assertSame($e, $storage->getEvent());
+    }
+    
+    public function testCanGetEmptiness()
+    {
+        $this->eventManager->expects($this->never())
+                ->method('trigger');
+        $this->innerStorage->expects($this->once())
+                ->method('isEmpty')
+                ->will($this->returnValue('result'));
+        $this->assertEquals('result', $this->storage->isEmpty());
+    }
+    
+    public function testCanWrite()
+    {
+        $this->innerStorage->expects($this->once())
+                ->method('write')
+                ->with(12);
+        $this->eventManager->expects($this->once())
+                ->method('trigger')
+                ->with('write', $this->logicalAnd(
+                        $this->isInstanceOf('UnicaenAuth\Authentication\Storage\ChainEvent'), 
+                        $this->attributeEqualTo('params', array('contents' => 12))));
+        $this->storage->write(12);
+    }
+    
+    public function testReadingReturnsCollectedIdentities()
+    {
+        $this->eventManager->expects($this->once())
+                ->method('trigger')
+                ->with('read', $this->isInstanceOf('UnicaenAuth\Authentication\Storage\ChainEvent'));
+        $this->event->expects($this->once())
+                ->method('getContents')
+                ->will($this->returnValue($expected = array('db' => 'db identity', 'ldap' => 'ldap identity')));
+        $this->assertEquals($expected, $this->storage->read());
+    }
+    
+    /**
+     * @depends testReadingReturnsCollectedIdentities
+     */
+    public function testReadingDoesNotCollectIdentitiesTwice()
+    {
+        $this->eventManager->expects($this->once())
+                ->method('trigger')
+                ->with('read', $this->isInstanceOf('UnicaenAuth\Authentication\Storage\ChainEvent'));
+        $this->event->expects($this->once())
+                ->method('getContents')
+                ->will($this->returnValue($expected = array('db' => 'db identity', 'ldap' => 'ldap identity')));
+        $this->assertEquals($expected, $this->storage->read());
+        
+        $this->eventManager->expects($this->never())
+                ->method('trigger');
+        $this->event->expects($this->never())
+                ->method('getContents');
+        $this->assertEquals($expected, $this->storage->read());
+    }
+    
+    public function getEmptyEventContents()
+    {
+        return array(
+            array(array()),
+            array(null),
+        );
+    }
+    
+    /**
+     * @dataProvider getEmptyEventContents
+     */
+    public function testReadingReturnsNullIfNoIdentitiesCollected($contents)
+    {
+        $this->eventManager->expects($this->once())
+                ->method('trigger')
+                ->with('read', $this->isInstanceOf('UnicaenAuth\Authentication\Storage\ChainEvent'));
+        $this->event->expects($this->once())
+                ->method('getContents')
+                ->will($this->returnValue($contents));
+        $this->assertNull($this->storage->read());
+    }
+    
+    /**
+     * @depends testReadingReturnsCollectedIdentities
+     */
+    public function testCanClear()
+    {
+        $this->innerStorage->expects($this->once())
+                ->method('clear');
+        $this->eventManager->expects($this->once())
+                ->method('trigger')
+                ->with('clear', $this->isInstanceOf('UnicaenAuth\Authentication\Storage\ChainEvent'));
+        $this->storage->clear();
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Authentication/Storage/DbTest.php b/tests/UnicaenAuthTest/Authentication/Storage/DbTest.php
index 88351fe1e6b1ed81f5bd897df9d810de0ede60e6..24fa8e585d688e6b56531ac74d30cb74ad3a1631 100644
--- a/tests/UnicaenAuthTest/Authentication/Storage/DbTest.php
+++ b/tests/UnicaenAuthTest/Authentication/Storage/DbTest.php
@@ -5,7 +5,9 @@ use PDOException;
 use PHPUnit_Framework_TestCase;
 use UnicaenAuth\Authentication\Storage\Db;
 use Zend\ServiceManager\Exception\ServiceNotFoundException;
+use Zend\ServiceManager\ServiceManager;
 use ZfcUser\Entity\User;
+use UnicaenAuth\Authentication\Storage\ChainEvent;
 
 /**
  * Description of DbTest
@@ -15,7 +17,9 @@ use ZfcUser\Entity\User;
 class DbTest extends PHPUnit_Framework_TestCase
 {
     protected $storage;
+    protected $serviceManager;
     protected $mapper;
+    protected $event;
     
     /**
      * Sets up the fixture, for example, open a network connection.
@@ -23,10 +27,43 @@ class DbTest extends PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->mapper = $this->getMock('ZfcUser\Mapper\User', array('findById', 'findByUsername'));
+        $this->serviceManager = $this->getMock('Zend\ServiceManager\ServiceManager', array('get'));
+        $this->innerStorage   = $this->getMock('Zend\Authentication\Storage\Session', array('write', 'clear', 'read'));
+        $this->mapper         = $this->getMock('ZfcUser\Mapper\User', array('findById', 'findByUsername'));
+        $this->event          = new ChainEvent();
+        $this->storage        = new Db();
+
+        $this->storage->setMapper($this->mapper)
+                      ->setServiceManager($this->serviceManager)
+                      ->setStorage($this->innerStorage);
+    }
+    
+    public function testCanRetrieveDefaultInnerStorage()
+    {
+        $storage = new Db();
+        $this->assertInstanceOf('Zend\Authentication\Storage\StorageInterface', $storage->getStorage());
+    }
+    
+    public function testCanRetrieveMapperFromServiceManager()
+    {
+        $this->serviceManager->expects($this->once())
+                ->method('get')
+                ->with('zfcuser_user_mapper')
+                ->will($this->returnValue('mapper'));
+        
+        $this->storage->setMapper(null);
+        $this->assertEquals('mapper', $this->storage->getMapper());
+    }
+    
+    public function testCanWrite()
+    {
+        $this->event->setParam('contents', 12);
+        
+        $this->innerStorage->expects($this->once())
+                     ->method('write')
+                     ->with(12);
         
-        $this->storage = new Db();
-        $this->storage->setMapper($this->mapper);
+        $this->storage->write($this->event);
     }
     
     public function getException()
@@ -42,26 +79,30 @@ class DbTest extends PHPUnit_Framework_TestCase
      */
     public function testReadingReturnsNullIfFindByIdThrowsException($exception)
     {
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue(12));
         $this->mapper->expects($this->once())
                      ->method('findById')
                      ->will($this->throwException($exception));
         
-        $this->storage->getStorage()->write(12); // id utilisateur
-        $result = $this->storage->read();
-        $this->assertNull($result);
+        $this->storage->read($this->event);
+        $this->assertEquals(array('db' => null), $this->event->getContents());
     }
     
-    public function testReadingReturnsEntityIfUserFoundById()
+    public function testReadingReturnsEntityIfUserIsFoundById()
     {
         $entity = new User();
         
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue(12));
         $this->mapper->expects($this->once())
                      ->method('findById')
                      ->will($this->returnValue($entity));
         
-        $this->storage->getStorage()->write(12); // id utilisateur
-        $result = $this->storage->read();
-        $this->assertSame($entity, $result);
+        $this->storage->read($this->event);
+        $this->assertEquals(array('db' => $entity), $this->event->getContents());
     }
     
     /**
@@ -69,6 +110,9 @@ class DbTest extends PHPUnit_Framework_TestCase
      */
     public function testReadingReturnsNullIfFindByUsernameThrowsException($exception)
     {
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue('username'));
         $this->mapper->expects($this->once())
                      ->method('findById')
                      ->will($this->returnValue(null));
@@ -76,15 +120,17 @@ class DbTest extends PHPUnit_Framework_TestCase
                      ->method('findByUsername')
                      ->will($this->throwException($exception));
         
-        $this->storage->getStorage()->write('username'); // login utilisateur
-        $result = $this->storage->read();
-        $this->assertNull($result);
+        $this->storage->read($this->event);
+        $this->assertEquals(array('db' => null), $this->event->getContents());
     }
     
     public function testReadingReturnsEntityIfUserFoundByUsername()
     {
         $entity = new User();
         
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue('username'));
         $this->mapper->expects($this->once())
                      ->method('findById')
                      ->will($this->returnValue(null));
@@ -92,8 +138,31 @@ class DbTest extends PHPUnit_Framework_TestCase
                      ->method('findByUsername')
                      ->will($this->returnValue($entity));
         
-        $this->storage->getStorage()->write('bob'); // login utilisateur
-        $result = $this->storage->read();
-        $this->assertSame($entity, $result);
+        $this->storage->read($this->event);
+        $this->assertEquals(array('db' => $entity), $this->event->getContents());
+    }
+    
+    public function testReadingReturnsEntityInInnerStorage()
+    {
+        $entity = new User();
+        
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue($entity));
+        $this->mapper->expects($this->never())
+                     ->method('findById');
+        $this->mapper->expects($this->never())
+                     ->method('findByUsername');
+        
+        $this->storage->read($this->event);
+        $this->assertEquals(array('db' => $entity), $this->event->getContents());
+    }
+    
+    public function testCanClear()
+    {
+        $this->innerStorage->expects($this->once())
+                     ->method('clear');
+        
+        $this->storage->clear($this->event);
     }
 }
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Authentication/Storage/LdapDbTest.php b/tests/UnicaenAuthTest/Authentication/Storage/LdapDbTest.php
deleted file mode 100644
index 84bf01db5be654051043e2dd25e7d6626423501e..0000000000000000000000000000000000000000
--- a/tests/UnicaenAuthTest/Authentication/Storage/LdapDbTest.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-namespace UnicaenAuthTest\Authentication\Storage;
-
-use PHPUnit_Framework_TestCase;
-use UnicaenApp\Entity\Ldap\People;
-use UnicaenAppTest\Entity\Ldap\TestAsset\People as PeopleTestAsset;
-use UnicaenAuth\Authentication\Storage\Db;
-use UnicaenAuth\Authentication\Storage\Ldap;
-use UnicaenAuth\Authentication\Storage\LdapDb;
-use Zend\ServiceManager\ServiceManager;
-use ZfcUser\Entity\User;
-
-/**
- * Description of LdapDbTest
- *
- * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
- */
-class LdapDbTest extends PHPUnit_Framework_TestCase
-{
-    protected $storage;
-    protected $serviceManager;
-    protected $options;
-    protected $dbStorage;
-    protected $ldapStorage;
-    
-    /**
-     * Sets up the fixture, for example, open a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        $this->options = $options = new \UnicaenAuth\Options\ModuleOptions();
-        
-        $this->serviceManager = new ServiceManager();
-        $this->serviceManager->setFactory('unicaen-auth_module_options', function() use ($options) {
-            return $options;
-        });
-        
-        $this->dbStorage   = $this->getMock('UnicaenAuth\Authentication\Storage\Db', array('read'));
-        $this->ldapStorage = $this->getMock('UnicaenAuth\Authentication\Storage\Ldap', array('read'));
-        
-        $this->storage = new LdapDb();
-        $this->storage->setDbStorage($this->dbStorage)
-                      ->setLdapStorage($this->ldapStorage)
-                      ->setServiceManager($this->serviceManager);
-    }
-    
-    public function testServiceManagerIsNullByDefault()
-    {
-        $storage = new LdapDb();
-        $this->assertNull($storage->getServiceManager());
-    }
-    
-    public function testCanRetrieveDefaultOptionsFromServiceManager()
-    {
-        $this->serviceManager = $this->getMock('Zend\ServiceManager\ServiceManager', array('get'));
-        $this->serviceManager->expects($this->once())
-                             ->method('get')
-                             ->will($this->returnValue(new \UnicaenAuth\Options\ModuleOptions()));
-        $this->storage->setServiceManager($this->serviceManager);
-        $this->storage->getOptions();
-    }
-    
-    public function testInnerStoragesAreNullByDefault()
-    {
-        $storage = new LdapDb();
-        $this->assertNull($storage->getDbStorage());
-        $this->assertNull($storage->getLdapStorage());
-    }
-    
-    public function testStorageIsEmptyOnlyIfBothInnerStoragesAreEmpty()
-    {
-        $this->storage->getDbStorage()->write('content');
-        $this->storage->getLdapStorage()->write('content');
-        $this->assertFalse($this->storage->isEmpty());
-        
-        $this->storage->clear();
-        $this->storage->getLdapStorage()->write('content');
-        $this->assertFalse($this->storage->isEmpty());
-        
-        $this->storage->clear();
-        $this->storage->getDbStorage()->write('content');
-        $this->assertFalse($this->storage->isEmpty());
-        
-        $this->storage->clear();
-        $this->assertTrue($this->storage->isEmpty());
-    }
-    
-    public function testCanWriteToInnerStorages()
-    {
-        $entity = new User();
-        
-        $this->storage->setDbStorage(new Db());
-        $this->storage->setLdapStorage(new Ldap());
-        
-        $this->storage->write($entity);
-        $this->assertFalse($this->storage->isEmpty());
-        $this->assertFalse($this->storage->getDbStorage()->isEmpty());
-        $this->assertFalse($this->storage->getLdapStorage()->isEmpty());
-        $this->assertEquals($entity, $this->storage->getDbStorage()->read());
-        $this->assertEquals($entity, $this->storage->getLdapStorage()->read());
-        
-        $this->storage->clear();
-        $this->assertTrue($this->storage->isEmpty());
-        $this->assertTrue($this->storage->getDbStorage()->isEmpty());
-        $this->assertTrue($this->storage->getLdapStorage()->isEmpty());
-    }
-    
-    public function testReadingReturnsStoredDbUser()
-    {
-        $entity = new User();
-        
-        $this->dbStorage->expects($this->once())
-                        ->method('read')
-                        ->will($this->returnValue($entity));
-        
-        $result = $this->storage->read();
-        $this->assertSame($entity, $result);
-    }
-    
-    public function testReadingReturnsLdapUserAdapterIfNoDbUserFound()
-    {
-        $entity = new People(PeopleTestAsset::$data1);
-        
-        $this->dbStorage->expects($this->once())
-                        ->method('read')
-                        ->will($this->returnValue(null));
-        $this->ldapStorage->expects($this->once())
-                        ->method('read')
-                        ->will($this->returnValue($entity));
-        
-        $result = $this->storage->read();
-        $this->assertInstanceOf('UnicaenAuth\Entity\Ldap\PeopleAdapter', $result);
-        $this->assertInstanceOf('UnicaenApp\Entity\Ldap\People', $result);
-        $this->assertEquals($result->getId(), $entity->getUid()); 
-    }
-    
-    public function testReadingReturnsNullIfNoUserFoundInDbOrLdap()
-    {
-        $this->dbStorage->expects($this->once())
-                        ->method('read')
-                        ->will($this->returnValue(null));
-        $this->ldapStorage->expects($this->once())
-                          ->method('read')
-                          ->will($this->returnValue(null));
-                
-        $result = $this->storage->read();
-        $this->assertNull($result);
-    }
-    
-    public function testReadingReturnsLdapUserAdapterIfDUserFoundInDbAndLdap()
-    {
-        $dbEntity   = new User();
-        $dbEntity->setId(12)
-                 ->setPassword('ldap'); // requis
-        
-        $ldapEntity = new People(PeopleTestAsset::$data1);
-        
-        $this->dbStorage->expects($this->once())
-                        ->method('read')
-                        ->will($this->returnValue($dbEntity));
-        $this->ldapStorage->expects($this->once())
-                        ->method('read')
-                        ->will($this->returnValue($ldapEntity));
-        
-        $result = $this->storage->read();
-        $this->assertInstanceOf('UnicaenAuth\Entity\Ldap\PeopleAdapter', $result);
-        $this->assertInstanceOf('UnicaenApp\Entity\Ldap\People', $result);
-        $this->assertEquals($result->getId(), $dbEntity->getId());
-    }
-}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Authentication/Storage/LdapTest.php b/tests/UnicaenAuthTest/Authentication/Storage/LdapTest.php
index 81499d50ae3c6b68d8b7da0c6e47d79f0f239260..fba8dcf5c1a422d036505617e7f157a2f92ae9f4 100644
--- a/tests/UnicaenAuthTest/Authentication/Storage/LdapTest.php
+++ b/tests/UnicaenAuthTest/Authentication/Storage/LdapTest.php
@@ -3,9 +3,10 @@ namespace UnicaenAuthTest\Authentication\Storage;
 
 use PHPUnit_Framework_TestCase;
 use UnicaenApp\Entity\Ldap\People;
+use UnicaenAuth\Entity\Ldap\People as AuthPeople;
 use UnicaenAppTest\Entity\Ldap\TestAsset\People as PeopleTestAsset;
 use UnicaenAuth\Authentication\Storage\Ldap;
-use Zend\ServiceManager\ServiceManager;
+use UnicaenAuth\Authentication\Storage\ChainEvent;
 
 /**
  * Description of LdapTest
@@ -18,6 +19,8 @@ class LdapTest extends PHPUnit_Framework_TestCase
     protected $mapper;
     protected $serviceManager;
     protected $options;
+    protected $event;
+    protected $innerStorage;
     
     /**
      * Sets up the fixture, for example, open a network connection.
@@ -25,106 +28,160 @@ class LdapTest extends PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->options = $options = new \UnicaenAuth\Options\ModuleOptions();
-        
-        $this->mapper = $mapper = $this->getMock('UnicaenApp\Mapper\Ldap\People', array('findOneByUsername'));
-        
-        $this->serviceManager = new ServiceManager();
-        $this->serviceManager->setFactory('ldap_people_mapper', function() use ($mapper) {
-            return $mapper;
-        });
-        $this->serviceManager->setFactory('unicaen-auth_module_options', function() use ($options) {
-            return $options;
-        });
-        
-        $this->storage = new Ldap();
+        $this->options        = new \UnicaenAuth\Options\ModuleOptions();
+        $this->serviceManager = $this->getMock('Zend\ServiceManager\ServiceManager', array('get'));
+        $this->innerStorage   = $this->getMock('Zend\Authentication\Storage\Session', array('write', 'clear', 'read'));
+        $this->mapper         = $this->getMock('UnicaenApp\Mapper\Ldap\People', array('findOneByUsername'));
+        $this->event          = new ChainEvent();
+        $this->storage        = new Ldap();
+
         $this->storage->setMapper($this->mapper)
-                      ->setServiceManager($this->serviceManager);
+                      ->setServiceManager($this->serviceManager)
+                      ->setStorage($this->innerStorage);
     }
     
     public function testCanRetrieveDefaultInnerStorage()
     {
-        $this->assertInstanceOf('Zend\Authentication\Storage\StorageInterface', $this->storage->getStorage());
+        $storage = new Ldap();
+        $this->assertInstanceOf('Zend\Authentication\Storage\StorageInterface', $storage->getStorage());
     }
     
-    public function testCanRetrieveDefaultMapperFromServiceManager()
+    public function testCanRetrieveMapperFromLdapService()
     {
-        $this->serviceManager = $this->getMock('Zend\ServiceManager\ServiceManager', array('get'));
         $this->serviceManager->expects($this->once())
                              ->method('get')
-                             ->with('ldap_people_mapper');
-        $this->storage = new Ldap();
-        $this->storage->setServiceManager($this->serviceManager);
-        $this->storage->getMapper();
+                             ->with('ldap_people_mapper')
+                             ->will($this->returnValue('result'));
+        
+        $this->storage->setMapper(null);
+        $this->assertEquals('result', $this->storage->getMapper());
     }
     
-    public function testCanWriteToInnerStorage()
+    public function testCanRetrieveOptionsFromServiceManager()
     {
-        $this->storage->write($content = 'content');
-        $this->assertFalse($this->storage->isEmpty());
-        $this->assertFalse($this->storage->getStorage()->isEmpty());
-        $this->assertEquals($content, $this->storage->getStorage()->read());
-        
-        $this->storage->clear();
-        $this->assertTrue($this->storage->isEmpty());
-        $this->assertTrue($this->storage->getStorage()->isEmpty());
+        $this->serviceManager->expects($this->once())
+                             ->method('get')
+                             ->with('unicaen-auth_module_options')
+                             ->will($this->returnValue($options = new \UnicaenAuth\Options\ModuleOptions()));
+        
+        $this->assertSame($options, $this->storage->getOptions());
     }
     
-    public function testCanRetrieveMapperFromLdapService()
+    public function testCanWrite()
     {
-        $this->assertSame($this->mapper, $this->storage->getMapper());
+        $this->event->setParam('contents', 12);
+        
+        $this->innerStorage->expects($this->once())
+                     ->method('write')
+                     ->with(12);
+        
+        $this->storage->write($this->event);
     }
     
-    public function testCanRetrieveOptionsFromServiceManager()
+    public function testCanClear()
     {
-        $this->assertSame($this->options, $this->storage->getOptions());
+        $this->innerStorage->expects($this->once())
+                           ->method('clear');
+        
+        $this->storage->clear($this->event);
     }
     
     public function testReadingReturnsNullIfInnerStorageIsEmpty()
     {
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue(null));
         $this->mapper->expects($this->never())
                      ->method('findOneByUsername');
         
-        $this->storage->clear();
-        $result = $this->storage->read();
-        $this->assertNull($result);
+        $this->storage->read($this->event);
+        $this->assertEquals(array('ldap' => null), $this->event->getContents());
     }
     
     public function testReadingReturnsNullIfNoUserFound()
     {
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue(12));
         $this->mapper->expects($this->once())
                      ->method('findOneByUsername')
                      ->will($this->returnValue(null));
         
-        $this->storage->write('username');
-        $result = $this->storage->read();
-        $this->assertNull($result);
+        $this->storage->read($this->event);
+        $this->assertEquals(array('ldap' => null), $this->event->getContents());
+    }
+    
+    public function getException()
+    {
+        return array(
+            array(new \Zend\Ldap\Exception\LdapException()),
+            array(new \UnicaenApp\Exception()),
+        );
+    }
+    
+    /**
+     * @dataProvider getException
+     */
+    public function testReadingReturnsNullIfFindByUsernameThrowsException($exception)
+    {
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue(12));
+        $this->mapper->expects($this->once())
+                     ->method('findOneByUsername')
+                     ->will($this->throwException($exception));
+        
+        $this->storage->read($this->event);
+        $this->assertEquals(array('ldap' => null), $this->event->getContents());
     }
     
-    public function testReadingReturnsFoundUser()
+    public function testReadingReturnsEntityIfUserFoundByUsername()
     {
         $entity = new People(PeopleTestAsset::$data1);
         
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue('username'));
         $this->mapper->expects($this->once())
                      ->method('findOneByUsername')
                      ->will($this->returnValue($entity));
         
-        $this->storage->write($login = 'username');
-        $result = $this->storage->read();
-        $this->assertSame($entity, $result);
+        $this->storage->read($this->event);
+        $this->assertEquals(array('ldap' => new AuthPeople($entity)), $this->event->getContents());
     }
     
-    public function testReadingDoesNotFetchUserTwice()
+    public function testReadingReturnsEntityInInnerStorageWithoutFetching()
     {
-        $this->mapper->expects($this->once())
-                     ->method('findOneByUsername')
-                     ->will($this->returnValue(new People(PeopleTestAsset::$data1)));
-        $this->storage->write('username');
-        $firestResult = $this->storage->read();
+        $entity = new People(PeopleTestAsset::$data1);
         
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue($entity));
         $this->mapper->expects($this->never())
                      ->method('findOneByUsername');
-        $nextResult = $this->storage->read();
-        $this->assertSame($firestResult, $nextResult);
+        
+        $this->storage->read($this->event);
+        $this->assertEquals(array('ldap' => new AuthPeople($entity)), $this->event->getContents());
+    }
+    
+    public function testReadingReturnsResolvedEntityWithoutReadingInnerStorage()
+    {
+        $entity = new People(PeopleTestAsset::$data1);
+        
+        $this->innerStorage->expects($this->once())
+                     ->method('read')
+                     ->will($this->returnValue(12));
+        $this->mapper->expects($this->once())
+                     ->method('findOneByUsername')
+                     ->will($this->returnValue($entity));
+        
+        $firstResult = $this->storage->read($this->event);
+        
+        $this->innerStorage->expects($this->never())
+                     ->method('read');
+        
+        $nextResult = $this->storage->read($this->event);
+        
+        $this->assertSame($firstResult, $nextResult);
     }
 }
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Entity/Db/RoleTest.php b/tests/UnicaenAuthTest/Entity/Db/RoleTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6348c39b9a9275f742550e7ea72b093e4387e706
--- /dev/null
+++ b/tests/UnicaenAuthTest/Entity/Db/RoleTest.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace UnicaenAuthTest\Entity\Db;
+
+use UnicaenAuth\Entity\Db\Role;
+use PHPUnit_Framework_TestCase;
+
+/**
+ * Description of UserTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class RoleTest extends PHPUnit_Framework_TestCase
+{
+    protected $role;
+    
+    protected function setUp()
+    {
+        $this->role = new Role();
+    }
+    
+    public function testImplementsInterfaces()
+    {
+        $this->assertInstanceOf('BjyAuthorize\Acl\HierarchicalRoleInterface', $this->role);
+    }
+    
+    public function testConstructorInitializeParent()
+    {
+        $this->assertNull($this->role->getParent());
+    }
+    
+    public function testCanSetId()
+    {
+        $this->role->setId(12);
+        $this->assertEquals(12, $this->role->getId());
+    }
+    
+    public function testCanSetRoleId()
+    {
+        $this->role->setRoleId('content');
+        $this->assertEquals('content', $this->role->getRoleId());
+    }
+    
+    public function testCanSetName()
+    {
+        $this->role->setName('content');
+        $this->assertEquals('content', $this->role->getName());
+    }
+    
+    public function testCanSetIsDefault()
+    {
+        $this->role->setIsDefault(true);
+        $this->assertEquals(true, $this->role->getIsDefault());
+    }
+    
+    public function testCanSetParent()
+    {
+        $this->role->setParent($parent = new \UnicaenAuth\Entity\Db\Role());
+        $this->assertEquals($parent, $this->role->getParent());
+    }
+    
+    public function testCanGetObjectToString()
+    {
+        $this->role->setRoleId('content');
+        $this->assertEquals('content', (string) $this->role);
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Entity/Db/UserTest.php b/tests/UnicaenAuthTest/Entity/Db/UserTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca71cd054ed739ff58b04d18076ea74ea4f2f767
--- /dev/null
+++ b/tests/UnicaenAuthTest/Entity/Db/UserTest.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace UnicaenAuthTest\Entity\Db;
+
+use UnicaenAuth\Entity\Db\User;
+use PHPUnit_Framework_TestCase;
+
+/**
+ * Description of UserTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class UserTest extends PHPUnit_Framework_TestCase
+{
+    protected $user;
+    
+    protected function setUp()
+    {
+        $this->user = new User();
+    }
+    
+    public function testImplementsInterfaces()
+    {
+        $this->assertInstanceOf('ZfcUser\Entity\UserInterface', $this->user);
+        $this->assertInstanceOf('BjyAuthorize\Provider\Role\ProviderInterface', $this->user);
+    }
+    
+    public function testConstructorInitializeRoles()
+    {
+        $this->assertEquals(array(), $this->user->getRoles());
+    }
+    
+    public function testCanSetId()
+    {
+        $this->user->setId(12);
+        $this->assertEquals(12, $this->user->getId());
+    }
+    
+    public function testCanSetUsername()
+    {
+        $this->user->setUsername('content');
+        $this->assertEquals('content', $this->user->getUsername());
+    }
+    
+    public function testCanSetEmail()
+    {
+        $this->user->setEmail('content');
+        $this->assertEquals('content', $this->user->getEmail());
+    }
+    
+    public function testCanSetDisplayName()
+    {
+        $this->user->setDisplayName('content');
+        $this->assertEquals('content', $this->user->getDisplayName());
+    }
+    
+    public function testCanSetPassword()
+    {
+        $this->user->setPassword('content');
+        $this->assertEquals('content', $this->user->getPassword());
+    }
+    
+    public function testCanSetState()
+    {
+        $this->user->setState(1);
+        $this->assertEquals(1, $this->user->getState());
+    }
+    
+    public function testCanAddRole()
+    {
+        $roles = new \Doctrine\Common\Collections\ArrayCollection(array(
+                new \UnicaenAuth\Entity\Db\Role(),
+                new \UnicaenAuth\Entity\Db\Role(),
+        ));
+        $this->user->addRole($roles[0]);
+        $this->user->addRole($roles[1]);
+        $this->assertEquals($roles->getValues(), $this->user->getRoles());
+    }
+    
+    public function testCanGetObjectToString()
+    {
+        $this->user->setDisplayName('content');
+        $this->assertEquals('content', (string) $this->user);
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Entity/Ldap/PeopleAdapterTest.php b/tests/UnicaenAuthTest/Entity/Ldap/PeopleTest.php
similarity index 75%
rename from tests/UnicaenAuthTest/Entity/Ldap/PeopleAdapterTest.php
rename to tests/UnicaenAuthTest/Entity/Ldap/PeopleTest.php
index b9c4e2b74e1af002fdadeb48bc57f9bfa3830c51..785038a3e5b00d767bab832584f857176a1699fd 100644
--- a/tests/UnicaenAuthTest/Entity/Ldap/PeopleAdapterTest.php
+++ b/tests/UnicaenAuthTest/Entity/Ldap/PeopleTest.php
@@ -1,15 +1,16 @@
 <?php
 namespace UnicaenAuthTest\Entity\Ldap;
 
-use UnicaenAuth\Entity\Ldap\PeopleAdapter;
+use UnicaenApp\Entity\Ldap\People as BasePeople;
+use UnicaenAuth\Entity\Ldap\People;
 use UnicaenAppTest\Entity\Ldap\TestAsset\People as PeopleTestAsset;
 
 /**
- * Description of PeopleAdapterTest
+ * Description of PeopleTest
  *
  * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
  */
-class PeopleAdapterTest extends \PHPUnit_Framework_TestCase
+class PeopleTest extends \PHPUnit_Framework_TestCase
 {
     protected $entity;
     
@@ -19,24 +20,23 @@ class PeopleAdapterTest extends \PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->entity = new PeopleAdapter(PeopleTestAsset::$data1, 12);
+        $this->entity = new People(PeopleTestAsset::$data1);
     }
     
-    public function testSuperClassAndInterface()
+    public function testCanConstructFromBasePeopleEntity()
     {
-        $this->assertInstanceOf('UnicaenApp\Entity\Ldap\People', $this->entity);
-        $this->assertInstanceOf('ZfcUser\Entity\UserInterface', $this->entity);
+        new People(new BasePeople(PeopleTestAsset::$data1));
     }
     
-    public function testConstrutorSetsSpecifiedUserId()
+    public function testSuperClassAndInterface()
     {
-        $entity = new PeopleAdapter(PeopleTestAsset::$data1, $id = 12);
-        $this->assertEquals($id, $entity->getId());
+        $this->assertInstanceOf('UnicaenApp\Entity\Ldap\People', $this->entity);
+        $this->assertInstanceOf('ZfcUser\Entity\UserInterface', $this->entity);
     }
     
     public function testGettingIdReturnsLdapUidAsDefaultValue()
     {
-        $entity = new PeopleAdapter(PeopleTestAsset::$data1);
+        $entity = new People(PeopleTestAsset::$data1);
         $this->assertEquals(PeopleTestAsset::$data1['uid'], $entity->getId());
     }
     
@@ -44,7 +44,7 @@ class PeopleAdapterTest extends \PHPUnit_Framework_TestCase
     {
         $this->assertEquals(1, $this->entity->getState());
         
-        $entity = new PeopleAdapter(PeopleTestAsset::$dataDeactivated, 12);
+        $entity = new People(PeopleTestAsset::$dataDeactivated, 12);
         $this->assertEquals(0, $entity->getState());
     }
     
@@ -84,6 +84,14 @@ class PeopleAdapterTest extends \PHPUnit_Framework_TestCase
         $this->entity->setEmail('whatever');
     }
     
+    /**
+     * @expectedException \BadMethodCallException
+     */
+    public function testSettingIdThrowsException()
+    {
+        $this->entity->setId('whatever');
+    }
+    
     public function testGetUsernameReturnsSupannAliasLogin()
     {
         $this->assertEquals(PeopleTestAsset::$data1['supannaliaslogin'], $this->entity->getUsername());
@@ -99,7 +107,7 @@ class PeopleAdapterTest extends \PHPUnit_Framework_TestCase
     
     public function testGetPasswordReturnsNull()
     {
-        $entity = new PeopleAdapter(PeopleTestAsset::$data1);
+        $entity = new People(PeopleTestAsset::$data1);
         $this->assertNull($entity->getPassword());
     }
     
@@ -110,4 +118,9 @@ class PeopleAdapterTest extends \PHPUnit_Framework_TestCase
     {
         $this->entity->setPassword('whatever');
     }
+    
+    public function testCanGettingRolesReturnsMembership()
+    {
+        $this->assertEquals($this->entity->getMemberOf(), $this->entity->getRoles());
+    }
 }
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/BaseServiceFactoryTest.php b/tests/UnicaenAuthTest/Provider/Identity/BaseServiceFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2bff7e7123b01c16f7f222b553b3c8d72e659482
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Identity/BaseServiceFactoryTest.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace UnicaenAuthTest\Provider\Identity;
+
+use PHPUnit_Framework_TestCase;
+
+/**
+ * Description of BaseServiceFactoryTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+abstract class BaseServiceFactoryTest extends PHPUnit_Framework_TestCase
+{
+    protected $serviceLocator;
+    protected $userService;
+    protected $factory;
+    protected $factoryClass;
+    protected $serviceClass;
+            
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->factory        = new $this->factoryClass();
+        $this->serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface', array());
+        $this->authService    = $this->getMock('Zend\Authentication\AuthenticationService', array());
+        $this->userService    = $this->getMock('ZfcUser\Service\User', array('getAuthService'));
+    }
+    
+    public function testCanCreateService()
+    {
+        $this->userService->expects($this->once())
+                ->method('getAuthService')
+                ->will($this->returnValue($this->authService));
+        
+        $map = array(
+            array('zfcuser_user_service', $this->userService),
+            array('BjyAuthorize\Config',  array('default_role' => 'default', 'authenticated_role' => 'auth')),
+        );
+        $this->serviceLocator->expects($this->any())
+                ->method('get')
+                ->will($this->returnValueMap($map));
+        
+        $service = $this->factory->createService($this->serviceLocator);
+        
+        $this->assertInstanceOf($this->serviceClass, $service);
+        $this->assertEquals('default', $service->getDefaultRole());
+        $this->assertEquals('auth', $service->getAuthenticatedRole());
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/BaseTest.php b/tests/UnicaenAuthTest/Provider/Identity/BaseTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e76e3424eb583660469fd413e24011cc688304dd
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Identity/BaseTest.php
@@ -0,0 +1,120 @@
+<?php
+namespace UnicaenAuthTest\Provider\Identity;
+
+use PHPUnit_Framework_TestCase;
+use UnicaenAuth\Acl\NamedRole;
+
+/**
+ * Description of LdapTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+abstract class BaseTest extends PHPUnit_Framework_TestCase
+{
+    protected $providerClass;
+    protected $provider;
+    protected $authService;
+    protected $serviceManager;
+    
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->serviceManager    = $this->getMock('Zend\ServiceManager\ServiceManager', array('get'));
+        $this->authService       = $this->getMock('Zend\Authentication\AuthenticationService', array('getIdentity'));
+        $this->provider          = new $this->providerClass($this->authService);
+    }
+    
+    public function getInvalidDefaultRole()
+    {
+        return array(
+            array(12),
+            array(new \stdClass()),
+            array(array('value')),
+        );
+    }
+    
+    public function testGettingIdentityRolesReturnsDefaultRoleWhenEmptyIdentityAvailable()
+    {
+        // fournisseur de l'identité de l'utilisateur connecté
+        $this->authService->expects($this->once())
+                          ->method('getIdentity')
+                          ->will($this->returnValue(null));
+        
+        $roles = $this->provider->getIdentityRoles();
+        $this->assertEquals(array($this->provider->getDefaultRole()), $roles);
+    }
+    
+    public function testGettingIdentityRolesReturnsAuthenticatedRoleWhenUnexpectedIdentityAvailable()
+    {
+        // fournisseur de l'identité de l'utilisateur connecté
+        $this->authService->expects($this->once())
+                          ->method('getIdentity')
+                          ->will($this->returnValue(new \DateTime()));
+        
+        $roles = $this->provider->getIdentityRoles();
+        $this->assertEquals(array($this->provider->getAuthenticatedRole()), $roles);
+    }
+    
+    /**
+     * @depends testGettingIdentityRolesReturnsPeopleRoles
+     */
+    public function testGettingIdentityRolesTrigger()
+    {
+        $event    = new \UnicaenAuth\Provider\Identity\ChainEvent();
+        $roles    = array(new NamedRole('role id'));
+        $provider = $this->getMock($this->providerClass, array('getIdentityRoles'), array($this->authService));
+
+        $provider->expects($this->once())
+                ->method('getIdentityRoles')
+                ->will($this->returnValue($roles));
+        
+        $provider->getIdentityRolesTrigger($event);
+        
+        $this->assertEquals($roles, $event->getRoles());
+    }
+    
+//    public function testGettingIdentityRolesReturnsDefaultRoleWhenIdentityLdapGroupDoesNotExistInAcl()
+//    {
+//        // fournisseur de l'identité de l'utilisateur connecté
+//        $this->authService->expects($this->once())
+//                          ->method('getIdentity')
+//                          ->will($this->returnValue($identity = new LdapPeopleEntity(LdapPeopleTestAsset::$data1)));
+//        
+//        $this->assertNotEmpty($identity->getMemberOf(), "Pré-requis non respecté : memberOf vide.");
+//        
+//        // fournisseur des ACL
+//        $this->authorize->expects($this->any())
+//                        ->method('getAcl')
+//                        ->will($this->returnValue($acl = new \Zend\Permissions\Acl\Acl()));
+//        
+//        $roles = $this->provider->getIdentityRoles();
+//        $this->assertEquals(array($this->defaultRole), $roles);
+//        
+//        // NB: le rôle par défaut n'a pas besoin d'être connu des ACL
+//        $this->setExpectedException('Zend\Permissions\Acl\Exception\InvalidArgumentException');
+//        $acl->getRole($this->defaultRole->getRoleId());
+//    }
+//    
+//    public function testGettingIdentityRolesReturnsIdentityLdapGroupsWhichExistInAcl()
+//    {
+//        // fournisseur de l'identité de l'utilisateur connecté
+//        $this->authService->expects($this->once())
+//                          ->method('getIdentity')
+//                          ->will($this->returnValue($identity = new LdapPeopleEntity(LdapPeopleTestAsset::$data1)));
+//        
+//        $this->assertNotEmpty($identity->getMemberOf(), "Pré-requis non respecté : memberOf vide.");
+//        
+//        // fournisseur des ACL
+//        $acl = new \Zend\Permissions\Acl\Acl();
+//        $acl->addRole($role = new GenericRole('cn=admin_reseau,ou=groups,dc=unicaen,dc=fr'));
+//        $this->authorize->expects($this->any())
+//                        ->method('getAcl')
+//                        ->will($this->returnValue($acl));
+//        
+//        $roles = $this->provider->getIdentityRoles();
+//        $this->assertEquals(array($role), $roles);
+//    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/ChainServiceFactoryTest.php b/tests/UnicaenAuthTest/Provider/Identity/ChainServiceFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e71f06ac0f6683871d166fb9f3f8bfcc7a0f464
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Identity/ChainServiceFactoryTest.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace UnicaenAuthTest\Provider\Identity;
+
+use PHPUnit_Framework_TestCase;
+use UnicaenAuth\Provider\Identity\ChainServiceFactory;
+
+/**
+ * Description of ChainServiceFactoryTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class ChainServiceFactoryTest extends PHPUnit_Framework_TestCase
+{
+    protected $serviceLocator;
+    protected $eventManager;
+    protected $factory;
+    protected $events = array('getIdentityRoles');
+            
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->factory        = new ChainServiceFactory();
+        $this->serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface', array());
+        $this->ldapProvider   = $this->getMock('UnicaenAuth\Provider\Identity\Ldap', $this->events, array(), '', false);
+        $this->dbProvider     = $this->getMock('UnicaenAuth\Provider\Identity\Db', $this->events, array(), '', false);
+    }
+    
+    public function testCanCreateService()
+    {
+        $this->serviceLocator->expects($this->exactly(2))
+                ->method('get')
+                ->will($this->onConsecutiveCalls($this->dbProvider, $this->ldapProvider));
+        
+        $service = $this->factory->createService($this->serviceLocator);
+        
+        $this->assertInstanceOf('UnicaenAuth\Provider\Identity\Chain', $service);
+        
+        foreach ($this->events as $event) {
+            $listeners = $service->getEventManager()->getListeners($event); /* @var $listeners \Zend\Stdlib\SplPriorityQueue */
+            $this->assertCount(2, $listeners);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/ChainTest.php b/tests/UnicaenAuthTest/Provider/Identity/ChainTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f6fd299da3c1052eba7835bda811227442d2cc7
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Identity/ChainTest.php
@@ -0,0 +1,121 @@
+<?php
+namespace UnicaenAuthTest\Provider\Identity;
+
+use PHPUnit_Framework_TestCase;
+use UnicaenAuth\Provider\Identity\Chain;
+use UnicaenAuth\Acl\NamedRole;
+
+/**
+ * Description of ChainTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class ChainTest extends PHPUnit_Framework_TestCase
+{
+    protected $provider;
+    protected $authorize;
+    protected $authService;
+    protected $serviceManager;
+    protected $eventManager;
+    protected $event;
+    protected $acl;
+    
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->authorize      = $this->getMock('BjyAuthorize\Service\Authorize', array('getAcl'), array(), '', false);
+        $this->serviceManager = $this->getMock('Zend\ServiceManager\ServiceManager', array('get'));
+        $this->authService    = $this->getMock('Zend\Authentication\AuthenticationService', array('getIdentity'));
+        $this->provider       = new Chain($this->authService);
+        $this->eventManager   = $this->getMock('Zend\EventManager\EventManager', array('trigger'));
+        $this->event          = $this->getMock('UnicaenAuth\Provider\Identity\ChainEvent', array('getRoles'));
+        $this->acl            = $this->getMock('Zend\Permissions\Acl\Acl', array('hasRole', 'getRole'));
+        
+        $this->authorize->expects($this->any())
+                ->method('getAcl')
+                ->will($this->returnValue($this->acl));
+
+        $this->serviceManager->expects($this->any())
+                ->method('get')
+                ->will($this->returnValue($this->authorize));
+        
+        $this->provider->setServiceLocator($this->serviceManager)
+                ->setEventManager($this->eventManager)
+                ->setEvent($this->event);
+    }
+    
+    public function testCanRetrieveDefaultEventManager()
+    {
+        $provider = new Chain($this->authService);
+        $this->assertInstanceOf('Zend\EventManager\EventManager', $provider->getEventManager());
+    }
+    
+    public function testCanRetrieveDefaultEvent()
+    {
+        $provider = new Chain($this->authService);
+        $this->assertInstanceOf('UnicaenAuth\Provider\Identity\ChainEvent', $event = $provider->getEvent());
+        $this->assertSame($provider, $event->getTarget());
+    }
+    
+    public function testCanSetServiceLocator()
+    {
+        $this->assertSame($this->serviceManager, $this->provider->getServiceLocator());
+    }
+    
+    public function testGettingIdentityRolesReturnsEmptyArrayWhenZeroRolesCollected()
+    {
+        $this->event->expects($this->once())
+                ->method('getRoles')
+                ->will($this->returnValue(array()));
+        
+        $this->assertEquals(array(), $this->provider->getIdentityRoles());
+        $this->assertEquals(array(), $this->readAttribute($this->provider, 'roles'));
+        
+        return $this->provider;
+    }
+    
+    /**
+     * @depends testGettingIdentityRolesReturnsEmptyArrayWhenZeroRolesCollected
+     */
+    public function testGettingIdentityRolesDoesNotCollectRolesTwice($provider)
+    {
+        $this->eventManager->expects($this->never())
+                ->method('trigger');
+        
+        $this->assertEquals(array(), $provider->getIdentityRoles());
+    }
+    
+    public function testGettingIdentityRolesDoesNotIncludeUnknownRoles()
+    {
+        $this->event->expects($this->once())
+                ->method('getRoles')
+                ->will($this->returnValue(array('role 1')));
+        
+        $this->acl->expects($this->once())
+                ->method('hasRole')
+                ->with('role 1')
+                ->will($this->returnValue(false));
+        
+        $this->assertEquals(array(), $this->provider->getIdentityRoles());
+    }
+    
+    public function testGettingIdentityRolesDoesNotIncludeSameRoleTwice()
+    {
+        $this->event->expects($this->once())
+                ->method('getRoles')
+                ->will($this->returnValue(array('role 1', 'role 1')));
+        
+        $this->acl->expects($this->exactly(2))
+                ->method('hasRole')
+                ->will($this->returnValue(true));
+        
+        $this->acl->expects($this->exactly(1))
+                ->method('getRole')
+                ->will($this->returnValue($role = new NamedRole('role 1')));
+        
+        $this->assertEquals(array($role), $this->provider->getIdentityRoles());
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/DbServiceFactoryTest.php b/tests/UnicaenAuthTest/Provider/Identity/DbServiceFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c56ec37c5581804c7a65953ac7ca58eae7be0f86
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Identity/DbServiceFactoryTest.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace UnicaenAuthTest\Provider\Identity;
+
+/**
+ * Description of DbServiceFactoryTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class DbServiceFactoryTest extends BaseServiceFactoryTest
+{
+    protected $factoryClass = 'UnicaenAuth\Provider\Identity\DbServiceFactory';
+    protected $serviceClass = 'UnicaenAuth\Provider\Identity\Db';
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/DbTest.php b/tests/UnicaenAuthTest/Provider/Identity/DbTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..11de7693ece0c88c1adca085ec15198fd448dd0e
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Identity/DbTest.php
@@ -0,0 +1,54 @@
+<?php
+namespace UnicaenAuthTest\Provider\Identity;
+
+use UnicaenAuth\Acl\NamedRole;
+
+/**
+ * Description of LdapTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class DbTest extends BaseTest
+{
+    protected $providerClass = 'UnicaenAuth\Provider\Identity\Db';
+    
+    public function provideAuthServiceIdentity()
+    {
+        $role = new \UnicaenAuth\Entity\Db\Role();
+        $role->setRoleId('role id');
+        
+        $identity1 = $this->getMock('UnicaenAuth\Entity\Db\User');
+        $identity1->expects($this->once())
+                  ->method('getRoles')
+                  ->will($this->returnValue(array($role)));
+        
+        $role2 = new \UnicaenAuth\Entity\Db\Role();
+        $role2->setRoleId('role id 2');
+        
+        $identity2 = $this->getMock('UnicaenAuth\Entity\Db\User');
+        $identity2->expects($this->once())
+                  ->method('getRoles')
+                  ->will($this->returnValue(array($role)));
+        
+        $expectedRoles = array($role);
+        
+        return array(
+            'object-identity' => array($identity1, $expectedRoles),
+            'array-identity'  => array(array('db' => $identity2), $expectedRoles),
+        );
+    }
+    
+    /**
+     * @dataProvider provideAuthServiceIdentity
+     */
+    public function testGettingIdentityRolesReturnsPeopleRoles($identity, $expectedRoles)
+    {
+        $this->authService->expects($this->once())
+                          ->method('getIdentity')
+                          ->will($this->returnValue($identity));
+        
+        $roles = $this->provider->getIdentityRoles();
+        
+        $this->assertEquals($expectedRoles, $roles);
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/LdapPeopleTest.php b/tests/UnicaenAuthTest/Provider/Identity/LdapPeopleTest.php
deleted file mode 100644
index b37312142edd3a96837aa65f449302ceaa09227b..0000000000000000000000000000000000000000
--- a/tests/UnicaenAuthTest/Provider/Identity/LdapPeopleTest.php
+++ /dev/null
@@ -1,164 +0,0 @@
-<?php
-namespace UnicaenAuthTest\Provider\Identity;
-
-use PHPUnit_Framework_TestCase;
-use UnicaenApp\Exception;
-use UnicaenApp\Entity\Ldap\People as LdapPeopleEntity;
-use UnicaenAppTest\Entity\Ldap\TestAsset\People as LdapPeopleTestAsset;
-use UnicaenAuth\Provider\Identity\LdapPeople;
-use UnicaenAuth\Acl\NamedRole;
-use Zend\ServiceManager\ServiceManager;
-use Zend\Permissions\Acl\Role\GenericRole;
-
-/**
- * Description of LdapPeopleTest
- *
- * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
- */
-class LdapPeopleTest extends PHPUnit_Framework_TestCase
-{
-    protected $provider;
-    protected $authorize;
-    protected $authService;
-    protected $serviceManager;
-    
-    /**
-     * Sets up the fixture, for example, open a network connection.
-     * This method is called before a test is executed.
-     */
-    protected function setUp()
-    {
-        $this->authorize = $this->getMock('BjyAuthorize\Service\Authorize', array('getAcl'), array(), '', false);
-        
-        $this->serviceManager = new ServiceManager();
-        $this->serviceManager->setService('BjyAuthorize\Service\Authorize', $this->authorize);
-        
-        $this->authService = $this->getMock('Zend\Authentication\AuthenticationService', array('getIdentity'));
-        
-        $this->provider = new LdapPeople($this->authService);
-        $this->provider->setServiceLocator($this->serviceManager);
-        
-        $this->defaultRole = $this->provider->getDefaultRole();
-    }
-    
-    public function testCanProvideDefaultRoleWhenNoneIsSet()
-    {
-        $this->assertInstanceOf('UnicaenAuth\Acl\NamedRole', $this->defaultRole);
-        $this->assertEquals('guest', $this->defaultRole->getRoleId());
-        $this->assertEquals("Invité", $this->defaultRole->getRoleName());
-        $this->assertNull($this->defaultRole->getParent());
-    }
-    
-    
-    public function getInvalidDefaultRole()
-    {
-        return array(
-            array(12),
-            array(new \stdClass()),
-            array(array('value')),
-        );
-    }
-    
-    /**
-     * @dataProvider getInvalidDefaultRole
-     * @expectedException Exception
-     * @param mixed $defaultRole
-     */
-    public function testSettingDefaultRoleThrowsExceptionWhenInvalidRoleSpecified($defaultRole)
-    {
-        $this->provider->setDefaultRole($defaultRole);
-    }
-    
-    public function testCanSetDefaultRoleAsString()
-    {
-        $defaultRole = 'role';
-        $this->provider->setDefaultRole($defaultRole);
-        $this->assertSame($defaultRole, $this->provider->getDefaultRole());
-    }
-    
-    public function testCanSetDefaultRoleAsObject()
-    {
-        $defaultRole = new GenericRole('role');
-        $this->provider->setDefaultRole($defaultRole);
-        $this->assertSame($defaultRole, $this->provider->getDefaultRole());
-    }
-    
-    public function getUnexpectedIdentity()
-    {
-        return array(
-            array(null),
-            array(new \stdClass()),
-        );
-    }
-    
-    /**
-     * @dataProvider getUnexpectedIdentity
-     */
-    public function testGettingIdentityRolesReturnsDefaultRoleWhenUnexpectedIdentityAvailable($identity)
-    {
-        // fournisseur de l'identité de l'utilisateur connecté
-        $this->authService->expects($this->once())
-                          ->method('getIdentity')
-                          ->will($this->returnValue($identity));
-        
-        $roles = $this->provider->getIdentityRoles();
-        $this->assertEquals(array($this->defaultRole), $roles);
-    }
-    
-    public function testGettingIdentityRolesReturnsDefaultRoleWhenWhenIdentityIsNotMemberOfAnyLdapGroup()
-    {
-        $data = LdapPeopleTestAsset::$data1;
-        unset($data['memberof']);
-        $identity = new LdapPeopleEntity($data);
-        
-        // fournisseur de l'identité de l'utilisateur connecté
-        $this->authService->expects($this->once())
-                          ->method('getIdentity')
-                          ->will($this->returnValue($identity));
-        
-        $roles = $this->provider->getIdentityRoles();
-        $this->assertEquals(array($this->defaultRole), $roles);
-    }
-    
-    public function testGettingIdentityRolesReturnsDefaultRoleWhenIdentityLdapGroupDoesNotExistInAcl()
-    {
-        // fournisseur de l'identité de l'utilisateur connecté
-        $this->authService->expects($this->once())
-                          ->method('getIdentity')
-                          ->will($this->returnValue($identity = new LdapPeopleEntity(LdapPeopleTestAsset::$data1)));
-        
-        $this->assertNotEmpty($identity->getMemberOf(), "Pré-requis non respecté : memberOf vide.");
-        
-        // fournisseur des ACL
-        $this->authorize->expects($this->any())
-                        ->method('getAcl')
-                        ->will($this->returnValue($acl = new \Zend\Permissions\Acl\Acl()));
-        
-        $roles = $this->provider->getIdentityRoles();
-        $this->assertEquals(array($this->defaultRole), $roles);
-        
-        // NB: le rôle par défaut n'a pas besoin d'être connu des ACL
-        $this->setExpectedException('Zend\Permissions\Acl\Exception\InvalidArgumentException');
-        $acl->getRole($this->defaultRole->getRoleId());
-    }
-    
-    public function testGettingIdentityRolesReturnsIdentityLdapGroupsWhichExistInAcl()
-    {
-        // fournisseur de l'identité de l'utilisateur connecté
-        $this->authService->expects($this->once())
-                          ->method('getIdentity')
-                          ->will($this->returnValue($identity = new LdapPeopleEntity(LdapPeopleTestAsset::$data1)));
-        
-        $this->assertNotEmpty($identity->getMemberOf(), "Pré-requis non respecté : memberOf vide.");
-        
-        // fournisseur des ACL
-        $acl = new \Zend\Permissions\Acl\Acl();
-        $acl->addRole($role = new GenericRole('cn=admin_reseau,ou=groups,dc=unicaen,dc=fr'));
-        $this->authorize->expects($this->any())
-                        ->method('getAcl')
-                        ->will($this->returnValue($acl));
-        
-        $roles = $this->provider->getIdentityRoles();
-        $this->assertEquals(array($role), $roles);
-    }
-}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/LdapServiceFactoryTest.php b/tests/UnicaenAuthTest/Provider/Identity/LdapServiceFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..942034d5a559a27a17d21da00f7a690e7753e4f7
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Identity/LdapServiceFactoryTest.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace UnicaenAuthTest\Provider\Identity;
+
+/**
+ * Description of LdapServiceFactoryTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class LdapServiceFactoryTest extends BaseServiceFactoryTest
+{
+    protected $factoryClass = 'UnicaenAuth\Provider\Identity\LdapServiceFactory';
+    protected $serviceClass = 'UnicaenAuth\Provider\Identity\Ldap';
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Identity/LdapTest.php b/tests/UnicaenAuthTest/Provider/Identity/LdapTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab2c610fb7b0be9f8389e235cabff48a85d65c6a
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Identity/LdapTest.php
@@ -0,0 +1,77 @@
+<?php
+namespace UnicaenAuthTest\Provider\Identity;
+
+use UnicaenApp\Entity\Ldap\Group;
+use UnicaenAuth\Acl\NamedRole;
+
+/**
+ * Description of LdapTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class LdapTest extends BaseTest
+{
+    protected $providerClass = 'UnicaenAuth\Provider\Identity\Ldap';
+    protected $mapper;
+    
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->mapper = $this->getMock('UnicaenApp\Mapper\Ldap\Db', array('findOneByDn'));
+        
+        $this->provider->setServiceLocator($this->serviceManager);
+    }
+    
+    public function provideAuthServiceIdentity()
+    {
+        $identity1 = $this->getMock('UnicaenAuth\Entity\Ldap\People');
+        $identity1->expects($this->once())
+                  ->method('getRoles')
+                  ->will($this->returnValue(array('cn=admin_reseau,ou=groups,dc=unicaen,dc=fr')));
+        
+        $identity2 = $this->getMock('UnicaenAuth\Entity\Ldap\People');
+        $identity2->expects($this->once())
+                  ->method('getRoles')
+                  ->will($this->returnValue(array('cn=admin_reseau,ou=groups,dc=unicaen,dc=fr')));
+        
+        return array(
+            'object-identity' => array($identity1),
+            'array-identity'  => array(array('ldap' => $identity2)),
+        );
+    }
+    
+    /**
+     * @dataProvider provideAuthServiceIdentity
+     */
+    public function testGettingIdentityRolesReturnsPeopleRoles($identity)
+    {
+        $group = new Group(array(
+            'dn'          => 'cn=admin_reseau,ou=groups,dc=unicaen,dc=fr',
+            'description' => 'ldap group'
+        ));
+        
+        $this->authService->expects($this->once())
+                          ->method('getIdentity')
+                          ->will($this->returnValue($identity));
+        
+        $this->mapper->expects($this->once())
+                ->method('findOneByDn')
+                ->with($group->getDn())
+                ->will($this->returnValue($group));
+        
+        $this->serviceManager->expects($this->once())
+                ->method('get')
+                ->with('ldap_group_mapper')
+                ->will($this->returnValue($this->mapper));
+        
+        $roles = $this->provider->getIdentityRoles();
+        
+        $expected = array(new NamedRole($group->getDn(), null, $group->getDescription()));
+        $this->assertEquals($expected, $roles);
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Role/BaseServiceFactoryTest.php b/tests/UnicaenAuthTest/Provider/Role/BaseServiceFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fbbfafb19ea5d83f65e6d0b0b2bd00a3554e1345
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Role/BaseServiceFactoryTest.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace UnicaenAuthTest\Provider\Role;
+
+use PHPUnit_Framework_TestCase;
+
+/**
+ * Description of ConfigServiceFactoryTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+abstract class BaseServiceFactoryTest extends PHPUnit_Framework_TestCase
+{
+    protected $serviceLocator;
+    protected $factoryClass;
+    protected $factory;
+    protected $serviceClass;
+            
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->factory        = new $this->factoryClass();
+        $this->serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface', array());
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Role/ConfigServiceFactoryTest.php b/tests/UnicaenAuthTest/Provider/Role/ConfigServiceFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..95a9592eefd7db05f8290976c119d0f380e9e32d
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Role/ConfigServiceFactoryTest.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace UnicaenAuthTest\Provider\Role;
+
+/**
+ * Description of ConfigServiceFactoryTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class ConfigServiceFactoryTest extends BaseServiceFactoryTest
+{
+    protected $factoryClass = 'UnicaenAuth\Provider\Role\ConfigServiceFactory';
+    protected $serviceClass = 'UnicaenAuth\Provider\Role\Config';
+    protected $mapper;
+            
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->mapper = $this->getMock('UnicaenApp\Mapper\Ldap\Group', array());
+    }
+    
+    public function provideInvalidOptions()
+    {
+        return array(
+            'a' => array(array()),
+            'b' => array(array('role_providers')),
+            'c' => array(array('role_providers' => array())),
+            'd' => array(array('role_providers' => array('UnicaenAuth\Provider\Role\Config' => null))),
+        );
+    }
+    
+    /**
+     * @dataProvider provideInvalidOptions
+     * @expectedException \BjyAuthorize\Exception\InvalidArgumentException
+     */
+    public function testCannotCreateServiceWithInvalidOptions($options)
+    {
+        $this->serviceLocator->expects($this->once())
+                ->method('get')
+                ->with('BjyAuthorize\Config')
+                ->will($this->returnValue($options));
+        
+        $this->factory->createService($this->serviceLocator);
+    }
+    
+    public function testCanCreateService()
+    {
+        $options = array(
+            'role_providers' => array(
+                'UnicaenAuth\Provider\Role\Config' => array(),
+            ),
+        );
+        $map = array(
+            array('BjyAuthorize\Config', $options),
+            array('ldap_group_mapper',   $this->mapper),
+        );
+        $this->serviceLocator->expects($this->exactly(2))
+                ->method('get')
+                ->will($this->returnValueMap($map));
+        
+        $service = $this->factory->createService($this->serviceLocator);
+        
+        $this->assertInstanceOf('UnicaenAuth\Provider\Role\Config', $service);
+    }
+}
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Role/ConfigTest.php b/tests/UnicaenAuthTest/Provider/Role/ConfigTest.php
index 4f305f5cd9afe40c4d2222ec86c1091b19593670..fef0132d6a83dc7871e5965ba297f58f889ac423 100644
--- a/tests/UnicaenAuthTest/Provider/Role/ConfigTest.php
+++ b/tests/UnicaenAuthTest/Provider/Role/ConfigTest.php
@@ -3,6 +3,8 @@ namespace UnicaenAuthTest\Provider\Role;
 
 use PHPUnit_Framework_TestCase;
 use UnicaenAuth\Provider\Role\Config;
+use UnicaenAuth\Acl\NamedRole;
+use UnicaenApp\Entity\Ldap\Group;
 
 /**
  * Description of ConfigTest
@@ -11,41 +13,119 @@ use UnicaenAuth\Provider\Role\Config;
  */
 class ConfigTest extends PHPUnit_Framework_TestCase
 {
-    protected $config;
-    protected $options = array(
-        'guest' => array(
-            'name' => "Profil standard",
-            'children' => array(
-                'cn=support_info,ou=groups,dc=unicaen,dc=fr', // pas de nom pour celui-là
-                'cn=dsi-infra,ou=groups,dc=unicaen,dc=fr' => array(
-                    'name' => "DSI Infrastructure",
-                ),
-            ),
-        ),
-    );
+    protected $mapper;
     
     protected function setUp()
     {
-        $this->config = new Config($this->options);
+        $this->mapper = $this->getMock('UnicaenApp\Mapper\Ldap\Group', array('findOneByDn'));
     }
     
-    public function testLoadRolesFormConfigCreateNamedRoles()
+    public function testLoadingRolesWithoutLdapDnCreatesNamedRoles()
     {
-        $roles = $this->config->getRoles();
+        $options = array(
+            'user' => array(
+                'name' => "Profil standard",
+                'children' => array(
+                    'Gestionnaire', // pas de nom pour celui-là
+                    'admin' => array(
+                        'name' => "Administrateur",
+                    ),
+                ),
+            ),
+        );
+
+        $this->mapper
+                ->expects($this->never())
+                ->method('findOneByDn');
+        
+        $config = new Config($this->mapper, $options);
+        
+        $roles = $config->getRoles();
+        
         $expected = array(
-            $guest = new \UnicaenAuth\Acl\NamedRole(
-                    'guest', 
+            $guest = new NamedRole('user', null, "Profil standard"),
+            new NamedRole('Gestionnaire', $guest, "Gestionnaire"), // le nom attribué par défaut est l'id
+            new NamedRole('admin', $guest, "Administrateur"),
+        );
+        $this->assertEquals($expected, $roles);
+    }
+    
+    public function testLoadingRolesWithExistingLdapDnCreatesNamedRoles()
+    {
+        $options = array(
+            'user' => array(
+                'name' => "Profil standard",
+                'children' => array(
+                    'cn=support_info,ou=groups,dc=unicaen,dc=fr', // pas de nom pour celui-là
+                    'cn=dsi-infra,ou=groups,dc=unicaen,dc=fr' => array(
+                        'name' => "DSI Infrastructure",
+                    ),
+                ),
+            ),
+        );
+        
+        $map = array(
+            array($dn = 'cn=support_info,ou=groups,dc=unicaen,dc=fr', new Group(array('dn' => $dn, 'description' => "DSI Support"))),
+        );
+        $this->mapper
+                ->expects($this->exactly(1))
+                ->method('findOneByDn')
+                ->will($this->returnValueMap($map));
+        
+        $config = new Config($this->mapper, $options);
+        
+        $roles = $config->getRoles();
+        
+        $expected = array(
+            $guest = new NamedRole(
+                    'user', 
                     null, 
                     "Profil standard"),
-            new \UnicaenAuth\Acl\NamedRole(
+            new NamedRole(
                     'cn=support_info,ou=groups,dc=unicaen,dc=fr', 
                     $guest, 
-                    "cn=support_info,ou=groups,dc=unicaen,dc=fr"), // le nom par défaut est l'id
-            new \UnicaenAuth\Acl\NamedRole(
+                    "DSI Support"), // le nom attribué est la description LDAP
+            new NamedRole(
                     'cn=dsi-infra,ou=groups,dc=unicaen,dc=fr', 
                     $guest, 
                     "DSI Infrastructure"),
         );
         $this->assertEquals($expected, $roles);
     }
+    
+    public function testLoadingRolesWithUnexistingLdapDnCreatesNamedRoles()
+    {
+        $options = array(
+            'user' => array(
+                'name' => "Profil standard",
+                'children' => array(
+                    'cn=unknown,ou=groups,dc=unicaen,dc=fr', // groupe introuvable
+                ),
+            ),
+        );
+        
+        $map = array(
+            array('cn=unknown,ou=groups,dc=unicaen,dc=fr', null),
+        );
+        $this->mapper
+                ->expects($this->exactly(1))
+                ->method('findOneByDn')
+                ->will($this->returnValueMap($map));
+        
+        $config = new Config($this->mapper, $options);
+        
+        $roles = $config->getRoles();
+        
+        $expected = array(
+            $guest = new NamedRole(
+                    'user', 
+                    null, 
+                    "Profil standard"),
+            new NamedRole(
+                    'cn=unknown,ou=groups,dc=unicaen,dc=fr', 
+                    $guest, 
+                    'cn=unknown,ou=groups,dc=unicaen,dc=fr'), // le nom attribué est l'id
+        );
+        $this->assertEquals($expected, $roles);
+    }
 }
\ No newline at end of file
diff --git a/tests/UnicaenAuthTest/Provider/Role/DbServiceFactoryTest.php b/tests/UnicaenAuthTest/Provider/Role/DbServiceFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0d2cc5dc9cd24a8da153bbe46bc3e06e9320308
--- /dev/null
+++ b/tests/UnicaenAuthTest/Provider/Role/DbServiceFactoryTest.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace UnicaenAuthTest\Provider\Role;
+
+/**
+ * Description of DbServiceFactoryTest
+ *
+ * @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
+ */
+class DbServiceFactoryTest extends BaseServiceFactoryTest
+{
+    protected $factoryClass = 'UnicaenAuth\Provider\Role\DbServiceFactory';
+    protected $serviceClass = 'UnicaenAuth\Provider\Role\Db';
+            
+    public function provideInvalidOptions()
+    {
+        return array(
+            'a' => array(array()),
+            'b' => array(array('role_providers')),
+            'c' => array(array('role_providers' => array())),
+            'd' => array(array('role_providers' => array('UnicaenAuth\Provider\Role\Db' => array()))),
+            'e' => array(array('role_providers' => array('UnicaenAuth\Provider\Role\Db' => array('role_entity_class' => null)))),
+            'f' => array(array('role_providers' => array('UnicaenAuth\Provider\Role\Db' => array('role_entity_class' => 'A', 'object_manager' => null)))),
+        );
+    }
+    
+    /**
+     * @dataProvider provideInvalidOptions
+     * @expectedException \BjyAuthorize\Exception\InvalidArgumentException
+     */
+    public function testCannotCreateServiceWithInvalidOptions($options)
+    {
+        $this->serviceLocator->expects($this->once())
+                ->method('get')
+                ->with('BjyAuthorize\Config')
+                ->will($this->returnValue($options));
+        
+        $this->factory->createService($this->serviceLocator);
+    }
+    
+    public function testCanCreateService()
+    {
+        $options = array(
+            'role_providers' => array(
+                'UnicaenAuth\Provider\Role\Db' => array(
+                    'role_entity_class' => 'Entity', 
+                    'object_manager'    => 'orm_default',
+                )
+            )
+        );
+        
+        $objectManager = $this->getMockForAbstractClass('Doctrine\Common\Persistence\ObjectManager', array('getRepository'));
+        $objectManager->expects($this->once())
+                ->method('getRepository')
+                ->will($this->returnValue($this->getMock('Doctrine\Common\Persistence\ObjectRepository', array())));
+        
+        $map = array(
+            array('BjyAuthorize\Config', $options),
+            array('orm_default',         $objectManager),
+        );
+        $this->serviceLocator->expects($this->exactly(2))
+                ->method('get')
+                ->will($this->returnValueMap($map));
+        
+        $service = $this->factory->createService($this->serviceLocator);
+        
+        $this->assertInstanceOf('UnicaenAuth\Provider\Role\Db', $service);
+    }
+}
\ No newline at end of file