anchor.diff:      });
       return result;
     }
  +
  +  /**
  +   * Returns true if `object` is a list of File.
  +   */
  +  bool _isFileList(Object object) {
  +    if (!_isResourceList(object)) {
  +      return false;
  +    }
  +    List<ws.Resource> resources = object as List;
  +    bool result = true;
  +    resources.forEach((ws.Resource resource) {
  +      if (resource is! ws.File) {
  +        result = false;
  +      }
  +    });
  +    return result;
  +  }
  +}
  +
  +class FileOpenInTabAction extends SparkAction implements ContextAction {
  +  FileOpenInTabAction(Spark spark) :
  +      super(spark, "file-open-in-tab", "Open in a New Tab") {
  +    defaultBinding("alt-click");
  +  }
  +
  +  void _invoke([List<ws.File> files]) {
  +    bool forceOpen = files.length > 1;
  +    files.forEach((ws.File file) {
  +      spark.selectInEditor(file, forceOpen: true, replaceCurrent: true);
  +    });
  +  }
  +
  +  String get category => 'resource';
  +
  +  bool appliesTo(Object object) => _isFileList(object);
   }
   
   class FileNewAction extends SparkAction implements ContextAction {
  
positive.code:   // Implementation of FilesControllerDelegate interface.
  
    void selectInEditor(ws.File file,
                        {bool forceOpen: false, bool replaceCurrent: true}) {
      if (forceOpen || editorManager.isFileOpened(file)) {
        editorArea.selectFile(file, forceOpen: forceOpen,
            replaceCurrent: replaceCurrent);
      }
    }
  
  
negative.code: 
    void createActions() {
      actionManager = new ActionManager();
      actionManager.registerAction(new FileOpenInTabAction(this));
      actionManager.registerAction(new FileNewAction(this));
      actionManager.registerAction(new FileOpenAction(this));
      actionManager.registerAction(new FileSaveAction(this));
  