Windows fixes (#42)

diff --git a/lib/src/backends/chroot/chroot_directory.dart b/lib/src/backends/chroot/chroot_directory.dart
index d743760..23d24c3 100644
--- a/lib/src/backends/chroot/chroot_directory.dart
+++ b/lib/src/backends/chroot/chroot_directory.dart
@@ -158,7 +158,7 @@
   }
 
   FileSystemEntity _denormalize(io.FileSystemEntity entity, String dirname) {
-    p.Context ctx = fileSystem._context;
+    p.Context ctx = fileSystem.path;
     String relativePart = ctx.relative(entity.path, from: dirname);
     String entityPath = ctx.join(path, relativePart);
     if (entity is io.File) {
diff --git a/lib/src/backends/chroot/chroot_file_system.dart b/lib/src/backends/chroot/chroot_file_system.dart
index bb51210..d3c861b 100644
--- a/lib/src/backends/chroot/chroot_file_system.dart
+++ b/lib/src/backends/chroot/chroot_file_system.dart
@@ -50,14 +50,14 @@
   ///
   /// **NOTE**: [root] must be a _canonicalized_ path; see [p.canonicalize].
   ChrootFileSystem(this.delegate, this.root) {
-    if (root != p.canonicalize(root)) {
+    if (root != delegate.path.canonicalize(root)) {
       throw new ArgumentError.value(root, 'root', 'Must be canonical path');
     }
     _cwd = _localRoot;
   }
 
   /// Gets the root path, as seen by entities in this file system.
-  String get _localRoot => p.rootPrefix(root);
+  String get _localRoot => delegate.path.rootPrefix(root);
 
   @override
   Directory directory(dynamic path) =>
@@ -82,8 +82,6 @@
     return directory(_systemTemp)..createSync();
   }
 
-  p.Context get _context => new p.Context(current: _cwd);
-
   /// Creates a directory object pointing to the current working directory.
   ///
   /// **NOTE** This does _not_ proxy to the underlying file system's current
@@ -120,7 +118,10 @@
       default:
         throw new FileSystemException('Not a directory');
     }
-    assert(() => p.isAbsolute(value) && value == p.canonicalize(value));
+    assert(() {
+      p.Context ctx = delegate.path;
+      return ctx.isAbsolute(value) && value == ctx.canonicalize(value);
+    });
     _cwd = value;
   }
 
@@ -195,7 +196,7 @@
     bool relative: false,
     bool keepInJail: false,
   }) {
-    assert(_context.isAbsolute(realPath));
+    assert(path.isAbsolute(realPath));
     if (!realPath.startsWith(root)) {
       if (keepInJail) {
         return _localRoot;
@@ -209,7 +210,7 @@
     }
     if (relative) {
       assert(result.startsWith(_cwd));
-      result = _context.relative(result, from: _cwd);
+      result = path.relative(result, from: _cwd);
     }
     return result;
   }
@@ -231,7 +232,7 @@
     if (resolve) {
       localPath = _resolve(localPath, followLinks: followLinks);
     } else {
-      assert(() => _context.isAbsolute(localPath));
+      assert(() => path.isAbsolute(localPath));
     }
     return '$root$localPath';
   }
@@ -261,7 +262,7 @@
     bool followLinks: true,
     _NotFoundBehavior notFound: _NotFoundBehavior.allow,
   }) {
-    p.Context ctx = _context;
+    p.Context ctx = this.path;
     String root = _localRoot;
     List<String> parts, ledger;
     if (ctx.isAbsolute(path)) {
diff --git a/lib/src/backends/chroot/chroot_file_system_entity.dart b/lib/src/backends/chroot/chroot_file_system_entity.dart
index a7a8388..89b1487 100644
--- a/lib/src/backends/chroot/chroot_file_system_entity.dart
+++ b/lib/src/backends/chroot/chroot_file_system_entity.dart
@@ -43,7 +43,7 @@
 
   /// Gets the path of this entity as an absolute path (unchanged if the
   /// entity already specifies an absolute path).
-  String get _absolutePath => fileSystem._context.absolute(path);
+  String get _absolutePath => fileSystem.path.absolute(path);
 
   /// Tells whether this entity's path references a symbolic link.
   bool get _isLink =>
@@ -166,5 +166,5 @@
       throw new UnsupportedError('watch is not supported on ChrootFileSystem');
 
   @override
-  bool get isAbsolute => fileSystem._context.isAbsolute(path);
+  bool get isAbsolute => fileSystem.path.isAbsolute(path);
 }
diff --git a/test/common_tests.dart b/test/common_tests.dart
index 867ba95..206b9c5 100644
--- a/test/common_tests.dart
+++ b/test/common_tests.dart
@@ -9,6 +9,7 @@
 
 import 'package:file/file.dart';
 import 'package:file/testing.dart';
+import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
 import 'package:test/test.dart' as testpkg show group, setUp, tearDown, test;
 
@@ -126,17 +127,25 @@
     /// Returns [path] prefixed by the [root] namespace.
     /// This is only intended for absolute paths.
     String ns(String path) {
-      // We purposefully don't use package:path here because some of our tests
-      // use non-standard paths that package:path would correct for us
-      // inadvertently (thus thwarting the purpose of that test).
-      assert(path.startsWith('/'));
-      return root == '/' ? path : (path == '/' ? root : '$root$path');
+      p.Context posix = new p.Context(style: p.Style.posix);
+      List<String> parts = posix.split(path);
+      path = fs.path.joinAll(parts);
+      String rootPrefix = fs.path.rootPrefix(path);
+      assert(rootPrefix.isNotEmpty);
+      String result = root == rootPrefix
+          ? path
+          : (path == rootPrefix
+              ? root
+              : fs.path.join(root, fs.path.joinAll(parts.sublist(1))));
+      return result;
     }
 
     setUp(() async {
       root = rootfn != null ? rootfn() : '/';
-      assert(root.startsWith('/') && (root == '/' || !root.endsWith('/')));
       fs = await createFs();
+      assert(fs.path.isAbsolute(root));
+      assert(!root.endsWith(fs.path.separator) ||
+          fs.path.rootPrefix(root) == root);
     });
 
     group('FileSystem', () {
@@ -454,8 +463,8 @@
 
     group('Directory', () {
       test('uri', () {
-        expect(
-            fs.directory(ns('/foo')).uri.toString(), 'file://${ns('/foo/')}');
+        expect(fs.directory(ns('/foo')).uri.toString(),
+            'file://${ns('/foo')}${fs.path.separator}');
         expect(fs.directory('foo').uri.toString(), 'foo/');
       });