public function authenticate(RequestInterface $request)
    {
        $token = $this->token();

        if (!$token && !$this->findMatchingArea($request)) {
            return $this;
        }

        if (!$token) {
            throw new AuthenticationException('Unable to authenticate, token is missing');
        }

        foreach ($this->providers as $provider) {
            if (!$provider->supportsToken($token)) {
                continue;
            }

            if (!$provider->authenticate($token)) {
                $this->stash()
                     ->destroy();

                throw new AuthenticationException(sprintf('Token could not be authenticated in provider "%s", destroying token', get_class($provider)));
            }

            $this->user = $provider->get($token);

            return $this;
        }

        $this->stash()
             ->destroy();

        throw new AuthenticationException(sprintf('Missing provider supporting token "%s", destroying token', get_class($token)));
    }