Fix analysis options, test on oldest supported SDK (#23)

diff --git a/.travis.yml b/.travis.yml
index 2b5aaa5..82ad616 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,16 +2,16 @@
 
 dart:
   - dev
-  - stable
+  - 2.1.0
 
 # See https://docs.travis-ci.com/user/languages/dart/ for details.
 dart_task:
   - test: --platform vm,firefox
-  - dartanalyzer
+  - dartanalyzer: --fatal-warnings --fatal-infos .
 
 matrix:
   include:
-    - dart: stable
+    - dart: dev
       dart_task: dartfmt
 
 # Only building master means that we don't run two builds for each pull request.
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..0711aca
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,43 @@
+include: package:pedantic/analysis_options.yaml
+analyzer:
+  strong-mode:
+    implicit-casts: false
+linter:
+  rules:
+    - avoid_empty_else
+    - avoid_init_to_null
+    - avoid_null_checks_in_equality_operators
+    - avoid_unused_constructor_parameters
+    - await_only_futures
+    - camel_case_types
+    - cancel_subscriptions
+    - constant_identifier_names
+    - control_flow_in_finally
+    - directives_ordering
+    - empty_catches
+    - empty_constructor_bodies
+    - empty_statements
+    - hash_and_equals
+    - implementation_imports
+    - iterable_contains_unrelated_type
+    - library_names
+    - library_prefixes
+    - list_remove_unrelated_type
+    - non_constant_identifier_names
+    - overridden_fields
+    - package_api_docs
+    - package_names
+    - package_prefixed_library_names
+    - prefer_equal_for_default_values
+    - prefer_final_fields
+    - prefer_generic_function_type_aliases
+    - prefer_is_not_empty
+    - slash_for_doc_comments
+    - test_types_in_equals
+    - throw_in_finally
+    - type_init_formals
+    - unnecessary_brace_in_string_interps
+    - unnecessary_const
+    - unnecessary_new
+    - unrelated_type_equality_checks
+    - valid_regexps
diff --git a/lib/glob.dart b/lib/glob.dart
index a7d6b4c..807b0c4 100644
--- a/lib/glob.dart
+++ b/lib/glob.dart
@@ -13,7 +13,7 @@
 import 'src/utils.dart';
 
 /// Regular expression used to quote globs.
-final _quoteRegExp = new RegExp(r'[*{[?\\}\],\-()]');
+final _quoteRegExp = RegExp(r'[*{[?\\}\],\-()]');
 
 /// A glob for matching and listing files and directories.
 ///
@@ -99,13 +99,13 @@
   /// regardless of case. This defaults to `false` when [context] is Windows and
   /// `true` otherwise.
   factory Glob(String pattern,
-      {p.Context context, bool recursive: false, bool caseSensitive}) {
+      {p.Context context, bool recursive = false, bool caseSensitive}) {
     context ??= p.context;
     caseSensitive ??= context.style == p.Style.windows ? false : true;
     if (recursive) pattern += "{,/**}";
 
-    var parser = new Parser(pattern, context, caseSensitive: caseSensitive);
-    return new Glob._(pattern, context, parser.parse(), recursive);
+    var parser = Parser(pattern, context, caseSensitive: caseSensitive);
+    return Glob._(pattern, context, parser.parse(), recursive);
   }
 
   Glob._(this.pattern, this.context, this._ast, this.recursive);
@@ -120,13 +120,13 @@
   /// [root] defaults to the current working directory.
   ///
   /// [followLinks] works the same as for [Directory.list].
-  Stream<FileSystemEntity> list({String root, bool followLinks: true}) {
+  Stream<FileSystemEntity> list({String root, bool followLinks = true}) {
     if (context.style != p.style) {
-      throw new StateError("Can't list glob \"$this\"; it matches "
+      throw StateError("Can't list glob \"$this\"; it matches "
           "${context.style} paths, but this platform uses ${p.style} paths.");
     }
 
-    if (_listTree == null) _listTree = new ListTree(_ast);
+    if (_listTree == null) _listTree = ListTree(_ast);
     return _listTree.list(root: root, followLinks: followLinks);
   }
 
@@ -141,13 +141,13 @@
   /// [root] defaults to the current working directory.
   ///
   /// [followLinks] works the same as for [Directory.list].
-  List<FileSystemEntity> listSync({String root, bool followLinks: true}) {
+  List<FileSystemEntity> listSync({String root, bool followLinks = true}) {
     if (context.style != p.style) {
-      throw new StateError("Can't list glob \"$this\"; it matches "
+      throw StateError("Can't list glob \"$this\"; it matches "
           "${context.style} paths, but this platform uses ${p.style} paths.");
     }
 
-    if (_listTree == null) _listTree = new ListTree(_ast);
+    if (_listTree == null) _listTree = ListTree(_ast);
     return _listTree.listSync(root: root, followLinks: followLinks);
   }
 
@@ -163,14 +163,14 @@
         (_contextIsAbsolute || context.isAbsolute(path))) {
       var absolutePath = context.normalize(context.absolute(path));
       if (_ast.matches(toPosixPath(context, absolutePath))) {
-        return new GlobMatch(path, this);
+        return GlobMatch(path, this);
       }
     }
 
     if (_patternCanMatchRelative) {
       var relativePath = context.relative(path);
       if (_ast.matches(toPosixPath(context, relativePath))) {
-        return new GlobMatch(path, this);
+        return GlobMatch(path, this);
       }
     }
 
diff --git a/lib/src/ast.dart b/lib/src/ast.dart
index 809d4bc..c8f4328 100644
--- a/lib/src/ast.dart
+++ b/lib/src/ast.dart
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:path/path.dart' as p;
 import 'package:collection/collection.dart';
+import 'package:path/path.dart' as p;
 
 import 'utils.dart';
 
-const _SEPARATOR = 0x2F; // "/"
+const _separator = 0x2F; // "/"
 
 /// A node in the abstract syntax tree for a glob.
 abstract class AstNode {
@@ -38,14 +38,14 @@
   ///
   /// For example, given the glob `{foo,bar}/{click/clack}`, this would return
   /// `{foo/click,foo/clack,bar/click,bar/clack}`.
-  OptionsNode flattenOptions() => new OptionsNode([
-        new SequenceNode([this], caseSensitive: caseSensitive)
+  OptionsNode flattenOptions() => OptionsNode([
+        SequenceNode([this], caseSensitive: caseSensitive)
       ], caseSensitive: caseSensitive);
 
   /// Returns whether this glob matches [string].
   bool matches(String string) {
     if (_regExp == null) {
-      _regExp = new RegExp('^${_toRegExp()}\$', caseSensitive: caseSensitive);
+      _regExp = RegExp('^${_toRegExp()}\$', caseSensitive: caseSensitive);
     }
     return _regExp.hasMatch(string);
   }
@@ -60,15 +60,16 @@
   final List<AstNode> nodes;
 
   bool get canMatchAbsolute => nodes.first.canMatchAbsolute;
+
   bool get canMatchRelative => nodes.first.canMatchRelative;
 
-  SequenceNode(Iterable<AstNode> nodes, {bool caseSensitive: true})
+  SequenceNode(Iterable<AstNode> nodes, {bool caseSensitive = true})
       : nodes = nodes.toList(),
         super._(caseSensitive);
 
   OptionsNode flattenOptions() {
     if (nodes.isEmpty) {
-      return new OptionsNode([this], caseSensitive: caseSensitive);
+      return OptionsNode([this], caseSensitive: caseSensitive);
     }
 
     var sequences =
@@ -84,9 +85,9 @@
       });
     }
 
-    return new OptionsNode(sequences.map((sequence) {
+    return OptionsNode(sequences.map((sequence) {
       // Combine any adjacent LiteralNodes in [sequence].
-      return new SequenceNode(
+      return SequenceNode(
           sequence.fold<List<AstNode>>([], (combined, node) {
             if (combined.isEmpty ||
                 combined.last is! LiteralNode ||
@@ -94,7 +95,7 @@
               return combined..add(node);
             }
 
-            combined[combined.length - 1] = new LiteralNode(
+            combined[combined.length - 1] = LiteralNode(
                 // TODO(nweiz): Avoid casting when sdk#25565 is fixed.
                 (combined.last as LiteralNode).text +
                     (node as LiteralNode).text,
@@ -127,8 +128,8 @@
 
     finishComponent() {
       if (currentComponent == null) return;
-      componentsToReturn.add(
-          new SequenceNode(currentComponent, caseSensitive: caseSensitive));
+      componentsToReturn
+          .add(SequenceNode(currentComponent, caseSensitive: caseSensitive));
       currentComponent = null;
     }
 
@@ -163,7 +164,7 @@
             // So we switch it back here.
             root = root.replaceAll("\\", "/");
           }
-          addNode(new LiteralNode(root, caseSensitive: caseSensitive));
+          addNode(LiteralNode(root, caseSensitive: caseSensitive));
         }
         finishComponent();
         components = components.skip(1);
@@ -173,13 +174,13 @@
       // For each component except the last one, add a separate sequence to
       // [sequences] containing only that component.
       for (var component in components.take(components.length - 1)) {
-        addNode(new LiteralNode(component, caseSensitive: caseSensitive));
+        addNode(LiteralNode(component, caseSensitive: caseSensitive));
         finishComponent();
       }
 
       // For the final component, only end its sequence (by adding a new empty
       // sequence) if it ends with a separator.
-      addNode(new LiteralNode(components.last, caseSensitive: caseSensitive));
+      addNode(LiteralNode(components.last, caseSensitive: caseSensitive));
       if (literal.text.endsWith('/')) finishComponent();
     }
 
@@ -200,7 +201,7 @@
 
 /// A node matching zero or more non-separator characters.
 class StarNode extends AstNode {
-  StarNode({bool caseSensitive: true}) : super._(caseSensitive);
+  StarNode({bool caseSensitive = true}) : super._(caseSensitive);
 
   String _toRegExp() => '[^/]*';
 
@@ -218,7 +219,7 @@
   /// This is used to determine what absolute paths look like.
   final p.Context _context;
 
-  DoubleStarNode(this._context, {bool caseSensitive: true})
+  DoubleStarNode(this._context, {bool caseSensitive = true})
       : super._(caseSensitive);
 
   String _toRegExp() {
@@ -226,7 +227,7 @@
     // wouldn't be listed with this glob. We only check for "../" at the
     // beginning since the paths are normalized before being checked against the
     // glob.
-    var buffer = new StringBuffer()..write(r'(?!^(?:\.\./|');
+    var buffer = StringBuffer()..write(r'(?!^(?:\.\./|');
 
     // A double star at the beginning of the glob also shouldn't match absolute
     // paths, since those also wouldn't be listed. Which root patterns we look
@@ -255,7 +256,7 @@
 
 /// A node matching a single non-separator character.
 class AnyCharNode extends AstNode {
-  AnyCharNode({bool caseSensitive: true}) : super._(caseSensitive);
+  AnyCharNode({bool caseSensitive = true}) : super._(caseSensitive);
 
   String _toRegExp() => '[^/]';
 
@@ -276,7 +277,7 @@
   /// Whether this range was negated.
   final bool negated;
 
-  RangeNode(Iterable<Range> ranges, {this.negated, bool caseSensitive: true})
+  RangeNode(Iterable<Range> ranges, {this.negated, bool caseSensitive = true})
       : ranges = ranges.toSet(),
         super._(caseSensitive);
 
@@ -287,18 +288,18 @@
 
     // If a range explicitly lists a set of characters, return each character as
     // a separate expansion.
-    return new OptionsNode(ranges.map((range) {
-      return new SequenceNode([
-        new LiteralNode(new String.fromCharCodes([range.min]),
+    return OptionsNode(ranges.map((range) {
+      return SequenceNode([
+        LiteralNode(String.fromCharCodes([range.min]),
             caseSensitive: caseSensitive)
       ], caseSensitive: caseSensitive);
     }), caseSensitive: caseSensitive);
   }
 
   String _toRegExp() {
-    var buffer = new StringBuffer();
+    var buffer = StringBuffer();
 
-    var containsSeparator = ranges.any((range) => range.contains(_SEPARATOR));
+    var containsSeparator = ranges.any((range) => range.contains(_separator));
     if (!negated && containsSeparator) {
       // Add `(?!/)` because ranges are never allowed to match separators.
       buffer.write('(?!/)');
@@ -313,27 +314,26 @@
     }
 
     for (var range in ranges) {
-      var start = new String.fromCharCodes([range.min]);
+      var start = String.fromCharCodes([range.min]);
       buffer.write(regExpQuote(start));
       if (range.isSingleton) continue;
       buffer.write('-');
-      buffer.write(regExpQuote(new String.fromCharCodes([range.max])));
+      buffer.write(regExpQuote(String.fromCharCodes([range.max])));
     }
 
     buffer.write(']');
     return buffer.toString();
   }
 
-  bool operator ==(Object other) {
-    if (other is! RangeNode) return false;
-    if ((other as RangeNode).negated != negated) return false;
-    return const SetEquality().equals(ranges, (other as RangeNode).ranges);
-  }
+  bool operator ==(Object other) =>
+      other is RangeNode &&
+      other.negated == negated &&
+      SetEquality().equals(ranges, other.ranges);
 
   int get hashCode => (negated ? 1 : 3) * const SetEquality().hash(ranges);
 
   String toString() {
-    var buffer = new StringBuffer()..write('[');
+    var buffer = StringBuffer()..write('[');
     for (var range in ranges) {
       buffer.writeCharCode(range.min);
       if (range.isSingleton) continue;
@@ -351,15 +351,16 @@
   final List<SequenceNode> options;
 
   bool get canMatchAbsolute => options.any((node) => node.canMatchAbsolute);
+
   bool get canMatchRelative => options.any((node) => node.canMatchRelative);
 
-  OptionsNode(Iterable<SequenceNode> options, {bool caseSensitive: true})
+  OptionsNode(Iterable<SequenceNode> options, {bool caseSensitive = true})
       : options = options.toList(),
         super._(caseSensitive);
 
-  OptionsNode flattenOptions() => new OptionsNode(
-      options.expand((option) => option.flattenOptions().options),
-      caseSensitive: caseSensitive);
+  OptionsNode flattenOptions() =>
+      OptionsNode(options.expand((option) => option.flattenOptions().options),
+          caseSensitive: caseSensitive);
 
   String _toRegExp() =>
       '(?:${options.map((option) => option._toRegExp()).join("|")})';
@@ -391,7 +392,7 @@
 
   bool get canMatchRelative => !canMatchAbsolute;
 
-  LiteralNode(this.text, {p.Context context, bool caseSensitive: true})
+  LiteralNode(this.text, {p.Context context, bool caseSensitive = true})
       : _context = context,
         super._(caseSensitive);
 
diff --git a/lib/src/list_tree.dart b/lib/src/list_tree.dart
index f51e4bb..8ae127a 100644
--- a/lib/src/list_tree.dart
+++ b/lib/src/list_tree.dart
@@ -7,16 +7,17 @@
 
 import 'package:async/async.dart';
 import 'package:path/path.dart' as p;
+import 'package:pedantic/pedantic.dart';
 
 import 'ast.dart';
 import 'utils.dart';
 
 /// The errno for a file or directory not existing on Mac and Linux.
-const _ENOENT = 2;
+const _enoent = 2;
 
 /// Another errno we see on Windows when trying to list a non-existent
 /// directory.
-const _ENOENT_WIN = 3;
+const _enoentWin = 3;
 
 /// A structure built from a glob that efficiently lists filesystem entities
 /// that match that glob.
@@ -55,7 +56,7 @@
   /// A map from filesystem roots to the list tree for those roots.
   ///
   /// A relative glob will use `.` as its root.
-  final _trees = new Map<String, _ListTreeNode>();
+  final _trees = Map<String, _ListTreeNode>();
 
   /// Whether paths listed might overlap.
   ///
@@ -138,19 +139,18 @@
           // each option's components separately, the same component is never
           // both a validator and a child.
           if (!parent.children.containsKey(component)) {
-            parent.children[component] = new _ListTreeNode();
+            parent.children[component] = _ListTreeNode();
           }
           parent = parent.children[component];
         }
       } else if (recursive) {
-        _trees[root] =
-            new _ListTreeNode.recursive(_join(components.sublist(i)));
+        _trees[root] = _ListTreeNode.recursive(_join(components.sublist(i)));
         return;
       } else if (complete) {
-        _trees[root] = new _ListTreeNode()..addOption(component);
+        _trees[root] = _ListTreeNode()..addOption(component);
       } else {
-        _trees[root] = new _ListTreeNode();
-        _trees[root].children[component] = new _ListTreeNode();
+        _trees[root] = _ListTreeNode();
+        _trees[root].children[component] = _ListTreeNode();
         parent = _trees[root].children[component];
       }
     }
@@ -168,9 +168,9 @@
   }
 
   /// List all entities that match this glob beneath [root].
-  Stream<FileSystemEntity> list({String root, bool followLinks: true}) {
+  Stream<FileSystemEntity> list({String root, bool followLinks = true}) {
     if (root == null) root = '.';
-    var group = new StreamGroup<FileSystemEntity>();
+    var group = StreamGroup<FileSystemEntity>();
     for (var rootDir in _trees.keys) {
       var dir = rootDir == '.' ? root : rootDir;
       group.add(_trees[rootDir].list(dir, followLinks: followLinks));
@@ -181,7 +181,7 @@
 
     // TODO(nweiz): Rather than filtering here, avoid double-listing directories
     // in the first place.
-    var seen = new Set();
+    var seen = Set();
     return group.stream.where((entity) {
       if (seen.contains(entity.path)) return false;
       seen.add(entity.path);
@@ -190,7 +190,7 @@
   }
 
   /// Synchronosuly list all entities that match this glob beneath [root].
-  List<FileSystemEntity> listSync({String root, bool followLinks: true}) {
+  List<FileSystemEntity> listSync({String root, bool followLinks = true}) {
     if (root == null) root = '.';
 
     var result = _trees.keys.expand((rootDir) {
@@ -202,7 +202,7 @@
 
     // TODO(nweiz): Rather than filtering here, avoid double-listing directories
     // in the first place.
-    var seen = new Set<String>();
+    var seen = Set<String>();
     return result.where((entity) {
       if (seen.contains(entity.path)) return false;
       seen.add(entity.path);
@@ -275,20 +275,20 @@
 
   /// Creates a node with no children and no validator.
   _ListTreeNode()
-      : children = new Map<SequenceNode, _ListTreeNode>(),
+      : children = Map<SequenceNode, _ListTreeNode>(),
         _validator = null;
 
   /// Creates a recursive node the given [validator].
   _ListTreeNode.recursive(SequenceNode validator)
       : children = null,
-        _validator = new OptionsNode([validator],
-            caseSensitive: validator.caseSensitive);
+        _validator =
+            OptionsNode([validator], caseSensitive: validator.caseSensitive);
 
   /// Transforms this into recursive node, folding all its children into its
   /// validator.
   void makeRecursive() {
     if (isRecursive) return;
-    _validator = new OptionsNode(children.keys.map((sequence) {
+    _validator = OptionsNode(children.keys.map((sequence) {
       var child = children[sequence];
       child.makeRecursive();
       return _join([sequence, child._validator]);
@@ -300,7 +300,7 @@
   void addOption(SequenceNode validator) {
     if (_validator == null) {
       _validator =
-          new OptionsNode([validator], caseSensitive: validator.caseSensitive);
+          OptionsNode([validator], caseSensitive: validator.caseSensitive);
     } else {
       _validator.options.add(validator);
     }
@@ -310,9 +310,9 @@
   ///
   /// This may return duplicate entities. These will be filtered out in
   /// [ListTree.list].
-  Stream<FileSystemEntity> list(String dir, {bool followLinks: true}) {
+  Stream<FileSystemEntity> list(String dir, {bool followLinks = true}) {
     if (isRecursive) {
-      return new Directory(dir)
+      return Directory(dir)
           .list(recursive: true, followLinks: followLinks)
           .where((entity) => _matches(p.relative(entity.path, from: dir)));
     }
@@ -320,7 +320,7 @@
     // Don't spawn extra [Directory.list] calls when we already know exactly
     // which subdirectories we're interested in.
     if (_isIntermediate && _caseSensitive) {
-      var resultGroup = new StreamGroup<FileSystemEntity>();
+      var resultGroup = StreamGroup<FileSystemEntity>();
       children.forEach((sequence, child) {
         resultGroup.add(child.list(
             p.join(dir, (sequence.nodes.single as LiteralNode).text),
@@ -332,12 +332,12 @@
 
     return StreamCompleter.fromFuture(() async {
       var entities =
-          await new Directory(dir).list(followLinks: followLinks).toList();
+          await Directory(dir).list(followLinks: followLinks).toList();
       await _validateIntermediateChildrenAsync(dir, entities);
 
-      var resultGroup = new StreamGroup<FileSystemEntity>();
-      var resultController = new StreamController<FileSystemEntity>(sync: true);
-      resultGroup.add(resultController.stream);
+      var resultGroup = StreamGroup<FileSystemEntity>();
+      var resultController = StreamController<FileSystemEntity>(sync: true);
+      unawaited(resultGroup.add(resultController.stream));
       for (var entity in entities) {
         var basename = p.relative(entity.path, from: dir);
         if (_matches(basename)) resultController.add(entity);
@@ -353,14 +353,14 @@
             // glob "foo/bar/*/baz" should fail if "foo/bar" doesn't exist but
             // succeed if "foo/bar/qux/baz" doesn't exist.
             return error is FileSystemException &&
-                (error.osError.errorCode == _ENOENT ||
-                    error.osError.errorCode == _ENOENT_WIN);
+                (error.osError.errorCode == _enoent ||
+                    error.osError.errorCode == _enoentWin);
           });
           resultGroup.add(stream);
         });
       }
-      resultController.close();
-      resultGroup.close();
+      unawaited(resultController.close());
+      unawaited(resultGroup.close());
       return resultGroup.stream;
     }());
   }
@@ -396,9 +396,9 @@
   ///
   /// This may return duplicate entities. These will be filtered out in
   /// [ListTree.listSync].
-  Iterable<FileSystemEntity> listSync(String dir, {bool followLinks: true}) {
+  Iterable<FileSystemEntity> listSync(String dir, {bool followLinks = true}) {
     if (isRecursive) {
-      return new Directory(dir)
+      return Directory(dir)
           .listSync(recursive: true, followLinks: followLinks)
           .where((entity) => _matches(p.relative(entity.path, from: dir)));
     }
@@ -413,7 +413,7 @@
       });
     }
 
-    var entities = new Directory(dir).listSync(followLinks: followLinks);
+    var entities = Directory(dir).listSync(followLinks: followLinks);
     _validateIntermediateChildrenSync(dir, entities);
 
     return entities.expand((entity) {
@@ -434,8 +434,8 @@
           // that we only ignore warnings below wild cards. For example, the
           // glob "foo/bar/*/baz" should fail if "foo/bar" doesn't exist but
           // succeed if "foo/bar/qux/baz" doesn't exist.
-          if (error.osError.errorCode == _ENOENT ||
-              error.osError.errorCode == _ENOENT_WIN) {
+          if (error.osError.errorCode == _enoent ||
+              error.osError.errorCode == _enoentWin) {
             return const [];
           } else {
             rethrow;
@@ -488,8 +488,8 @@
   var first = componentsList.removeAt(0);
   var nodes = [first];
   for (var component in componentsList) {
-    nodes.add(new LiteralNode('/', caseSensitive: first.caseSensitive));
+    nodes.add(LiteralNode('/', caseSensitive: first.caseSensitive));
     nodes.add(component);
   }
-  return new SequenceNode(nodes, caseSensitive: first.caseSensitive);
+  return SequenceNode(nodes, caseSensitive: first.caseSensitive);
 }
diff --git a/lib/src/parser.dart b/lib/src/parser.dart
index a4e840c..3fa58ae 100644
--- a/lib/src/parser.dart
+++ b/lib/src/parser.dart
@@ -8,8 +8,8 @@
 import 'ast.dart';
 import 'utils.dart';
 
-const _HYPHEN = 0x2D;
-const _SLASH = 0x2F;
+const _hyphen = 0x2D;
+const _slash = 0x2F;
 
 /// A parser for globs.
 class Parser {
@@ -22,8 +22,8 @@
   /// Whether this glob is case-sensitive.
   final bool _caseSensitive;
 
-  Parser(String component, this._context, {bool caseSensitive: true})
-      : _scanner = new StringScanner(component),
+  Parser(String component, this._context, {bool caseSensitive = true})
+      : _scanner = StringScanner(component),
         _caseSensitive = caseSensitive;
 
   /// Parses an entire glob.
@@ -32,7 +32,7 @@
   /// Parses a [SequenceNode].
   ///
   /// If [inOptions] is true, this is parsing within an [OptionsNode].
-  SequenceNode _parseSequence({bool inOptions: false}) {
+  SequenceNode _parseSequence({bool inOptions = false}) {
     var nodes = <AstNode>[];
 
     if (_scanner.isDone) {
@@ -44,13 +44,13 @@
       nodes.add(_parseNode(inOptions: inOptions));
     }
 
-    return new SequenceNode(nodes, caseSensitive: _caseSensitive);
+    return SequenceNode(nodes, caseSensitive: _caseSensitive);
   }
 
   /// Parses an [AstNode].
   ///
   /// If [inOptions] is true, this is parsing within an [OptionsNode].
-  AstNode _parseNode({bool inOptions: false}) {
+  AstNode _parseNode({bool inOptions = false}) {
     var star = _parseStar();
     if (star != null) return star;
 
@@ -72,8 +72,8 @@
   AstNode _parseStar() {
     if (!_scanner.scan('*')) return null;
     return _scanner.scan('*')
-        ? new DoubleStarNode(_context, caseSensitive: _caseSensitive)
-        : new StarNode(caseSensitive: _caseSensitive);
+        ? DoubleStarNode(_context, caseSensitive: _caseSensitive)
+        : StarNode(caseSensitive: _caseSensitive);
   }
 
   /// Tries to parse an [AnyCharNode].
@@ -81,7 +81,7 @@
   /// Returns `null` if there's not one to parse.
   AstNode _parseAnyChar() {
     if (!_scanner.scan('?')) return null;
-    return new AnyCharNode(caseSensitive: _caseSensitive);
+    return AnyCharNode(caseSensitive: _caseSensitive);
   }
 
   /// Tries to parse an [RangeNode].
@@ -94,7 +94,7 @@
 
     readRangeChar() {
       var char = _scanner.readChar();
-      if (negated || char != _SLASH) return char;
+      if (negated || char != _slash) return char;
       _scanner.error('"/" may not be used in a range.',
           position: _scanner.position - 1);
     }
@@ -108,8 +108,8 @@
 
       if (_scanner.scan('-')) {
         if (_scanner.matches(']')) {
-          ranges.add(new Range.singleton(char));
-          ranges.add(new Range.singleton(_HYPHEN));
+          ranges.add(Range.singleton(char));
+          ranges.add(Range.singleton(_hyphen));
           continue;
         }
 
@@ -122,14 +122,13 @@
           _scanner.error("Range out of order.",
               position: start, length: _scanner.position - start);
         }
-        ranges.add(new Range(char, end));
+        ranges.add(Range(char, end));
       } else {
-        ranges.add(new Range.singleton(char));
+        ranges.add(Range.singleton(char));
       }
     }
 
-    return new RangeNode(ranges,
-        negated: negated, caseSensitive: _caseSensitive);
+    return RangeNode(ranges, negated: negated, caseSensitive: _caseSensitive);
   }
 
   /// Tries to parse an [OptionsNode].
@@ -148,18 +147,17 @@
     if (options.length == 1) _scanner.expect(',');
     _scanner.expect('}');
 
-    return new OptionsNode(options, caseSensitive: _caseSensitive);
+    return OptionsNode(options, caseSensitive: _caseSensitive);
   }
 
   /// Parses a [LiteralNode].
-  AstNode _parseLiteral({bool inOptions: false}) {
+  AstNode _parseLiteral({bool inOptions = false}) {
     // If we're in an options block, we want to stop parsing as soon as we hit a
     // comma. Otherwise, commas are fair game for literals.
-    var regExp =
-        new RegExp(inOptions ? r'[^*{[?\\}\],()]*' : r'[^*{[?\\}\]()]*');
+    var regExp = RegExp(inOptions ? r'[^*{[?\\}\],()]*' : r'[^*{[?\\}\]()]*');
 
     _scanner.scan(regExp);
-    var buffer = new StringBuffer()..write(_scanner.lastMatch[0]);
+    var buffer = StringBuffer()..write(_scanner.lastMatch[0]);
 
     while (_scanner.scan('\\')) {
       buffer.writeCharCode(_scanner.readChar());
@@ -172,7 +170,7 @@
     }
     if (!inOptions && _scanner.matches('}')) _scanner.error('unexpected "}"');
 
-    return new LiteralNode(buffer.toString(),
+    return LiteralNode(buffer.toString(),
         context: _context, caseSensitive: _caseSensitive);
   }
 }
diff --git a/lib/src/stream_pool.dart b/lib/src/stream_pool.dart
index cce94ed..dfb8ca5 100644
--- a/lib/src/stream_pool.dart
+++ b/lib/src/stream_pool.dart
@@ -12,7 +12,7 @@
   final StreamController<T> _controller;
 
   /// Subscriptions to the streams that make up the pool.
-  final _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();
+  final _subscriptions = Map<Stream<T>, StreamSubscription<T>>();
 
   /// Whether this pool should be closed when it becomes empty.
   bool _closeWhenEmpty = false;
@@ -25,7 +25,7 @@
       // Create the controller as sync so that any sync input streams will be
       // forwarded synchronously. Async input streams will have their asynchrony
       // preserved, since _controller.add will be called asynchronously.
-      : _controller = new StreamController<T>(sync: true);
+      : _controller = StreamController<T>(sync: true);
 
   /// Creates a new stream pool where [stream] can be listened to more than
   /// once.
@@ -36,7 +36,7 @@
       // Create the controller as sync so that any sync input streams will be
       // forwarded synchronously. Async input streams will have their asynchrony
       // preserved, since _controller.add will be called asynchronously.
-      : _controller = new StreamController<T>.broadcast(sync: true);
+      : _controller = StreamController<T>.broadcast(sync: true);
 
   /// Adds [stream] as a member of this pool.
   ///
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 13c0b99..268c273 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -43,7 +43,7 @@
   String operator [](int group) => this.group(group);
 
   String group(int group) {
-    if (group != 0) throw new RangeError.range(group, 0, 0);
+    if (group != 0) throw RangeError.range(group, 0, 0);
     return input;
   }
 
@@ -51,7 +51,7 @@
       groupIndices.map((index) => group(index)).toList();
 }
 
-final _quote = new RegExp(r"[+*?{}|[\]\\().^$-]");
+final _quote = RegExp(r"[+*?{}|[\]\\().^$-]");
 
 /// Returns [contents] with characters that are meaningful in regular
 /// expressions backslash-escaped.
diff --git a/pubspec.yaml b/pubspec.yaml
index 5ad9543..bb49580 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,19 +1,20 @@
 name: glob
-version: 1.1.7
+version: 1.1.8-dev
 
 description: Bash-style filename globbing.
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/glob
 
 environment:
-  sdk: '>=1.23.0 <3.0.0'
+  sdk: '>=2.1.0 <3.0.0'
 
 dependencies:
   async: '>=1.2.0 <3.0.0'
   collection: ^1.1.0
   path: ^1.3.0
+  pedantic: ^1.2.0
   string_scanner: '>=0.1.0 <2.0.0'
 
 dev_dependencies:
-  test: '>=0.12.0 <2.0.0'
+  test: ^1.6.0
   test_descriptor: ^1.0.0
diff --git a/test/glob_test.dart b/test/glob_test.dart
index 4cbb453..3923031 100644
--- a/test/glob_test.dart
+++ b/test/glob_test.dart
@@ -19,13 +19,13 @@
 
   group("Glob.matches()", () {
     test("returns whether the path matches the glob", () {
-      var glob = new Glob("foo*");
+      var glob = Glob("foo*");
       expect(glob.matches("foobar"), isTrue);
       expect(glob.matches("baz"), isFalse);
     });
 
     test("only matches the entire path", () {
-      var glob = new Glob("foo");
+      var glob = Glob("foo");
       expect(glob.matches("foo/bar"), isFalse);
       expect(glob.matches("bar/foo"), isFalse);
     });
@@ -33,36 +33,36 @@
 
   group("Glob.matchAsPrefix()", () {
     test("returns a match if the path matches the glob", () {
-      var glob = new Glob("foo*");
-      expect(glob.matchAsPrefix("foobar"), new isInstanceOf<Match>());
+      var glob = Glob("foo*");
+      expect(glob.matchAsPrefix("foobar"), isA<Match>());
       expect(glob.matchAsPrefix("baz"), isNull);
     });
 
     test("returns null for start > 0", () {
-      var glob = new Glob("*");
+      var glob = Glob("*");
       expect(glob.matchAsPrefix("foobar", 1), isNull);
     });
   });
 
   group("Glob.allMatches()", () {
     test("returns a single match if the path matches the glob", () {
-      var matches = new Glob("foo*").allMatches("foobar");
+      var matches = Glob("foo*").allMatches("foobar");
       expect(matches, hasLength(1));
-      expect(matches.first, new isInstanceOf<Match>());
+      expect(matches.first, isA<Match>());
     });
 
     test("returns an empty list if the path doesn't match the glob", () {
-      expect(new Glob("foo*").allMatches("baz"), isEmpty);
+      expect(Glob("foo*").allMatches("baz"), isEmpty);
     });
 
     test("returns no matches for start > 0", () {
-      var glob = new Glob("*");
+      var glob = Glob("*");
       expect(glob.allMatches("foobar", 1), isEmpty);
     });
   });
 
   group("GlobMatch", () {
-    var glob = new Glob("foo*");
+    var glob = Glob("foo*");
     var match = glob.matchAsPrefix("foobar");
 
     test("returns the string as input", () {
@@ -94,18 +94,18 @@
   });
 
   test("globs are case-sensitive by default for Posix and URL contexts", () {
-    expect("foo", contains(new Glob("foo", context: p.posix)));
-    expect("FOO", isNot(contains(new Glob("foo", context: p.posix))));
-    expect("foo", isNot(contains(new Glob("FOO", context: p.posix))));
+    expect("foo", contains(Glob("foo", context: p.posix)));
+    expect("FOO", isNot(contains(Glob("foo", context: p.posix))));
+    expect("foo", isNot(contains(Glob("FOO", context: p.posix))));
 
-    expect("foo", contains(new Glob("foo", context: p.url)));
-    expect("FOO", isNot(contains(new Glob("foo", context: p.url))));
-    expect("foo", isNot(contains(new Glob("FOO", context: p.url))));
+    expect("foo", contains(Glob("foo", context: p.url)));
+    expect("FOO", isNot(contains(Glob("foo", context: p.url))));
+    expect("foo", isNot(contains(Glob("FOO", context: p.url))));
   });
 
   test("globs are case-insensitive by default for Windows contexts", () {
-    expect("foo", contains(new Glob("foo", context: p.windows)));
-    expect("FOO", contains(new Glob("foo", context: p.windows)));
-    expect("foo", contains(new Glob("FOO", context: p.windows)));
+    expect("foo", contains(Glob("foo", context: p.windows)));
+    expect("FOO", contains(Glob("foo", context: p.windows)));
+    expect("foo", contains(Glob("FOO", context: p.windows)));
   });
 }
diff --git a/test/list_test.dart b/test/list_test.dart
index ee9814f..2504f55 100644
--- a/test/list_test.dart
+++ b/test/list_test.dart
@@ -22,52 +22,52 @@
 
   group("list()", () {
     test("fails if the context doesn't match the system context", () {
-      expect(new Glob("*", context: p.url).list, throwsStateError);
+      expect(Glob("*", context: p.url).list, throwsStateError);
     });
 
     test("reports exceptions for non-existent case-sensitive directories", () {
-      expect(new Glob("non/existent/**", caseSensitive: true).list().toList(),
-          throwsA(new isInstanceOf<FileSystemException>()));
+      expect(Glob("non/existent/**", caseSensitive: true).list().toList(),
+          throwsA(isA<FileSystemException>()));
     });
 
     test("reports exceptions for non-existent case-insensitive directories",
         () {
-      expect(new Glob("non/existent/**", caseSensitive: false).list().toList(),
-          throwsA(new isInstanceOf<FileSystemException>()));
+      expect(Glob("non/existent/**", caseSensitive: false).list().toList(),
+          throwsA(isA<FileSystemException>()));
     });
   });
 
   group("listSync()", () {
     test("fails if the context doesn't match the system context", () {
-      expect(new Glob("*", context: p.url).listSync, throwsStateError);
+      expect(Glob("*", context: p.url).listSync, throwsStateError);
     });
 
     test("reports exceptions for non-existent case-sensitive directories", () {
-      expect(new Glob("non/existent/**", caseSensitive: true).listSync,
-          throwsA(new isInstanceOf<FileSystemException>()));
+      expect(Glob("non/existent/**", caseSensitive: true).listSync,
+          throwsA(isA<FileSystemException>()));
     });
 
     test("reports exceptions for non-existent case-insensitive directories",
         () {
-      expect(new Glob("non/existent/**", caseSensitive: false).listSync,
-          throwsA(new isInstanceOf<FileSystemException>()));
+      expect(Glob("non/existent/**", caseSensitive: false).listSync,
+          throwsA(isA<FileSystemException>()));
     });
   });
 
   group("when case-sensitive", () {
     test("lists literals case-sensitively", () {
-      expect(new Glob("foo/BAZ/qux", caseSensitive: true).listSync,
-          throwsA(new isInstanceOf<FileSystemException>()));
+      expect(Glob("foo/BAZ/qux", caseSensitive: true).listSync,
+          throwsA(isA<FileSystemException>()));
     });
 
     test("lists ranges case-sensitively", () {
-      expect(new Glob("foo/[BX][A-Z]z/qux", caseSensitive: true).listSync,
-          throwsA(new isInstanceOf<FileSystemException>()));
+      expect(Glob("foo/[BX][A-Z]z/qux", caseSensitive: true).listSync,
+          throwsA(isA<FileSystemException>()));
     });
 
     test("options preserve case-sensitivity", () {
-      expect(new Glob("foo/{BAZ,ZAP}/qux", caseSensitive: true).listSync,
-          throwsA(new isInstanceOf<FileSystemException>()));
+      expect(Glob("foo/{BAZ,ZAP}/qux", caseSensitive: true).listSync,
+          throwsA(isA<FileSystemException>()));
     });
   });
 
@@ -215,7 +215,7 @@
 
     group("with symlinks", () {
       setUp(() async {
-        await new Link(p.join(d.sandbox, "dir", "link"))
+        await Link(p.join(d.sandbox, "dir", "link"))
             .create(p.join(d.sandbox, "foo", "baz"), recursive: true);
       });
 
@@ -235,7 +235,7 @@
       });
 
       test("shouldn't crash on broken symlinks", () async {
-        await new Directory(p.join(d.sandbox, "foo")).delete(recursive: true);
+        await Directory(p.join(d.sandbox, "foo")).delete(recursive: true);
 
         expect(await list("dir/**"), equals([p.join("dir", "link")]));
       });
@@ -313,16 +313,16 @@
   });
 }
 
-typedef FutureOr<List<String>> ListFn(String glob,
+typedef ListFn = FutureOr<List<String>> Function(String glob,
     {bool recursive, bool followLinks, bool caseSensitive});
 
 /// Runs [callback] in two groups with two values of [listFn]: one that uses
 /// [Glob.list], one that uses [Glob.listSync].
 void syncAndAsync(FutureOr callback(ListFn listFn)) {
   group("async", () {
-    callback((pattern, {recursive: false, followLinks: true, caseSensitive}) {
+    callback((pattern, {recursive = false, followLinks = true, caseSensitive}) {
       var glob =
-          new Glob(pattern, recursive: recursive, caseSensitive: caseSensitive);
+          Glob(pattern, recursive: recursive, caseSensitive: caseSensitive);
 
       return glob
           .list(root: d.sandbox, followLinks: followLinks)
@@ -332,9 +332,9 @@
   });
 
   group("sync", () {
-    callback((pattern, {recursive: false, followLinks: true, caseSensitive}) {
+    callback((pattern, {recursive = false, followLinks = true, caseSensitive}) {
       var glob =
-          new Glob(pattern, recursive: recursive, caseSensitive: caseSensitive);
+          Glob(pattern, recursive: recursive, caseSensitive: caseSensitive);
 
       return glob
           .listSync(root: d.sandbox, followLinks: followLinks)
diff --git a/test/match_test.dart b/test/match_test.dart
index 50d6f13..d5c1e6a 100644
--- a/test/match_test.dart
+++ b/test/match_test.dart
@@ -7,89 +7,88 @@
 import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
 
-const RAW_ASCII_WITHOUT_SLASH = "\t\n\r !\"#\$%&'()*+`-.0123456789:;<=>?@ABCDEF"
+const _rawAsciiWithoutSlash = "\t\n\r !\"#\$%&'()*+`-.0123456789:;<=>?@ABCDEF"
     "GHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~";
 
 // URL-encode the path for a URL context.
 final asciiWithoutSlash = p.style == p.Style.url
-    ? Uri.encodeFull(RAW_ASCII_WITHOUT_SLASH)
-    : RAW_ASCII_WITHOUT_SLASH;
+    ? Uri.encodeFull(_rawAsciiWithoutSlash)
+    : _rawAsciiWithoutSlash;
 
 void main() {
   test("literals match exactly", () {
-    expect("foo", contains(new Glob("foo")));
-    expect("foo/bar", contains(new Glob("foo/bar")));
-    expect("foo*", contains(new Glob(r"foo\*")));
+    expect("foo", contains(Glob("foo")));
+    expect("foo/bar", contains(Glob("foo/bar")));
+    expect("foo*", contains(Glob(r"foo\*")));
   });
 
   test("backslashes match nothing on Windows", () {
-    expect(
-        r"foo\bar", isNot(contains(new Glob(r"foo\\bar", context: p.windows))));
+    expect(r"foo\bar", isNot(contains(Glob(r"foo\\bar", context: p.windows))));
   });
 
   group("star", () {
     test("matches non-separator characters", () {
-      var glob = new Glob("*");
+      var glob = Glob("*");
       expect(asciiWithoutSlash, contains(glob));
     });
 
     test("matches the empty string", () {
-      expect("foo", contains(new Glob("foo*")));
-      expect("", contains(new Glob("*")));
+      expect("foo", contains(Glob("foo*")));
+      expect("", contains(Glob("*")));
     });
 
     test("doesn't match separators", () {
-      var glob = new Glob("*");
+      var glob = Glob("*");
       expect("foo/bar", isNot(contains(glob)));
     });
   });
 
   group("double star", () {
     test("matches non-separator characters", () {
-      var glob = new Glob("**");
+      var glob = Glob("**");
       expect(asciiWithoutSlash, contains(glob));
     });
 
     test("matches the empty string", () {
-      var glob = new Glob("foo**");
+      var glob = Glob("foo**");
       expect("foo", contains(glob));
     });
 
     test("matches any level of nesting", () {
-      var glob = new Glob("**");
+      var glob = Glob("**");
       expect("a", contains(glob));
       expect("a/b/c/d/e/f", contains(glob));
     });
 
     test("doesn't match unresolved dot dots", () {
-      expect("../foo/bar", isNot(contains(new Glob("**"))));
+      expect("../foo/bar", isNot(contains(Glob("**"))));
     });
 
     test("matches entities containing dot dots", () {
-      expect("..foo/bar", contains(new Glob("**")));
-      expect("foo../bar", contains(new Glob("**")));
-      expect("foo/..bar", contains(new Glob("**")));
-      expect("foo/bar..", contains(new Glob("**")));
+      expect("..foo/bar", contains(Glob("**")));
+      expect("foo../bar", contains(Glob("**")));
+      expect("foo/..bar", contains(Glob("**")));
+      expect("foo/bar..", contains(Glob("**")));
     });
   });
 
   group("any char", () {
     test("matches any non-separator character", () {
-      var glob = new Glob("foo?");
-      for (var char in RAW_ASCII_WITHOUT_SLASH.split('')) {
+      var glob = Glob("foo?");
+      for (var char in _rawAsciiWithoutSlash.split('')) {
         if (p.style == p.Style.url) char = Uri.encodeFull(char);
         expect("foo$char", contains(glob));
       }
     });
 
     test("doesn't match a separator", () {
-      expect("foo/bar", isNot(contains(new Glob("foo?bar"))));
+      expect("foo/bar", isNot(contains(Glob("foo?bar"))));
     });
   });
 
   group("range", () {
     test("can match individual characters", () {
-      var glob = new Glob("foo[a<.*]");
+      var glob = Glob("foo[a<.*]");
       expect("fooa", contains(glob));
       expect("foo<", contains(glob));
       expect("foo.", contains(glob));
@@ -99,7 +98,7 @@
     });
 
     test("can match a range of characters", () {
-      var glob = new Glob("foo[a-z]");
+      var glob = Glob("foo[a-z]");
       expect("fooa", contains(glob));
       expect("foon", contains(glob));
       expect("fooz", contains(glob));
@@ -108,7 +107,7 @@
     });
 
     test("can match multiple ranges of characters", () {
-      var glob = new Glob("foo[a-zA-Z]");
+      var glob = Glob("foo[a-zA-Z]");
       expect("fooa", contains(glob));
       expect("foon", contains(glob));
       expect("fooz", contains(glob));
@@ -120,7 +119,7 @@
     });
 
     test("can match individual characters and ranges of characters", () {
-      var glob = new Glob("foo[a-z_A-Z]");
+      var glob = Glob("foo[a-z_A-Z]");
       expect("fooa", contains(glob));
       expect("foon", contains(glob));
       expect("fooz", contains(glob));
@@ -133,7 +132,7 @@
     });
 
     test("can be negated", () {
-      var glob = new Glob("foo[^a<.*]");
+      var glob = Glob("foo[^a<.*]");
       expect("fooa", isNot(contains(glob)));
       expect("foo<", isNot(contains(glob)));
       expect("foo.", isNot(contains(glob)));
@@ -144,37 +143,37 @@
 
     test("never matches separators", () {
       // "\t-~" contains "/".
-      expect("foo/bar", isNot(contains(new Glob("foo[\t-~]bar"))));
-      expect("foo/bar", isNot(contains(new Glob("foo[^a]bar"))));
+      expect("foo/bar", isNot(contains(Glob("foo[\t-~]bar"))));
+      expect("foo/bar", isNot(contains(Glob("foo[^a]bar"))));
     });
 
     test("allows dangling -", () {
-      expect("-", contains(new Glob(r"[-]")));
+      expect("-", contains(Glob(r"[-]")));
 
-      var glob = new Glob(r"[a-]");
+      var glob = Glob(r"[a-]");
       expect("-", contains(glob));
       expect("a", contains(glob));
 
-      glob = new Glob(r"[-b]");
+      glob = Glob(r"[-b]");
       expect("-", contains(glob));
       expect("b", contains(glob));
     });
 
     test("allows multiple -s", () {
-      expect("-", contains(new Glob(r"[--]")));
-      expect("-", contains(new Glob(r"[---]")));
+      expect("-", contains(Glob(r"[--]")));
+      expect("-", contains(Glob(r"[---]")));
 
-      var glob = new Glob(r"[--a]");
+      var glob = Glob(r"[--a]");
       expect("-", contains(glob));
       expect("a", contains(glob));
     });
 
     test("allows negated /", () {
-      expect("foo-bar", contains(new Glob("foo[^/]bar")));
+      expect("foo-bar", contains(Glob("foo[^/]bar")));
     });
 
     test("doesn't choke on RegExp-active characters", () {
-      var glob = new Glob(r"foo[\]].*");
+      var glob = Glob(r"foo[\]].*");
       expect("foobar", isNot(contains(glob)));
       expect("foo].*", contains(glob));
     });
@@ -182,7 +181,7 @@
 
   group("options", () {
     test("match if any of the options match", () {
-      var glob = new Glob("foo/{bar,baz,bang}");
+      var glob = Glob("foo/{bar,baz,bang}");
       expect("foo/bar", contains(glob));
       expect("foo/baz", contains(glob));
       expect("foo/bang", contains(glob));
@@ -190,7 +189,7 @@
     });
 
     test("can contain nested operators", () {
-      var glob = new Glob("foo/{ba?,*az,ban{g,f}}");
+      var glob = Glob("foo/{ba?,*az,ban{g,f}}");
       expect("foo/bar", contains(glob));
       expect("foo/baz", contains(glob));
       expect("foo/bang", contains(glob));
@@ -198,7 +197,7 @@
     });
 
     test("can conditionally match separators", () {
-      var glob = new Glob("foo/{bar,baz/bang}");
+      var glob = Glob("foo/{bar,baz/bang}");
       expect("foo/bar", contains(glob));
       expect("foo/baz/bang", contains(glob));
       expect("foo/baz", isNot(contains(glob)));
@@ -208,40 +207,39 @@
 
   group("normalization", () {
     test("extra slashes are ignored", () {
-      expect("foo//bar", contains(new Glob("foo/bar")));
-      expect("foo/", contains(new Glob("*")));
+      expect("foo//bar", contains(Glob("foo/bar")));
+      expect("foo/", contains(Glob("*")));
     });
 
     test("dot directories are ignored", () {
-      expect("foo/./bar", contains(new Glob("foo/bar")));
-      expect("foo/.", contains(new Glob("foo")));
+      expect("foo/./bar", contains(Glob("foo/bar")));
+      expect("foo/.", contains(Glob("foo")));
     });
 
     test("dot dot directories are resolved", () {
-      expect("foo/../bar", contains(new Glob("bar")));
-      expect("../foo/bar", contains(new Glob("../foo/bar")));
-      expect("foo/../../bar", contains(new Glob("../bar")));
+      expect("foo/../bar", contains(Glob("bar")));
+      expect("../foo/bar", contains(Glob("../foo/bar")));
+      expect("foo/../../bar", contains(Glob("../bar")));
     });
 
     test("Windows separators are converted in a Windows context", () {
-      expect(r"foo\bar", contains(new Glob("foo/bar", context: p.windows)));
-      expect(r"foo\bar/baz",
-          contains(new Glob("foo/bar/baz", context: p.windows)));
+      expect(r"foo\bar", contains(Glob("foo/bar", context: p.windows)));
+      expect(r"foo\bar/baz", contains(Glob("foo/bar/baz", context: p.windows)));
     });
   });
 
   test("an absolute path can be matched by a relative glob", () {
     var path = p.absolute('foo/bar');
-    expect(path, contains(new Glob("foo/bar")));
+    expect(path, contains(Glob("foo/bar")));
   });
 
   test("a relative path can be matched by an absolute glob", () {
     var pattern = separatorToForwardSlash(p.absolute('foo/bar'));
-    expect('foo/bar', contains(new Glob(pattern)));
+    expect('foo/bar', contains(Glob(pattern)));
   }, testOn: 'vm');
 
   group("with recursive: true", () {
-    var glob = new Glob("foo/bar", recursive: true);
+    var glob = Glob("foo/bar", recursive: true);
 
     test("still matches basic files", () {
       expect("foo/bar", contains(glob));
@@ -259,95 +257,85 @@
   });
 
   test("absolute POSIX paths", () {
-    expect("/foo/bar", contains(new Glob("/foo/bar", context: p.posix)));
-    expect("/foo/bar", isNot(contains(new Glob("**", context: p.posix))));
-    expect("/foo/bar", contains(new Glob("/**", context: p.posix)));
+    expect("/foo/bar", contains(Glob("/foo/bar", context: p.posix)));
+    expect("/foo/bar", isNot(contains(Glob("**", context: p.posix))));
+    expect("/foo/bar", contains(Glob("/**", context: p.posix)));
   });
 
   test("absolute Windows paths", () {
-    expect(r"C:\foo\bar", contains(new Glob("C:/foo/bar", context: p.windows)));
-    expect(r"C:\foo\bar", isNot(contains(new Glob("**", context: p.windows))));
-    expect(r"C:\foo\bar", contains(new Glob("C:/**", context: p.windows)));
+    expect(r"C:\foo\bar", contains(Glob("C:/foo/bar", context: p.windows)));
+    expect(r"C:\foo\bar", isNot(contains(Glob("**", context: p.windows))));
+    expect(r"C:\foo\bar", contains(Glob("C:/**", context: p.windows)));
 
-    expect(r"\\foo\bar\baz",
-        contains(new Glob("//foo/bar/baz", context: p.windows)));
     expect(
-        r"\\foo\bar\baz", isNot(contains(new Glob("**", context: p.windows))));
-    expect(r"\\foo\bar\baz", contains(new Glob("//**", context: p.windows)));
-    expect(
-        r"\\foo\bar\baz", contains(new Glob("//foo/**", context: p.windows)));
+        r"\\foo\bar\baz", contains(Glob("//foo/bar/baz", context: p.windows)));
+    expect(r"\\foo\bar\baz", isNot(contains(Glob("**", context: p.windows))));
+    expect(r"\\foo\bar\baz", contains(Glob("//**", context: p.windows)));
+    expect(r"\\foo\bar\baz", contains(Glob("//foo/**", context: p.windows)));
   });
 
   test("absolute URL paths", () {
     expect(r"http://foo.com/bar",
-        contains(new Glob("http://foo.com/bar", context: p.url)));
-    expect(
-        r"http://foo.com/bar", isNot(contains(new Glob("**", context: p.url))));
-    expect(
-        r"http://foo.com/bar", contains(new Glob("http://**", context: p.url)));
+        contains(Glob("http://foo.com/bar", context: p.url)));
+    expect(r"http://foo.com/bar", isNot(contains(Glob("**", context: p.url))));
+    expect(r"http://foo.com/bar", contains(Glob("http://**", context: p.url)));
     expect(r"http://foo.com/bar",
-        contains(new Glob("http://foo.com/**", context: p.url)));
+        contains(Glob("http://foo.com/**", context: p.url)));
 
-    expect("/foo/bar", contains(new Glob("/foo/bar", context: p.url)));
-    expect("/foo/bar", isNot(contains(new Glob("**", context: p.url))));
-    expect("/foo/bar", contains(new Glob("/**", context: p.url)));
+    expect("/foo/bar", contains(Glob("/foo/bar", context: p.url)));
+    expect("/foo/bar", isNot(contains(Glob("**", context: p.url))));
+    expect("/foo/bar", contains(Glob("/**", context: p.url)));
   });
 
   group("when case-sensitive", () {
     test("literals match case-sensitively", () {
-      expect("foo", contains(new Glob("foo", caseSensitive: true)));
-      expect("FOO", isNot(contains(new Glob("foo", caseSensitive: true))));
-      expect("foo", isNot(contains(new Glob("FOO", caseSensitive: true))));
+      expect("foo", contains(Glob("foo", caseSensitive: true)));
+      expect("FOO", isNot(contains(Glob("foo", caseSensitive: true))));
+      expect("foo", isNot(contains(Glob("FOO", caseSensitive: true))));
     });
 
     test("ranges match case-sensitively", () {
-      expect("foo", contains(new Glob("[fx][a-z]o", caseSensitive: true)));
-      expect(
-          "FOO", isNot(contains(new Glob("[fx][a-z]o", caseSensitive: true))));
-      expect(
-          "foo", isNot(contains(new Glob("[FX][A-Z]O", caseSensitive: true))));
+      expect("foo", contains(Glob("[fx][a-z]o", caseSensitive: true)));
+      expect("FOO", isNot(contains(Glob("[fx][a-z]o", caseSensitive: true))));
+      expect("foo", isNot(contains(Glob("[FX][A-Z]O", caseSensitive: true))));
     });
 
     test("sequences preserve case-sensitivity", () {
-      expect("foo/bar", contains(new Glob("foo/bar", caseSensitive: true)));
-      expect(
-          "FOO/BAR", isNot(contains(new Glob("foo/bar", caseSensitive: true))));
-      expect(
-          "foo/bar", isNot(contains(new Glob("FOO/BAR", caseSensitive: true))));
+      expect("foo/bar", contains(Glob("foo/bar", caseSensitive: true)));
+      expect("FOO/BAR", isNot(contains(Glob("foo/bar", caseSensitive: true))));
+      expect("foo/bar", isNot(contains(Glob("FOO/BAR", caseSensitive: true))));
     });
 
     test("options preserve case-sensitivity", () {
-      expect("foo", contains(new Glob("{foo,bar}", caseSensitive: true)));
-      expect(
-          "FOO", isNot(contains(new Glob("{foo,bar}", caseSensitive: true))));
-      expect(
-          "foo", isNot(contains(new Glob("{FOO,BAR}", caseSensitive: true))));
+      expect("foo", contains(Glob("{foo,bar}", caseSensitive: true)));
+      expect("FOO", isNot(contains(Glob("{foo,bar}", caseSensitive: true))));
+      expect("foo", isNot(contains(Glob("{FOO,BAR}", caseSensitive: true))));
     });
   });
 
   group("when case-insensitive", () {
     test("literals match case-insensitively", () {
-      expect("foo", contains(new Glob("foo", caseSensitive: false)));
-      expect("FOO", contains(new Glob("foo", caseSensitive: false)));
-      expect("foo", contains(new Glob("FOO", caseSensitive: false)));
+      expect("foo", contains(Glob("foo", caseSensitive: false)));
+      expect("FOO", contains(Glob("foo", caseSensitive: false)));
+      expect("foo", contains(Glob("FOO", caseSensitive: false)));
     });
 
     test("ranges match case-insensitively", () {
-      expect("foo", contains(new Glob("[fx][a-z]o", caseSensitive: false)));
-      expect("FOO", contains(new Glob("[fx][a-z]o", caseSensitive: false)));
-      expect("foo", contains(new Glob("[FX][A-Z]O", caseSensitive: false)));
+      expect("foo", contains(Glob("[fx][a-z]o", caseSensitive: false)));
+      expect("FOO", contains(Glob("[fx][a-z]o", caseSensitive: false)));
+      expect("foo", contains(Glob("[FX][A-Z]O", caseSensitive: false)));
     });
 
     test("sequences preserve case-insensitivity", () {
-      expect("foo/bar", contains(new Glob("foo/bar", caseSensitive: false)));
-      expect("FOO/BAR", contains(new Glob("foo/bar", caseSensitive: false)));
-      expect("foo/bar", contains(new Glob("FOO/BAR", caseSensitive: false)));
+      expect("foo/bar", contains(Glob("foo/bar", caseSensitive: false)));
+      expect("FOO/BAR", contains(Glob("foo/bar", caseSensitive: false)));
+      expect("foo/bar", contains(Glob("FOO/BAR", caseSensitive: false)));
     });
 
     test("options preserve case-insensitivity", () {
-      expect("foo", contains(new Glob("{foo,bar}", caseSensitive: false)));
-      expect("FOO", contains(new Glob("{foo,bar}", caseSensitive: false)));
-      expect("foo", contains(new Glob("{FOO,BAR}", caseSensitive: false)));
+      expect("foo", contains(Glob("{foo,bar}", caseSensitive: false)));
+      expect("FOO", contains(Glob("{foo,bar}", caseSensitive: false)));
+      expect("foo", contains(Glob("{FOO,BAR}", caseSensitive: false)));
     });
   });
 }
diff --git a/test/parse_test.dart b/test/parse_test.dart
index 77dba95..2ea3bb9 100644
--- a/test/parse_test.dart
+++ b/test/parse_test.dart
@@ -8,89 +8,89 @@
 
 void main() {
   test("supports backslash-escaped characters", () {
-    expect(r"*[]{,}?()", contains(new Glob(r"\*\[\]\{\,\}\?\(\)")));
+    expect(r"*[]{,}?()", contains(Glob(r"\*\[\]\{\,\}\?\(\)")));
     if (p.style != p.Style.windows) {
-      expect(r"foo\bar", contains(new Glob(r"foo\\bar")));
+      expect(r"foo\bar", contains(Glob(r"foo\\bar")));
     }
   });
 
   test("disallows an empty glob", () {
-    expect(() => new Glob(""), throwsFormatException);
+    expect(() => Glob(""), throwsFormatException);
   });
 
   group("range", () {
     test("supports either ^ or ! for negated ranges", () {
-      var bang = new Glob("fo[!a-z]");
+      var bang = Glob("fo[!a-z]");
       expect("foo", isNot(contains(bang)));
       expect("fo2", contains(bang));
 
-      var caret = new Glob("fo[^a-z]");
+      var caret = Glob("fo[^a-z]");
       expect("foo", isNot(contains(caret)));
       expect("fo2", contains(caret));
     });
 
     test("supports backslash-escaped characters", () {
-      var glob = new Glob(r"fo[\*\--\]]");
+      var glob = Glob(r"fo[\*\--\]]");
       expect("fo]", contains(glob));
       expect("fo-", contains(glob));
       expect("fo*", contains(glob));
     });
 
     test("disallows inverted ranges", () {
-      expect(() => new Glob(r"[z-a]"), throwsFormatException);
+      expect(() => Glob(r"[z-a]"), throwsFormatException);
     });
 
     test("disallows empty ranges", () {
-      expect(() => new Glob(r"[]"), throwsFormatException);
+      expect(() => Glob(r"[]"), throwsFormatException);
     });
 
     test("disallows unclosed ranges", () {
-      expect(() => new Glob(r"[abc"), throwsFormatException);
-      expect(() => new Glob(r"[-"), throwsFormatException);
+      expect(() => Glob(r"[abc"), throwsFormatException);
+      expect(() => Glob(r"[-"), throwsFormatException);
     });
 
     test("disallows dangling ]", () {
-      expect(() => new Glob(r"abc]"), throwsFormatException);
+      expect(() => Glob(r"abc]"), throwsFormatException);
     });
 
     test("disallows explicit /", () {
-      expect(() => new Glob(r"[/]"), throwsFormatException);
-      expect(() => new Glob(r"[ -/]"), throwsFormatException);
-      expect(() => new Glob(r"[/-~]"), throwsFormatException);
+      expect(() => Glob(r"[/]"), throwsFormatException);
+      expect(() => Glob(r"[ -/]"), throwsFormatException);
+      expect(() => Glob(r"[/-~]"), throwsFormatException);
     });
   });
 
   group("options", () {
     test("allows empty branches", () {
-      var glob = new Glob("foo{,bar}");
+      var glob = Glob("foo{,bar}");
       expect("foo", contains(glob));
       expect("foobar", contains(glob));
     });
 
     test("disallows empty options", () {
-      expect(() => new Glob("{}"), throwsFormatException);
+      expect(() => Glob("{}"), throwsFormatException);
     });
 
     test("disallows single options", () {
-      expect(() => new Glob("{foo}"), throwsFormatException);
+      expect(() => Glob("{foo}"), throwsFormatException);
     });
 
     test("disallows unclosed options", () {
-      expect(() => new Glob("{foo,bar"), throwsFormatException);
-      expect(() => new Glob("{foo,"), throwsFormatException);
+      expect(() => Glob("{foo,bar"), throwsFormatException);
+      expect(() => Glob("{foo,"), throwsFormatException);
     });
 
     test("disallows dangling }", () {
-      expect(() => new Glob("foo}"), throwsFormatException);
+      expect(() => Glob("foo}"), throwsFormatException);
     });
 
     test("disallows dangling ] in options", () {
-      expect(() => new Glob(r"{abc]}"), throwsFormatException);
+      expect(() => Glob(r"{abc]}"), throwsFormatException);
     });
   });
 
   test("disallows unescaped parens", () {
-    expect(() => new Glob("foo(bar"), throwsFormatException);
-    expect(() => new Glob("foo)bar"), throwsFormatException);
+    expect(() => Glob("foo(bar"), throwsFormatException);
+    expect(() => Glob("foo)bar"), throwsFormatException);
   });
 }