public async Task <IFileSystemNode> AddAsync(Stream stream, string name = "", AddFileOptions options = null, CancellationToken cancel = default(CancellationToken))
        {
            if (options == null)
            {
                options = new AddFileOptions();
            }
            var opts = new List <string>();

            if (!options.Pin)
            {
                opts.Add("pin=false");
            }
            if (options.Wrap)
            {
                opts.Add("wrap-with-directory=true");
            }
            if (options.RawLeaves)
            {
                opts.Add("raw-leaves=true");
            }
            if (options.OnlyHash)
            {
                opts.Add("only-hash=true");
            }
            if (options.Trickle)
            {
                opts.Add("trickle=true");
            }
            if (options.Progress != null)
            {
                opts.Add("progress=true");
            }
            if (options.Hash != MultiHash.DefaultAlgorithmName)
            {
                opts.Add($"hash=${options.Hash}");
            }
            if (options.Encoding != MultiBase.DefaultAlgorithmName)
            {
                opts.Add($"cid-base=${options.Encoding}");
            }
            if (!string.IsNullOrWhiteSpace(options.ProtectionKey))
            {
                opts.Add($"protect={options.ProtectionKey}");
            }
            opts.Add($"chunker=size-{options.ChunkSize}");

            var response = await ipfs.Upload2Async("add", cancel, stream, name, opts.ToArray());

            // The result is a stream of LDJSON objects.
            // See https://github.com/ipfs/go-ipfs/issues/4852
            FileSystemNode fsn = null;

            using (var sr = new StreamReader(response))
                using (var jr = new JsonTextReader(sr)
                {
                    SupportMultipleContent = true
                })
                {
                    while (jr.Read())
                    {
                        var r = await JObject.LoadAsync(jr, cancel);

                        // If a progress report.
                        if (r.ContainsKey("Bytes"))
                        {
                            options.Progress?.Report(new TransferProgress
                            {
                                Name  = (string)r["Name"],
                                Bytes = (ulong)r["Bytes"]
                            });
                        }

                        // Else must be an added file.
                        else
                        {
                            fsn = new FileSystemNode
                            {
                                Id          = (string)r["Hash"],
                                Size        = long.Parse((string)r["Size"]),
                                IsDirectory = false,
                                Name        = name,
                                IpfsClient  = ipfs
                            };
                            if (log.IsDebugEnabled)
                            {
                                log.Debug("added " + fsn.Id + " " + fsn.Name);
                            }
                        }
                    }
                }

            fsn.IsDirectory = options.Wrap;
            return(fsn);
        }