public void AddDirectoryRecursive()
        {
            var ipfs = TestFixture.Ipfs;
            var temp = MakeTemp();

            try
            {
                var dir = ipfs.FileSystem.AddDirectoryAsync(temp, true).Result;
                Assert.IsTrue(dir.IsDirectory);

                var files = dir.Links.ToArray();
                Assert.AreEqual(3, files.Length);
                Assert.AreEqual("alpha.txt", files[0].Name);
                Assert.AreEqual("beta.txt", files[1].Name);
                Assert.AreEqual("x", files[2].Name);
                Assert.IsFalse(files[0].IsDirectory);
                Assert.IsFalse(files[1].IsDirectory);
                Assert.IsTrue(files[2].IsDirectory);
                Assert.AreNotEqual(0, files[0].Size);
                Assert.AreNotEqual(0, files[1].Size);

                var xfiles = new FileSystemNode
                {
                    Id         = files[2].Id,
                    IpfsClient = ipfs,
                }.Links.ToArray();
                Assert.AreEqual(2, xfiles.Length);
                Assert.AreEqual("x.txt", xfiles[0].Name);
                Assert.AreEqual("y", xfiles[1].Name);
                Assert.IsFalse(xfiles[0].IsDirectory);
                Assert.IsTrue(xfiles[1].IsDirectory);

                var yfiles = new FileSystemNode
                {
                    Id         = xfiles[1].Id,
                    IpfsClient = ipfs
                }.Links.ToArray();
                Assert.AreEqual(1, yfiles.Length);
                Assert.AreEqual("y.txt", yfiles[0].Name);
                Assert.IsFalse(yfiles[0].IsDirectory);

                var y = new FileSystemNode
                {
                    Id         = yfiles[0].Id,
                    IpfsClient = ipfs
                };
                Assert.AreEqual("y", Encoding.UTF8.GetString(y.DataBytes));
                Assert.AreEqual("y", ipfs.FileSystem.ReadAllTextAsync(dir.Id + "/x/y/y.txt").Result);
            }
            finally
            {
                DeleteTemp(temp);
            }
        }
        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);
        }