public function authenticate(TokenInterface $token)
    {
        if (false === $this->supports($token)) {
            throw new SecurityException('Invalid token provided', SecurityException::UNSUPPORTED_TOKEN);
        }

        try {
            $user = $this->userProvider->loadUserByUsername($token->getUsername());
            $secret = $user->getPassword();
            if ($this->encoderFactory) {
                try {
                    $encoder = $this->encoderFactory->getEncoder($user);

                    if ($encoder instanceof PlaintextPasswordEncoder) {
                        $secret = md5($secret);
                    } elseif ($encoder instanceof MessageDigestPasswordEncoder) {
                        // $secret is already md5 encoded
                        // NB: only md5 algo without salt is currently supported due to frontend dependency
                    } else {
                        // currently there is a dependency on md5 in frontend so all other encoders can't be supported
                        throw new \RuntimeException('Encoder is not supported: '.get_class($encoder));
                    }
                } catch (\RuntimeException $e) {
                    // no encoder defined
                    $secret = md5($secret);
                }
            } else {
                // no encoder - still have to encode with md5
                $secret = md5($secret);
            }

            $this->checkNonce($token, $secret);
        } catch (\Exception $e) {
            $this->clearNonce($token);
            throw $e;
        }

        $validToken = new BBUserToken($user->getRoles());
        $validToken
            ->setUser($user)
            ->setNonce($token->getNonce())
            ->setCreated(new \DateTime())
            ->setLifetime($this->lifetime)
        ;

        $this->writeNonceValue($validToken);

        return $validToken;
    }