async public Task SaveConfig(ServerMapDocument mapDocument)
        {
            try
            {
                if (MapDocument == null)
                {
                    return;
                }

                var map = mapDocument?.Maps.First() as Map;
                if (map == null)
                {
                    throw new MapServerException("Mapdocument don't contain a map");
                }

                XmlStream stream = new XmlStream("MapServer");
                stream.Save("MapDocument", mapDocument);

                stream.WriteStream(_mapServerService.Options.ServicesPath + "/" + map.Name + ".mxl");

                if (map is Map)
                {
                    await ApplyMetadata(map);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError($"Map { mapDocument?.Maps?.First()?.Name }: LoadConfig - { ex.Message }");
            }
        }
        public MapServiceDeploymentManager(MapServiceManager mapServicerService,
                                           AccessControlService accessControlService,
                                           ILogger <MapServiceDeploymentManager> logger = null)
        {
            _mapServerService     = mapServicerService;
            _accessControlService = accessControlService;
            _logger = logger ?? new ConsoleLogger <MapServiceDeploymentManager>();

            MapDocument = new ServerMapDocument(_mapServerService);
        }
        async private Task <bool> AddMap(string mapName, string mapXml)
        {
            string folder = mapName.FolderName();

            if (!String.IsNullOrWhiteSpace(folder))
            {
                if (!Directory.Exists((_mapServerService.Options.ServicesPath + "/" + folder).ToPlatformPath()))
                {
                    throw new MapServerException("Folder not exists");
                }
            }

            if (String.IsNullOrEmpty(mapXml))
            {
                return(await ReloadMap(mapName));
            }

            if ((await _mapServerService.Instance.Maps(null)).Count() >= _mapServerService.Instance.MaxServices)
            {
                // Überprüfen, ob schon eine Service mit gleiche Namen gibt...
                // wenn ja, ist es nur einem Refresh eines bestehenden Services
                bool found = false;
                foreach (IMapService existingMap in await _mapServerService.Instance.Maps(null))
                {
                    if (existingMap.Name == mapName)
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    //return false;
                    throw new MapServerException("Unknown error");
                }
            }

            XmlStream xmlStream = new XmlStream("MapDocument");

            using (StringReader sr = new StringReader(mapXml))
            {
                if (!xmlStream.ReadStream(sr, String.Empty))  // invariant culture
                {
                    throw new MapServerException("Unable to read MapXML");
                }
            }

            ServerMapDocument mapDocument = new ServerMapDocument(_mapServerService);
            await mapDocument.LoadAsync(xmlStream);

            if (mapDocument.Maps.Count() == 0)
            {
                throw new MapServerException("No maps found in document");
            }

            var map = mapDocument.Maps.First() as Map;

            //Map map = new Map();
            //map.Load(xmlStream);
            map.Name = mapName;

            StringBuilder errors    = new StringBuilder();
            bool          hasErrors = false;

            foreach (var dataset in map.Datasets)
            {
                if (!String.IsNullOrWhiteSpace(dataset.LastErrorMessage))
                {
                    errors.Append("Dataset " + dataset.GetType().ToString() + Environment.NewLine);
                    errors.Append(dataset.LastErrorMessage + Environment.NewLine + Environment.NewLine);
                    hasErrors = true;
                }
            }

            if (map.HasErrorMessages)
            {
                //errors.Append("Map Errors/Warnings:" + Environment.NewLine);
                foreach (var errorMessage in map.ErrorMessages)
                {
                    errors.Append(errorMessage + Environment.NewLine);
                    hasErrors |= errorMessage.ToLower().StartsWith("warning:") == false;  // Warnings should not throw an exception
                }
            }
            if (map.LastException != null)
            {
                errors.Append("Map Exception:" + Environment.NewLine);
                errors.Append(map.LastException.Message?.ToString());
                hasErrors = true;
            }

            foreach (IFeatureLayer featureLayer in map.MapElements.Where(e => e is IFeatureLayer))
            {
                if (featureLayer.Class is IFeatureClass && ((IFeatureClass)featureLayer.Class).SpatialReference == null)
                {
                    if (map.LayerDefaultSpatialReference != null)
                    {
                        errors.Append($"Warning: { featureLayer.Title } has no spatial reference. Map default '{ map.LayerDefaultSpatialReference.EpsgCode }' will used for this layer." + Environment.NewLine);
                    }
                    else
                    {
                        errors.Append($"Error: { featureLayer.Title } has no spatial reference. Fix this or at least set a default spatial reference for this map in the carto app" + Environment.NewLine);
                    }
                }
            }

            if (hasErrors)
            {
                throw new MapServerException("Errors: " + Environment.NewLine + errors.ToString());
            }

            XmlStream pluginStream = new XmlStream("Moduls");

            using (StringReader sr = new StringReader(mapXml))
            {
                if (!xmlStream.ReadStream(sr))
                {
                    throw new MapServerException("Unable to read MapXML (Moduls)");
                }
            }

            ModulesPersists modules = new ModulesPersists(map);

            modules.Load(pluginStream);

            //foreach (IMap m in ListOperations<IMap>.Clone(_doc.Maps))
            //{
            //    if (m.Name == map.Name) _doc.RemoveMap(m);
            //}

            //if (!_doc.AddMap(map)) return false;
            _mapServerService.AddMapService(mapName, MapServiceType.MXL);

            await SaveConfig(mapDocument);

            var result = await ReloadMap(mapName);

            if (errors.Length > 0)  // Warnings
            {
                throw new MapServerException("Warnings: " + Environment.NewLine + errors.ToString());
            }

            return(result);
        }
        async public Task <IMap> LoadMap(string name)
        {
            IMap map = null;

            try
            {
                DirectoryInfo di = new DirectoryInfo(_mapServerService.Options.ServicesPath);
                if (!di.Exists)
                {
                    di.Create();
                }

                FileInfo fi = new FileInfo(_mapServerService.Options.ServicesPath + @"/" + name + ".mxl");
                if (fi.Exists)
                {
                    ServerMapDocument doc = new ServerMapDocument(_mapServerService);
                    await doc.LoadMapDocumentAsync(fi.FullName);

                    if (doc.Maps.Count() == 1)
                    {
                        map = doc.Maps.First();
                        if (map.Name != name &&
                            name.Contains("/") &&
                            !map.Name.StartsWith(name.FolderName() + "/")) // Folder?
                        {
                            map.Name = name.Split('/')[0] + "/" + map.Name;
                        }

                        await ApplyMetadata(map as Map);

                        if (map.HasErrorMessages || !MapDocument.AddMap(map))
                        {
                            return(null);
                        }

                        MapDocument.SetMapModules(map, doc.GetMapModules(map));

                        var mapService = _mapServerService.MapServices.Where(s => s.Fullname == map.Name).FirstOrDefault();
                        if (mapService != null)
                        {
                            mapService.ServiceRefreshed();
                        }


                        return(map);
                    }
                    return(null);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError($"Map {name}: LoadConfig - { ex.Message }");
                _mapServerService?.Instance?.LogAsync(name, "LoadMap.Exception", loggingMethod.error, ex.Message);
            }
            finally
            {
                if (map != null && map.HasErrorMessages)
                {
                    foreach (var errorMessage in map.ErrorMessages)
                    {
                        _logger.LogWarning($"{ map.Name }: LoadMap - { errorMessage} ");
                        _mapServerService?.Instance?.LogAsync(map.Name, "LoadMap.MapErrors", loggingMethod.error, errorMessage);
                    }
                }
            }

            return(null);
        }