public function callback(Request $request)
    {
        // Check to see if this provider exists and has a callback implemented
        $provider = strtolower($request->attributes->get('provider'));

        if (! $this->providerExists($provider)) {
            return $this->createNotFoundResponse();
        }

        if (! method_exists($this, $provider)) {
            throw new LogicException(sprintf(
                'Callback for provider \'%s\' not implemented',
                $provider
            ));
        }

        // Use provider service and access token from provider to create a LoginRequest for our app
        $code            = $request->query->get('code');
        $providerService = $this->getServiceByProvider($provider);
        $providerToken   = $providerService->requestAccessToken($code);

        $socialLoginRequest = $this->$provider($providerService, $providerToken);

        // Handle login or link-account request and redirect to the redirect-url
        $state = (int) $request->query->get('state');
        try {
            if ($state === self::ACTION_LOGIN_WITH_ACCOUNT) {
                $token = $this->service->handleLoginRequest($socialLoginRequest);
            } elseif ($state === self::ACTION_LINK_ACCOUNT) {
                $token = $this->service->handleLinkRequest(
                    $socialLoginRequest,
                    $this->session->get('user')
                );
            } else {
                return new Response(
                    'State parameter not set',
                    422
                );
            }

            $redirect = $this->config['redirect-url'];
            $redirect .= '?'.http_build_query($token);
        } catch (NoLinkedAccountException $e) {
            $redirect = $this->config['redirect-url'];
            $redirect .= '?login_failure=1&error=no_linked_account';
        } catch (LinkedAccountExistsException $e) {
            $redirect = $this->config['redirect-url'];
            $redirect .= '?login_failure=1&error=account_already_linked';
        } catch (OutOfBoundsException $e) {
            $redirect = $this->config['redirect-url'];
            $redirect .= '?login_failure=1';

            if ($e->getCode() === SocialLoginService::EXCEPTION_ACCOUNT_NOT_FOUND) {
                $redirect .= '&error=account_not_found';
            }
        }

        $response = new Response();
        $response->setStatusCode(301);
        $response->headers->set('Location', $redirect);

        return $response;
    }