public function createFile($uri, $data, &$etag = null)
    {
        list($dir, $name) = Uri\split($uri);

        if (!$this->emit('beforeBind', [$uri])) {
            return false;
        }

        $parent = $this->tree->getNodeForPath($dir);
        if (!$parent instanceof ICollection) {
            throw new Exception\Conflict('Files can only be created as children of collections');
        }

        // It is possible for an event handler to modify the content of the
        // body, before it gets written. If this is the case, $modified
        // should be set to true.
        //
        // If $modified is true, we must not send back an ETag.
        $modified = false;
        if (!$this->emit('beforeCreateFile', [$uri, &$data, $parent, &$modified])) {
            return false;
        }

        $etag = $parent->createFile($name, $data);

        if ($modified) {
            $etag = null;
        }

        $this->tree->markDirty($dir.'/'.$name);

        $this->emit('afterBind', [$uri]);
        $this->emit('afterCreateFile', [$uri, $parent]);

        return true;
    }