docs: function RegistryClientV1(opts) {
      var self = this;
      assert.object(opts, 'opts');
      assert.string(opts.name, 'opts.name');
      assert.optionalObject(opts.log, 'opts.log');
      assert.optionalString(opts.username, 'opts.username');
      assert.optionalString(opts.password, 'opts.password');
      assert.optionalBool(opts.insecure, 'opts.insecure');
      assert.optionalString(opts.scheme, 'opts.scheme');
      // TODO: options to control the trust db for CA verification
      // TODO add passing through other restify options
      // Restify/Node HTTP client options.
      // opt.agent (optional, bool or object)
      assert.optionalString(opts.userAgent, 'opts.userAgent');
      // opts.proxy (optional, bool or object or string);
  
      this.log = opts.log
          ? opts.log.child({
                  component: 'registry',
                  serializers: restifyClients.bunyan.serializers
              })
          : bunyan.createLogger({
                  name: 'registry',
                  serializers: restifyClients.bunyan.serializers
              });
  
      this.insecure = Boolean(opts.insecure);
      this.repo = common.parseRepo(opts.name);
      if (opts.scheme) {
          this.repo.index.scheme = opts.scheme;
      } else if (common.isLocalhost(this.repo.index.name)) {
          // Per docker.git:registry/config.go#NewServiceConfig we special
          // case localhost to allow HTTP. Note that this lib doesn't do
          // the "try HTTPS, then fallback to HTTP if allowed" thing that
          // docker-docker does, we'll just prefer HTTP for localhost.
          this.repo.index.scheme = 'http';
      }
  
      if (opts.username && opts.password) {
          var buffer = new Buffer(opts.username + ':' + opts.password, 'utf8');
          this._authorization = 'Basic ' + buffer.toString('base64');
      }
      this._ensuredSession = false;
      this._cookieJar = new tough.CookieJar();
  
      this._indexUrl = common.urlFromIndex(this.repo.index);
  
      this._commonHttpClientOpts = {
          log: this.log,
          agent: opts.agent,
          proxy: opts.proxy,
          rejectUnauthorized: !this.insecure,
          userAgent: opts.userAgent || common.DEFAULT_USERAGENT
      };
      this._clientsToClose = [];
  
      Object.defineProperty(this, '_indexApi', {
          get: function () {
              if (self.__indexApi === undefined) {
                  self.__indexApi = self._createClient('json', self._indexUrl);
              }
              return this.__indexApi;
          }
      });
  
      /*
       * The registry endpoint can vary. By default one can infer it from
       * the repo. E.g. "quay.io/foo" has a registry host of "quay.io". For
       * repos not specifying and index, e.g. "busybox" or "trentm/blah", the
       * default index is "index.docker.io", for which the default registry host
       * is registry-1.docker.io.
       *
       * Typically that is all you need. However two others things can happen:
       * - The `listRepoImgs` response can redirect to a totally different
       *   registry. E.g. Docker Hub does this for the "rhel7" image. And/or:
       * - The `listRepoImgs` can (typically does, always does?) include a
       *   X-Docker-Endpoints header with a registry host to use.
       *   See `_ensureSession` below.
       *
       * The properties below are to lazily determine and use the registry
       * URL after `_ensureSession` has been run to provide redirects and/or
       * endpoints.
       */
      Object.defineProperty(this, '_registryUrl', {
          get: function () {
              assert.ok(self._ensuredSession,
                  'getting _registryUrl before session');
              if (self.__registryUrl === undefined) {
                  if (self._endpoints && self._endpoints.length > 0) {
                      self.__registryUrl = self._endpoints[0];
                  } else if (self.repo.index.official) {
                      self.__registryUrl = DEFAULT_REGISTRY_URL_V1;
                  } else {
                      self.__registryUrl = common.urlFromIndex(self.repo.index);
                  }
                  self.log.trace({_registryUrl: self.__registryUrl},
                      'set _registryUrl');
              }
              return self.__registryUrl;
          }
      });
      Object.defineProperty(this, '_registryHost', {
          get: function () {
              if (self.__registryHost === undefined) {
                  self.__registryHost = mod_url.parse(self._registryUrl).host;
              }
              return self.__registryHost;
          }
      });
      Object.defineProperty(this, '_registryApi', {
          get: function () {
              if (self.__registryApi === undefined) {
                  self.__registryApi = self._createClient(
                      'json', self._registryUrl);
              }
              return self.__registryApi;
          }
      });
  }