public ImportExportSettings Merge([NotNull] ImportExportSettings settings)
        {
            ProcessPlugIns  = ProcessPlugIns && settings.ProcessPlugIns;
            ProcessRadios   = ProcessRadios && settings.ProcessRadios;
            ProcessScripts  = ProcessScripts && settings.ProcessScripts;
            ProcessSettings = ProcessSettings && settings.ProcessSettings;

            return(this);
        }
        public void ExportFiles(string filename, ImportExportSettings settings, IProgress<ActiveProgress> progress)
        {
            if (filename == null) throw new ArgumentNullException(nameof(filename));
            if (settings == null) throw new ArgumentNullException(nameof(settings));
            if (progress == null) throw new ArgumentNullException(nameof(progress));

            var helper = new ReportingHelper(settings, progress, type =>
            {
                switch (type)
                {
                    case ReportingStepType.Plugins:
                        return new StepInfo(RadioStreamerResources.SettingIEProcessingPlugIns,
                                            _plugInManager.GetInstalledAddIns().Count());
                    case ReportingStepType.Radios:
                        return new StepInfo(RadioStreamerResources.SettingIEProcessingRadios, _radioDatabase.Count);
                    case ReportingStepType.Scripts:
                        return new StepInfo(RadioStreamerResources.SettingIEProcessingScripts, _scriptEngine.FileNames.Count());
                    case ReportingStepType.Settings:
                        return new StepInfo(RadioStreamerResources.SettingIEProcessingSettings, _radioEnvironment.Settings.PropertyStore.Count);
                    default:
                        throw new ArgumentOutOfRangeException(nameof(type));
                }
            });

            var export = new RadioStreamerExport(settings);

            var store = _radioEnvironment.Settings.PropertyStore;

            if (settings.ProcessSettings)
            {
                helper.SwitchToStep(ReportingStepType.Settings);
                foreach (var name in store)
                {
                    helper.Step();
                    string value = store.GetValue(name, null);
                    if (!string.IsNullOrEmpty(value)) export.RadioSettings[name] = value;
                }
            }

            if (settings.ProcessRadios)
            {
                helper.SwitchToStep(ReportingStepType.Radios);
                foreach (var radioEntry in _radioDatabase.GetRadios())
                {
                    helper.Step();
                    var entry = new ExportRadio();
                    var qentry = new ExportQuality {Name = radioEntry.Name};

                    if (radioEntry.Metadata == null) continue;

                    entry.Entries.AddRange(GetEntries(radioEntry.Metadata));

                    foreach (var quality in radioEntry.Metadata.GetQualitys())
                    {
                        var qent = new QualityEntry();
                        qent.Entries.AddRange(GetEntries(radioEntry.Metadata.GetQuality(quality)));
                        qentry.Qualitys.Add(qent);
                    }

                    export.Qualities.Add(qentry);
                    export.Radios.Add(entry);
                }
            }

            if (settings.ProcessPlugIns)
            {
                helper.SwitchToStep(ReportingStepType.Plugins);
                foreach (var installedPackInfo in _plugInManager.GetInstalledAddIns())
                {
                    helper.Step();
                    export.PlugIns.Add(installedPackInfo.Name);
                }
            }

            if (settings.ProcessScripts)
            {
                helper.SwitchToStep(ReportingStepType.Scripts);
                foreach (var scriptFile in _scriptEngine.FileNames)
                {
                    helper.Step();
                    export.Scripts.Add(new ExportScript(scriptFile.GetFileName(), scriptFile.ReadAllBytesIfExis()));
                }
            }

            progress.Report(new ActiveProgress(RadioStreamerResources.SettingIEProcessingFile, 0, 100));

            using (var stream = new DeflateStream(new FileStream(filename, FileMode.Create),CompressionLevel.Optimal))
            {
                new BinaryFormatter().Serialize(stream, export);
            }
        }
        public void ImportFiles(string file, bool merge, ImportExportSettings settings, IProgress<ActiveProgress> progress)
        {
            if (file == null) throw new ArgumentNullException(nameof(file));
            if (settings == null) throw new ArgumentNullException(nameof(settings));
            if (progress == null) throw new ArgumentNullException(nameof(progress));

            try
            {
                progress.Report(new ActiveProgress(RadioStreamerResources.SettingIEProcessingFile, 0, 0));

                RadioStreamerExport exported;

                using (var stream = new DeflateStream(new FileStream(file, FileMode.Open), CompressionMode.Decompress))
                    exported = (RadioStreamerExport) new BinaryFormatter().Deserialize(stream);

                var exportSettings = exported.ImportExportSettings.Merge(settings);

                var helper = new ReportingHelper(exportSettings, progress, type =>
                {
                    switch (type)
                    {
                        case ReportingStepType.Plugins:
                            return new StepInfo(RadioStreamerResources.SettingIEProcessingPlugIns, exported.PlugIns.Count);
                        case ReportingStepType.Radios:
                            return new StepInfo(RadioStreamerResources.SettingIEProcessingRadios, exported.Radios.Count + 1);
                        case ReportingStepType.Scripts:
                            return new StepInfo(RadioStreamerResources.SettingIEProcessingScripts, exported.Scripts.Count + 1);
                        case ReportingStepType.Settings:
                            return new StepInfo(RadioStreamerResources.SettingIEProcessingSettings, exported.RadioSettings.Count);
                        default:
                            throw new ArgumentOutOfRangeException("type");
                    }
                });

                if (exportSettings.ProcessSettings)
                {
                    helper.SwitchToStep(ReportingStepType.Settings);
                    var store = _radioEnvironment.Settings.PropertyStore;

                    foreach (var setting in exported.RadioSettings)
                    {
                        helper.Step();
                        store.SetValue(setting.Key, setting.Value);
                    }

                    _radioEnvironment.Settings.Save();
                    _radioEnvironment.ReloadSetting();
                }

                if (exportSettings.ProcessRadios)
                {
                    helper.SwitchToStep(ReportingStepType.Radios);
                    if (!merge) _radioDatabase.Clear();

                    var fac = _radioDatabase.GetEntryFactory();

                    fac.BeginChanging();
                    try
                    {
                        foreach (var exportRadio in exported.Radios)
                        {
                            helper.Step();
                            var name = exportRadio.Entries.FirstOrDefault(e => e.Key == RadioEntry.MetaName);
                            if (name == null) continue;

                            bool cr;
                            var ent = fac.AddOrGetEntry(name.Value, out cr);
                            var meta = ent.Metadata;
                            if (meta == null) continue;

                            foreach (var metadataEntry in exportRadio.Entries) meta[metadataEntry.Key] = metadataEntry.Value;

                            var qfac = new RadioQualityFactory(ent);
                            var equality = exported.Qualities.FirstOrDefault(q => q.Name == ent.Name);
                            if (equality == null) continue;

                            foreach (var qualityEntry in equality.Qualitys)
                            {
                                name = qualityEntry.Entries.FirstOrDefault(e => e.Key == RadioQuality.MetaName);
                                if (name == null) continue;

                                var qua = qfac.Create(name.Value, string.Empty, string.Empty);
                                meta = qua.Metadata;
                                if (meta == null) continue;

                                foreach (var metadataEntry in qualityEntry.Entries) meta[metadataEntry.Key] = metadataEntry.Value;
                            }
                        }
                    }
                    finally
                    {
                        helper.Step(RadioStreamerResources.SettingIEProcessingDatabaseSave);
                        fac.Compled();
                    }
                }

                if (exportSettings.ProcessScripts)
                {
                    helper.SwitchToStep(ReportingStepType.Scripts);

                    foreach (var script in exported.Scripts)
                    {
                        helper.Step();
                        _scriptEngine.CopyFile(script.FileName, script.Content);
                    }

                    helper.Step(RadioStreamerResources.SettingIEProcessingPrecompile);
                    _scriptEngine.PreCompile(new StringWriter());
                }

                if (!exportSettings.ProcessPlugIns) return;

                helper.SwitchToStep(ReportingStepType.Plugins);
                var installedPlagIns = new List<string>(_plugInManager.GetInstalledAddIns().Select(p => p.Name));

                foreach (var plugIn in exported.PlugIns.Where(p => !installedPlagIns.Contains(p)))
                {
                    helper.Step();
                    _plugInManager.InstallPlugIn(plugIn);
                }
            }
            catch (Exception e)
            {
                if (CriticalExceptions.IsCriticalException(e)) throw;
            }
        }