private ProtocolJournalBuilder InitializeJournalBuilder()
        {
            var retval = new ProtocolJournalBuilder {
                OutputPath = Parameters.OutputPath
            };

            if (!Directory.Exists(retval.OutputPath))
            {
                throw new FileNotFoundException("Percorso OutputPath non trovato: " + retval.OutputPath);
            }
            FileLogger.Info(Name, "OutputPath: " + retval.OutputPath);

            retval.TemplatePath = Parameters.TemplatePath;
            if (!File.Exists(retval.TemplatePath))
            {
                throw new FileNotFoundException("Percorso TemplatePath non trovato: " + retval.TemplatePath);
            }
            FileLogger.Info(Name, "TemplatePath: " + retval.TemplatePath);

            retval.ApplySign = Parameters.ApplySign;
            FileLogger.Info(Name, "ApplySign: " + retval.ApplySign.ToString());

            retval.ApplyTimeStamp = Parameters.ApplyTimeStamp;
            FileLogger.Info(Name, "ApplyTimeStamp: " + retval.ApplyTimeStamp.ToString());

            FileLogger.Info(Name, "Location: " + Parameters.Location.ToString(CultureInfo.InvariantCulture));
            retval.Location = LocationFacade.GetById(Parameters.Location);
            if (retval.Location == null)
            {
                throw new ArgumentNullException("La location specificata è inesistente.", new Exception());
            }

            retval.ChainObjectDateFormat = Parameters.DateFormat;
            FileLogger.Info(Name, "ChainObjectDateFormat: " + retval.ChainObjectDateFormat);

            // Parametri necessari per la firma.
            if (retval.ApplySign)
            {
                retval.CertificateName = Parameters.CertificateName;
                FileLogger.Info(Name, "CertificateName: " + retval.CertificateName);
            }

            // Parametri necessari per la marcatura temporale.
            if (retval.ApplyTimeStamp)
            {
                retval.InfoCamereFormat = Parameters.InfoCamereFormat;
                FileLogger.Info(Name, "InfoCamereFormat: " + retval.InfoCamereFormat);
            }

            // Imposto il Logger
            retval.LoggerName = Name;

            return(retval);
        }
        /// <summary>
        /// Crea i registri nell'intervallo di date specificato.
        /// </summary>
        /// <param name="pjb">Builder del registro</param>
        /// <param name="start">Data limite inferiore di creazione</param>
        /// <param name="end">Data limite superiore di creazione</param>
        private void CreateJournals(ref ProtocolJournalBuilder pjb, DateTime start, DateTime end)
        {
            if (start.AddDays(-1) == end)
            {
                FileLogger.Info(Name, "Nessuna data da elaborare nell'intervallo indicato.");
                return;
            }

            if (end < start)
            {
                var message = "La data di limite superiore ({0}) è antecedente alla data di limite inferiore ({1}).";
                message = string.Format(message, end, start);
                throw new InvalidOperationException(message);
            }

            for (var date = start; date <= end; date = date.AddDays(1))
            {
                if (Cancel)
                {
                    FileLogger.Info(Name, "Chiusura modulo invocata dall'utente.");
                    return;
                }

                if (!CheckTimeStamps())
                {
                    FileLogger.Info(Name, "Elaborazione Registro annullata per problemi in Verifica Marche Temporali");
                    continue;
                }

                try
                {
                    BuildJournalByDate(ref pjb, date);
                    SendMessage(string.Format("REGISTRO CREATO CORRETTAMENTE ({0:dddd dd/MM/yyyy}) - Protocolli registrati: {1}", date, pjb.Protocols.Count));
                }
                catch (Exception ex)
                {
                    FileLogger.Error(Name, "Errore in createJournals", ex);
                    SendMessage("Errore in createJournals: " + ex);
                }
            }
        }
        /// <summary>
        /// Recupera i registri incompleti e ne tenta la rigenerazione.
        /// </summary>
        /// <param name="pjb">Builder del registro</param>
        /// <param name="start">Data limite inferiore di verifica</param>
        /// <param name="end">Data limite superiore di verifica</param>
        private void RestoreJournals(ref ProtocolJournalBuilder pjb, DateTime start, DateTime end)
        {
            // Recupero i registri la cui creazione è rimasta incompleta.
            var brokenLogs = LogFacade.GetBrokenJournals(start, end);

            if (brokenLogs != null && brokenLogs.Count > 0)
            {
                FileLogger.Info(Name, "Registri giornalieri incompleti da riprocessare: " + brokenLogs.Count.ToString(CultureInfo.InvariantCulture));
                var joined = JournalListToString(brokenLogs);
                FileLogger.Info(Name, "Registri da riprocessare: " + joined);

                foreach (var journal in brokenLogs)
                {
                    if (Cancel)
                    {
                        FileLogger.Info(Name, "Chiusura modulo invocata dall'utente.");
                        return;
                    }

                    if (!CheckTimeStamps())
                    {
                        FileLogger.Info(Name, "Recupero Registro annullato per problemi in Verifica Marche Temporali");
                        continue;
                    }

                    try
                    {
                        // Elimino il registro incompleto per predisporne la rigenerazione.
                        var discarded = journal;
                        if (discarded.IdDocument.HasValue)
                        {
                            Services.Biblos.Service.DetachDocument(discarded.Location.DocumentServer, discarded.Location.ProtBiblosDSDB,
                                                                   discarded.IdDocument.Value);
                        }
                        LogFacade.Delete(ref discarded);
                    }
                    catch (Exception ex)
                    {
                        FileLogger.Error(Name, "Errore in cancellazione registro da ripristinare.", ex);
                        SendMessage("Errore in cancellazione registro da ripristinare: " + ex);
                        return;
                    }

                    try
                    {
                        if (journal.ProtocolJournalDate != null)
                        {
                            BuildJournalByDate(ref pjb, journal.ProtocolJournalDate.Value);
                        }
                    }
                    catch (Exception ex)
                    {
                        FileLogger.Error(Name, "Errore in restoreJournals", ex);
                        SendMessage("Errore in restoreJournals: " + ex);
                    }
                }
            }
            else
            {
                FileLogger.Info(Name, "Nessun registro incompleto da riprocessare.");
            }
        }
        /// <summary>
        /// Crea un registro giornaliero di protocollo per la data specificata.
        /// </summary>
        /// <param name="pjb">Builder del registro</param>
        /// <param name="date">Data di cui creare il registro</param>
        private void BuildJournalByDate(ref ProtocolJournalBuilder pjb, DateTimeOffset date)
        {
            try
            {
                // Elimino dai protocolli per la data di cui creare il registro ogni riferimento a precedenti registri.
                LogFacade.ClearProtocolJournalReferencesByDate(date);
            }
            catch (Exception ex)
            {
                string err = "Errore in fase ripristino registro: ClearProtocolJournalReferencesByDate, " + date.Date.ToShortDateString();
                FileLogger.Error(Name, err);
                throw new Exception(err, ex);
            }

            try
            {
                // Imposto la data
                pjb.Date = date.Date;

                // Verifico se devo annullare protocolli
                if (Parameters.CancelBrokenProtocols)
                {
                    FileLogger.Info(Name, "Verifica protocolli da annullare...");
                    foreach (var protocol in pjb.Protocols.Where(
                                 protocol => protocol.IdStatus.HasValue && (protocol.IdStatus.Value == (int)ProtocolStatusId.Errato) &&
                                 (DateTimeOffset.Now - protocol.RegistrationDate).TotalDays > 0)
                             )
                    {
                        var currentProtocol = protocol;
                        currentProtocol.IdStatus          = (int?)ProtocolStatusId.Annullato;
                        currentProtocol.LastChangedReason = Parameters.CancelBrokenProtocolMessage.Trim();
                        ProtocolFacade.Update(ref currentProtocol);
                        FileLogger.Info(Name, String.Format("Annullato protocollo {0}", protocol));
                    }
                }

                FileLogger.Info(Name, "Creazione registro per la data del: " + date.ToString("dd/MM/yyyy"));
                FileLogger.Info(Name, "Protocolli da registrare: " + pjb.Protocols.Count);

                //FileLogger.Info(Name, "Attributi ChainObject: " + pjb.ChainObjectToString());

                // Costruisco il registro.
                pjb.Build();
                FileLogger.Info(Name, "Creazione registro completata.");
                try
                {
                    FileLogger.Info(Name, "Elimino file temporanei: " + pjb.TempName);
                    // Se va tutto a buon fine elimino i file temporanei.
                    pjb.DiscardTempFiles();
                }
                catch (Exception discardTempFilesEx)
                {
                    // Se si verifica un errore in fase di eliminazione dei file temporanei comunque non dismetto il registro creato correttamente.
                    FileLogger.Info(Name, "Si è verificato un errore in: CreateJournals.DiscardTempFiles");
                    FileLogger.Error(Name, discardTempFilesEx.Message, discardTempFilesEx);
                }
            }
            catch (Exception buildEx)
            {
                SendMessage("Errore in creazione Journal Report per il giorno " + date.Date.ToLongDateString());
                FileLogger.Info(Name, "Si è verificato un errore in: CreateJournals.Build");
                FileLogger.Error(Name, buildEx.Message, buildEx);
                FileLogger.Info(Name, "File temporanei preservati per verifiche: " + pjb.TempName);
                throw new Exception("Errore in creazione Journal Report per il giorno " + date.Date.ToLongDateString());
            }
        }