code: func Spool(to io.Writer, from io.Reader, dir string) (n int64, err error) {
  	// First, buffer up to `memoryBufferLimit` in memory.
  	buf := make([]byte, memoryBufferLimit)
  	if bn, err := from.Read(buf); err != nil && err != io.EOF {
  		return int64(bn), err
  	} else {
  		buf = buf[:bn]
  	}
  
  	var spool io.Reader = bytes.NewReader(buf)
  	if err != io.EOF {
  		// If we weren't at the end of the stream, create a temporary
  		// file, and spool the remaining contents there.
  		tmp, err := ioutil.TempFile(dir, "")
  		if err != nil {
  			return 0, errors.Wrap(err, "spool tmp")
  		}
  		defer os.Remove(tmp.Name())
  
  		if n, err = io.Copy(tmp, from); err != nil {
  			return n, errors.Wrap(err, "unable to spool")
  		}
  
  		if _, err = tmp.Seek(0, io.SeekStart); err != nil {
  			return 0, errors.Wrap(err, "unable to seek")
  		}
  
  		// The spooled contents will now be the concatenation of the
  		// contents we stored in memory, then the remainder of the
  		// contents on disk.
  		spool = io.MultiReader(spool, tmp)
  	}
  
  	return io.Copy(to, spool)
  }
docs: // Spool spools the contents from 'from' to 'to' by buffering the entire
  // contents of 'from' into a temprorary file created in the directory "dir".
  // That buffer is held in memory until the file grows to larger than
  // 'memoryBufferLimit`, then the remaining contents are spooled to disk.
  //
  // The temporary file is cleaned up after the copy is complete.
  //
  // The number of bytes written to "to", as well as any error encountered are
  // returned.