/// <summary>
        /// Submits the changes the user has made to inputs and outputs on the Parameter sheet to the data-source.
        /// </summary>
        /// <param name="session">
        /// The current <see cref="ISession"/> that is submitting the outputs.
        /// </param>
        /// <param name="iteration">
        /// The <see cref="Iteration"/> that that contains the value sets that value-sets that if changed need to be submitted.
        /// </param>
        public async Task SubmitAll(ISession session, Iteration iteration)
        {
            this.application.StatusBar = string.Empty;

            var workbookSession = await this.CreateWorkbookSession(session.Dal, session.Credentials);

            try
            {
                IReadOnlyDictionary <Guid, ProcessedValueSet> processedValueSets;
                var parameterSheetProcessor = new ParameterSheetProcessor(workbookSession, iteration);
                parameterSheetProcessor.ValidateValuesAndCheckForChanges(this.application, this.workbook, out processedValueSets);

                if (!processedValueSets.Any())
                {
                    this.application.StatusBar = "Submit cancelled: no values changed";
                    return;
                }

                var submitConfirmationViewModel = new SubmitConfirmationViewModel(processedValueSets, ValueSetKind.All);
                var dialogResult = this.DialogNavigationService.NavigateModal(submitConfirmationViewModel);

                if (dialogResult.Result.HasValue && dialogResult.Result.Value)
                {
                    var submitConfirmationDialogResult = (SubmitConfirmationDialogResult)dialogResult;

                    var context     = TransactionContextResolver.ResolveContext(iteration);
                    var transaction = new ThingTransaction(context);

                    foreach (var clone in submitConfirmationDialogResult.Clones)
                    {
                        transaction.CreateOrUpdate(clone);
                    }

                    // TODO: enable when OperationContainer.ResolveRoute supports this
                    //var clonedEngineeringModel = (EngineeringModel)iteration.Container.Clone();
                    //var logEntry = new ModelLogEntry(iid: Guid.NewGuid())
                    //                   {
                    //                       Content = submitConfirmationDialogResult.SubmitMessage,
                    //                       Author = session.ActivePerson,
                    //                       LanguageCode = "en-GB",
                    //                       Level = LogLevelKind.USER,
                    //                       AffectedItemIid = submitConfirmationDialogResult.Clones.Select(clone => clone.Iid).ToList()
                    //                   };
                    //clonedEngineeringModel.LogEntry.Add(logEntry);
                    //transaction.Create(logEntry);

                    var operationContainer = transaction.FinalizeTransaction();

                    this.application.StatusBar = string.Format("CDP4: Submitting data to {0}", session.DataSourceUri);
                    this.application.Cursor    = XlMousePointer.xlWait;

                    var sw = new Stopwatch();
                    sw.Start();
                    await session.Write(operationContainer);

                    sw.Stop();
                    this.application.StatusBar = string.Format("CDP4: SitedirectoryData submitted in {0} [ms]", sw.ElapsedMilliseconds);

                    this.application.StatusBar = "CDP4: Writing session data to workbook";
                    sw.Start();
                    this.WriteWorkbookDataToWorkbook(iteration);
                    sw.Stop();
                    this.application.StatusBar = string.Format("CDP4: Session data written in {0} [ms]", sw.ElapsedMilliseconds);
                }
                else
                {
                    this.application.StatusBar = "CDP4: Submit parameters and subscription has been cancelled by the user.";

                    var parameterSheetRowHighligter = new ParameterSheetRowHighligter();
                    parameterSheetRowHighligter.HighlightRows(this.application, this.workbook, processedValueSets);
                }
            }
            catch (Exception ex)
            {
                this.application.StatusBar = "CDP4: submission failed.";
                Logger.Error(ex);
            }
            finally
            {
                this.application.Cursor = XlMousePointer.xlDefault;
            }
        }
        /// <summary>
        /// Rebuild the Parameter Sheet
        /// </summary>
        /// <param name="session">
        /// The current <see cref="ISession"/> that is rebuilding the parameter sheet
        /// </param>
        /// <param name="iteration">
        /// The <see cref="Iteration"/> that contains the <see cref="ElementDefinition"/>s, <see cref="ElementUsage"/>s and <see cref="Parameter"/>s that
        /// are being written to the workbook
        /// </param>
        /// <param name="participant">
        /// The active <see cref="Participant"/> for which the workbook is being rebuilt.
        /// </param>
        public async Task Rebuild(ISession session, Iteration iteration, Participant participant)
        {
            this.application.StatusBar = string.Empty;

            var workbookSession = await this.CreateWorkbookSession(session.Dal, session.Credentials);

            try
            {
                var sw = new Stopwatch();
                sw.Start();

                IReadOnlyDictionary <Guid, ProcessedValueSet> processedValueSets;

                var parameterSheetProcessor = new ParameterSheetProcessor(workbookSession, iteration);
                parameterSheetProcessor.ValidateValuesAndCheckForChanges(this.application, this.workbook, out processedValueSets);

                if (processedValueSets.Any())
                {
                    var workbookRebuildViewModel = new WorkbookRebuildViewModel(processedValueSets, ValueSetKind.All);
                    var dialogResult             = this.DialogNavigationService.NavigateModal(workbookRebuildViewModel);

                    if (dialogResult.Result.HasValue && dialogResult.Result.Value)
                    {
                        var rebuildKind = ((WorkbookRebuildDialogResult)dialogResult).RebuildKind;
                        switch (rebuildKind)
                        {
                        case RebuildKind.Overwrite:
                            processedValueSets = new Dictionary <Guid, ProcessedValueSet>();
                            break;

                        case RebuildKind.RestoreChanges:
                            // keep clones
                            break;
                        }
                    }
                    else
                    {
                        var parameterSheetRowHighligter = new ParameterSheetRowHighligter();
                        parameterSheetRowHighligter.HighlightRows(this.application, this.workbook, processedValueSets);

                        this.application.StatusBar = "Rebuild Parameter sheet has been cancelled";
                        return;
                    }
                }

                await this.RefreshSessionData(session);

                this.WriteParameterSheet(session, iteration, participant, processedValueSets);
                this.WriteOptionSheets(session, iteration, participant);

                this.WriteSessionInfoToWorkbook(session, iteration, participant);
                this.WriteWorkbookDataToWorkbook(iteration);

                this.ActivateParametersSheet();

                this.application.StatusBar = string.Format("Rebuild Parameter completed in [{0}] ms", sw.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                this.application.StatusBar = "Rebuild Parameter sheet failed";
                Logger.Error(ex);
            }
            finally
            {
                this.application.Cursor = XlMousePointer.xlDefault;
            }
        }