diff --git a/vendor/github.com/rjeczalik/notify/README.md b/vendor/github.com/rjeczalik/notify/README.md
index a728d1dd04261ae3150483089dc4f7623b378ea7..02a5f32908959c71d35477ddca86c83006d7c6fa 100644
--- a/vendor/github.com/rjeczalik/notify/README.md
+++ b/vendor/github.com/rjeczalik/notify/README.md
@@ -18,4 +18,4 @@ Filesystem event notification library on steroids. (under active development)
 - [github.com/rjeczalik/cmd/notify](https://godoc.org/github.com/rjeczalik/cmd/notify)
 - [github.com/cortesi/devd](https://github.com/cortesi/devd)
 - [github.com/cortesi/modd](https://github.com/cortesi/modd)
-
+- [github.com/syncthing/syncthing-inotify](https://github.com/syncthing/syncthing-inotify)
diff --git a/vendor/github.com/rjeczalik/notify/appveyor.yml b/vendor/github.com/rjeczalik/notify/appveyor.yml
index 8e762d05cb848a1b3e3adb63f4369fae6c801cbb..a495bd7c7300c7a4d97df0cfed69a065d82fca38 100644
--- a/vendor/github.com/rjeczalik/notify/appveyor.yml
+++ b/vendor/github.com/rjeczalik/notify/appveyor.yml
@@ -16,7 +16,7 @@ install:
 build_script:
  - go tool vet -all .
  - go build ./...
- - go test -v -race ./...
+ - go test -v -timeout 60s -race ./...
 
 test: off
 
diff --git a/vendor/github.com/rjeczalik/notify/debug.go b/vendor/github.com/rjeczalik/notify/debug.go
index bd9bc468dfd3c6e7e54ebcb4eb926e3c8a2e5081..2a3eb33700ec00a3a60d8521950f3fc73a12756c 100644
--- a/vendor/github.com/rjeczalik/notify/debug.go
+++ b/vendor/github.com/rjeczalik/notify/debug.go
@@ -2,10 +2,52 @@
 // Use of this source code is governed by the MIT license that can be
 // found in the LICENSE file.
 
-// +build !debug
-
 package notify
 
-func dbgprint(...interface{}) {}
+import (
+	"log"
+	"os"
+	"runtime"
+	"strings"
+)
+
+var dbgprint func(...interface{})
+
+var dbgprintf func(string, ...interface{})
+
+var dbgcallstack func(max int) []string
 
-func dbgprintf(string, ...interface{}) {}
+func init() {
+	if _, ok := os.LookupEnv("NOTIFY_DEBUG"); ok || debugTag {
+		log.SetOutput(os.Stdout)
+		log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)
+		dbgprint = func(v ...interface{}) {
+			v = append([]interface{}{"[D] "}, v...)
+			log.Println(v...)
+		}
+		dbgprintf = func(format string, v ...interface{}) {
+			format = "[D] " + format
+			log.Printf(format, v...)
+		}
+		dbgcallstack = func(max int) []string {
+			pc, stack := make([]uintptr, max), make([]string, 0, max)
+			runtime.Callers(2, pc)
+			for _, pc := range pc {
+				if f := runtime.FuncForPC(pc); f != nil {
+					fname := f.Name()
+					idx := strings.LastIndex(fname, string(os.PathSeparator))
+					if idx != -1 {
+						stack = append(stack, fname[idx+1:])
+					} else {
+						stack = append(stack, fname)
+					}
+				}
+			}
+			return stack
+		}
+		return
+	}
+	dbgprint = func(v ...interface{}) {}
+	dbgprintf = func(format string, v ...interface{}) {}
+	dbgcallstack = func(max int) []string { return nil }
+}
diff --git a/vendor/github.com/rjeczalik/notify/debug_debug.go b/vendor/github.com/rjeczalik/notify/debug_debug.go
index f0622917f500200c26ef162b5d32df9b70134854..6fca891ab305a99641416f56397b60c45358ca57 100644
--- a/vendor/github.com/rjeczalik/notify/debug_debug.go
+++ b/vendor/github.com/rjeczalik/notify/debug_debug.go
@@ -6,38 +6,4 @@
 
 package notify
 
-import (
-	"fmt"
-	"os"
-	"runtime"
-	"strings"
-)
-
-func dbgprint(v ...interface{}) {
-	fmt.Printf("[D] ")
-	fmt.Print(v...)
-	fmt.Printf("\n\n")
-}
-
-func dbgprintf(format string, v ...interface{}) {
-	fmt.Printf("[D] ")
-	fmt.Printf(format, v...)
-	fmt.Printf("\n\n")
-}
-
-func dbgcallstack(max int) []string {
-	pc, stack := make([]uintptr, max), make([]string, 0, max)
-	runtime.Callers(2, pc)
-	for _, pc := range pc {
-		if f := runtime.FuncForPC(pc); f != nil {
-			fname := f.Name()
-			idx := strings.LastIndex(fname, string(os.PathSeparator))
-			if idx != -1 {
-				stack = append(stack, fname[idx+1:])
-			} else {
-				stack = append(stack, fname)
-			}
-		}
-	}
-	return stack
-}
+var debugTag bool = true
diff --git a/vendor/github.com/rjeczalik/notify/debug_nodebug.go b/vendor/github.com/rjeczalik/notify/debug_nodebug.go
new file mode 100644
index 0000000000000000000000000000000000000000..be391a2769d966f468354cd4222738261f8a28f1
--- /dev/null
+++ b/vendor/github.com/rjeczalik/notify/debug_nodebug.go
@@ -0,0 +1,9 @@
+// Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+// +build !debug
+
+package notify
+
+var debugTag bool = false
diff --git a/vendor/github.com/rjeczalik/notify/doc.go b/vendor/github.com/rjeczalik/notify/doc.go
index 8a99ddda62eea859d664df4bf86dda1df82e1d06..60543c0838b7508290e68eac066b98ce7e243870 100644
--- a/vendor/github.com/rjeczalik/notify/doc.go
+++ b/vendor/github.com/rjeczalik/notify/doc.go
@@ -12,11 +12,14 @@
 // source file.
 //
 // On top of filesystem watchers notify maintains a watchpoint tree, which provides
-// strategy for creating and closing filesystem watches and dispatching filesystem
+// a strategy for creating and closing filesystem watches and dispatching filesystem
 // events to user channels.
 //
 // An event set is just an event list joint using bitwise OR operator
 // into a single event value.
+// Both the platform-independent (see Constants) and specific events can be used.
+// Refer to the event_*.go source files for information about the available
+// events.
 //
 // A filesystem watch or just a watch is platform-specific entity which represents
 // a single path registered for notifications for specific event set. Setting a watch
@@ -35,6 +38,6 @@
 // A watchpoint is a list of user channel and event set pairs for particular
 // path (watchpoint tree's node). A single watchpoint can contain multiple
 // different user channels registered to listen for one or more events. A single
-// user channel can be registered in one or more watchpoints, recurisve and
+// user channel can be registered in one or more watchpoints, recursive and
 // non-recursive ones as well.
 package notify
diff --git a/vendor/github.com/rjeczalik/notify/event.go b/vendor/github.com/rjeczalik/notify/event.go
index e045edcecc93461ad2f2a36f5035e3ee9f450213..c128841972a7d377d3adcdeba08bc6607e2a2f2e 100644
--- a/vendor/github.com/rjeczalik/notify/event.go
+++ b/vendor/github.com/rjeczalik/notify/event.go
@@ -73,7 +73,7 @@ func (e Event) String() string {
 //
 //    https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/index.html#//apple_ref/doc/constant_group/FSEventStreamEventFlags
 //
-// Under Linux (inotify) Sys() always returns a non-nil *syscall.InotifyEvent
+// Under Linux (inotify) Sys() always returns a non-nil *unix.InotifyEvent
 // value, defined as:
 //
 //   type InotifyEvent struct {
diff --git a/vendor/github.com/rjeczalik/notify/event_inotify.go b/vendor/github.com/rjeczalik/notify/event_inotify.go
index 82954a9b3821dfeb838ecef319aba010350b5c5d..1f32bb73e0f2dd290ae0fbdbd78549e6b86df4a9 100644
--- a/vendor/github.com/rjeczalik/notify/event_inotify.go
+++ b/vendor/github.com/rjeczalik/notify/event_inotify.go
@@ -6,7 +6,7 @@
 
 package notify
 
-import "syscall"
+import "golang.org/x/sys/unix"
 
 // Platform independent event values.
 const (
@@ -25,18 +25,18 @@ const (
 // Inotify specific masks are legal, implemented events that are guaranteed to
 // work with notify package on linux-based systems.
 const (
-	InAccess       = Event(syscall.IN_ACCESS)        // File was accessed
-	InModify       = Event(syscall.IN_MODIFY)        // File was modified
-	InAttrib       = Event(syscall.IN_ATTRIB)        // Metadata changed
-	InCloseWrite   = Event(syscall.IN_CLOSE_WRITE)   // Writtable file was closed
-	InCloseNowrite = Event(syscall.IN_CLOSE_NOWRITE) // Unwrittable file closed
-	InOpen         = Event(syscall.IN_OPEN)          // File was opened
-	InMovedFrom    = Event(syscall.IN_MOVED_FROM)    // File was moved from X
-	InMovedTo      = Event(syscall.IN_MOVED_TO)      // File was moved to Y
-	InCreate       = Event(syscall.IN_CREATE)        // Subfile was created
-	InDelete       = Event(syscall.IN_DELETE)        // Subfile was deleted
-	InDeleteSelf   = Event(syscall.IN_DELETE_SELF)   // Self was deleted
-	InMoveSelf     = Event(syscall.IN_MOVE_SELF)     // Self was moved
+	InAccess       = Event(unix.IN_ACCESS)        // File was accessed
+	InModify       = Event(unix.IN_MODIFY)        // File was modified
+	InAttrib       = Event(unix.IN_ATTRIB)        // Metadata changed
+	InCloseWrite   = Event(unix.IN_CLOSE_WRITE)   // Writtable file was closed
+	InCloseNowrite = Event(unix.IN_CLOSE_NOWRITE) // Unwrittable file closed
+	InOpen         = Event(unix.IN_OPEN)          // File was opened
+	InMovedFrom    = Event(unix.IN_MOVED_FROM)    // File was moved from X
+	InMovedTo      = Event(unix.IN_MOVED_TO)      // File was moved to Y
+	InCreate       = Event(unix.IN_CREATE)        // Subfile was created
+	InDelete       = Event(unix.IN_DELETE)        // Subfile was deleted
+	InDeleteSelf   = Event(unix.IN_DELETE_SELF)   // Self was deleted
+	InMoveSelf     = Event(unix.IN_MOVE_SELF)     // Self was moved
 )
 
 var osestr = map[Event]string{
@@ -56,15 +56,15 @@ var osestr = map[Event]string{
 
 // Inotify behavior events are not **currently** supported by notify package.
 const (
-	inDontFollow = Event(syscall.IN_DONT_FOLLOW)
-	inExclUnlink = Event(syscall.IN_EXCL_UNLINK)
-	inMaskAdd    = Event(syscall.IN_MASK_ADD)
-	inOneshot    = Event(syscall.IN_ONESHOT)
-	inOnlydir    = Event(syscall.IN_ONLYDIR)
+	inDontFollow = Event(unix.IN_DONT_FOLLOW)
+	inExclUnlink = Event(unix.IN_EXCL_UNLINK)
+	inMaskAdd    = Event(unix.IN_MASK_ADD)
+	inOneshot    = Event(unix.IN_ONESHOT)
+	inOnlydir    = Event(unix.IN_ONLYDIR)
 )
 
 type event struct {
-	sys   syscall.InotifyEvent
+	sys   unix.InotifyEvent
 	path  string
 	event Event
 }
@@ -72,4 +72,4 @@ type event struct {
 func (e *event) Event() Event         { return e.event }
 func (e *event) Path() string         { return e.path }
 func (e *event) Sys() interface{}     { return &e.sys }
-func (e *event) isDir() (bool, error) { return e.sys.Mask&syscall.IN_ISDIR != 0, nil }
+func (e *event) isDir() (bool, error) { return e.sys.Mask&unix.IN_ISDIR != 0, nil }
diff --git a/vendor/github.com/rjeczalik/notify/event_readdcw.go b/vendor/github.com/rjeczalik/notify/event_readdcw.go
index 11ead9e2970ddb71187cce16352c01baf8c61d60..f7b82de0c4ab3537ed634c7beac8c7ece3240a97 100644
--- a/vendor/github.com/rjeczalik/notify/event_readdcw.go
+++ b/vendor/github.com/rjeczalik/notify/event_readdcw.go
@@ -27,7 +27,11 @@ const (
 	dirmarker
 )
 
-// ReadDirectoryChangesW filters.
+// ReadDirectoryChangesW filters
+// On Windows the following events can be passed to Watch. A different set of
+// events (see actions below) are received on the channel passed to Watch.
+// For more information refer to
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx
 const (
 	FileNotifyChangeFileName   = Event(syscall.FILE_NOTIFY_CHANGE_FILE_NAME)
 	FileNotifyChangeDirName    = Event(syscall.FILE_NOTIFY_CHANGE_DIR_NAME)
@@ -48,7 +52,13 @@ const (
 // this flag should be declared in: http://golang.org/src/pkg/syscall/ztypes_windows.go
 const syscallFileNotifyChangeSecurity = 0x00000100
 
-// ReadDirectoryChangesW actions.
+// ReadDirectoryChangesW actions
+// The following events are returned on the channel passed to Watch, but cannot
+// be passed to Watch itself (see filters above). You can find a table showing
+// the relation between actions and filteres at
+// https://github.com/rjeczalik/notify/issues/10#issuecomment-66179535
+// The msdn documentation on actions is part of
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364391(v=vs.85).aspx
 const (
 	FileActionAdded          = Event(syscall.FILE_ACTION_ADDED) << 12
 	FileActionRemoved        = Event(syscall.FILE_ACTION_REMOVED) << 12
diff --git a/vendor/github.com/rjeczalik/notify/node.go b/vendor/github.com/rjeczalik/notify/node.go
index 29c1bb20af401667e1beb331ea6f68763d32f7ef..aced8b9c44a1b283c54f84df97504b51a994e6ab 100644
--- a/vendor/github.com/rjeczalik/notify/node.go
+++ b/vendor/github.com/rjeczalik/notify/node.go
@@ -6,7 +6,6 @@ package notify
 
 import (
 	"errors"
-	"fmt"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -71,7 +70,11 @@ Traverse:
 		case errSkip:
 			continue Traverse
 		default:
-			return fmt.Errorf("error while traversing %q: %v", nd.Name, err)
+			return &os.PathError{
+				Op:   "error while traversing",
+				Path: nd.Name,
+				Err:  err,
+			}
 		}
 		// TODO(rjeczalik): tolerate open failures - add failed names to
 		// AddDirError and notify users which names are not added to the tree.
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fen.go b/vendor/github.com/rjeczalik/notify/watcher_fen.go
index dd069f2a26f1734b0be32ce1663f83949458d83e..dfe77f2f1d9295c79985783cd11c18aaa677ca5a 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_fen.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_fen.go
@@ -33,14 +33,7 @@ type fen struct {
 
 // watched is a data structure representing watched file/directory.
 type watched struct {
-	// p is a path to watched file/directory
-	p string
-	// fi provides information about watched file/dir
-	fi os.FileInfo
-	// eDir represents events watched directly
-	eDir Event
-	// eNonDir represents events watched indirectly
-	eNonDir Event
+	trgWatched
 }
 
 // Stop implements trigger.
@@ -55,7 +48,7 @@ func (f *fen) Close() (err error) {
 
 // NewWatched implements trigger.
 func (*fen) NewWatched(p string, fi os.FileInfo) (*watched, error) {
-	return &watched{p: p, fi: fi}, nil
+	return &watched{trgWatched{p: p, fi: fi}}, nil
 }
 
 // Record implements trigger.
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents.go
index 9062c17c7f4377fc8e8c25e9d50c389c83088cf2..7d9b97b65d028369550ba82fd927bda1de39e17a 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_fsevents.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents.go
@@ -12,8 +12,6 @@ import (
 	"sync/atomic"
 )
 
-// TODO(rjeczalik): get rid of calls to canonical, it's tree responsibility
-
 const (
 	failure = uint32(FSEventsMustScanSubDirs | FSEventsUserDropped | FSEventsKernelDropped)
 	filter  = uint32(FSEventsCreated | FSEventsRemoved | FSEventsRenamed |
@@ -189,9 +187,6 @@ func newWatcher(c chan<- EventInfo) watcher {
 }
 
 func (fse *fsevents) watch(path string, event Event, isrec int32) (err error) {
-	if path, err = canonical(path); err != nil {
-		return err
-	}
 	if _, ok := fse.watches[path]; ok {
 		return errAlreadyWatched
 	}
@@ -211,9 +206,6 @@ func (fse *fsevents) watch(path string, event Event, isrec int32) (err error) {
 }
 
 func (fse *fsevents) unwatch(path string) (err error) {
-	if path, err = canonical(path); err != nil {
-		return
-	}
 	w, ok := fse.watches[path]
 	if !ok {
 		return errNotWatched
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go
index 5be64632e8a4f4f2fd6102c61cd8db6241b36e71..fb70de6af031d8a5d59defecc7af5e0a3eb75b71 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go
@@ -48,7 +48,7 @@ var wg sync.WaitGroup      // used to wait until the runloop starts
 // started and is ready via the wg. It also serves purpose of a dummy source,
 // thanks to it the runloop does not return as it also has at least one source
 // registered.
-var source = C.CFRunLoopSourceCreate(nil, 0, &C.CFRunLoopSourceContext{
+var source = C.CFRunLoopSourceCreate(refZero, 0, &C.CFRunLoopSourceContext{
 	perform: (C.CFRunLoopPerformCallBack)(C.gosource),
 })
 
@@ -159,8 +159,8 @@ func (s *stream) Start() error {
 		return nil
 	}
 	wg.Wait()
-	p := C.CFStringCreateWithCStringNoCopy(nil, C.CString(s.path), C.kCFStringEncodingUTF8, nil)
-	path := C.CFArrayCreate(nil, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil)
+	p := C.CFStringCreateWithCStringNoCopy(refZero, C.CString(s.path), C.kCFStringEncodingUTF8, refZero)
+	path := C.CFArrayCreate(refZero, (*unsafe.Pointer)(unsafe.Pointer(&p)), 1, nil)
 	ctx := C.FSEventStreamContext{}
 	ref := C.EventStreamCreate(&ctx, C.uintptr_t(s.info), path, C.FSEventStreamEventId(atomic.LoadUint64(&since)), latency, flags)
 	if ref == nilstream {
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.10.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.10.go
new file mode 100644
index 0000000000000000000000000000000000000000..0edd3782f5b9404fc4a69ba63a1533f4c5bf5036
--- /dev/null
+++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.10.go
@@ -0,0 +1,9 @@
+// Copyright (c) 2017 The Notify Authors. All rights reserved.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+// +build darwin,!kqueue,go1.10
+
+package notify
+
+const refZero = 0
diff --git a/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.9.go b/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.9.go
new file mode 100644
index 0000000000000000000000000000000000000000..b81c3c1859c5995dad520099df216eaa08aa1372
--- /dev/null
+++ b/vendor/github.com/rjeczalik/notify/watcher_fsevents_go1.9.go
@@ -0,0 +1,14 @@
+// Copyright (c) 2017 The Notify Authors. All rights reserved.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+// +build darwin,!kqueue,cgo,!go1.10
+
+package notify
+
+/*
+#include <CoreServices/CoreServices.h>
+*/
+import "C"
+
+var refZero = (*C.struct___CFAllocator)(nil)
diff --git a/vendor/github.com/rjeczalik/notify/watcher_inotify.go b/vendor/github.com/rjeczalik/notify/watcher_inotify.go
index 3ceaa8f3ab208656ca3f230cda5ab7ab6fe74767..d082baca0f9a814f38b6769e8fff99b34468f119 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_inotify.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_inotify.go
@@ -13,14 +13,15 @@ import (
 	"runtime"
 	"sync"
 	"sync/atomic"
-	"syscall"
 	"unsafe"
+
+	"golang.org/x/sys/unix"
 )
 
 // eventBufferSize defines the size of the buffer given to read(2) function. One
 // should not depend on this value, since it was arbitrary chosen and may be
 // changed in the future.
-const eventBufferSize = 64 * (syscall.SizeofInotifyEvent + syscall.PathMax + 1)
+const eventBufferSize = 64 * (unix.SizeofInotifyEvent + unix.PathMax + 1)
 
 // consumersCount defines the number of consumers in producer-consumer based
 // implementation. Each consumer is run in a separate goroutine and has read
@@ -43,7 +44,7 @@ type inotify struct {
 	fd           int32                 // inotify file descriptor
 	pipefd       []int                 // pipe's read and write descriptors
 	epfd         int                   // epoll descriptor
-	epes         []syscall.EpollEvent  // epoll events
+	epes         []unix.EpollEvent     // epoll events
 	buffer       [eventBufferSize]byte // inotify event buffer
 	wg           sync.WaitGroup        // wait group used to close main loop
 	c            chan<- EventInfo      // event dispatcher channel
@@ -56,13 +57,13 @@ func newWatcher(c chan<- EventInfo) watcher {
 		fd:     invalidDescriptor,
 		pipefd: []int{invalidDescriptor, invalidDescriptor},
 		epfd:   invalidDescriptor,
-		epes:   make([]syscall.EpollEvent, 0),
+		epes:   make([]unix.EpollEvent, 0),
 		c:      c,
 	}
 	runtime.SetFinalizer(i, func(i *inotify) {
 		i.epollclose()
 		if i.fd != invalidDescriptor {
-			syscall.Close(int(i.fd))
+			unix.Close(int(i.fd))
 		}
 	})
 	return i
@@ -82,13 +83,13 @@ func (i *inotify) Rewatch(path string, _, newevent Event) error {
 // one. If called for the first time, this function initializes inotify filesystem
 // monitor and starts producer-consumers goroutines.
 func (i *inotify) watch(path string, e Event) (err error) {
-	if e&^(All|Event(syscall.IN_ALL_EVENTS)) != 0 {
+	if e&^(All|Event(unix.IN_ALL_EVENTS)) != 0 {
 		return errors.New("notify: unknown event")
 	}
 	if err = i.lazyinit(); err != nil {
 		return
 	}
-	iwd, err := syscall.InotifyAddWatch(int(i.fd), path, encode(e))
+	iwd, err := unix.InotifyAddWatch(int(i.fd), path, encode(e))
 	if err != nil {
 		return
 	}
@@ -119,13 +120,13 @@ func (i *inotify) lazyinit() error {
 		i.Lock()
 		defer i.Unlock()
 		if atomic.LoadInt32(&i.fd) == invalidDescriptor {
-			fd, err := syscall.InotifyInit()
+			fd, err := unix.InotifyInit1(unix.IN_CLOEXEC)
 			if err != nil {
 				return err
 			}
 			i.fd = int32(fd)
 			if err = i.epollinit(); err != nil {
-				_, _ = i.epollclose(), syscall.Close(int(fd)) // Ignore errors.
+				_, _ = i.epollclose(), unix.Close(int(fd)) // Ignore errors.
 				i.fd = invalidDescriptor
 				return err
 			}
@@ -145,33 +146,33 @@ func (i *inotify) lazyinit() error {
 // with inotify event queue and the read end of the pipe are added to epoll set.
 // Note that `fd` member must be set before this function is called.
 func (i *inotify) epollinit() (err error) {
-	if i.epfd, err = syscall.EpollCreate1(0); err != nil {
+	if i.epfd, err = unix.EpollCreate1(0); err != nil {
 		return
 	}
-	if err = syscall.Pipe(i.pipefd); err != nil {
+	if err = unix.Pipe(i.pipefd); err != nil {
 		return
 	}
-	i.epes = []syscall.EpollEvent{
-		{Events: syscall.EPOLLIN, Fd: i.fd},
-		{Events: syscall.EPOLLIN, Fd: int32(i.pipefd[0])},
+	i.epes = []unix.EpollEvent{
+		{Events: unix.EPOLLIN, Fd: i.fd},
+		{Events: unix.EPOLLIN, Fd: int32(i.pipefd[0])},
 	}
-	if err = syscall.EpollCtl(i.epfd, syscall.EPOLL_CTL_ADD, int(i.fd), &i.epes[0]); err != nil {
+	if err = unix.EpollCtl(i.epfd, unix.EPOLL_CTL_ADD, int(i.fd), &i.epes[0]); err != nil {
 		return
 	}
-	return syscall.EpollCtl(i.epfd, syscall.EPOLL_CTL_ADD, i.pipefd[0], &i.epes[1])
+	return unix.EpollCtl(i.epfd, unix.EPOLL_CTL_ADD, i.pipefd[0], &i.epes[1])
 }
 
 // epollclose closes the file descriptor created by the call to epoll_create(2)
 // and two file descriptors opened by pipe(2) function.
 func (i *inotify) epollclose() (err error) {
 	if i.epfd != invalidDescriptor {
-		if err = syscall.Close(i.epfd); err == nil {
+		if err = unix.Close(i.epfd); err == nil {
 			i.epfd = invalidDescriptor
 		}
 	}
 	for n, fd := range i.pipefd {
 		if fd != invalidDescriptor {
-			switch e := syscall.Close(fd); {
+			switch e := unix.Close(fd); {
 			case e != nil && err == nil:
 				err = e
 			case e == nil:
@@ -187,10 +188,10 @@ func (i *inotify) epollclose() (err error) {
 // one of the event's consumers. If pipe fd became ready, loop function closes
 // all file descriptors opened by lazyinit method and returns afterwards.
 func (i *inotify) loop(esch chan<- []*event) {
-	epes := make([]syscall.EpollEvent, 1)
+	epes := make([]unix.EpollEvent, 1)
 	fd := atomic.LoadInt32(&i.fd)
 	for {
-		switch _, err := syscall.EpollWait(i.epfd, epes, -1); err {
+		switch _, err := unix.EpollWait(i.epfd, epes, -1); err {
 		case nil:
 			switch epes[0].Fd {
 			case fd:
@@ -199,17 +200,17 @@ func (i *inotify) loop(esch chan<- []*event) {
 			case int32(i.pipefd[0]):
 				i.Lock()
 				defer i.Unlock()
-				if err = syscall.Close(int(fd)); err != nil && err != syscall.EINTR {
+				if err = unix.Close(int(fd)); err != nil && err != unix.EINTR {
 					panic("notify: close(2) error " + err.Error())
 				}
 				atomic.StoreInt32(&i.fd, invalidDescriptor)
-				if err = i.epollclose(); err != nil && err != syscall.EINTR {
+				if err = i.epollclose(); err != nil && err != unix.EINTR {
 					panic("notify: epollclose error " + err.Error())
 				}
 				close(esch)
 				return
 			}
-		case syscall.EINTR:
+		case unix.EINTR:
 			continue
 		default: // We should never reach this line.
 			panic("notify: epoll_wait(2) error " + err.Error())
@@ -220,22 +221,22 @@ func (i *inotify) loop(esch chan<- []*event) {
 // read reads events from an inotify file descriptor. It does not handle errors
 // returned from read(2) function since they are not critical to watcher logic.
 func (i *inotify) read() (es []*event) {
-	n, err := syscall.Read(int(i.fd), i.buffer[:])
-	if err != nil || n < syscall.SizeofInotifyEvent {
+	n, err := unix.Read(int(i.fd), i.buffer[:])
+	if err != nil || n < unix.SizeofInotifyEvent {
 		return
 	}
-	var sys *syscall.InotifyEvent
-	nmin := n - syscall.SizeofInotifyEvent
+	var sys *unix.InotifyEvent
+	nmin := n - unix.SizeofInotifyEvent
 	for pos, path := 0, ""; pos <= nmin; {
-		sys = (*syscall.InotifyEvent)(unsafe.Pointer(&i.buffer[pos]))
-		pos += syscall.SizeofInotifyEvent
+		sys = (*unix.InotifyEvent)(unsafe.Pointer(&i.buffer[pos]))
+		pos += unix.SizeofInotifyEvent
 		if path = ""; sys.Len > 0 {
 			endpos := pos + int(sys.Len)
 			path = string(bytes.TrimRight(i.buffer[pos:endpos], "\x00"))
 			pos = endpos
 		}
 		es = append(es, &event{
-			sys: syscall.InotifyEvent{
+			sys: unix.InotifyEvent{
 				Wd:     sys.Wd,
 				Mask:   sys.Mask,
 				Cookie: sys.Cookie,
@@ -268,7 +269,7 @@ func (i *inotify) transform(es []*event) []*event {
 	var multi []*event
 	i.RLock()
 	for idx, e := range es {
-		if e.sys.Mask&(syscall.IN_IGNORED|syscall.IN_Q_OVERFLOW) != 0 {
+		if e.sys.Mask&(unix.IN_IGNORED|unix.IN_Q_OVERFLOW) != 0 {
 			es[idx] = nil
 			continue
 		}
@@ -317,7 +318,7 @@ func encode(e Event) uint32 {
 // can be nil when the event should not be passed on.
 func decode(mask Event, e *event) (syse *event) {
 	if sysmask := uint32(mask) & e.sys.Mask; sysmask != 0 {
-		syse = &event{sys: syscall.InotifyEvent{
+		syse = &event{sys: unix.InotifyEvent{
 			Wd:     e.sys.Wd,
 			Mask:   e.sys.Mask,
 			Cookie: e.sys.Cookie,
@@ -357,7 +358,7 @@ func (i *inotify) Unwatch(path string) (err error) {
 		return errors.New("notify: path " + path + " is already watched")
 	}
 	fd := atomic.LoadInt32(&i.fd)
-	if _, err = syscall.InotifyRmWatch(int(fd), uint32(iwd)); err != nil {
+	if err = removeInotifyWatch(fd, iwd); err != nil {
 		return
 	}
 	i.Lock()
@@ -377,12 +378,12 @@ func (i *inotify) Close() (err error) {
 		return nil
 	}
 	for iwd := range i.m {
-		if _, e := syscall.InotifyRmWatch(int(i.fd), uint32(iwd)); e != nil && err == nil {
+		if e := removeInotifyWatch(i.fd, iwd); e != nil && err == nil {
 			err = e
 		}
 		delete(i.m, iwd)
 	}
-	switch _, errwrite := syscall.Write(i.pipefd[1], []byte{0x00}); {
+	switch _, errwrite := unix.Write(i.pipefd[1], []byte{0x00}); {
 	case errwrite != nil && err == nil:
 		err = errwrite
 		fallthrough
@@ -394,3 +395,11 @@ func (i *inotify) Close() (err error) {
 	}
 	return
 }
+
+// if path was removed, notify already removed the watch and returns EINVAL error
+func removeInotifyWatch(fd int32, iwd int32) (err error) {
+	if _, err = unix.InotifyRmWatch(int(fd), uint32(iwd)); err != nil && err != unix.EINVAL {
+		return
+	}
+	return nil
+}
diff --git a/vendor/github.com/rjeczalik/notify/watcher_kqueue.go b/vendor/github.com/rjeczalik/notify/watcher_kqueue.go
index 6d500b700d736a38b4a008eef90d5cf2b5fa45a9..22e3c2c4a46018c9185e7de574411c73777bf9e5 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_kqueue.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_kqueue.go
@@ -36,16 +36,9 @@ type kq struct {
 
 // watched is a data structure representing watched file/directory.
 type watched struct {
-	// p is a path to watched file/directory.
-	p string
+	trgWatched
 	// fd is a file descriptor for watched file/directory.
 	fd int
-	// fi provides information about watched file/dir.
-	fi os.FileInfo
-	// eDir represents events watched directly.
-	eDir Event
-	// eNonDir represents events watched indirectly.
-	eNonDir Event
 }
 
 // Stop implements trigger.
@@ -66,7 +59,10 @@ func (*kq) NewWatched(p string, fi os.FileInfo) (*watched, error) {
 	if err != nil {
 		return nil, err
 	}
-	return &watched{fd: fd, p: p, fi: fi}, nil
+	return &watched{
+		trgWatched: trgWatched{p: p, fi: fi},
+		fd:         fd,
+	}, nil
 }
 
 // Record implements trigger.
diff --git a/vendor/github.com/rjeczalik/notify/watcher_readdcw.go b/vendor/github.com/rjeczalik/notify/watcher_readdcw.go
index 5923bfddae5818f1419770199675312eb387de4e..1494fcd79993a04b6eafd88a14f269c6b99568b4 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_readdcw.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_readdcw.go
@@ -284,16 +284,18 @@ func (r *readdcw) watch(path string, event Event, recursive bool) (err error) {
 			return
 		}
 		r.Lock()
+		defer r.Unlock()
 		if wd, ok = r.m[path]; ok {
-			r.Unlock()
+			dbgprint("watch: exists already")
 			return
 		}
 		if wd, err = newWatched(r.cph, uint32(event), recursive, path); err != nil {
-			r.Unlock()
 			return
 		}
 		r.m[path] = wd
-		r.Unlock()
+		dbgprint("watch: new watch added")
+	} else {
+		dbgprint("watch: exists already")
 	}
 	return nil
 }
@@ -337,33 +339,32 @@ func (r *readdcw) loop() {
 			continue
 		}
 		overEx := (*overlappedEx)(unsafe.Pointer(overlapped))
-		if n == 0 {
-			r.loopstate(overEx)
-		} else {
+		if n != 0 {
 			r.loopevent(n, overEx)
 			if err = overEx.parent.readDirChanges(); err != nil {
 				// TODO: error handling
 			}
 		}
+		r.loopstate(overEx)
 	}
 }
 
 // TODO(pknap) : doc
 func (r *readdcw) loopstate(overEx *overlappedEx) {
-	filter := atomic.LoadUint32(&overEx.parent.parent.filter)
+	r.Lock()
+	defer r.Unlock()
+	filter := overEx.parent.parent.filter
 	if filter&onlyMachineStates == 0 {
 		return
 	}
 	if overEx.parent.parent.count--; overEx.parent.parent.count == 0 {
 		switch filter & onlyMachineStates {
 		case stateRewatch:
-			r.Lock()
+			dbgprint("loopstate rewatch")
 			overEx.parent.parent.recreate(r.cph)
-			r.Unlock()
 		case stateUnwatch:
-			r.Lock()
+			dbgprint("loopstate unwatch")
 			delete(r.m, syscall.UTF16ToString(overEx.parent.pathw))
-			r.Unlock()
 		case stateCPClose:
 		default:
 			panic(`notify: windows loopstate logic error`)
@@ -450,8 +451,8 @@ func (r *readdcw) rewatch(path string, oldevent, newevent uint32, recursive bool
 	}
 	var wd *watched
 	r.Lock()
-	if wd, err = r.nonStateWatched(path); err != nil {
-		r.Unlock()
+	defer r.Unlock()
+	if wd, err = r.nonStateWatchedLocked(path); err != nil {
 		return
 	}
 	if wd.filter&(onlyNotifyChanges|onlyNGlobalEvents) != oldevent {
@@ -462,21 +463,19 @@ func (r *readdcw) rewatch(path string, oldevent, newevent uint32, recursive bool
 	if err = wd.closeHandle(); err != nil {
 		wd.filter = oldevent
 		wd.recursive = recursive
-		r.Unlock()
 		return
 	}
-	r.Unlock()
 	return
 }
 
 // TODO : pknap
-func (r *readdcw) nonStateWatched(path string) (wd *watched, err error) {
+func (r *readdcw) nonStateWatchedLocked(path string) (wd *watched, err error) {
 	wd, ok := r.m[path]
 	if !ok || wd == nil {
 		err = errors.New(`notify: ` + path + ` path is unwatched`)
 		return
 	}
-	if filter := atomic.LoadUint32(&wd.filter); filter&onlyMachineStates != 0 {
+	if wd.filter&onlyMachineStates != 0 {
 		err = errors.New(`notify: another re/unwatching operation in progress`)
 		return
 	}
@@ -497,17 +496,26 @@ func (r *readdcw) RecursiveUnwatch(path string) error {
 func (r *readdcw) unwatch(path string) (err error) {
 	var wd *watched
 	r.Lock()
-	if wd, err = r.nonStateWatched(path); err != nil {
-		r.Unlock()
+	defer r.Unlock()
+	if wd, err = r.nonStateWatchedLocked(path); err != nil {
 		return
 	}
 	wd.filter |= stateUnwatch
 	if err = wd.closeHandle(); err != nil {
 		wd.filter &^= stateUnwatch
-		r.Unlock()
 		return
 	}
-	r.Unlock()
+	if _, attrErr := syscall.GetFileAttributes(&wd.pathw[0]); attrErr != nil {
+		for _, g := range wd.digrip {
+			if g != nil {
+				dbgprint("unwatch: posting")
+				if err = syscall.PostQueuedCompletionStatus(r.cph, 0, 0, (*syscall.Overlapped)(unsafe.Pointer(g.ovlapped))); err != nil {
+					wd.filter &^= stateUnwatch
+					return
+				}
+			}
+		}
+	}
 	return
 }
 
diff --git a/vendor/github.com/rjeczalik/notify/watcher_trigger.go b/vendor/github.com/rjeczalik/notify/watcher_trigger.go
index d079d59b0a10991243de9fb393e98bfd8932ad06..78151f909bc905d3ec68d9603b06529d1293b73c 100644
--- a/vendor/github.com/rjeczalik/notify/watcher_trigger.go
+++ b/vendor/github.com/rjeczalik/notify/watcher_trigger.go
@@ -23,6 +23,7 @@
 package notify
 
 import (
+	"fmt"
 	"os"
 	"path/filepath"
 	"strings"
@@ -56,6 +57,19 @@ type trigger interface {
 	IsStop(n interface{}, err error) bool
 }
 
+// trgWatched is a the base data structure representing watched file/directory.
+// The platform specific full data structure (watched) must embed this type.
+type trgWatched struct {
+	// p is a path to watched file/directory.
+	p string
+	// fi provides information about watched file/dir.
+	fi os.FileInfo
+	// eDir represents events watched directly.
+	eDir Event
+	// eNonDir represents events watched indirectly.
+	eNonDir Event
+}
+
 // encode Event to native representation. Implementation is to be provided by
 // platform specific implementation.
 var encode func(Event, bool) int64
@@ -117,6 +131,9 @@ func (t *trg) Close() (err error) {
 		dbgprintf("trg: closing native watch failed: %q\n", e)
 		err = nonil(err, e)
 	}
+	if remaining := len(t.pthLkp); remaining != 0 {
+		err = nonil(err, fmt.Errorf("Not all watches were removed: len(t.pthLkp) == %v", len(t.pthLkp)))
+	}
 	t.Unlock()
 	return
 }
@@ -175,7 +192,7 @@ func decode(o int64, w Event) (e Event) {
 func (t *trg) watch(p string, e Event, fi os.FileInfo) error {
 	if err := t.singlewatch(p, e, dir, fi); err != nil {
 		if err != errAlreadyWatched {
-			return nil
+			return err
 		}
 	}
 	if fi.IsDir() {
@@ -361,7 +378,7 @@ func (t *trg) singleunwatch(p string, direct mode) error {
 	}
 	if w.eNonDir|w.eDir != 0 {
 		mod := dir
-		if w.eNonDir == 0 {
+		if w.eNonDir != 0 {
 			mod = ndir
 		}
 		if err := t.singlewatch(p, w.eNonDir|w.eDir, mod,
diff --git a/vendor/vendor.json b/vendor/vendor.json
index ddcff21fc1794ab3775f3593aaf56141bcb835b8..17844bd8ddef5865a45a87f589031214686952f1 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -286,10 +286,10 @@
 			"revisionTime": "2016-11-28T21:05:44Z"
 		},
 		{
-			"checksumSHA1": "yOMpVYuaPAtsMIo9DvQP8WZqxQs=",
+			"checksumSHA1": "tnQdt7bxmueZFl0EPrW9YrWiqGg=",
 			"path": "github.com/rjeczalik/notify",
-			"revision": "9d5aa0c3b735c3340018a4627446c3ea5a04a097",
-			"revisionTime": "2017-01-28T20:05:44Z"
+			"revision": "e1801ee34d54c4bf45126ef51fe9750b4e42bee8",
+			"revisionTime": "2017-12-10T15:45:11Z"
 		},
 		{
 			"checksumSHA1": "5uqO4ITTDMklKi3uNaE/D9LQ5nM=",