protected String requestAccessToken(ApiConfiguration configuration)
            throws AccessDeniedException
    {
        try
        {
            if (configuration.getAccessToken() != null)
            {
                return configuration.getAccessToken();
            }
                
            Form form = new Form();
            form.add("client_id", configuration.getClientId());
            form.add("scope",  configuration.getAuthorizationScope());
            form.add("response_type", "device_code");

            Client client = Client.create(new DefaultClientConfig());
            client.addFilter(new ClientFilter()
            {
                @Override
                public ClientResponse handle(ClientRequest request) throws ClientHandlerException
                {
                    logger.fine(request.getMethod() + " to " + request.getURI().toString());
                    ClientResponse response = null;
                    try
                    {
                        response = getNext().handle(request);
                    }
                    catch(ClientHandlerException t)
                    {
                        throw new BaseSpaceException(t.getMessage(), t,request.getURI());
                    }
                    return response;
                }
            });
            
            WebResource resource = client.resource(UriBuilder.fromUri(configuration.getApiRootUri())
                    .path(configuration.getVersion())
                    .path(configuration.getAuthorizationUriFragment())
                    .build());
            logger.finer(resource.toString());
        
            ClientResponse response = resource.accept(
                    MediaType.APPLICATION_XHTML_XML,
                    MediaType.APPLICATION_FORM_URLENCODED,
                    MediaType.APPLICATION_JSON)
                    .post(ClientResponse.class,form);
            String responseAsJSONString = response.getEntity(String.class);
            logger.finer(responseAsJSONString);
            
            final ObjectMapper mapper = new ObjectMapper();
            AuthVerificationCode authCode = mapper.readValue(responseAsJSONString, AuthVerificationCode.class);
            if (authCode.getError() != null)
            {
                throw new BaseSpaceException(authCode.getErrorDescription(),null,resource.getURI());
            }
            
            logger.finer(authCode.toString());
            
            String uri = authCode.getVerificationWithCodeUri();
            BrowserLaunch.openURL(uri);
            
            //Poll for approval
            form = new Form();
            form.add("client_id", configuration.getClientId());
            form.add("client_secret",configuration.getClientSecret());
            form.add("code",authCode.getDeviceCode());
            form.add("grant_type","device");
           
            resource = client.resource(UriBuilder.fromUri(configuration.getApiRootUri())
                    .path(configuration.getVersion())
                    .path(configuration.getAccessTokenUriFragment())
                    .build());
            
            String accessToken = null;
            while(accessToken == null)
            {
                long interval = authCode.getInterval() * 1000;
                Thread.sleep(interval);
                response = resource.accept(
                        MediaType.APPLICATION_XHTML_XML,
                        MediaType.APPLICATION_FORM_URLENCODED,
                        MediaType.APPLICATION_JSON)
                        .post(ClientResponse.class,form);
               
                responseAsJSONString = response.getEntity(String.class); 
                logger.finer(responseAsJSONString);
                if(response.getClientResponseStatus().getStatusCode() > 400)
                {
                    AccessToken error =  mapper.readValue(responseAsJSONString, AccessToken.class);
                    throw new BaseSpaceException(resource.getURI(),error.getErrorDescription(),response.getClientResponseStatus().getStatusCode());
                }
                if(response.getClientResponseStatus().getStatusCode() == 200)
                {
                  
                    AccessToken token = mapper.readValue(responseAsJSONString, AccessToken.class);
                    accessToken = token.getAccessToken();
                }
            } 
            return accessToken;
            
        }
        catch(BaseSpaceException bs)
        {
            throw bs;
        }
        catch(Throwable t)
        {
            t.printStackTrace();
            throw new RuntimeException("Error requesting access token from BaseSpace: " + t.getMessage());
        }
    }