internal static PrebuiltConfigurations ConvertToDto(
            this Processing.TableConfigurations tableConfigurations,
            Func <Processing.TableConfiguration, IDictionary <ColumnRole, ColumnRoleEntry> > convertColumnRoles)
        {
            var dtoTableConfigurations = new PrebuiltConfigurations()
            {
                Version = PrebuiltConfigurations.DTOVersion,
                Tables  = new TableConfigurations[]
                {
                    new TableConfigurations()
                    {
                        TableId                  = tableConfigurations.TableId,
                        Configurations           = tableConfigurations.Select(config => config.ConvertToDto(convertColumnRoles)).ToArray(),
                        DefaultConfigurationName = tableConfigurations.DefaultConfigurationName
                    }
                }
            };

            return(dtoTableConfigurations);
        }
        private static void SerializeTableConfigurations(
            Stream stream,
            PrebuiltConfigurations dtoPrebuiltConfigurations,
            ILogger logger)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            try
            {
                using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
                           stream, Encoding.Default, false, true, indentChars))
                {
                    var serializer = new DataContractJsonSerializer(typeof(PrebuiltConfigurations));
                    serializer.WriteObject(writer, dtoPrebuiltConfigurations);
                }
            }
            catch (Exception exception)
            {
                logger?.Warn($"Failed to serialize table configurations: {exception.Message}");
            }
        }
        /// <inheritdoc/>
        public IEnumerable <Processing.TableConfigurations> DeserializeTableConfigurations(Stream stream, ILogger logger)
        {
            if (stream == null)
            {
                return(Enumerable.Empty <Processing.TableConfigurations>());
            }

            var skipByteOrderMark = false;
            var startingPosition  = stream.Position;

            using (var binaryReader = new BinaryReader(stream, Encoding.UTF8, true))
            {
                var byte1 = binaryReader.ReadByte();
                if (byte1 == 0xEF)
                {
                    var byte2 = binaryReader.ReadByte();
                    if (byte2 == 0xBB)
                    {
                        var byte3 = binaryReader.ReadByte();
                        if (byte3 == 0xBF)
                        {
                            skipByteOrderMark = true;
                        }
                    }
                }
            }

            if (!skipByteOrderMark)
            {
                stream.Position = startingPosition;
            }

            PrebuiltConfigurations prebuiltConfigurations = null;

            try
            {
                var serializer = new DataContractJsonSerializer(typeof(PrebuiltConfigurations));

                prebuiltConfigurations = serializer.ReadObject(stream) as PrebuiltConfigurations;
                if (prebuiltConfigurations == null)
                {
                    return(Enumerable.Empty <Processing.TableConfigurations>());
                }
            }
            catch (InvalidDataContractException e)
            {
                logger?.Warn($"Invalid {nameof(Processing.TableConfiguration)} data found: {e.Message}");
                return(Enumerable.Empty <Processing.TableConfigurations>());
            }

            catch (SerializationException e)
            {
                logger?.Warn(
                    $"An exception was encountered while deserializing {nameof(Processing.TableConfiguration)}: " +
                    $"{e.Message}");
                return(Enumerable.Empty <Processing.TableConfigurations>());
            }

            // _CDS_
            // todo:validate the version

            return(ConvertDataTransferObjectsToTableConfigurations(prebuiltConfigurations.Tables));
        }