/// <summary>
        /// Serialize the <see cref="CDP4Common.CommonData.Thing"/> to a JSON string
        /// </summary>
        /// <param name="source">The <see cref="CDP4Common.CommonData.Thing"/></param>
        /// <param name="isExtentDeep">A value indicating whether the contained <see cref="CDP4Common.CommonData.Thing"/> shall be processed</param>
        /// <returns>The JSON string</returns>
        public string SerializeToString(CDP4Common.CommonData.Thing source, bool isExtentDeep)
        {
            if (this.RequestDataModelVersion == null || this.MetaInfoProvider == null)
            {
                throw new InvalidOperationException("The supported version or the metainfo provider has not been set. Call the Initialize method to set them.");
            }

            string jsonString;

            Logger.Trace("initializing MemoryStream");

            using (var stream = new MemoryStream())
            {
                this.SerializeToStream(source, stream, isExtentDeep);

                Logger.Trace("rewind MemoryStream");
                stream.Position = 0;

                Logger.Trace("initializing StreamReader");
                using (var reader = new StreamReader(stream))
                {
                    var sw = new Stopwatch();
                    sw.Start();
                    jsonString = reader.ReadToEnd();
                    sw.Stop();
                    Logger.Trace("write json stream to json string in {0} [ms]", sw.ElapsedMilliseconds);
                }
            }

            return(jsonString);
        }
        public async Task VerifyThatCloseModelWorks()
        {
            var siteDir     = new CDP4Common.SiteDirectoryData.SiteDirectory(Guid.NewGuid(), null, null);
            var modelRdlDto = new CDP4Common.DTO.ModelReferenceDataLibrary {
                Iid = Guid.NewGuid()
            };
            var siteDirDto = new CDP4Common.DTO.SiteDirectory {
                Iid = Guid.NewGuid()
            };
            var requiredPocoDto = new CDP4Common.DTO.SiteReferenceDataLibrary {
                Iid = Guid.NewGuid()
            };
            var containerEngModelSetupDto = new EngineeringModelSetup {
                Iid = Guid.NewGuid()
            };
            var containerEngModelSetup = new CDP4Common.SiteDirectoryData.EngineeringModelSetup {
                Iid = containerEngModelSetupDto.Iid
            };
            var iterationDto = new Iteration {
                Iid = Guid.NewGuid()
            };
            var iteration = new CDP4Common.EngineeringModelData.Iteration {
                Iid = iterationDto.Iid
            };
            var iterationSetupDto = new CDP4Common.DTO.IterationSetup {
                Iid = Guid.NewGuid(), IterationIid = iterationDto.Iid
            };

            iterationDto.IterationSetup = iterationSetupDto.IterationIid;
            siteDir.Model.Add(containerEngModelSetup);
            modelRdlDto.RequiredRdl = requiredPocoDto.Iid;

            var credentials = new Credentials("admin", "pass", new Uri("http://www.rheagroup.com"));
            var session2    = new Session(this.mockedDal.Object, credentials);

            var iterationSetup = new CDP4Common.SiteDirectoryData.IterationSetup {
                Iid = iterationSetupDto.Iid, Container = containerEngModelSetup, IterationIid = iteration.Iid
            };
            var thingsToAdd = new List <Thing> {
                siteDirDto, requiredPocoDto, containerEngModelSetupDto, modelRdlDto, iterationSetupDto
            };

            await session2.Assembler.Synchronize(thingsToAdd);

            var lazyiteration = new Lazy <CDP4Common.CommonData.Thing>(() => iteration);

            session2.Assembler.Cache.GetOrAdd(new CacheKey(iterationDto.Iid, null), lazyiteration);

            CDP4Common.CommonData.Thing changedObject = null;
            CDPMessageBus.Current.Listen <ObjectChangedEvent>(typeof(CDP4Common.EngineeringModelData.Iteration)).Subscribe(x => changedObject = x.ChangedThing);
            await session2.CloseIterationSetup(iterationSetup);

            Assert.NotNull(changedObject);
        }
        /// <summary>
        /// Serialize the <see cref="CDP4Common.CommonData.Thing"/> to a JSON stream
        /// </summary>
        /// <param name="source">
        /// The <see cref="CDP4Common.CommonData.Thing"/>
        /// </param>
        /// <param name="outputStream">
        /// The output stream to which the serialized JSON objects are written
        /// </param>
        /// <param name="isExtentDeep">
        /// A value indicating whether the contained <see cref="CDP4Common.CommonData.Thing"/> shall be included in the JSON stream
        /// </param>
        /// <returns>A JSON stream</returns>
        public void SerializeToStream(CDP4Common.CommonData.Thing source, Stream outputStream, bool isExtentDeep)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source), "the source Thing may not be null");
            }

            if (outputStream == null)
            {
                throw new ArgumentNullException(nameof(outputStream), "outputstream may not be null");
            }

            if (this.RequestDataModelVersion == null || this.MetaInfoProvider == null)
            {
                throw new InvalidOperationException("The supported version or the metainfo provider has not been set. Call the Initialize method to set them.");
            }

            var dtos = new List <Thing>();

            if (isExtentDeep)
            {
                var pocos = source.QueryContainedThingsDeep();
                foreach (var poco in pocos)
                {
                    dtos.Add(poco.ToDto());
                }
            }
            else
            {
                dtos.Add(source.ToDto());
            }

            Logger.Debug("serializing {0} DTO's", dtos.Count);

            this.SerializeToStream(dtos, outputStream);
        }