 
     /// Creates deep copy of the object.
     public func copy() -> InMemoryFileSystem {
-        let fs = InMemoryFileSystem()
-        fs.root = root.copy()
-        return fs
-    }
-
-    /// Get the node corresponding to the given path.
+        return lock.withLock {
+            let fs = InMemoryFileSystem()
+            fs.root = root.copy()
+            return fs
+        }
+    }
+
+    /// Private function to look up the node corresponding to a path.
+    /// Not threadsafe.
     private func getNode(_ path: AbsolutePath, followSymlink: Bool = true) throws -> Node? {
         func getNodeInternal(_ path: AbsolutePath) throws -> Node? {
             // If this is the root node, return it.

        contents.entries[path.basename] = Node(.directory(DirectoryContents()))
    }

    public func createSymbolicLink(_ path: AbsolutePath, pointingAt destination: AbsolutePath, relative: Bool) throws {
        // Create directory to destination parent.
        guard let destinationParent = try getNode(path.parentDirectory) else {
            throw FileSystemError.noEntry
        }

        // Check that the parent is a directory.
        guard case .directory(let contents) = destinationParent.contents else {
            throw FileSystemError.notDirectory
        }

        guard contents.entries[path.basename] == nil else {
            throw FileSystemError.alreadyExistsAtDestination
        }

        let destination = relative ? destination.relative(to: path.parentDirectory).pathString : destination.pathString

        contents.entries[path.basename] = Node(.symlink(destination))
    }

    public func readFileContents(_ path: AbsolutePath) throws -> ByteString {
        // Get the node.
        guard let node = try getNode(path) else {
            throw FileSystemError.noEntry
        }

        // Check that the node is a file.
        guard case .file(let contents) = node.contents else {
            // The path is a directory, this is an error.
            throw FileSystemError.isDirectory
        }

        // Return the file contents.
        return contents
    }

    public func writeFileContents(_ path: AbsolutePath, bytes: ByteString) throws {
        // It is an error if this is the root node.
        let parentPath = path.parentDirectory
        guard path != parentPath else {
            throw FileSystemError.isDirectory
        }

        // Get the parent node.
        guard let parent = try getNode(parentPath) else {
            throw FileSystemError.noEntry
        }

        // Check that the parent is a directory.
        guard case .directory(let contents) = parent.contents else {
            // The parent isn't a directory, this is an error.
            throw FileSystemError.notDirectory
        }

        // Check if the node exists.
        if let node = contents.entries[path.basename] {
            // Verify it is a file.
            guard case .file = node.contents else {
                // The path is a directory, this is an error.
                throw FileSystemError.isDirectory
            }
        }

        // Write the file.
        contents.entries[path.basename] = Node(.file(bytes))
    }

    public func writeFileContents(_ path: AbsolutePath, bytes: ByteString, atomically: Bool) throws {

//
/// Concrete FileSystem implementation which simulates an empty disk.
public class InMemoryFileSystem: FileSystem {
    
    /// Private internal representation of a file system node.
    /// Not threadsafe.
    private class Node {
        /// The actual node data.
        let contents: NodeContents
