/// <summary>
        /// Creates a new authorization for the specified OAuth application if an authorization for that application doesn’t already
        /// exist for the user; otherwise, returns the user’s existing authorization for that application.
        /// </summary>
        /// <remarks>
        /// This method requires authentication.
        /// See the <a href="http://developer.github.com/v3/oauth/#get-or-create-an-authorization-for-a-specific-app">API documentation</a> for more information.
        /// </remarks>
        /// <param name="clientId">Client ID of the OAuth application for the token</param>
        /// <param name="clientSecret">The client secret</param>
        /// <param name="newAuthorization">Describes the new authorization to create</param>
        /// <param name="twoFactorAuthenticationCode">The two-factor authentication code in response to the current user's previous challenge</param>
        /// <exception cref="AuthorizationException">
        /// Thrown when the current user does not have permission to make this request.
        /// </exception>
        /// <exception cref="TwoFactorRequiredException">
        /// Thrown when the current account has two-factor authentication enabled and an authentication code is required.
        /// </exception>
        /// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
        /// <returns>The created <see cref="Authorization"/>.</returns>
        public async Task <ApplicationAuthorization> GetOrCreateApplicationAuthentication(
            string clientId,
            string clientSecret,
            NewAuthorization newAuthorization,
            string twoFactorAuthenticationCode)
        {
            Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
            Ensure.ArgumentNotNullOrEmptyString(clientSecret, "clientSecret");
            Ensure.ArgumentNotNull(newAuthorization, "authorization");
            Ensure.ArgumentNotNullOrEmptyString(twoFactorAuthenticationCode, "twoFactorAuthenticationCode");

            var requestData = new
            {
                client_secret = clientSecret,
                scopes        = newAuthorization.Scopes,
                note          = newAuthorization.Note,
                note_url      = newAuthorization.NoteUrl,
                fingerprint   = newAuthorization.Fingerprint
            };

            try
            {
                var endpoint = ApiUrls.AuthorizationsForClient(clientId);

                return(await ApiConnection.Put <ApplicationAuthorization>(
                           endpoint,
                           requestData,
                           twoFactorAuthenticationCode));
            }
            catch (AuthorizationException e)
            {
                throw new TwoFactorChallengeFailedException(twoFactorAuthenticationCode, e);
            }
        }
        /// <summary>
        /// Creates a new authorization for the specified OAuth application if an authorization for that application doesn’t already
        /// exist for the user; otherwise, returns the user’s existing authorization for that application.
        /// </summary>
        /// <remarks>
        /// This method requires authentication.
        /// See the <a href="http://developer.github.com/v3/oauth/#get-or-create-an-authorization-for-a-specific-app">API documentation</a> for more information.
        /// </remarks>
        /// <param name="clientId">Client ID of the OAuth application for the token</param>
        /// <param name="clientSecret">The client secret</param>
        /// <param name="newAuthorization">Describes the new authorization to create</param>
        /// <exception cref="AuthorizationException">
        /// Thrown when the current user does not have permission to make this request.
        /// </exception>
        /// <exception cref="TwoFactorRequiredException">
        /// Thrown when the current account has two-factor authentication enabled and an authentication code is required.
        /// </exception>
        /// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
        /// <returns>The created <see cref="Authorization"/>.</returns>
        public Task <ApplicationAuthorization> GetOrCreateApplicationAuthentication(
            string clientId,
            string clientSecret,
            NewAuthorization newAuthorization)
        {
            Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
            Ensure.ArgumentNotNullOrEmptyString(clientSecret, "clientSecret");
            Ensure.ArgumentNotNull(newAuthorization, "authorization");

            var requestData = new
            {
                client_secret = clientSecret,
                scopes        = newAuthorization.Scopes,
                note          = newAuthorization.Note,
                note_url      = newAuthorization.NoteUrl
            };

            if (String.IsNullOrWhiteSpace(newAuthorization.Fingerprint))
            {
                // use classic API
                var endpoint = ApiUrls.AuthorizationsForClient(clientId);
                return(ApiConnection.Put <ApplicationAuthorization>(endpoint, requestData));
            }
            else
            {
                // use new API
                var endpoint = ApiUrls.AuthorizationsForClient(clientId, newAuthorization.Fingerprint);
                return(ApiConnection.Put <ApplicationAuthorization>(endpoint, requestData, null, previewAcceptsHeader));
            }
        }
        /// <summary>
        /// Creates a new authorization for the specified OAuth application if an authorization for that application doesn’t already
        /// exist for the user; otherwise, returns the user’s existing authorization for that application.
        /// </summary>
        /// <remarks>
        /// This method requires authentication.
        /// See the <a href="http://developer.github.com/v3/oauth/#get-or-create-an-authorization-for-a-specific-app">API documentation</a> for more information.
        /// </remarks>
        /// <param name="clientId">Client ID of the OAuth application for the token</param>
        /// <param name="clientSecret">The client secret</param>
        /// <param name="newAuthorization">Describes the new authorization to create</param>
        /// <param name="twoFactorAuthenticationCode">The two-factor authentication code in response to the current user's previous challenge</param>
        /// <exception cref="AuthorizationException">
        /// Thrown when the current user does not have permission to make this request.
        /// </exception>
        /// <exception cref="TwoFactorRequiredException">
        /// Thrown when the current account has two-factor authentication enabled and an authentication code is required.
        /// </exception>
        /// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
        /// <returns>The created <see cref="Authorization"/>.</returns>
        public async Task <ApplicationAuthorization> GetOrCreateApplicationAuthentication(
            string clientId,
            string clientSecret,
            NewAuthorization newAuthorization,
            string twoFactorAuthenticationCode)
        {
            Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
            Ensure.ArgumentNotNullOrEmptyString(clientSecret, "clientSecret");
            Ensure.ArgumentNotNull(newAuthorization, "authorization");
            Ensure.ArgumentNotNullOrEmptyString(twoFactorAuthenticationCode, "twoFactorAuthenticationCode");

            var requestData = new
            {
                client_secret = clientSecret,
                scopes        = newAuthorization.Scopes,
                note          = newAuthorization.Note,
                note_url      = newAuthorization.NoteUrl
            };

            try
            {
                if (String.IsNullOrWhiteSpace(newAuthorization.Fingerprint))
                {
                    // use classic API
                    var endpoint = ApiUrls.AuthorizationsForClient(clientId);
                    return(await ApiConnection.Put <ApplicationAuthorization>(
                               endpoint,
                               requestData,
                               twoFactorAuthenticationCode));
                }
                else
                {
                    // use new API
                    var endpoint = ApiUrls.AuthorizationsForClient(clientId, newAuthorization.Fingerprint);
                    return(await ApiConnection.Put <ApplicationAuthorization>(
                               endpoint,
                               requestData,
                               twoFactorAuthenticationCode,
                               previewAcceptsHeader));
                }
            }
            catch (AuthorizationException e)
            {
                throw new TwoFactorChallengeFailedException(e);
            }
        }
        /// <summary>
        /// Creates a new authorization for the specified OAuth application if an authorization for that application doesn’t already
        /// exist for the user; otherwise, returns the user’s existing authorization for that application.
        /// </summary>
        /// <remarks>
        /// This method requires authentication.
        /// See the <a href="http://developer.github.com/v3/oauth/#get-or-create-an-authorization-for-a-specific-app">API documentation</a> for more information.
        /// </remarks>
        /// <param name="clientId">Client ID of the OAuth application for the token</param>
        /// <param name="clientSecret">The client secret</param>
        /// <param name="newAuthorization">Describes the new authorization to create</param>
        /// <exception cref="AuthorizationException">
        /// Thrown when the current user does not have permission to make this request.
        /// </exception>
        /// <exception cref="TwoFactorRequiredException">
        /// Thrown when the current account has two-factor authentication enabled and an authentication code is required.
        /// </exception>
        /// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
        /// <returns>The created <see cref="Authorization"/>.</returns>
        public Task <ApplicationAuthorization> GetOrCreateApplicationAuthentication(
            string clientId,
            string clientSecret,
            NewAuthorization newAuthorization)
        {
            Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
            Ensure.ArgumentNotNullOrEmptyString(clientSecret, "clientSecret");
            Ensure.ArgumentNotNull(newAuthorization, "authorization");

            var requestData = new
            {
                client_secret = clientSecret,
                scopes        = newAuthorization.Scopes,
                note          = newAuthorization.Note,
                note_url      = newAuthorization.NoteUrl,
                fingerprint   = newAuthorization.Fingerprint
            };

            var endpoint = ApiUrls.AuthorizationsForClient(clientId);

            return(ApiConnection.Put <ApplicationAuthorization>(endpoint, requestData));
        }