var ACME = require( '../' )
var URL = require( 'url' )
var request = require( 'request' )
var info = require( '../package.json' )

/**
 * ACME Protocol Client
 * @constructor
 * @param {Object} options
 * @return {Client}
 */
function Client( options ) {

  if( !(this instanceof Client) )
    return new Client( options )

  this.options = Object.assign( {}, Client.defaults, options )

  if( !this.options.baseUrl || typeof this.options.baseUrl !== 'string' )
    throw new TypeError( 'baseUrl must be a string' )

  this.directory = null

  this._replayNonce = null

  this._request = request.defaults({
    gzip: true,
    json: true,
    baseUrl: this.options.baseUrl,
    headers: {
      'User-Agent': this.options.userAgent,
      'Connection': 'Keep-Alive',
    },
  })

}

/**
 * Client default options
 * @type {Object}
 */
Client.defaults = {
  baseUrl: null,
  directoryPath: 'directory',
  privateKey: null,
  publicKey: null,
  userAgent: process.release.name + '/' + process.versions.node +
    ' ' + info.name + '/' + info.version,
}

/**
 * Build a detailed error from a problem response
 * @param  {Error} error
 * @param  {Object} response
 * @param  {Object} body
 * @return {Error}
 */
Client.getResponseError = function( error, response, body ) {

  var error = new Error( response.statusMessage )
  error.detail = body

  if( response.headers['content-type'] === 'application/problem+json' ) {
    var errorType = body.type.replace( 'urn:acme:error:', '' ).toUpperCase()
    error.message = body.detail || ACME[ 'E_' + errorType ]
    Object.assign( error, body )
  }

  return error

}

/**
 * Client prototype
 * @type {Object}
 */
Client.prototype = {

  constructor: Client,

  get isConfigured() {
    return this.directory != null
  },

  hasCapability: function( capability ) {
    return !!this.directory[ capability ]
  },

  configure: function(/* [path,] callback */) {

    var self = this
    var argv = Array.prototype.slice.call( arguments )
    var callback = argv.pop()
    var path = this.options.directoryPath = argv.pop() ||
      this.options.directoryPath

    return this._request.get( path, function( error, response, body ) {

      if( error ) return callback.call( self, error, body );

      if( response.statusCode < 200 || response.statusCode >= 300 ) {
        error = Client.getResponseError( error, response, body )
      }

      self._replayNonce = response.headers['replay-nonce']
      self.directory = body

      callback.call( self, error, self.directory )

    })

  },

  getNonce: function( callback ) {

    var self = this

    this._request.head( this.options.directoryPath, function( error, response, body ) {
      if( error ) return callback.call( self, error );
      if( response.statusCode !== 200 ) {
        error = Client.getResponseError( error, response, body )
      }
      self._replayNonce = response.headers['replay-nonce']
      callback.call( self, error, self._replayNonce )
    })

  },

}

// Exports
module.exports = Client

@@ -506,24 +506,63 @@
  string' )%0A%0A
+  /** @type %7BObject%7D ACME Directory */%0A
   this.direc
@@ -1736,16 +1736,54 @@
 lient,%0A%0A
+  /** @type %7BBoolean%7D isConfigured */%0A
   get is
@@ -1843,95 +1843,448 @@
 %0A%0A  
-hasCapability: function( capability ) %7B%0A    return !!this.directory%5B capability %5D%0A  %7D,%0A
+/**%0A   * Check whether the client has a certain capability,%0A   * e.g. supports new registartions via %60.hasCapability('new-reg')%60%0A   * @param  %7BString%7D  capability%0A   * @return %7BBoolean%7D%0A   */%0A  hasCapability: function( capability ) %7B%0A    return !!this.directory%5B capability %5D%0A  %7D,%0A%0A  /**%0A   * Configure the client directory from a given path / URL%0A   * @param %7BString%7D %5Bpath%5D URL%0A   * @param %7BFunction%7D callback%0A   * @return %7BRequest%7D%0A   */
 %0A  c
@@ -2959,16 +2959,183 @@
 %0A%0A  %7D,%0A%0A
+  /**%0A   * Fetch a new replay-nonce from the ACME server%0A   * @internal to replenish the nonce, if empty%0A   * @param  %7BFunction%7D callback%0A   * @return %7BRequest%7D%0A   */%0A
   getNon
@@ -3183,24 +3183,31 @@
 = this%0A%0A    
+return 
 this._reques

Update lib/client: Add more jsdoc blocks