major version: negate char classes with ! or ^
diff --git a/.travis.yml b/.travis.yml
index 78a90e7..51cf057 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,9 @@
 language: go
 
 go:
-  - 1.12
   - 1.13
   - 1.14
+  - 1.15
 
 os:
   - linux
diff --git a/README.md b/README.md
index 2f6781c..5d95352 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
 
 ## About
 
-#### [Updating from v1 to v2?](UPGRADING.md)
+#### [Upgrading to v2? To v3?](UPGRADING.md)
 
 **doublestar** is a [golang](http://golang.org/) implementation of path pattern
 matching and globbing with support for "doublestar" (aka globstar: `**`)
diff --git a/UPGRADING.md b/UPGRADING.md
index 8193544..9a3b82d 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -1,3 +1,11 @@
+# Upgrading from v2 to v3
+
+v3 introduced using `!` to negate character classes, in addition to `^`. If any
+of your patterns include a character class that starts with an exclamation mark
+(ie, `[!...]`), you'll need to update the pattern to escape or move the
+exclamation mark. Note that, like the caret (`^`), it only negates the
+character class if it is the first character in the character class.
+
 # Upgrading from v1 to v2
 
 The change from v1 to v2 was fairly minor: the return type of the `Open` method
diff --git a/doublestar.go b/doublestar.go
index aacff06..36919e5 100644
--- a/doublestar.go
+++ b/doublestar.go
@@ -163,7 +163,7 @@
 //    '**'        matches any sequence of characters, including
 //                path separators.
 //    '?'         matches any single non-path-separator character
-//    '[' [ '^' ] { character-range } ']'
+//    '[' [ '^' '!' ] { character-range } ']'
 //          character class (must be non-empty)
 //    '{' { term } [ ',' { term } ... ] '}'
 //    c           matches character c (c != '*', '?', '\\', '[')
@@ -515,7 +515,8 @@
 			if classRunesLen > 0 {
 				classIdx := 0
 				matchClass := false
-				if classRunes[0] == '^' {
+				negate := classRunes[0] == '^' || classRunes[0] == '!'
+				if negate {
 					classIdx++
 				}
 				for classIdx < classRunesLen {
@@ -556,7 +557,7 @@
 						matchClass = true
 					}
 				}
-				if matchClass == (classRunes[0] == '^') {
+				if matchClass == negate {
 					return nil, nil
 				}
 			} else {
diff --git a/doublestar_test.go b/doublestar_test.go
index 7401dea..e72d8c0 100644
--- a/doublestar_test.go
+++ b/doublestar_test.go
@@ -54,6 +54,7 @@
 	{"a\\*b", "ab", false, nil, true, true},
 	{"a?b", "a☺b", true, nil, true, true},
 	{"a[^a]b", "a☺b", true, nil, true, true},
+	{"a[!a]b", "a☺b", true, nil, false, true},
 	{"a???b", "a☺b", false, nil, true, true},
 	{"a[^a][^a][^a]b", "a☺b", false, nil, true, true},
 	{"[a-ζ]*", "α", true, nil, true, true},
diff --git a/examples/find.go b/examples/find.go
index 0388d22..ebddbca 100644
--- a/examples/find.go
+++ b/examples/find.go
@@ -5,7 +5,7 @@
 	"os"
 	"strings"
 
-	"github.com/bmatcuk/doublestar/v2"
+	"github.com/bmatcuk/doublestar/v3"
 )
 
 // To run:
diff --git a/go.mod b/go.mod
index f0fa6bc..cf77e57 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
-module github.com/bmatcuk/doublestar/v2
+module github.com/bmatcuk/doublestar/v3
 
 go 1.12