diff --git a/fsnotify/README.txt b/fsnotify/README.txt
deleted file mode 100644
index 2ba49f6..0000000
--- a/fsnotify/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Please use gopkg.in/fsnotify.v0 instead.
-
-For updates, see: https://fsnotify.org/
diff --git a/winfsnotify/go.mod b/winfsnotify/go.mod
deleted file mode 100644
index 248af1a..0000000
--- a/winfsnotify/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module golang.org/x/exp/winfsnotify
-
-go 1.11
diff --git a/winfsnotify/winfsnotify.go b/winfsnotify/winfsnotify.go
deleted file mode 100644
index e25ecfa..0000000
--- a/winfsnotify/winfsnotify.go
+++ /dev/null
@@ -1,586 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build windows
-// +build windows
-
-// Package winfsnotify allows the user to receive
-// file system event notifications on Windows.
-//
-// Deprecated: winfsnotify has been unmaintained since 2016 (see
-// https://go.dev/issue/51447). Forks of this package with more recent
-// maintenance and cross-platform support can be found at
-// https://pkg.go.dev/search?q=fsnotify.
-package winfsnotify // import "golang.org/x/exp/winfsnotify"
-
-import (
-	"errors"
-	"fmt"
-	"os"
-	"path/filepath"
-	"runtime"
-	"syscall"
-	"unsafe"
-)
-
-// Event is the type of the notification messages
-// received on the watcher's Event channel.
-type Event struct {
-	Mask   uint32 // Mask of events
-	Cookie uint32 // Unique cookie associating related events (for rename)
-	Name   string // File name (optional)
-}
-
-const (
-	opAddWatch = iota
-	opRemoveWatch
-)
-
-const (
-	provisional uint64 = 1 << (32 + iota)
-)
-
-type input struct {
-	op    int
-	path  string
-	flags uint32
-	reply chan error
-}
-
-type inode struct {
-	handle syscall.Handle
-	volume uint32
-	index  uint64
-}
-
-type watch struct {
-	ov     syscall.Overlapped
-	ino    *inode            // i-number
-	path   string            // Directory path
-	mask   uint64            // Directory itself is being watched with these notify flags
-	names  map[string]uint64 // Map of names being watched and their notify flags
-	rename string            // Remembers the old name while renaming a file
-	buf    [4096]byte
-}
-
-type indexMap map[uint64]*watch
-type watchMap map[uint32]indexMap
-
-// A Watcher waits for and receives event notifications
-// for a specific set of files and directories.
-type Watcher struct {
-	port     syscall.Handle // Handle to completion port
-	watches  watchMap       // Map of watches (key: i-number)
-	input    chan *input    // Inputs to the reader are sent on this channel
-	Event    chan *Event    // Events are returned on this channel
-	Error    chan error     // Errors are sent on this channel
-	isClosed bool           // Set to true when Close() is first called
-	quit     chan chan<- error
-	cookie   uint32
-}
-
-// NewWatcher creates and returns a Watcher.
-func NewWatcher() (*Watcher, error) {
-	port, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0)
-	if e != nil {
-		return nil, os.NewSyscallError("CreateIoCompletionPort", e)
-	}
-	w := &Watcher{
-		port:    port,
-		watches: make(watchMap),
-		input:   make(chan *input, 1),
-		Event:   make(chan *Event, 50),
-		Error:   make(chan error),
-		quit:    make(chan chan<- error, 1),
-	}
-	go w.readEvents()
-	return w, nil
-}
-
-// Close closes a Watcher.
-// It sends a message to the reader goroutine to quit and removes all watches
-// associated with the watcher.
-func (w *Watcher) Close() error {
-	if w.isClosed {
-		return nil
-	}
-	w.isClosed = true
-
-	// Send "quit" message to the reader goroutine
-	ch := make(chan error)
-	w.quit <- ch
-	if err := w.wakeupReader(); err != nil {
-		return err
-	}
-	return <-ch
-}
-
-// AddWatch adds path to the watched file set.
-func (w *Watcher) AddWatch(path string, flags uint32) error {
-	if w.isClosed {
-		return errors.New("watcher already closed")
-	}
-	in := &input{
-		op:    opAddWatch,
-		path:  filepath.Clean(path),
-		flags: flags,
-		reply: make(chan error),
-	}
-	w.input <- in
-	if err := w.wakeupReader(); err != nil {
-		return err
-	}
-	return <-in.reply
-}
-
-// Watch adds path to the watched file set, watching all events.
-func (w *Watcher) Watch(path string) error {
-	return w.AddWatch(path, FS_ALL_EVENTS)
-}
-
-// RemoveWatch removes path from the watched file set.
-func (w *Watcher) RemoveWatch(path string) error {
-	in := &input{
-		op:    opRemoveWatch,
-		path:  filepath.Clean(path),
-		reply: make(chan error),
-	}
-	w.input <- in
-	if err := w.wakeupReader(); err != nil {
-		return err
-	}
-	return <-in.reply
-}
-
-func (w *Watcher) wakeupReader() error {
-	e := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil)
-	if e != nil {
-		return os.NewSyscallError("PostQueuedCompletionStatus", e)
-	}
-	return nil
-}
-
-func getDir(pathname string) (dir string, err error) {
-	pathnamep, e := syscall.UTF16PtrFromString(pathname)
-	if e != nil {
-		return "", e
-	}
-	attr, e := syscall.GetFileAttributes(pathnamep)
-	if e != nil {
-		return "", os.NewSyscallError("GetFileAttributes", e)
-	}
-	if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
-		dir = pathname
-	} else {
-		dir, _ = filepath.Split(pathname)
-		dir = filepath.Clean(dir)
-	}
-	return
-}
-
-func getIno(path string) (ino *inode, err error) {
-	pathp, e := syscall.UTF16PtrFromString(path)
-	if e != nil {
-		return nil, e
-	}
-	h, e := syscall.CreateFile(pathp,
-		syscall.FILE_LIST_DIRECTORY,
-		syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
-		nil, syscall.OPEN_EXISTING,
-		syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0)
-	if e != nil {
-		return nil, os.NewSyscallError("CreateFile", e)
-	}
-	var fi syscall.ByHandleFileInformation
-	if e = syscall.GetFileInformationByHandle(h, &fi); e != nil {
-		syscall.CloseHandle(h)
-		return nil, os.NewSyscallError("GetFileInformationByHandle", e)
-	}
-	ino = &inode{
-		handle: h,
-		volume: fi.VolumeSerialNumber,
-		index:  uint64(fi.FileIndexHigh)<<32 | uint64(fi.FileIndexLow),
-	}
-	return ino, nil
-}
-
-// Must run within the I/O thread.
-func (m watchMap) get(ino *inode) *watch {
-	if i := m[ino.volume]; i != nil {
-		return i[ino.index]
-	}
-	return nil
-}
-
-// Must run within the I/O thread.
-func (m watchMap) set(ino *inode, watch *watch) {
-	i := m[ino.volume]
-	if i == nil {
-		i = make(indexMap)
-		m[ino.volume] = i
-	}
-	i[ino.index] = watch
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) addWatch(pathname string, flags uint64) error {
-	dir, err := getDir(pathname)
-	if err != nil {
-		return err
-	}
-	if flags&FS_ONLYDIR != 0 && pathname != dir {
-		return nil
-	}
-	ino, err := getIno(dir)
-	if err != nil {
-		return err
-	}
-	watchEntry := w.watches.get(ino)
-	if watchEntry == nil {
-		if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil {
-			syscall.CloseHandle(ino.handle)
-			return os.NewSyscallError("CreateIoCompletionPort", e)
-		}
-		watchEntry = &watch{
-			ino:   ino,
-			path:  dir,
-			names: make(map[string]uint64),
-		}
-		w.watches.set(ino, watchEntry)
-		flags |= provisional
-	} else {
-		syscall.CloseHandle(ino.handle)
-	}
-	if pathname == dir {
-		watchEntry.mask |= flags
-	} else {
-		watchEntry.names[filepath.Base(pathname)] |= flags
-	}
-	if err = w.startRead(watchEntry); err != nil {
-		return err
-	}
-	if pathname == dir {
-		watchEntry.mask &= ^provisional
-	} else {
-		watchEntry.names[filepath.Base(pathname)] &= ^provisional
-	}
-	return nil
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) removeWatch(pathname string) error {
-	dir, err := getDir(pathname)
-	if err != nil {
-		return err
-	}
-	ino, err := getIno(dir)
-	if err != nil {
-		return err
-	}
-	watch := w.watches.get(ino)
-	if watch == nil {
-		return fmt.Errorf("can't remove non-existent watch for: %s", pathname)
-	}
-	if pathname == dir {
-		w.sendEvent(watch.path, watch.mask&FS_IGNORED)
-		watch.mask = 0
-	} else {
-		name := filepath.Base(pathname)
-		w.sendEvent(watch.path+"/"+name, watch.names[name]&FS_IGNORED)
-		delete(watch.names, name)
-	}
-	return w.startRead(watch)
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) deleteWatch(watch *watch) {
-	for name, mask := range watch.names {
-		if mask&provisional == 0 {
-			w.sendEvent(watch.path+"/"+name, mask&FS_IGNORED)
-		}
-		delete(watch.names, name)
-	}
-	if watch.mask != 0 {
-		if watch.mask&provisional == 0 {
-			w.sendEvent(watch.path, watch.mask&FS_IGNORED)
-		}
-		watch.mask = 0
-	}
-}
-
-// Must run within the I/O thread.
-func (w *Watcher) startRead(watch *watch) error {
-	if e := syscall.CancelIo(watch.ino.handle); e != nil {
-		w.Error <- os.NewSyscallError("CancelIo", e)
-		w.deleteWatch(watch)
-	}
-	mask := toWindowsFlags(watch.mask)
-	for _, m := range watch.names {
-		mask |= toWindowsFlags(m)
-	}
-	if mask == 0 {
-		if e := syscall.CloseHandle(watch.ino.handle); e != nil {
-			w.Error <- os.NewSyscallError("CloseHandle", e)
-		}
-		delete(w.watches[watch.ino.volume], watch.ino.index)
-		return nil
-	}
-	e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0],
-		uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0)
-	if e != nil {
-		err := os.NewSyscallError("ReadDirectoryChanges", e)
-		if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 {
-			// Watched directory was probably removed
-			if w.sendEvent(watch.path, watch.mask&FS_DELETE_SELF) {
-				if watch.mask&FS_ONESHOT != 0 {
-					watch.mask = 0
-				}
-			}
-			err = nil
-		}
-		w.deleteWatch(watch)
-		w.startRead(watch)
-		return err
-	}
-	return nil
-}
-
-// readEvents reads from the I/O completion port, converts the
-// received events into Event objects and sends them via the Event channel.
-// Entry point to the I/O thread.
-func (w *Watcher) readEvents() {
-	var (
-		n, key uint32
-		ov     *syscall.Overlapped
-	)
-	runtime.LockOSThread()
-
-	for {
-		e := syscall.GetQueuedCompletionStatus(w.port, &n, &key, &ov, syscall.INFINITE)
-		watch := (*watch)(unsafe.Pointer(ov))
-
-		if watch == nil {
-			select {
-			case ch := <-w.quit:
-				for _, index := range w.watches {
-					for _, watch := range index {
-						w.deleteWatch(watch)
-						w.startRead(watch)
-					}
-				}
-				var err error
-				if e := syscall.CloseHandle(w.port); e != nil {
-					err = os.NewSyscallError("CloseHandle", e)
-				}
-				close(w.Event)
-				close(w.Error)
-				ch <- err
-				return
-			case in := <-w.input:
-				switch in.op {
-				case opAddWatch:
-					in.reply <- w.addWatch(in.path, uint64(in.flags))
-				case opRemoveWatch:
-					in.reply <- w.removeWatch(in.path)
-				}
-			default:
-			}
-			continue
-		}
-
-		switch e {
-		case syscall.ERROR_ACCESS_DENIED:
-			// Watched directory was probably removed
-			w.sendEvent(watch.path, watch.mask&FS_DELETE_SELF)
-			w.deleteWatch(watch)
-			w.startRead(watch)
-			continue
-		case syscall.ERROR_OPERATION_ABORTED:
-			// CancelIo was called on this handle
-			continue
-		default:
-			w.Error <- os.NewSyscallError("GetQueuedCompletionPort", e)
-			continue
-		case nil:
-		}
-
-		var offset uint32
-		for {
-			if n == 0 {
-				w.Event <- &Event{Mask: FS_Q_OVERFLOW}
-				w.Error <- errors.New("short read in readEvents()")
-				break
-			}
-
-			// Point "raw" to the event in the buffer
-			raw := (*syscall.FileNotifyInformation)(unsafe.Pointer(&watch.buf[offset]))
-			buf := (*[syscall.MAX_PATH]uint16)(unsafe.Pointer(&raw.FileName))
-			name := syscall.UTF16ToString(buf[:raw.FileNameLength/2])
-			fullname := watch.path + "/" + name
-
-			var mask uint64
-			switch raw.Action {
-			case syscall.FILE_ACTION_REMOVED:
-				mask = FS_DELETE_SELF
-			case syscall.FILE_ACTION_MODIFIED:
-				mask = FS_MODIFY
-			case syscall.FILE_ACTION_RENAMED_OLD_NAME:
-				watch.rename = name
-			case syscall.FILE_ACTION_RENAMED_NEW_NAME:
-				if watch.names[watch.rename] != 0 {
-					watch.names[name] |= watch.names[watch.rename]
-					delete(watch.names, watch.rename)
-					mask = FS_MOVE_SELF
-				}
-			}
-
-			sendNameEvent := func() {
-				if w.sendEvent(fullname, watch.names[name]&mask) {
-					if watch.names[name]&FS_ONESHOT != 0 {
-						delete(watch.names, name)
-					}
-				}
-			}
-			if raw.Action != syscall.FILE_ACTION_RENAMED_NEW_NAME {
-				sendNameEvent()
-			}
-			if raw.Action == syscall.FILE_ACTION_REMOVED {
-				w.sendEvent(fullname, watch.names[name]&FS_IGNORED)
-				delete(watch.names, name)
-			}
-			if w.sendEvent(fullname, watch.mask&toFSnotifyFlags(raw.Action)) {
-				if watch.mask&FS_ONESHOT != 0 {
-					watch.mask = 0
-				}
-			}
-			if raw.Action == syscall.FILE_ACTION_RENAMED_NEW_NAME {
-				fullname = watch.path + "/" + watch.rename
-				sendNameEvent()
-			}
-
-			// Move to the next event in the buffer
-			if raw.NextEntryOffset == 0 {
-				break
-			}
-			offset += raw.NextEntryOffset
-		}
-
-		if err := w.startRead(watch); err != nil {
-			w.Error <- err
-		}
-	}
-}
-
-func (w *Watcher) sendEvent(name string, mask uint64) bool {
-	if mask == 0 {
-		return false
-	}
-	event := &Event{Mask: uint32(mask), Name: name}
-	if mask&FS_MOVE != 0 {
-		if mask&FS_MOVED_FROM != 0 {
-			w.cookie++
-		}
-		event.Cookie = w.cookie
-	}
-	select {
-	case ch := <-w.quit:
-		w.quit <- ch
-	case w.Event <- event:
-	}
-	return true
-}
-
-// String formats the event e in the form
-// "filename: 0xEventMask = FS_ACCESS|FS_ATTRIB_|..."
-func (e *Event) String() string {
-	var events string
-	m := e.Mask
-	for _, b := range eventBits {
-		if m&b.Value != 0 {
-			m &^= b.Value
-			events += "|" + b.Name
-		}
-	}
-	if m != 0 {
-		events += fmt.Sprintf("|%#x", m)
-	}
-	if len(events) > 0 {
-		events = " == " + events[1:]
-	}
-	return fmt.Sprintf("%q: %#x%s", e.Name, e.Mask, events)
-}
-
-func toWindowsFlags(mask uint64) uint32 {
-	var m uint32
-	if mask&FS_ACCESS != 0 {
-		m |= syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS
-	}
-	if mask&FS_MODIFY != 0 {
-		m |= syscall.FILE_NOTIFY_CHANGE_LAST_WRITE
-	}
-	if mask&FS_ATTRIB != 0 {
-		m |= syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES
-	}
-	if mask&(FS_MOVE|FS_CREATE|FS_DELETE) != 0 {
-		m |= syscall.FILE_NOTIFY_CHANGE_FILE_NAME | syscall.FILE_NOTIFY_CHANGE_DIR_NAME
-	}
-	return m
-}
-
-func toFSnotifyFlags(action uint32) uint64 {
-	switch action {
-	case syscall.FILE_ACTION_ADDED:
-		return FS_CREATE
-	case syscall.FILE_ACTION_REMOVED:
-		return FS_DELETE
-	case syscall.FILE_ACTION_MODIFIED:
-		return FS_MODIFY
-	case syscall.FILE_ACTION_RENAMED_OLD_NAME:
-		return FS_MOVED_FROM
-	case syscall.FILE_ACTION_RENAMED_NEW_NAME:
-		return FS_MOVED_TO
-	}
-	return 0
-}
-
-const (
-	// Options for AddWatch
-	FS_ONESHOT = 0x80000000
-	FS_ONLYDIR = 0x1000000
-
-	// Events
-	FS_ACCESS      = 0x1
-	FS_ALL_EVENTS  = 0xfff
-	FS_ATTRIB      = 0x4
-	FS_CLOSE       = 0x18
-	FS_CREATE      = 0x100
-	FS_DELETE      = 0x200
-	FS_DELETE_SELF = 0x400
-	FS_MODIFY      = 0x2
-	FS_MOVE        = 0xc0
-	FS_MOVED_FROM  = 0x40
-	FS_MOVED_TO    = 0x80
-	FS_MOVE_SELF   = 0x800
-
-	// Special events
-	FS_IGNORED    = 0x8000
-	FS_Q_OVERFLOW = 0x4000
-)
-
-var eventBits = []struct {
-	Value uint32
-	Name  string
-}{
-	{FS_ACCESS, "FS_ACCESS"},
-	{FS_ATTRIB, "FS_ATTRIB"},
-	{FS_CREATE, "FS_CREATE"},
-	{FS_DELETE, "FS_DELETE"},
-	{FS_DELETE_SELF, "FS_DELETE_SELF"},
-	{FS_MODIFY, "FS_MODIFY"},
-	{FS_MOVED_FROM, "FS_MOVED_FROM"},
-	{FS_MOVED_TO, "FS_MOVED_TO"},
-	{FS_MOVE_SELF, "FS_MOVE_SELF"},
-	{FS_IGNORED, "FS_IGNORED"},
-	{FS_Q_OVERFLOW, "FS_Q_OVERFLOW"},
-}
diff --git a/winfsnotify/winfsnotify_test.go b/winfsnotify/winfsnotify_test.go
deleted file mode 100644
index de4f514..0000000
--- a/winfsnotify/winfsnotify_test.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build windows
-// +build windows
-
-package winfsnotify
-
-import (
-	"io/ioutil"
-	"os"
-	"sync/atomic"
-	"testing"
-	"time"
-)
-
-func expect(t *testing.T, eventstream <-chan *Event, name string, mask uint32) {
-	t.Logf(`expected: "%s": 0x%x`, name, mask)
-	select {
-	case event := <-eventstream:
-		if event == nil {
-			t.Fatal("nil event received")
-		}
-		t.Logf("received: %s", event)
-		if event.Name != name || event.Mask != mask {
-			t.Fatal("did not receive expected event")
-		}
-	case <-time.After(1 * time.Second):
-		t.Fatal("timed out waiting for event")
-	}
-}
-
-func TestNotifyEvents(t *testing.T) {
-	watcher, err := NewWatcher()
-	if err != nil {
-		t.Fatalf("NewWatcher() failed: %s", err)
-	}
-
-	testDir := "TestNotifyEvents.testdirectory"
-	testFile := testDir + "/TestNotifyEvents.testfile"
-	testFile2 := testFile + ".new"
-	const mask = FS_ALL_EVENTS & ^(FS_ATTRIB|FS_CLOSE) | FS_IGNORED
-
-	// Add a watch for testDir
-	os.RemoveAll(testDir)
-	if err = os.Mkdir(testDir, 0777); err != nil {
-		t.Fatalf("Failed to create test directory: %s", err)
-	}
-	defer os.RemoveAll(testDir)
-	err = watcher.AddWatch(testDir, mask)
-	if err != nil {
-		t.Fatalf("Watcher.Watch() failed: %s", err)
-	}
-
-	// Receive errors on the error channel on a separate goroutine
-	go func() {
-		for err := range watcher.Error {
-			t.Fatalf("error received: %s", err)
-		}
-	}()
-
-	// Create a file
-	file, err := os.Create(testFile)
-	if err != nil {
-		t.Fatalf("creating test file failed: %s", err)
-	}
-	expect(t, watcher.Event, testFile, FS_CREATE)
-
-	err = watcher.AddWatch(testFile, mask)
-	if err != nil {
-		t.Fatalf("Watcher.Watch() failed: %s", err)
-	}
-
-	if _, err = file.WriteString("hello, world"); err != nil {
-		t.Fatalf("failed to write to test file: %s", err)
-	}
-	if err = file.Close(); err != nil {
-		t.Fatalf("failed to close test file: %s", err)
-	}
-	expect(t, watcher.Event, testFile, FS_MODIFY)
-	expect(t, watcher.Event, testFile, FS_MODIFY)
-
-	if err = os.Rename(testFile, testFile2); err != nil {
-		t.Fatalf("failed to rename test file: %s", err)
-	}
-	expect(t, watcher.Event, testFile, FS_MOVED_FROM)
-	expect(t, watcher.Event, testFile2, FS_MOVED_TO)
-	expect(t, watcher.Event, testFile, FS_MOVE_SELF)
-
-	if err = os.RemoveAll(testDir); err != nil {
-		t.Fatalf("failed to remove test directory: %s", err)
-	}
-	expect(t, watcher.Event, testFile2, FS_DELETE_SELF)
-	expect(t, watcher.Event, testFile2, FS_IGNORED)
-	expect(t, watcher.Event, testFile2, FS_DELETE)
-	expect(t, watcher.Event, testDir, FS_DELETE_SELF)
-	expect(t, watcher.Event, testDir, FS_IGNORED)
-
-	t.Log("calling Close()")
-	if err = watcher.Close(); err != nil {
-		t.Fatalf("failed to close watcher: %s", err)
-	}
-}
-
-func TestNotifyClose(t *testing.T) {
-	watcher, _ := NewWatcher()
-	watcher.Close()
-
-	var done int32
-	go func() {
-		watcher.Close()
-		atomic.StoreInt32(&done, 1)
-	}()
-
-	time.Sleep(50 * time.Millisecond)
-	if atomic.LoadInt32(&done) == 0 {
-		t.Fatal("double Close() test failed: second Close() call didn't return")
-	}
-
-	dir, err := ioutil.TempDir("", "wininotify")
-	if err != nil {
-		t.Fatalf("TempDir failed: %s", err)
-	}
-	defer os.RemoveAll(dir)
-
-	err = watcher.Watch(dir)
-	if err == nil {
-		t.Fatal("expected error on Watch() after Close(), got nil")
-	}
-}
