internal void UpdateState(string directory, ref FileChangeList changes, ref FileSystemEntry file)
        {
            int index = _state.IndexOf(directory, file.FileName);

            if (index == -1) // file added
            {
                string path = file.FileName.ToString();

                changes.AddAdded(directory, path.ToString());

                var newFileState = new FileState(directory, path);
                newFileState.LastWriteTimeUtc = file.LastWriteTimeUtc;
                newFileState.Length           = file.Length;
                newFileState._version         = _version;
                _state.Add(directory, path, newFileState);
                return;
            }

            _state.Values[index]._version = _version;

            FileState previousState = _state.Values[index];

            if (file.LastWriteTimeUtc != previousState.LastWriteTimeUtc || file.Length != previousState.Length)
            {
                changes.AddChanged(directory, previousState.Path);
                _state.Values[index].LastWriteTimeUtc = file.LastWriteTimeUtc;
                _state.Values[index].Length           = file.Length;
            }
        }
        private void TimerHandler(object context)
        {
            try
            {
                FileChangeList changes = ComputeChangesAndUpdateState();

                if (!changes.IsEmpty)
                {
                    Changed?.Invoke(this, EventArgs.Empty);
                    ChangedDetailed?.Invoke(this, new PollingFileSystemEventArgs(changes.ToArray()));
                }
            }
            catch (Exception e)
            {
                Error?.Invoke(this, new ErrorEventArgs(e));
            }

            if (!_disposed)
            {
                _timer.Change(PollingInterval, Timeout.Infinite);
            }
        }
        // This function walks all watched files, collects changes, and updates state
        private FileChangeList ComputeChangesAndUpdateState()
        {
            _version++;

            var enumerator = new FileSystemChangeEnumerator(this, Path, EnumerationOptions);

            while (enumerator.MoveNext())
            {
                // Ignore `.Current`
            }
            FileChangeList changes = enumerator.Changes;

            foreach (FileState value in _state)
            {
                if (value._version != _version)
                {
                    changes.AddRemoved(value.Directory, value.Path);
                    _state.Remove(value.Directory, value.Path);
                }
            }

            return(changes);
        }