public static void Save()
        {
            EnsureLoaded();

            ThreadListData data = new ThreadListData {
                FileVersion = _currentFileVersion,
                Threads     = _watchers.Select(w => w.GetConfig()).ToArray()
            };

            string path     = Path.Combine(Settings.GetSettingsDirectory(), Settings.ThreadsFileName);
            string contents = JsonConvert.SerializeObject(data, Formatting.Indented);

            File.WriteAllText(path, contents);
        }
        public static void Load(Action <ThreadWatcher> onThreadLoad)
        {
            if (_watchers != null)
            {
                throw new Exception("Threads have already been loaded.");
            }

            _watchers = new List <ThreadWatcher>();

            string path = Path.Combine(Settings.GetSettingsDirectory(), Settings.ThreadsFileName);

            if (!File.Exists(path))
            {
                return;
            }

            ThreadListData data = JsonConvert.DeserializeObject <ThreadListData>(File.ReadAllText(path));

            if (data.FileVersion > _currentFileVersion)
            {
                throw new Exception("Threads file was created with a newer version of this program.");
            }
            else if (data.FileVersion <= 1)
            {
                // Skip loading if not backwards compatible
                return;
            }

            foreach (ThreadWatcherConfig config in data.Threads)
            {
                ThreadWatcher watcher = ThreadWatcher.Create(config);

                onThreadLoad(watcher);

                if (!watcher.IsStopping)
                {
                    watcher.Start();
                }

                _watchers.Add(watcher);
            }
        }