public async Task Initialize()
        {
            // Clear any existing items.
            Items.Clear();

            // Get the data folder.
            string filepath = OfflineDataStorageHelper.GetDataFolder();

            foreach (string subDirectory in Directory.GetDirectories(filepath))
            {
                try
                {
                    // Note: the downloaded map packages are stored as *unpacked* mobile map packages.
                    var mmpk = await MobileMapPackage.OpenAsync(subDirectory);

                    if (mmpk?.Item != null)
                    {
                        Items.Add(new PortalItemViewModel(mmpk.Item));
                    }
                }
                catch (Exception)
                {
                    // Ignored - not a valid map package
                }
            }
        }
        private async void DownloadMapArea()
        {
            try
            {
                _windowService.SetBusyMessage("Downloading selected area...");
                _windowService.SetBusy(true);
                string offlineDataFolder = Path.Combine(OfflineDataStorageHelper.GetDataFolderForMap(Map));

                // If temporary data folder exists remove it
                try
                {
                    if (Directory.Exists(offlineDataFolder))
                    {
                        Directory.Delete(offlineDataFolder, true);
                    }
                }
                catch (Exception)
                {
                    // If folder can't be deleted, open a new one.
                    offlineDataFolder = Path.Combine(offlineDataFolder, DateTime.Now.Ticks.ToString());
                }

                // Step 1 Create task that is used to access map information and download areas
                var task = await OfflineMapTask.CreateAsync(Map);

                // Step 2 Create job that handles the download and provides status information
                // about the progress
                var job = task.DownloadPreplannedOfflineMap(SelectedMapArea.MapArea, offlineDataFolder);
                job.ProgressChanged += async(s, e) =>
                {
                    await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        var generateOfflineMapJob = s as DownloadPreplannedOfflineMapJob;
                        _windowService.SetBusyMessage($"Downloading offline map... {generateOfflineMapJob.Progress}%");
                    });
                };

                // Step 3 Run the job and wait the results
                var results = await job.GetResultAsync();

                // Step 4 Check errors
                if (results.HasErrors)
                {
                    string errorString = "";
                    // If one or more layers fails, layer errors are populated with corresponding errors.
                    foreach (KeyValuePair <Layer, Exception> layerError in results.LayerErrors)
                    {
                        errorString += $"Error occurred on {layerError.Key.Name} : {layerError.Value.Message}\r\n";
                    }
                    foreach (KeyValuePair <Esri.ArcGISRuntime.Data.FeatureTable, Exception> tableError in results.TableErrors)
                    {
                        errorString += $"Error occurred on {tableError.Key.TableName} : {tableError.Value.Message}\r\n";
                    }
                    OfflineDataStorageHelper.FlushLogToDisk(errorString, Map);
                }

                // Step 5 Set offline map to use
                Map = results.OfflineMap;
                _areasOverlay.Graphics.Clear();
            }
            catch (Exception ex)
            {
                await _windowService.ShowAlertAsync(ex.Message, "Couldn't download map area");
            }
            finally
            {
                RefreshCommands();
                _windowService.SetBusy(false);
            }
        }
        private async void GenerateMapArea()
        {
            try
            {
                _windowService.SetBusyMessage("Taking map offline");
                _windowService.SetBusy(true);

                string offlineDataFolder = OfflineDataStorageHelper.GetDataFolderForMap(Map);

                // If temporary data folder exists remove it
                try
                {
                    if (Directory.Exists(offlineDataFolder))
                    {
                        Directory.Delete(offlineDataFolder, true);
                    }
                }
                catch (Exception)
                {
                    // If folder can't be deleted, open a new one.
                    offlineDataFolder = Path.Combine(offlineDataFolder, DateTime.Now.Ticks.ToString());
                }

                // If temporary data folder doesn't exists, create it
                if (!Directory.Exists(offlineDataFolder))
                {
                    Directory.CreateDirectory(offlineDataFolder);
                }

                // Get area of interest as a envelope from the map view
                var areaOfInterest =
                    _mapViewService.GetCurrentViewpoint(ViewpointType.BoundingGeometry)
                    .TargetGeometry as Envelope;

                // Step 1 : Create task with the map that is taken offline
                var task = await OfflineMapTask.CreateAsync(Map);

                // Step 2 : Create parameters based on selections
                var parameters = await task.CreateDefaultGenerateOfflineMapParametersAsync(
                    areaOfInterest);

                parameters.MaxScale       = _levelsOfDetail[SelectedLevelOfDetail].Scale;
                parameters.MinScale       = 0;
                parameters.IncludeBasemap = IncludeBasemap;
                parameters.ReturnLayerAttachmentOption = ReturnLayerAttachmentOption.None;

                // Step 3 : Create job that does the work asynchronously and
                //          set progress indication
                _job = task.GenerateOfflineMap(parameters, offlineDataFolder);
                _job.ProgressChanged += GenerateOfflineMap_ProgressChanged;

                // Step 4 : Run the job and wait the results
                var results = await _job.GetResultAsync();

                if (results.HasErrors)
                {
                    string errorString = "";
                    // If one or more layers fails, layer errors are populated with corresponding errors.
                    foreach (var(key, value) in results.LayerErrors)
                    {
                        errorString += $"Error occurred on {key.Name} : {value.Message}\r\n";
                    }
                    foreach (var(key, value) in results.TableErrors)
                    {
                        errorString += $"Error occurred on {key.TableName} : {value.Message}\r\n";
                    }
                    OfflineDataStorageHelper.FlushLogToDisk(errorString, Map);
                }

                // Step 5 : Use results
                Map = results.OfflineMap;

                RefreshCommands();
            }
            catch (Exception ex)
            {
                await _windowService.ShowAlertAsync(ex.Message, "Error generating offline map");
            }
            finally
            {
                _windowService.SetBusy(false);
            }
        }