public DiskImageBasedStoragePlugin(PluginContext context, IDictionary <string, object> pluginConfig)
        {
            ApplyConfiguration(pluginConfig);

            this.basePathForDiskImages =
                pluginConfig.GetValueOrDefault <string>("diskImagesDirectory", "").AsAbsolutePath();

            filesListInConfig = pluginConfig
                                .GetValueOrDefault("diskImageFiles", new string[0])
                                .Take(MaxNumberOfDevices)
                                .Select(f => StringExtensions.AsAbsolutePath(f, basePathForDiskImages))
                                .ToArray();

            this.slotNumber = new SlotNumber(pluginConfig.GetValue <byte>("NestorMSX.slotNumber"));

            var machineName = pluginConfig.GetValue <string>("NestorMSX.machineName");

            stateFileFullPath = $"{machineName}/{PluginDisplayName} in slot {slotNumber}.dat".AsAbsolutePath();
            if (File.Exists(stateFileFullPath))
            {
                filesListFromState = File.ReadAllLines(stateFileFullPath, Encoding.UTF8)
                                     .Take(MaxNumberOfDevices)
                                     .ToArray()
                                     .WithEmptiesAsNulls();
            }
            else
            {
                filesListFromState = filesListInConfig.WithMinimumSizeOf(MaxNumberOfDevices);
            }

            imageFiles = new ImageFileInfo[MaxNumberOfDevices];

            this.setMenuEntry = context.SetMenuEntry;
            CreateMenu();

            this.openFileDialog             = new OpenFileDialog();
            openFileDialog.Title            = "Select disk image file";
            openFileDialog.InitialDirectory = basePathForDiskImages.Replace('/', Path.DirectorySeparatorChar);
            openFileDialog.Filter           = "Disk image files|*.dsk;*.img|All files|*.*";
            this.hostForm = context.HostForm;

            this.kernelFilePath = pluginConfig.GetMachineFilePath(pluginConfig.GetValueOrDefault("kernelFile", defaultKernelFileName));

            for (int i = 0; i < filesListFromState.Length; i++)
            {
                if (filesListFromState[i] == null)
                {
                    continue;
                }
                var diskImageFilePath = filesListFromState[i].AsAbsolutePath(basePathForDiskImages);
                SetFile(diskImageFilePath, i + 1, Path.GetFileName(diskImageFilePath));
            }

            for (int i = 0; i < MaxNumberOfDevices; i++)
            {
                removeFileMenuEntries[i].IsVisible = imageFiles[i] != null;
            }

            this.z80    = context.Cpu;
            this.memory = context.SlotsSystem;

            z80.BeforeInstructionFetch += (sender, args) => BeforeZ80InstructionFetch(z80.Registers.PC);

            this.kernelContents = File.ReadAllBytes(kernelFilePath);
            ValidateKernelFileContents(kernelContents);
        }