public void Save([NotNull] Stream stream, [CanBeNull] ITyresMachineExtras extras) { using (var zip = new ZipArchive(stream, ZipArchiveMode.Create, true)) { Add("Options.json", _options); Add("Input/Sources.json", _tyresSources); Add("Input/LUTs.json", _luts.Select(x => x.Where(y => y.Value != null).ToDictionary(y => y.Key, y => y.Value.ToString()))); Add("Input/Normalizations.json", _inputNormalizations); Add("Output/Keys.json", _outputKeys); Add("Output/Normalizations.json", _outputNormalizations); var manifest = _loadedManifest ?? new JObject(); manifest["version"] = SaveFormatVersion; manifest["tyresVersion"] = TyresVersion; _loadedManifest = manifest; extras?.OnSave(zip, manifest, this); Add("Manifest.json", manifest); if (_networks != null) { for (var i = 0; i < _networks.Length; i++) { var key = _outputKeys[i]; var network = _networks[i]; var networkType = network.GetType().FullName; var data = network.Save(); if (networkType == null || data == null) { continue; } zip.AddString($"Networks/{key}/Type.txt", networkType); zip.AddBytes($"Networks/{key}/Data.bin", data); } } else if (_singleNetwork != null) { var networkType = _singleNetwork.GetType().FullName; var data = _singleNetwork.Save(); if (networkType != null && data != null) { zip.AddString("Network/Type.txt", networkType); zip.AddBytes("Network/Data.bin", data); } } void Add(string key, object data) { zip.AddString(key, JsonConvert.SerializeObject(data, Formatting.Indented)); } } }