docs: function specialObjectClone(obj, seen) {
  	if (obj === undefined || obj === null) {
  		return obj;
  	}
  	const type = typeof(obj);
  	if (type === 'function') {
  		return null;
  	}
  	if (type !== 'object') {
  		return obj;
  	}
  	if (obj instanceof Error) {
  		return obj;
  	}
  	if (obj instanceof Buffer) {
  		return '[Buffer]';
  	}
  	if (obj instanceof RegExp) {
  		return '/' + obj.source + '/';
  	}
  	let newobj = {};
  	if (Array.isArray(obj)) {
  		const maskFields = [ '--password', '-password' ];
  		newobj = null;
  		for (let i = 0, l = obj.length; i < l; ++i) {
  			if (maskFields.indexOf(obj[i]) > -1 && obj[++i]) {
  				if (newobj === null) {
  					newobj = obj.slice(0);
  				}
  				newobj[i] = '[HIDDEN]';
  			}
  		}
  		return newobj ? newobj : obj;
  	}
  
  	// we need to deal with circular references
  	seen = seen || [];
  
  	// clone so we don't mutate original object
  	const keys = Object.keys(obj),
  		length = keys.length;
  	for (let c = 0; c < length; c++) {
  		const key = keys[c];
  		let value = obj[key];
  		// if the object contains a password key, we want to
  		// not log the actual password
  		if (/^password[-_]?/.test(key)) {
  			value = '[HIDDEN]';
  		} else if (key === 'req' || key === 'res') {
  			// Skip.
  		} else if (typeof(value) === 'object') {
  			if (seen.indexOf(value) !== -1) {
  				value = '[Circular]';
  			} else {
  				seen.push(value);
  				value = specialObjectClone(value, seen);
  			}
  		}
  		newobj[key] = value;
  	}
  	return newobj;
  }