Esempio n. 1
0
        /// <summary>
        /// Routine for flushing the log file to the correct zip file.
        /// </summary>
        public void FlushLog()
        {
            if (_archiveLog == null)
            {
                return;
            }

            Platform.Log(LogLevel.Info, "Flushing log of {0} for {1}", _logType, _archiveLog.FirstTimestamp.ToLongDateString());

            if (!Directory.Exists(_logDirectory))
            {
                Directory.CreateDirectory(_logDirectory);
            }
            if (!Directory.Exists(_archiveLog.ZipDirectory))
            {
                Directory.CreateDirectory(_archiveLog.ZipDirectory);
            }

            using (ZipFile zip = File.Exists(_archiveLog.ZipFile) ?
                                 ZipFile.Read(_archiveLog.ZipFile) :
                                 new ZipFile(_archiveLog.ZipFile))
            {
                zip.UseZip64WhenSaving = Zip64Option.AsNecessary;

                ZipEntry e = zip.AddFileStream(_archiveLog.LogFileName, string.Empty, _archiveLog.Stream);
                e.Comment =
                    String.Format("Log of {0} from {1} to {2}", _logType, _archiveLog.FirstTimestamp.ToString("yyyy-MM-dd HH:mm:ss.fff"),
                                  _archiveLog.LastTimestamp.ToString("yyyy-MM-dd HH:mm:ss.fff"));

                zip.Save();
            }

            _archiveLog.Dispose();
            _archiveLog = null;
        }
Esempio n. 2
0
        public void SaveToDirectory(string destDirectory, DateTime start, DateTime end)
        {
            if (!Directory.Exists(destDirectory))
            {
                Directory.CreateDirectory(destDirectory);
            }

            while (start <= end)
            {
                using (MemoryStream memStream = new MemoryStream())
                {
                    using (StreamWriter streamWriter = new StreamWriter(memStream))
                    {
                        SaveDayToStream(streamWriter, start);
                        streamWriter.Flush();

                        string fileName    = start.ToString("yyyy.MM.dd");
                        string fileZipPath = Path.Combine(destDirectory, fileName + ".zip");
                        if (File.Exists(fileZipPath))
                        {
                            File.Delete(fileZipPath);
                        }
                        ZipFile zip = new ZipFile(fileZipPath);
                        zip.AddFileStream(fileName + ".csv", "", memStream);
                        zip.Save();
                    }
                }
                start = start.AddDays(1);
            }
        }
Esempio n. 3
0
        /// <summary></summary>
        /// <param name="blobData"></param>
        /// <param name="appNameFileSystem"></param>
        /// <param name="appContentType"></param>
        /// <param name="Base64TokenApplication"></param>
        /// <returns></returns>
        public OperationResult AssembleTokenApplication(Byte[] blobData, out string appContentType, out string Base64TokenApplication)
        {
            appContentType         = null;
            Base64TokenApplication = null;

            try
            {
                using (Stream st = new MemoryStream(blobData))
                {
                    using (ZipFile _zip = ZipFile.Read(_getTemplateFile()))
                    {
                        _zip.RemoveEntry(cBLOBFILEPATH + cBLOBFILENAME);
                        _zip.AddFileStream(cBLOBFILENAME, cBLOBFILEPATH, st);

                        using (MemoryStream _oStream = new MemoryStream())
                        {
                            _zip.Save(_oStream);
                            appContentType         = cCONTENT_TYPE_NAME;
                            Base64TokenApplication = Convert.ToBase64String(_oStream.ToArray());
                            _oStream.Close();
                        }
                    }
                    st.Close();
                }
                return(OperationResult.Success);
            }
            catch
            {
                Base64TokenApplication = null;
                return(OperationResult.Error);
            }
        }
Esempio n. 4
0
        static public void DownloadNewQuotes(string symbols, DateTime from, DateTime to,
                                             bool IsSaveOnlyMinutes)
        {
            foreach (string csymbol in symbols.Split(new char[] { ',' }))
            {
                string symbol = csymbol.Trim();
                using (StreamWriter log = new StreamWriter(symbol + ".log", false))
                {
                    log.WriteLine("Start to download data.");
                    if (!Directory.Exists(symbol))
                    {
                        Directory.CreateDirectory(symbol);
                    }

                    //day
                    DateTime startDate   = from;
                    DateTime endDate     = to;
                    DateTime currentDate = endDate;
                    int      errorCount  = 0;

                    while (currentDate >= startDate)
                    {
                        foreach (int period in new int[] { 0 })
                        {
                            using (MemoryStream memStream = new MemoryStream())
                            {
                                using (StreamWriter streamWriter = new StreamWriter(memStream))
                                {
                                    if (0 == DownloadTicksPerDay(symbol, currentDate, streamWriter, log, period, IsSaveOnlyMinutes))
                                    {
                                        if (++errorCount > 100)
                                        {
                                            currentDate = startDate.AddDays(-1);
                                            break;
                                        }
                                        continue;
                                    }

                                    errorCount = 0;
                                    streamWriter.Flush();

                                    string fileName    = currentDate.ToString("yyyy.MM.dd");
                                    string fileZipPath = symbol + "//" + fileName + ".zip";
                                    if (File.Exists(fileZipPath))
                                    {
                                        File.Delete(fileZipPath);
                                    }
                                    ZipFile zip = new ZipFile(fileZipPath);
                                    zip.AddFileStream(fileName + ".csv", "", memStream);
                                    zip.Save();
                                }
                            }
                        }

                        currentDate = currentDate.AddDays(-1);
                    }
                }
            }
        }
Esempio n. 5
0
 public void Compress(string nameOfFile, byte[] content, string targetFilePath)
 {
     using (MemoryStream memStreamIn = new MemoryStream(content, false))
     {
         using (ZipFile zip = new ZipFile(targetFilePath))
         {
             zip.AddFileStream(nameOfFile, string.Empty, memStreamIn);
             zip.Save();
         }
     }
 }
Esempio n. 6
0
 public void CompressFile(string sourceFilePath, string sourceFileNameInZip, string targetFilePath)
 {
     using (ZipFile zip = new ZipFile(targetFilePath))
     {
         using (FileStream fileStream = File.OpenRead(sourceFilePath))
         {
             if (string.IsNullOrEmpty(sourceFileNameInZip))
             {
                 sourceFileNameInZip = Path.GetFileName(sourceFilePath);
             }
             zip.AddFileStream(sourceFileNameInZip, string.Empty, fileStream);
             zip.Save();
         }
     }
 }
Esempio n. 7
0
 public byte[] Compress(string nameOfFile, byte[] content)
 {
     using (MemoryStream memStreamOut = new MemoryStream())
     {
         using (MemoryStream memStreamIn = new MemoryStream(content, false))
         {
             using (ZipFile zip = new ZipFile(memStreamOut))
             {
                 zip.AddFileStream(nameOfFile, string.Empty, memStreamIn);
                 zip.Save();
             }
         }
         memStreamOut.Flush();
         return(memStreamOut.ToArray());  // Only return the first file
     }
 }
Esempio n. 8
0
        public void ProcessRequest(HttpContext context)
        {
            try
            {
                var nomeArquivo = "Arquivo Intermac " + DateTime.Now.ToString("dd/MM/yyyy hh:mm");

                var lstArqMesa  = new List <byte[]>();                            // Arquivos para mesa de corte
                var lstCodArq   = new List <string>();                            // Código dos arquivos para mesa de corte
                var lstErrosArq = new List <KeyValuePair <string, Exception> >(); // Erros ao gerar os arquivos

                //Busca os produtos do pedido espelho
                var lstProdPedEsp = ProdutosPedidoEspelhoDAO.Instance.GetForRpt(Glass.Conversoes.StrParaUint(context.Request["idPedido"]),
                                                                                Glass.Conversoes.StrParaUint(context.Request["idCliente"]), context.Request["NomeCliente"],
                                                                                Glass.Conversoes.StrParaUint(context.Request["idLoja"]), Glass.Conversoes.StrParaUint(context.Request["idFunc"]),
                                                                                Glass.Conversoes.StrParaUint(context.Request["idFuncionarioConferente"]), Glass.Conversoes.StrParaInt(context.Request["situacao"]),
                                                                                context.Request["situacaoPedOri"], context.Request["idsProcesso"], context.Request["dataIniEnt"], context.Request["dataFimEnt"],
                                                                                context.Request["dataIniFab"], context.Request["dataFimFab"], context.Request["dataIniFin"], context.Request["dataFimFin"],
                                                                                context.Request["dataIniConf"], context.Request["dataFimConf"], false, context.Request["pedidosSemAnexos"] == "true",
                                                                                context.Request["pedidosAComprar"] == "true", context.Request["pedidos"], context.Request["situacaoCnc"],
                                                                                context.Request["dataIniSituacaoCnc"], context.Request["dataFimSituacaoCnc"], context.Request["tipoPedido"], context.Request["idsRotas"],
                                                                                Glass.Conversoes.StrParaInt(context.Request["origemPedido"]), Conversoes.StrParaInt(context.Request["pedidosConferidos"]), Conversoes.StrParaInt(context.Request["tipoVenda"]));

                var lstEtiqueta = EtiquetaDAO.Instance.EtiquetasGerarDxf(null, lstProdPedEsp);

                if (lstEtiqueta.Count == 0)
                {
                    throw new Exception("Nenhum pedido filtrado possui arquivo Intermac para ser gerado.");
                }

                ImpressaoEtiquetaDAO.Instance.MontaArquivoMesaOptyway(null, lstEtiqueta, lstArqMesa, lstCodArq, lstErrosArq, 0, false, (int)TipoArquivoMesaCorte.DXF, false, true, true);

                if (!lstArqMesa.Any() && !lstErrosArq.Any())
                {
                    var mensagem = "O pedido não possui projetos com arquivos para execução na máquina.";
                    context.Response.Write(string.Format("<script>alert(\"{0}\"); window.close();</script>", mensagem));
                    context.Response.Flush();
                    return;
                }

                // Adiciona o arquivo de otimização ao zip
                context.Response.ContentType = "application/zip";
                context.Response.AddHeader("content-disposition", "attachment; filename=\"" + nomeArquivo + ".zip\"");

                // Adiciona os arquivos
                using (ZipFile zip = new ZipFile(context.Response.OutputStream))
                {
                    for (var i = 0; i < lstArqMesa.Count; i++)
                    {
                        if (Glass.Data.Helper.Utils.VerificarArquivoZip(lstArqMesa[i]))
                        {
                            using (var zip2 = ZipFile.Read(lstArqMesa[i]))
                            {
                                foreach (var entryFileName in zip2.EntryFilenames)
                                {
                                    var entryStream = new System.IO.MemoryStream();
                                    zip2.Extract(entryFileName, entryStream);
                                    entryStream.Position = 0;

                                    var fileName  = System.IO.Path.GetFileName(entryFileName);
                                    var extension = System.IO.Path.GetExtension(fileName)?.ToLower();
                                    if (extension == ".cni" || extension == ".xml")
                                    {
                                        fileName = System.IO.Path.GetFileNameWithoutExtension(lstCodArq[i].Trim()) + extension;
                                    }

                                    zip.AddFileStream(fileName, System.IO.Path.GetDirectoryName(entryFileName), entryStream);
                                }
                            }
                        }
                        else
                        {
                            zip.AddFileStream(lstCodArq[i].Replace("  ", "").Replace(" ", ""), "", new System.IO.MemoryStream(lstArqMesa[i]));
                        }
                    }

                    // Verifica se existe algum erro tratado no momento da geração do arquivo.
                    if (lstErrosArq.Any(f => f.Value != null))
                    {
                        // Monta um texto com todos os problemas ocorridos ao gerar o arquivo de mesa, ao final do método, o texto é salvo em um arquivo separado e é zipado junto com o ASC.
                        var errosGeracaoMarcacao = string.Format("Situações com arquivos de mesa: </br></br>{0}",
                                                                 string.Join("</br>", lstErrosArq.Where(f => f.Value != null).Select(f => string.Format("Etiqueta: {0} Erro: {1}.", f.Key, Glass.MensagemAlerta.FormatErrorMsg(null, f.Value)))));

                        if (!string.IsNullOrEmpty(errosGeracaoMarcacao))
                        {
                            zip.AddStringAsFile(errosGeracaoMarcacao, "Erros.htm", string.Empty);
                        }
                    }

                    zip.Save();
                }
            }
            catch (Exception ex)
            {
                // Devolve o erro
                context.Response.ContentType = "text/html";
                context.Response.Write(GetErrorResponse(ex));
                context.Response.Write("<script>window.close();</script>");
            }
        }
Esempio n. 9
0
        public void ProcessRequest(HttpContext context)
        {
            try
            {
                var nomeArquivo = "Arquivo DXF " + DateTime.Now.ToString("dd/MM/yyyy hh:mm");

                var lstArqMesa           = new List <byte[]>();                            // Arquivos para mesa de corte
                var lstCodArq            = new List <string>();                            // Código dos arquivos para mesa de corte
                var lstErrosArq          = new List <KeyValuePair <string, Exception> >(); // Erros ao gerar os arquivos
                var errosGeracaoMarcacao = string.Empty;

                //Busca os produtos do pedido espelho
                var lstProdPedEsp = ProdutosPedidoEspelhoDAO.Instance.GetForRpt(Glass.Conversoes.StrParaUint(context.Request["idPedido"]),
                                                                                Glass.Conversoes.StrParaUint(context.Request["idCliente"]), context.Request["NomeCliente"],
                                                                                Glass.Conversoes.StrParaUint(context.Request["idLoja"]), Glass.Conversoes.StrParaUint(context.Request["idFunc"]),
                                                                                Glass.Conversoes.StrParaUint(context.Request["idFuncionarioConferente"]), Glass.Conversoes.StrParaInt(context.Request["situacao"]),
                                                                                context.Request["situacaoPedOri"], context.Request["idsProcesso"], context.Request["dataIniEnt"], context.Request["dataFimEnt"],
                                                                                context.Request["dataIniFab"], context.Request["dataFimFab"], context.Request["dataIniFin"], context.Request["dataFimFin"],
                                                                                context.Request["dataIniConf"], context.Request["dataFimConf"], false, context.Request["pedidosSemAnexos"] == "true",
                                                                                context.Request["pedidosAComprar"] == "true", context.Request["pedidos"], context.Request["situacaoCnc"],
                                                                                context.Request["dataIniSituacaoCnc"], context.Request["dataFimSituacaoCnc"], context.Request["tipoPedido"], context.Request["idsRotas"],
                                                                                Glass.Conversoes.StrParaInt(context.Request["origemPedido"]), Conversoes.StrParaInt(context.Request["pedidosConferidos"]), Conversoes.StrParaInt(context.Request["tipoVenda"]));

                var lstEtiqueta = EtiquetaDAO.Instance.EtiquetasGerarDxf(null, lstProdPedEsp);

                if (lstEtiqueta.Count == 0)
                {
                    throw new Exception("Nenhum pedido filtrado possui arquivo DXF para ser gerado.");
                }

                ImpressaoEtiquetaDAO.Instance.MontaArquivoMesaOptyway(null, lstEtiqueta, lstArqMesa, lstCodArq, lstErrosArq, 0, false, (int)TipoArquivoMesaCorte.DXF, false, false, false);

                if (!lstArqMesa.Any() && !lstErrosArq.Any())
                {
                    var mensagem = "O pedido não possui projetos com arquivos para execução na máquina.";
                    context.Response.Write(string.Format("<script>alert(\"{0}\"); window.close();</script>", mensagem));
                    context.Response.Flush();
                    return;
                }

                if (lstErrosArq.Any())
                {
                    var erros = string.Join("</br>", lstErrosArq.Where(f => !string.IsNullOrWhiteSpace(f.Key))
                                            .Select(f => string.Format("Etiqueta: {0} Erro: {1}.", f.Key, Glass.MensagemAlerta.FormatErrorMsg(null, f.Value))));

                    context.Response.Write(string.Format("Situações com arquivos de mesa: </br></br>{0}", erros));
                    context.Response.Flush();
                    return;
                }

                // Adiciona o arquivo de otimização ao zip
                context.Response.ContentType = "application/zip";
                context.Response.AddHeader("content-disposition", "attachment; filename=\"" + nomeArquivo + ".zip\"");

                // Adiciona os arquivos DXF
                using (ZipFile zip = new ZipFile(context.Response.OutputStream))
                {
                    for (var i = 0; i < lstArqMesa.Count; i++)
                    {
                        zip.AddFileStream(lstCodArq[i].Replace("  ", string.Empty).Replace(" ", string.Empty).Replace('ç', Convert.ToChar(135)), string.Empty, new System.IO.MemoryStream(lstArqMesa[i]));
                    }

                    if (!string.IsNullOrEmpty(errosGeracaoMarcacao))
                    {
                        zip.AddStringAsFile(errosGeracaoMarcacao, "Situações com arquivos de mesa.error", string.Empty);
                    }

                    zip.Save();
                }
            }
            catch (Exception ex)
            {
                // Devolve o erro
                context.Response.ContentType = "text/html";
                context.Response.Write(GetErrorResponse(ex));
                context.Response.Write("<script>window.close();</script>");
            }
        }
Esempio n. 10
0
        private void SaveImpl(String fileName, bool rebuildZipEntries)
        {
            using (ExposeReadOnly())
            {
                var newzip = new ZipFile()
                {
                    Encoding = Encoding.UTF8
                };

                // bug. here we face a potential tho very unprobable sync problem
                // if we've imported some nodes from another vault and are now unbinding them
                // it's possible that the vault will right now undergo certain changes that
                // won't be propagated to the nodes we've just unbound
                Root.GetValuesRecursive(ValueKind.RegularAndInternal).ForEach(Bind);
                Root.GetBranchesRecursive().ForEach(Bind);

                // mapping between values/branches and entries in the new file
                var newZeIndex = new Dictionary <IElement, String>();

                // save all values -> this will also automatically create corresponding branches
                foreach (Value value in Root.GetValuesRecursive(ValueKind.RegularAndInternal))
                {
                    var contentStream = value.ContentStream.FixupForBeingSaved();
                    var valueZe       = newzip.AddFileStream(value.Name, value.VPath.Parent.ToZipPathDir(), contentStream);
                    newZeIndex.Add(value, valueZe.FileName);

                    if (value.Metadata.Raw != null)
                    {
                        newzip.AddFileStream(value.Name + "$", value.VPath.Parent.ToZipPathDir(), value.Metadata.Raw.AsStream());
                    }
                }

                // despite of the previous step having created the branches,
                // we still need to explicitly add them in order to store the metadata
                foreach (Branch branch in Root.GetBranchesRecursive())
                {
                    var branchZe = newzip.AddDirectoryByName(branch.VPath.ToZipPathDir());
                    newZeIndex.Add(branch, branchZe.FileName);

                    if (branch.Metadata.Raw != null)
                    {
                        newzip.AddFileStream("$", branch.VPath.ToZipPathDir(), branch.Metadata.Raw.AsStream());
                    }
                }

                // root metadata requires special treatment since root doesn't get enumerated
                if (Root.Metadata.Raw.IsNeitherNullNorEmpty())
                {
                    newzip.AddFileStream("$", String.Empty.ToZipPathDir(), Root.Metadata.Raw.AsStream());
                }

                if (rebuildZipEntries)
                {
                    GC.Collect(); // is this really necessary here?
                    var deletedButStillAlive = BoundElements.Select(wr => wr.IsAlive ? (IElement)wr.Target : null)
                                               .Where(el => el != null)
                                               .Except(Root.GetValuesRecursive(ValueKind.RegularAndInternal).Cast <IElement>())
                                               .Except(Root.GetBranchesRecursive().Cast <IElement>())
                                               .Except(Root.MkArray())
                                               .Distinct();

                    // fixup metadata/content streams of deleted and not yet gcollected nodes
                    Action <Action> neverFail = a => { try { a(); } catch { /* just ignore */ } };
                    deletedButStillAlive.ForEach(el => neverFail(() => el.CacheInMemory()));

                    // only now can we dispose the previous zip instance
                    // previously it was necessary to extract streams we're going to repack
                    if (Zip != null)
                    {
                        Zip.Dispose();
                    }

                    Zip = newzip;
                    newzip.Save(fileName);

                    // fixup content/metadata streams to reference the new file/vpaths
                    var opt = Zip.Entries.ToDictionary(ze => ze.FileName, ze => ze);
                    foreach (Value value in Root.GetValuesRecursive(ValueKind.RegularAndInternal))
                    {
                        var contentFile  = newZeIndex[value];
                        var metadataFile = contentFile + "$";

                        value.SetContent(() => opt[contentFile].ExtractEager());
                        value.RawSetMetadata(() => opt.GetOrDefault(metadataFile).ExtractEager());
                    }

                    foreach (Branch branch in Root.GetBranchesRecursive())
                    {
                        var metadataFile = newZeIndex[branch] + "$";
                        branch.RawSetMetadata(() => opt.GetOrDefault(metadataFile).ExtractEager());
                    }

                    // root metadata requires special treatment since root doesn't get enumerated
                    Root.RawSetMetadata(() => (opt.GetOrDefault("/$") ?? opt.GetOrDefault("$")).ExtractEager());

                    // set the changes in stone
                    Root.AfterSave();
                    Root.GetBranchesRecursive().Cast <Branch>().ForEach(b => b.AfterSave());
                    Root.GetValuesRecursive(ValueKind.RegularAndInternal).Cast <Value>().ForEach(v => v.AfterSave());
                }
                else
                {
                    if (Uri == fileName)
                    {
                        throw new InvalidOperationException("Saving vault into its source file requires rebuilding ZIP entries.");
                    }
                    else
                    {
                        newzip.Save(fileName);
                        newzip.Dispose();
                    }
                }
            }
        }
Esempio n. 11
0
        public static FileContentResult GenerarArchivos(Reunion reunion, string itemsToExport)
        {
            string       fileName        = string.Format("DatosIBVD_{0}.zip", DateTime.Now.ToString("dd-MM-yyyy"));
            string       fileContentType = "application/octet-stream";
            var          listaCanciones  = reunion.ItemsReunion.Where(m => m.GetTipo() == TipoItemReunion.CANCION).Select(m => (Cancion)m).ToList();
            MemoryStream output          = new MemoryStream();

            Ionic.Zip.ZipFile fileZip = new ZipFile();

            Dictionary <string, MemoryStream> files = new Dictionary <string, MemoryStream>();

            if (itemsToExport.Contains("ExportarCancionesXML"))
            {
                MemoryStream fileXmlCanciones = new MemoryStream();
                var          xmlDocument      = XMLGenerator.GenerarXmlCancionesExport(listaCanciones);
                xmlDocument.Save(fileXmlCanciones);
                files.Add(string.Format("ExportCanciones_{0}.xml", DateTime.Now.ToString("dd-MM-yyyy")), fileXmlCanciones);

                fileContentType = "application/xml";
            }

            if (itemsToExport.Contains("ExportarReunionPDF"))
            {
                MemoryStream filePdfReunion = new MemoryStream();
                var          pdfDocument    = PDFGenerator.GenerarReunion(reunion);
                pdfDocument.Save(filePdfReunion, false);
                files.Add(string.Format("Planilla_Reunion_{0}.pdf", reunion.Id), filePdfReunion);
                fileContentType = "application/pdf";
            }

            if (itemsToExport.Contains("ExportarItemsPDF"))
            {
                MemoryStream filePdfCanciones = new MemoryStream();
                var          pdfCanciones     = PDFGenerator.GenerarItems(reunion.ItemsReunion, true);
                pdfCanciones.Save(filePdfCanciones, false);
                files.Add(string.Format("Reunion_{0}_Items.pdf", reunion.Id), filePdfCanciones);
                fileContentType = "application/pdf";
            }

            if (itemsToExport.Contains("ExportarCancionesPDF"))
            {
                MemoryStream filePdfCanciones = new MemoryStream();
                var          pdfCanciones     = PDFGenerator.GenerarCanciones(listaCanciones, true);
                pdfCanciones.Save(filePdfCanciones, false);
                files.Add(string.Format("Reunion_{0}_Canciones.pdf", reunion.Id), filePdfCanciones);
                fileContentType = "application/pdf";
            }


            foreach (var item in files)
            {
                fileZip.AddFileStream(item.Key, string.Empty, item.Value);
                fileContentType = "application/octet-stream";
            }

            if (files.Count > 1)
            {
                fileZip.Save(output);
            }
            else
            {
                var archivo = files.First();
                output   = archivo.Value;
                fileName = archivo.Key;
            }
            FileContentResult file = new FileContentResult(output.ToArray(), fileContentType);

            file.FileDownloadName = fileName;
            return(file);
        }
Esempio n. 12
0
        private void SaveImpl(String fileName, bool rebuildZipEntries)
        {
            using (ExposeReadOnly())
            {
                var newzip = new ZipFile(){Encoding = Encoding.UTF8};

                // bug. here we face a potential tho very unprobable sync problem
                // if we've imported some nodes from another vault and are now unbinding them
                // it's possible that the vault will right now undergo certain changes that
                // won't be propagated to the nodes we've just unbound
                Root.GetValuesRecursive(ValueKind.RegularAndInternal).ForEach(Bind);
                Root.GetBranchesRecursive().ForEach(Bind);

                // mapping between values/branches and entries in the new file
                var newZeIndex = new Dictionary<IElement, String>();

                // save all values -> this will also automatically create corresponding branches
                foreach (Value value in Root.GetValuesRecursive(ValueKind.RegularAndInternal))
                {
                    var contentStream = value.ContentStream.FixupForBeingSaved();
                    var valueZe = newzip.AddFileStream(value.Name, value.VPath.Parent.ToZipPathDir(), contentStream);
                    newZeIndex.Add(value, valueZe.FileName);

                    if (value.Metadata.Raw != null)
                        newzip.AddFileStream(value.Name + "$", value.VPath.Parent.ToZipPathDir(), value.Metadata.Raw.AsStream());
                }

                // despite of the previous step having created the branches, 
                // we still need to explicitly add them in order to store the metadata
                foreach(Branch branch in Root.GetBranchesRecursive())
                {
                    var branchZe = newzip.AddDirectoryByName(branch.VPath.ToZipPathDir());
                    newZeIndex.Add(branch, branchZe.FileName);

                    if (branch.Metadata.Raw != null)
                        newzip.AddFileStream("$", branch.VPath.ToZipPathDir(), branch.Metadata.Raw.AsStream());
                }

                // root metadata requires special treatment since root doesn't get enumerated
                if (Root.Metadata.Raw.IsNeitherNullNorEmpty())
                    newzip.AddFileStream("$", String.Empty.ToZipPathDir(), Root.Metadata.Raw.AsStream());

                if (rebuildZipEntries)
                {
                    GC.Collect(); // is this really necessary here?
                    var deletedButStillAlive = BoundElements.Select(wr => wr.IsAlive ? (IElement)wr.Target : null)
                        .Where(el => el != null)
                        .Except(Root.GetValuesRecursive(ValueKind.RegularAndInternal).Cast<IElement>())
                        .Except(Root.GetBranchesRecursive().Cast<IElement>())
                        .Except(Root.MkArray())
                        .Distinct();

                    // fixup metadata/content streams of deleted and not yet gcollected nodes
                    Action<Action> neverFail = a => { try { a(); } catch { /* just ignore */ } };
                    deletedButStillAlive.ForEach(el => neverFail(() => el.CacheInMemory()));

                    // only now can we dispose the previous zip instance
                    // previously it was necessary to extract streams we're going to repack
                    if (Zip != null)
                    {
                        Zip.Dispose();
                    }

                    Zip = newzip;
                    newzip.Save(fileName);

                    // fixup content/metadata streams to reference the new file/vpaths
                    var opt = Zip.Entries.ToDictionary(ze => ze.FileName, ze => ze);
                    foreach (Value value in Root.GetValuesRecursive(ValueKind.RegularAndInternal))
                    {
                        var contentFile = newZeIndex[value];
                        var metadataFile = contentFile + "$";

                        value.SetContent(() => opt[contentFile].ExtractEager());
                        value.RawSetMetadata(() => opt.GetOrDefault(metadataFile).ExtractEager());
                    }

                    foreach (Branch branch in Root.GetBranchesRecursive())
                    {
                        var metadataFile = newZeIndex[branch] + "$";
                        branch.RawSetMetadata(() => opt.GetOrDefault(metadataFile).ExtractEager());
                    }

                    // root metadata requires special treatment since root doesn't get enumerated
                    Root.RawSetMetadata(() => (opt.GetOrDefault("/$") ?? opt.GetOrDefault("$")).ExtractEager());

                    // set the changes in stone
                    Root.AfterSave();
                    Root.GetBranchesRecursive().Cast<Branch>().ForEach(b => b.AfterSave());
                    Root.GetValuesRecursive(ValueKind.RegularAndInternal).Cast<Value>().ForEach(v => v.AfterSave());
                }
                else
                {
                    if (Uri == fileName)
                    {
                        throw new InvalidOperationException("Saving vault into its source file requires rebuilding ZIP entries.");
                    }
                    else
                    {
                        newzip.Save(fileName);
                        newzip.Dispose();
                    }
                }
            }
        }