send(params, responseCtor = undefined) {
    // Standard TS API Client preprocessing to drop undefined queryParams.
    processParams(params);

    const path = params.path || '';
    const url = apiclient.getSafeApiUrl() + path;
    const args = apiclient.makeRequest_(params.queryParams || {});
    const body = params.body ? JSON.stringify(params.body) : undefined;
    if (this.sync) {
      const raw = apiclient.send(
          url, args, undefined, params.httpMethod, body, this.retries,
          this.detectPartialError);
      const value = responseCtor ? deserialize(responseCtor, raw) : raw;
      // Converts a value into an "instant" promise, with a then method that
      // immediately applies a function and builds a new thenable of the result.
      // Any errors will be thrown back to the original caller synchronously.
      const thenable = (v) => ({'then': (f) => thenable(f(v))});
      return /** @type {!Promise<T>} */(thenable(value));
    }
    const value = new Promise((resolve, reject) => {
      const resolveOrReject = (value, error = undefined) => {
        if (error) {
          reject(error);
        } else {
          resolve(value);
        }
      };
      apiclient.send(
          url, args, resolveOrReject, params.httpMethod, body, this.retries,
          this.detectPartialError);
    });
    return value.then(r => responseCtor ? deserialize(responseCtor, r) : r);
  }
Implements the JSON RPC using the logic in apiclient.send().
Handles both sync and async cases.  In sync mode the returned promise will
resolve immediately: this is unwrapped by Call.handle() above.

@template T
@param {!MakeRequestParams} params Provided by the autogenerated client.
@param {!SerializableCtor<T>=} responseCtor Also provided by the generated
    code.  Will be a constructor for one of the ee.api.* response objects,
    which builds a Serializable type from a raw js object.
@return {!Promise<T>}
@override