/// <summary>
        /// Allow the API user to update the copyright information with custom data
        /// </summary>
        /// <param name="person">The <see cref="CDP4Common.SiteDirectoryData.Person"/> that is used to create the <see cref="ExchangeFileHeader"/></param>
        /// <param name="headerCopyright">Header copyright text</param>
        /// <param name="headerRemark">Header remark text</param>
        public void UpdateExchangeFileHeader(CDP4Common.SiteDirectoryData.Person person, string headerCopyright = null, string headerRemark = null)
        {
            var exchangeFileHeader = JsonFileDalUtils.CreateExchangeFileHeader(person);

            exchangeFileHeader.Remark    = headerRemark ?? exchangeFileHeader.Remark;
            exchangeFileHeader.Copyright = headerCopyright ?? exchangeFileHeader.Copyright;

            this.FileHeader = exchangeFileHeader;
        }
        /// <summary>
        /// Write all the <see cref="Operation"/>s from all the <see cref="OperationContainer"/>s asynchronously.
        /// </summary>
        /// <param name="operationContainers">
        /// The provided <see cref="OperationContainer"/> to write
        /// </param>
        /// <param name="extensionFiles">
        /// The path to the files that need to be uploaded. If <paramref name="extensionFiles"/> is null, then no files are to be uploaded
        /// </param>
        /// <returns>
        /// A list of <see cref="Thing"/>s that has been created or updated since the last Read or Write operation.
        /// </returns>
        public override Task <IEnumerable <Thing> > Write(IEnumerable <OperationContainer> operationContainers, IEnumerable <string> extensionFiles = null)
        {
            this.ValidateOperationContainers(operationContainers);

            CDP4Common.SiteDirectoryData.SiteDirectory siteDirectory = null;
            var iterations = new HashSet <CDP4Common.EngineeringModelData.Iteration>();
            var siteReferenceDataLibraries  = new HashSet <CDP4Common.SiteDirectoryData.SiteReferenceDataLibrary>();
            var modelReferenceDataLibraries = new HashSet <CDP4Common.SiteDirectoryData.ModelReferenceDataLibrary>();
            var domainOfExpertises          = new HashSet <CDP4Common.SiteDirectoryData.DomainOfExpertise>();
            var persons                = new HashSet <CDP4Common.SiteDirectoryData.Person>();
            var personRoles            = new HashSet <CDP4Common.SiteDirectoryData.PersonRole>();
            var participantRoles       = new HashSet <CDP4Common.SiteDirectoryData.ParticipantRole>();
            var organizations          = new HashSet <CDP4Common.SiteDirectoryData.Organization>();
            var engineeringModelSetups = new HashSet <CDP4Common.SiteDirectoryData.EngineeringModelSetup>();
            var iterationSetups        = new HashSet <CDP4Common.SiteDirectoryData.IterationSetup>();

            foreach (var operationContainer in operationContainers)
            {
                var operation     = operationContainer.Operations.First(x => x.ModifiedThing is CDP4Common.DTO.Iteration);
                var iterationDto  = (CDP4Common.DTO.Iteration)operation.ModifiedThing;
                var iterationPoco = (CDP4Common.EngineeringModelData.Iteration)iterationDto.QuerySourceThing();

                JsonFileDalUtils.AddIteration(iterationPoco, ref iterations);

                var iterationSetup = iterationPoco.IterationSetup;
                JsonFileDalUtils.AddIterationSetup(iterationSetup, ref iterationSetups);

                var iterationRequiredRls = iterationPoco.RequiredRdls;
                JsonFileDalUtils.AddReferenceDataLibraries(iterationRequiredRls, ref siteReferenceDataLibraries, ref modelReferenceDataLibraries);

                var engineeringModelSetup = (CDP4Common.SiteDirectoryData.EngineeringModelSetup)iterationSetup.Container;
                JsonFileDalUtils.AddEngineeringModelSetup(engineeringModelSetup, ref engineeringModelSetups);

                if (siteDirectory == null)
                {
                    siteDirectory = (CDP4Common.SiteDirectoryData.SiteDirectory)engineeringModelSetup.Container;
                }

                // add the domains-of-expertise that are to be included in the File
                JsonFileDalUtils.AddDomainsOfExpertise(engineeringModelSetup, ref domainOfExpertises);

                // add the Persons that are to be included in the File
                JsonFileDalUtils.AddPersons(engineeringModelSetup, ref persons, ref personRoles, ref participantRoles, ref organizations);

                // add organizations that are referrenced by ReferencedSource
                JsonFileDalUtils.AddOrganizations(iterationRequiredRls, ref organizations);
            }

            var path = this.Session.Credentials.Uri.LocalPath;

            var prunedSiteDirectoryDtos = JsonFileDalUtils.CreateSiteDirectoryAndPrunedContainedThingDtos(
                siteDirectory,
                siteReferenceDataLibraries,
                domainOfExpertises,
                persons,
                personRoles,
                participantRoles,
                organizations,
                engineeringModelSetups,
                iterationSetups);

            var activePerson = JsonFileDalUtils.QueryActivePerson(this.Session.Credentials.UserName, siteDirectory);

            var exchangeFileHeader = this.FileHeader as ExchangeFileHeader ?? JsonFileDalUtils.CreateExchangeFileHeader(activePerson);

            try
            {
                using (var zipFile = new ZipFile())
                {
                    zipFile.Password = this.Session.Credentials.Password;

                    this.WriteHeaderToZipFile(exchangeFileHeader, zipFile, path);

                    this.WriteSiteDirectoryToZipFile(prunedSiteDirectoryDtos, zipFile, path);

                    this.WriteSiteReferenceDataLibraryToZipFile(siteReferenceDataLibraries, zipFile, path);

                    this.WriteModelReferenceDataLibraryToZipFile(modelReferenceDataLibraries, zipFile, path);

                    this.WriteIterationsToZipFile(iterations, zipFile, path);

                    this.WriteExtensionFilesToZipFile(extensionFiles, zipFile, path);
                }

                Logger.Info("Successfully exported the open session {1} to {0}.", path, this.Session.Credentials.Uri);
            }
            catch (Exception ex)
            {
                Logger.Error("Failed to export the open session to {0}. Error: {1}", path, ex.Message);
            }

            return(Task.FromResult(Enumerable.Empty <Thing>()));
        }