class GithubScm extends AbstractScm {

    @Override
    public HttpResponse validateAndCreate(@JsonBody JSONObject request) {
        String accessToken = (String) request.get("accessToken");
        if(accessToken == null){
            throw new ServiceException.BadRequestException("accessToken is required");
        }

        accessToken = accessToken.trim();

        try {
            User authenticatedUser =  getAuthenticatedUser();

            HttpURLConnection connection = connect(String.format("%s/%s", getUri(), "user"),accessToken);
            validateAccessTokenScopes(connection);
            String data = IOUtils.toString(HttpRequest.getInputStream(connection));
            GHUser user = GithubScm.getMappingObjectReader().forType(GHUser.class).readValue(data);

            if(user.getEmail() != null){
                Mailer.UserProperty p = authenticatedUser.getProperty(Mailer.UserProperty.class);
                //XXX: If there is already email address of this user, should we update it with
                // the one from Github?
                if (p==null){
                    authenticatedUser.addProperty(new Mailer.UserProperty(user.getEmail()));
                }
            }

            //Now we know the token is valid. Lets find credential
            String credentialId = createCredentialId(getUri());
            StandardUsernamePasswordCredentials githubCredential = CredentialsUtils.findCredential(credentialId, StandardUsernamePasswordCredentials.class, new BlueOceanDomainRequirement());
            final StandardUsernamePasswordCredentials credential = new UsernamePasswordCredentialsImpl(CredentialsScope.USER, credentialId, getCredentialDescription(), authenticatedUser.getId(), accessToken);

            if(githubCredential == null) {
                CredentialsUtils.createCredentialsInUserStore(
                        credential, authenticatedUser, getCredentialDomainName(),
                        ImmutableList.<DomainSpecification>of(new BlueOceanDomainSpecification()));
            }else{
                CredentialsUtils.updateCredentialsInUserStore(
                        githubCredential, credential, authenticatedUser, getCredentialDomainName(),
                        ImmutableList.<DomainSpecification>of(new BlueOceanDomainSpecification()));
            }

            return createResponse(credential.getId());

        } catch (IOException e) {
            if (e instanceof MalformedURLException || e instanceof UnknownHostException) {
                throw new ServiceException.BadRequestException(
                    new ErrorMessage(400, "Invalid apiUrl").add(
                        new ErrorMessage.Error("apiUrl", ErrorMessage.Error.ErrorCodes.INVALID.toString(), e.getMessage())
                    )
                );
            }
            throw new ServiceException.UnexpectedErrorException(e.getMessage());
        }
    }

    public  GithubScm(Reachable parent);

}