/// <summary>
        /// A general "one size fits all" factory method that creates a <see cref="FileSystemWatcher"/> which calls a specified method
        /// <see cref="action"/> when files at a given path change.
        /// </summary>
        /// <param name="configDirectory">The path to monitor.</param>
        /// <param name="action">The function to run.</param>
        /// <param name="events">The events which trigger the action.</param>
        /// <param name="enableSubdirectories">Decides whether subdirectories in a given path should be monitored.</param>
        /// <param name="filter">The filter used to determine which files are being watched for.</param>
        public static FileSystemWatcher CreateGeneric(string configDirectory, Action action, FileSystemWatcherEvents events, bool enableSubdirectories = true, string filter = "*.json")
        {
            var watcher = new FileSystemWatcher(configDirectory);

            watcher.EnableRaisingEvents   = true;
            watcher.IncludeSubdirectories = enableSubdirectories;
            watcher.Filter = filter;

            if (events.HasFlag(FileSystemWatcherEvents.Deleted))
            {
                watcher.Deleted += (a, b) => { action(); }
            }
            ;

            if (events.HasFlag(FileSystemWatcherEvents.Changed))
            {
                watcher.Changed += (a, b) => { action(); }
            }
            ;

            if (events.HasFlag(FileSystemWatcherEvents.Renamed))
            {
                watcher.Renamed += (a, b) => { action(); }
            }
            ;

            if (events.HasFlag(FileSystemWatcherEvents.Created))
            {
                watcher.Created += (a, b) => { action(); }
            }
            ;

            return(watcher);
        }
        /// <summary>
        /// A factory method that creates a <see cref="FileSystemWatcher"/> which calls a specified method
        /// <see cref="action"/> when files at a given path change.
        /// </summary>
        /// <param name="configDirectory">The path of the directory containing the configurations.</param>
        /// <param name="action">The function to run when a configuration is altered or changed.</param>
        /// <param name="events">The events which trigger the launching of given action.</param>
        /// <param name="enableSubdirectories">Decides whether subdirectories in a given path should be monitored.</param>
        /// <param name="filter">The filter used to determine which files are being watched for.</param>
        public static FileSystemWatcher CreateChangeCreateDelete(string configDirectory, FileSystemEventHandler action, FileSystemWatcherEvents events, bool enableSubdirectories = true, string filter = "*.json")
        {
            var watcher = new FileSystemWatcher(configDirectory);

            watcher.EnableRaisingEvents   = true;
            watcher.IncludeSubdirectories = enableSubdirectories;
            watcher.Filter = filter;

            if (events.HasFlag(FileSystemWatcherEvents.Deleted))
            {
                watcher.Deleted += action;
            }

            if (events.HasFlag(FileSystemWatcherEvents.Changed))
            {
                watcher.Changed += action;
            }

            if (events.HasFlag(FileSystemWatcherEvents.Created))
            {
                watcher.Created += action;
            }

            if (events.HasFlag(FileSystemWatcherEvents.Renamed))
            {
                throw new ArgumentException($"{FileSystemWatcherEvents.Renamed} is not supported.");
            }

            return(watcher);
        }
    /// <summary>
    /// A factory method that creates a <see cref="FileSystemWatcher"/> which calls a specified method
    /// <see cref="Action{T}"/> when files at a given path change.
    /// </summary>
    /// <param name="configDirectory">The path of the directory containing the configurations.</param>
    /// <param name="action">The function to run when a configuration is altered or changed.</param>
    /// <param name="renamedEventHandler">The function to run when an item is renamed.</param>
    /// <param name="events">The events which trigger the launching of given action.</param>
    /// <param name="enableSubdirectories">Decides whether subdirectories in a given path should be monitored.</param>
    /// <param name="filter">The filter used to determine which files are being watched for.</param>
    /// <param name="useBigBuffers">If true, uses a big internal buffer for receiving changes.</param>
    public static FileSystemWatcher Create(string configDirectory, FileSystemEventHandler action, RenamedEventHandler renamedEventHandler, FileSystemWatcherEvents events, bool enableSubdirectories = true, string filter = "*.json", bool useBigBuffers = true)
    {
        var watcher = new FileSystemWatcher(configDirectory);

        watcher.EnableRaisingEvents   = true;
        watcher.IncludeSubdirectories = enableSubdirectories;
        watcher.Filter       = filter;
        watcher.NotifyFilter = 0;

        if (useBigBuffers)
        {
            watcher.InternalBufferSize = 65536;
        }

        if (events.HasFlag(FileSystemWatcherEvents.Deleted))
        {
            watcher.Deleted      += action;
            watcher.NotifyFilter |= NotifyFilters.DirectoryName | NotifyFilters.FileName;
        }

        if (events.HasFlag(FileSystemWatcherEvents.Changed))
        {
            watcher.Changed      += action;
            watcher.NotifyFilter |= NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastWrite;
        }

        if (events.HasFlag(FileSystemWatcherEvents.Created))
        {
            watcher.Created      += action;
            watcher.NotifyFilter |= NotifyFilters.DirectoryName | NotifyFilters.FileName;
        }

        if (events.HasFlag(FileSystemWatcherEvents.Renamed))
        {
            watcher.Renamed      += renamedEventHandler;
            watcher.NotifyFilter |= NotifyFilters.DirectoryName | NotifyFilters.FileName;
        }

        return(watcher);
    }