text: /**
   * Copyright 2012 Google Inc. All Rights Reserved.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  var Request = require('./requests.js').Request;
  var BatchRequest = require('./requests.js').BatchRequest;
  
  /**
   * Constructs a new client with given API name and version.
   * @constructor
   *
   * @param {object} apiMeta Schema returned by Discovery API.
   */
  function Client(apiMeta) {
    this.apiMeta = apiMeta;
    this.authClient = null;
    this.defaultParams = null;
    // generate helper methods
    this.extend_(this, apiMeta.methods || {}, apiMeta.resources || {});
  }
  
  /**
   * Gets the API's name.
   * @return {String}
   */
  Client.prototype.getName = function() {
    return this.apiMeta.name;
  };
  
  /**
   * Gets the API's version.
   * @return {String}
   */
  Client.prototype.getVersion = function() {
    return this.apiMeta.version;
  };
  
  /**
   * @private
   * Generate a request builder helper.
   *
   * @param {object} methodMeta Method's schema returned by Discovery API.
   * @return {Function} Function generated by methodMeta.
   */
  Client.prototype.generateHelper_ = function(methodMeta) {
    var that = this;
    // generates a function to make a request
    // to the resource on given method
    return function(params, body) {
      return that.newRequest(methodMeta, params, body);
    };
  };
  
  /**
   * Constructs a request to method with given parameters.
   *
   * @param {object} methodMetada Discovery metadata of the method.
   * @param {?object} params Parameters.
   * @param {object=} opt_resource Optional resource.
   *
   * @return {Request} New Request object constructed with given args.
   */
  Client.prototype.newRequest = function(methodMetada, params, opt_resource) {
  
    return new Request(this.apiMeta, methodMetada, params, opt_resource,
                       this.defaultParams).withAuthClient(this.authClient);
  };
  
  /**
   * Adds global auth client.
   *
   * @param {auth.AuthClient} client An auth client instance.
   *
   * @return {Client} Returns itself.
   */
  Client.prototype.withAuthClient = function(client) {
    this.authClient = client;
    return this;
  };
  
  /**
   * Add default params.
   *
   * @param {object} params Default parameters for all methods.
   *
   * @return {Client} Returns itself.
   */
  Client.prototype.withDefaultParams = function(params) {
    this.defaultParams = params;
    return this;
  };
  
  /**
   * @private
   * Extends the object with the given resource and its methods
   * recursively.
   * @param {?object} root Object to be extended.
   * @param {object} methods  Discovery methods to extend the object with.
   * @param {object} resources Discovery resources to extend the object with.
   */
  Client.prototype.extend_ = function(root, methods, resources) {
    for (var methodName in methods) {
      root[methodName] = this.generateHelper_(methods[methodName]);
    }
    for (var key in resources) {
      root[key] = root[key] || {};
      this.extend_(
        root[key],
        resources[key].methods || {},
        resources[key].resources || {});
    }
  };
  
  /**
   * Exporting Client.
   */
  module.exports = Client;
  