function Resource(options) {
  options = options ?? Frozen.EMPTY_OBJECT;
  if (typeof options === "string") {
    options = {
      url: options,
    };
  }

  //>>includeStart('debug', pragmas.debug);
  Check.typeOf.string("options.url", options.url);
  //>>includeEnd('debug');

  this._url = undefined;
  this._templateValues = defaultClone(options.templateValues, {});
  this._queryParameters = defaultClone(options.queryParameters, {});

  /**
   * Additional HTTP headers that will be sent with the request.
   *
   * @type {object}
   */
  this.headers = defaultClone(options.headers, {});

  /**
   * A Request object that will be used. Intended for internal use only.
   *
   * @type {Request}
   */
  this.request = options.request ?? new Request();

  /**
   * A proxy to be used when loading the resource.
   *
   * @type {Proxy}
   */
  this.proxy = options.proxy;

  /**
   * Function to call when a request for this resource fails. If it returns true or a Promise that resolves to true, the request will be retried.
   *
   * @type {Function}
   */
  this.retryCallback = options.retryCallback;

  /**
   * The number of times the retryCallback should be called before giving up.
   *
   * @type {number}
   */
  this.retryAttempts = options.retryAttempts ?? 0;
  this._retryCount = 0;

  const parseUrl = options.parseUrl ?? true;
  if (parseUrl) {
    this.parseUrl(options.url, true, true);
  } else {
    this._url = options.url;
  }

  this._credits = options.credits;
}
A resource that includes the location and any other parameters we need to retrieve it or create derived resources. It also provides the ability to retry requests.

@alias Resource
@constructor

@param {string|Resource.ConstructorOptions} options A url or an object describing initialization options

@example
function refreshTokenRetryCallback(resource, error) {
  if (error.statusCode === 403) {
    // 403 status code means a new token should be generated
    return getNewAccessToken()
      .then(function(token) {
        resource.queryParameters.access_token = token;
        return true;
      })
      .catch(function() {
        return false;
      });
  }

  return false;
}

const resource = new Resource({
   url: 'http://server.com/path/to/resource.json',
   proxy: new DefaultProxy('/proxy/'),
   headers: {
     'X-My-Header': 'valueOfHeader'
   },
   queryParameters: {
     'access_token': '123-435-456-000'
   },
   retryCallback: refreshTokenRetryCallback,
   retryAttempts: 1
});