/// <summary>
 /// Creates the packages for prepared data.
 /// </summary>
 /// <param name="rootContext">The root context.</param>
 private void createPackages(SaveProtocolParams rootContext)
 {
     if (rootContext.Worker.CancellationPending) return;
     removeEmptySessions();
     var i = 0;
     foreach (var sessionList in BuildSessionInfo.PacketTargets.Values)
     {
         rootContext.Worker.ReportPercent((double)i++ / (double)BuildSessionInfo.PacketTargets.Values.Count());
         if (rootContext.Worker.CancellationPending) break;
         foreach (var saveSessionInfo in sessionList)
         {
             if (rootContext.Worker.CancellationPending) break;
             var sessionParams = new SaveProtocolSessionParams(rootContext, saveSessionInfo.ProtocolSession);
             foreach (var protocolRecord in saveSessionInfo.ProtocolRecords)
             {
                 if (rootContext.Worker.CancellationPending) break;
                 var recordParams = new SaveProtocolRecordParams(sessionParams, protocolRecord);
                 createPackageRecord(recordParams, saveSessionInfo.TargetNode);
             }
         }
     }
     BuildSessionInfo.PacketTargets.Clear();
 }
        /// <summary>
        /// Create and save packages for pending records.
        /// </summary>
        /// <param name="worker">The worker.</param>
        /// <returns></returns>
        public bool BuildPackages(ActionWorker worker)
        {
            bool result;
            worker.ReportProgress(Localizer.BuildingPackages);

            using (var applicationObjectSpace = XafDeltaModule.XafApp.CreateObjectSpace())
            {
                Owner.DoBeforeBuildPackages(new BeforeBuildPackagesArgs(applicationObjectSpace));

                try
                {
                    var unsavedSessions =
                        applicationObjectSpace.GetObjects<ProtocolSession>(CriteriaOperator.Parse("Not SessionIsSaved"));

                    // select session (don't replicate external sessions for broadcasts)
                    var sessionsToSave = (from c in unsavedSessions where !(c is ExternalProtocolSession)
                                              || (Owner.ReplicateExternalData
                                              && Owner.RoutingType != RoutingType.BroadcastRouting)
                                          orderby c.CommitedOn select c).ToList();

                    var rootContext = new SaveProtocolParams(worker, applicationObjectSpace,
                                                              new Dictionary<ReplicationNode, PackageSaveInfo>(),
                                                              applicationObjectSpace.GetObjects<ReplicationNode>(),
                                                              ReplicationNode.GetCurrentNode(applicationObjectSpace));

                    prepareDataForSave(rootContext, sessionsToSave);
                    createPackages(rootContext);

                    // close created packages
                    rootContext.CreatedPackages.Values.ToList().ForEach(x => x.Package.CloseUnitOfWork(true));

                    result = !worker.CancellationPending;

                    if(result)
                        Owner.DoAfterBuildPackages(new AfterBuildPackagesArgs(from c in
                            rootContext.CreatedPackages.Values select c.Package));

                }
                catch (Exception exception)
                {
                    worker.ReportError(
                        Localizer.PackageSaveFailed, exception.Message);
                    result = false;
                }

                // on success, commit changes to app database and package storage
                if (result)
                    applicationObjectSpace.CommitChanges();
            }

            if (result)
                worker.ReportProgress(Color.Blue, Localizer.PackageSavingIs,
                                                  (worker.CancellationPending ? Localizer.Aborted : Localizer.Finished));

            return result;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SaveProtocolRecordParams"/> class.
 /// </summary>
 /// <param name="baseParams">The base params.</param>
 protected SaveProtocolParams(SaveProtocolParams baseParams)
     : this(baseParams.Worker, baseParams.ObjectSpace, 
     baseParams.CreatedPackages, baseParams.AllNodes, 
     baseParams.CurrentNode)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SaveProtocolSessionParams"/> class.
 /// </summary>
 /// <param name="baseParams">The base params.</param>
 /// <param name="protocolSession">The protocol session.</param>
 public SaveProtocolSessionParams(SaveProtocolParams baseParams, ProtocolSession protocolSession)
     : base(baseParams)
 {
     ProtocolSession = protocolSession;
 }
 /// <summary>
 /// Prepares the data for save.
 /// </summary>
 /// <param name="rootContext">The root context.</param>
 /// <param name="sessionsToSave">The sessions to save.</param>
 private void prepareDataForSave(SaveProtocolParams rootContext, IEnumerable<ProtocolSession> sessionsToSave)
 {
     BuildSessionInfo.PacketTargets.Clear();
     var i = 0;
     // for each unsaved session route data
     foreach (var protocolSession in sessionsToSave.TakeWhile(x => !rootContext.Worker.CancellationPending))
     {
         rootContext.Worker.ReportPercent((double)i++ / (double)sessionsToSave.Count());
         routeProtocolSession(new SaveProtocolSessionParams(rootContext, protocolSession));
     }
 }