code: function upload(params, options, callback) {
      if (typeof options === 'function' && callback === undefined) {
        callback = options;
        options = null;
      }
  
      options = options || {};
      options = AWS.util.merge(options || {}, {service: this, params: params});
  
      var uploader = new AWS.S3.ManagedUpload(options);
      if (typeof callback === 'function') uploader.send(callback);
      return uploader;
    }
docs: @see AWS.S3.ManagedUpload
  @overload upload(params = {}, [options], [callback])
  Uploads an arbitrarily sized buffer, blob, or stream, using intelligent
  concurrent handling of parts if the payload is large enough. You can
  configure the concurrent queue size by setting `options`. Note that this
  is the only operation for which the SDK can retry requests with stream
  bodies.
  
  @param (see AWS.S3.putObject)
  @option (see AWS.S3.ManagedUpload.constructor)
  @return [AWS.S3.ManagedUpload] the managed upload object that can call
  `send()` or track progress.
  @example Uploading a stream object
  var params = {Bucket: 'bucket', Key: 'key', Body: stream};
  s3.upload(params, function(err, data) {
  console.log(err, data);
  });
  @example Uploading a stream with concurrency of 1 and partSize of 10mb
  var params = {Bucket: 'bucket', Key: 'key', Body: stream};
  var options = {partSize: 10 * 1024 * 1024, queueSize: 1};
  s3.upload(params, options, function(err, data) {
  console.log(err, data);
  });
  @callback callback function(err, data)
  @param err [Error] an error or null if no error occurred.
  @param data [map] The response data from the successful upload:
  @param data.Location [String] the URL of the uploaded object
  @param data.ETag [String] the ETag of the uploaded object
  @param data.Bucket [String]  the bucket to which the object was uploaded
  @param data.Key [String] the key to which the object was uploaded