function (requestor) {
  /**
   * {{{name}}} service.
   * @module api/{{{name}}}
   * @version {{{version}}}
   */

  /**
   * {{{name}}} service.
   * @alias module:api/{{{name}}}
   */
  var {{{name}}} = {};

  {{#methods}}
    {{{../name}}}.{{methodName}} = function ({{#parameters}}{{#required}}{{^isSingleton}}{{&camelCaseName}},{{/isSingleton}}{{/required}}{{/parameters}}{{#hasOptionalParameter}}opts,{{/hasOptionalParameter}}cb) {
      {{#parameters}}
        {{#required}}
          // verify the required parameter '{{name}}' is set
          if ({{&camelCaseName}} == undefined || {{&camelCaseName}} == null) {
            throw new Error("Missing the required parameter '{{camelCaseName}}' when calling {{../methodName}}");
          }
        {{/required}}
      {{/parameters}}
      {{#hasOptionalParameter}}
        if (typeof opts === 'function') {
          cb = opts;
          opts = null;
        }
        opts = opts || {};
      {{/hasOptionalParameter}}

      var pathParams = {};
      var queryParams = {};
      var headerParams = {};
      var formParams = {};

      {{#parameters}}
        {{#isPathParameter}}
          pathParams['{{{name}}}'] = {{^required}}opts['{{/required}}{{&camelCaseName}}{{^required}}']{{/required}};
        {{/isPathParameter}}
      {{/parameters}}

      {{#parameters}}
        {{#isQueryParameter}}
          {{#isSingleton}}
              queryParams['{{{name}}}'] = '{{&singleton}}';
          {{/isSingleton}}
          {{^isSingleton}}
            {{#isPatternType}}
              throws new Error('Unsupported parameter')
            {{/isPatternType}}
            {{^isPatternType}}
              queryParams['{{{name}}}'] = {{^required}}opts['{{/required}}{{&camelCaseName}}{{^required}}']{{/required}};
            {{/isPatternType}}
          {{/isSingleton}}
        {{/isQueryParameter}}
      {{/parameters}}

      {{#parameters}}
        {{#isHeaderParameter}}
          {{#isSingleton}}
            headerParams['{{{name}}}'] = '{{&singleton}}';
          {{/isSingleton}}
          {{^isSingleton}}
            headerParams['{{{name}}}'] = {{^required}}opts['{{/required}}{{{camelCaseName}}}{{^required}}']{{/required}};
          {{/isSingleton}}
        {{/isHeaderParameter}}
      {{/parameters}}

      {{#parameters}}
        {{#isFormParameter}}
          {{#isSingleton}}
            formParams['{{{name}}}'] = '{{&singleton}}';
          {{/isSingleton}}
          {{^isSingleton}}
            formParams['{{{name}}}'] = {{^required}}opts['{{/required}}{{&camelCaseName}}{{^required}}']{{/required}};
          {{/isSingleton}}
        {{/isFormParameter}}
      {{/parameters}}

      var postBody = null;
      {{#parameters}}
        {{#if isBodyParameter}}
          postBody = {{^required}}opts['{{/required}}{{&camelCaseName}}{{^required}}']{{/required}};
        {{/if}}
      {{/parameters}}

      var authNames = [];
      var contentTypes = [{{#contentTypes}}'{{&.}}'{{#unless @last}},{{/unless}}{{/contentTypes}}];
      var accepts = [{{#accepts}}'{{&.}}'{{#unless @last}},{{/unless}}{{/accepts}}];
      var returnType = Object;

      return requestor.request(
        '{{&path}}', '{{&method}}',
        pathParams, queryParams, headerParams, formParams, postBody,
        authNames, contentTypes, accepts, returnType, cb
      );
    };
  {{/methods}}

  return {{{name}}};
}
