anchor.diff:      return _dirEntry.removeRecursively().then((_) => _parent._removeChild(this));
     }
   
  +  Future _refresh() {
  +    return _dirEntry.createReader().readEntries().then((List<chrome.Entry> entries) {
  +      List<String> currentNames = _localChildren.map((r) => r.name).toList();
  +      List<String> newNames = entries.map((e) => e.name).toList();
  +      List<Resource> checkChanged = [];
  +
  +      // Check for deleted files.
  +      for (int i = currentNames.length - 1; i >= 0; i--) {
  +        String name = currentNames[i];
  +
  +        if (newNames.contains(name)) {
  +          checkChanged.add(_localChildren[i]);
  +        } else {
  +          Resource resource = _localChildren.removeAt(i);
  +          _fireResourceEvent(new ChangeDelta(resource, EventType.DELETE));
  +        }
  +      }
  +
  +      // Check for added files.
  +      for (int i = newNames.length - 1; i >= 0; i--) {
  +        String name = newNames[i];
  +
  +        if (!currentNames.contains(name)) {
  +          // TODO: handle folders too!
  +          Resource resource = new File(this, entries[i]);
  +          _localChildren.add(resource);
  +          _fireResourceEvent(new ChangeDelta(resource, EventType.ADD));
  +        }
  +      }
  +
  +      // Check for modified files.
  +      return Future.forEach(checkChanged, (Resource resource) {
  +        if (resource is File) {
  +          return resource._refresh();
  +        } else if (resource is Folder) {
  +          return resource._refresh();
  +        }
  +      });
  +    });
  +  }
  +
     chrome.DirectoryEntry get _dirEntry => entry;
   }
   
   class File extends Resource {
     List<Marker> _markers = [];
  -
  -  File(Container parent, chrome.Entry entry):
  -    super(parent, entry);
  +  int _timestamp;
  +
  +  File(Container parent, chrome.Entry entry) : super(parent, entry) {
  +    entry.getMetadata().then((/*Metadata*/ metaData) {
  +      _timestamp = metaData.modificationTime.millisecondsSinceEpoch;
  +    });
  +  }
   
     Future<String> getContents() => _fileEntry.readText();
   
  
positive.code:   Container get parent => null;
    Project get project => null;
    Workspace get workspace => this;
  
    /**
     * Stops the posting of [MarkerChangeEvent] to the stream. Clients should
  
negative.code:   }
  
    /**
     * Read the sync file system and restore entries.
     */
    Future restoreSyncFs() {
      chrome.syncFileSystem.requestFileSystem().then((/*chrome.FileSystem*/ fs) {
        _syncFileSystem = fs;
        _syncFileSystem.root.createReader().readEntries().then((List<chrome.Entry> entries) {
          pauseResourceEvents();
          Future.forEach(entries, (chrome.Entry entry) {
            return _link(entry, syncable: true);
          }).whenComplete(() {
            resumeResourceEvents();
          }).then((_) => _whenAvailableSyncFs.complete(this));
        });
      }, onError: (e) {
  