code: function S3Adapter (options, schema) {
  	var self = this;
  	this.options = assign({}, DEFAULT_OPTIONS, options.s3);
  
  	// Check required options are set.
  	var requiredOptions = ['key', 'secret', 'bucket'];
  	requiredOptions.forEach(function (key) {
  		if (!self.options[key]) {
  			throw new Error('Configuration error: Missing required option `' + key + '`');
  		}
  	});
  
  	// Check that `uploadParams` does not include any that we will be setting.
  	var restrictedPrams = ['Key', 'Body', 'Bucket', 'ContentType', 'ContentLength'];
  	Object.keys(this.options.uploadParams).forEach(function (key) {
  		if (restrictedPrams.indexOf(key) !== -1) {
  			throw new Error('Configuration error: `' + key + '` must not be set on `uploadParams`.');
  		}
  	});
  
  	// Ensure the path has a leading "/"
  	this.options.path = ensureLeadingSlash(this.options.path);
  
  	// Create the s3 client
  	this.s3Client = new S3({
  		accessKeyId: this.options.key,
  		secretAccessKey: this.options.secret,
  		region: this.options.region,
  	});
  
  	// Ensure the generateFilename option takes a callback
  	this.options.generateFilename = ensureCallback(this.options.generateFilename);
  }
docs: The schema can contain the additional fields { path, bucket, etag }. See README.md for details and usage examples.