static apr_byte_t oidc_oauth_resolve_access_token(request_rec *r, oidc_cfg *c,
		const char *access_token, json_t **token, char **response) {

	json_t *result = NULL;

	/* see if we've got the claims for this access_token cached already */
	oidc_oauth_get_cached_access_token(r, c, access_token, &result);

	if (result == NULL) {

		const char *s_json = NULL;

		/* not cached, go out and validate the access_token against the Authorization server and get the JSON claims back */
		if (oidc_oauth_validate_access_token(r, c, access_token,
				&s_json) == FALSE) {
			oidc_error(r,
					"could not get a validation response from the Authorization server");
			return FALSE;
		}

		/* decode and see if it is not an error response somehow */
		if (oidc_util_decode_json_and_check_error(r, s_json, &result) == FALSE)
			return FALSE;

		json_t *active = json_object_get(result, "active");
		apr_time_t cache_until;
		if (active != NULL) {

			if (json_is_boolean(active)) {
				if (!json_is_true(active)) {
					oidc_debug(r,
							"\"active\" boolean object with value \"false\" found in response JSON object");
					json_decref(result);
					return FALSE;
				}
			} else if (json_is_string(active)) {
				if (apr_strnatcasecmp(json_string_value(active), "true") != 0) {
					oidc_debug(r,
							"\"active\" string object with value that is not equal to \"true\" found in response JSON object: %s",
							json_string_value(active));
					json_decref(result);
					return FALSE;
				}
			} else {
				oidc_debug(r,
						"no \"active\" boolean or string object found in response JSON object");
				json_decref(result);
				return FALSE;
			}

			if (oidc_oauth_parse_and_cache_token_expiry(r, c, result, "exp",
					TRUE, FALSE, &cache_until) == FALSE) {
				json_decref(result);
				return FALSE;
			}

			/* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */
			oidc_oauth_cache_access_token(r, c, cache_until, access_token,
					result);

		} else {

			if (oidc_oauth_parse_and_cache_token_expiry(r, c, result,
					c->oauth.introspection_token_expiry_claim_name,
					apr_strnatcmp(
							c->oauth.introspection_token_expiry_claim_format,
							"absolute") == 0,
							c->oauth.introspection_token_expiry_claim_required,
							&cache_until) == FALSE) {
				json_decref(result);
				return FALSE;
			}

			/* set it in the cache so subsequent request don't need to validate the access_token and get the claims anymore */
			oidc_oauth_cache_access_token(r, c, cache_until, access_token,
					result);

		}

	}

	/* return the access_token JSON object */
	json_t *tkn = json_object_get(result, "access_token");
	if ((tkn != NULL) && (json_is_object(tkn))) {

		/*
		 * assume PingFederate validation: copy over those claims from the access_token
		 * that are relevant for authorization purposes
		 */
		json_object_set(tkn, "client_id", json_object_get(result, "client_id"));
		json_object_set(tkn, "scope", json_object_get(result, "scope"));

		//oidc_oauth_spaced_string_to_array(r, result, "scope", tkn, "scopes");

		/* return only the pimped access_token results */
		*token = json_deep_copy(tkn);

		json_decref(result);

	} else {

		//oidc_oauth_spaced_string_to_array(r, result, "scope", result, "scopes");

		/* assume spec compliant introspection */
		*token = result;

	}

	char *s_token = json_dumps(*token, 0);
	*response = apr_pstrdup(r->pool, s_token);
	free(s_token);

	return TRUE;
}
static apr_byte_t oidc_oauth_resolve_access_token(request_rec *r, oidc_cfg *c,
		const char *access_token, json_t **token, char **response) {

	json_t *result = NULL;

	 
	oidc_oauth_get_cached_access_token(r, c, access_token, &result);

	if (result == NULL) {

		const char *s_json = NULL;

		 
		if (oidc_oauth_validate_access_token(r, c, access_token,
				&s_json) == FALSE) {
			oidc_error(r,
					"could not get a validation response from the Authorization server");
			return FALSE;
		}

		 
		if (oidc_util_decode_json_and_check_error(r, s_json, &result) == FALSE)
			return FALSE;

		json_t *active = json_object_get(result, "active");
		apr_time_t cache_until;
		if (active != NULL) {

			if (json_is_boolean(active)) {
				if (!json_is_true(active)) {
					oidc_debug(r,
							"\"active\" boolean object with value \"false\" found in response JSON object");
					json_decref(result);
					return FALSE;
				}
			} else if (json_is_string(active)) {
				if (apr_strnatcasecmp(json_string_value(active), "true") != 0) {
					oidc_debug(r,
							"\"active\" string object with value that is not equal to \"true\" found in response JSON object: %s",
							json_string_value(active));
					json_decref(result);
					return FALSE;
				}
			} else {
				oidc_debug(r,
						"no \"active\" boolean or string object found in response JSON object");
				json_decref(result);
				return FALSE;
			}

			if (oidc_oauth_parse_and_cache_token_expiry(r, c, result, "exp",
					TRUE, FALSE, &cache_until) == FALSE) {
				json_decref(result);
				return FALSE;
			}

			 
			oidc_oauth_cache_access_token(r, c, cache_until, access_token,
					result);

		} else {

			if (oidc_oauth_parse_and_cache_token_expiry(r, c, result,
					c->oauth.introspection_token_expiry_claim_name,
					apr_strnatcmp(
							c->oauth.introspection_token_expiry_claim_format,
							"absolute") == 0,
							c->oauth.introspection_token_expiry_claim_required,
							&cache_until) == FALSE) {
				json_decref(result);
				return FALSE;
			}

			 
			oidc_oauth_cache_access_token(r, c, cache_until, access_token,
					result);

		}

	}

	 
	json_t *tkn = json_object_get(result, "access_token");
	if ((tkn != NULL) && (json_is_object(tkn))) {

		 
		json_object_set(tkn, "client_id", json_object_get(result, "client_id"));
		json_object_set(tkn, "scope", json_object_get(result, "scope"));

		 

		 
		*token = json_deep_copy(tkn);

		json_decref(result);

	} else {

		 

		 
		*token = result;

	}

	char *s_token = json_dumps(*token, 0);
	*response = apr_pstrdup(r->pool, s_token);
	free(s_token);

	return TRUE;
}