app.controller('FileEditorController', function($scope, $timeout, WorkspaceService) {

  var aceModeList = ace.require("ace/ext/modelist");

  $scope.files = null;
  $scope.tabsScroll = {};

  function findCurrentActiveFile() {
    for(var i = 0; i < $scope.files.length; i++) {
      if($scope.files[i].active)
        return i;
    }
    return -1;
  }

  function deactivateAll() {
    angular.forEach($scope.files, function(file) {
      file.active = false;
    });
  }

  function saveFile(file) {
    cancelScheduledSave(file);
    WorkspaceService.request('save', file.path, file.data);
  }

  function cancelScheduledSave(file) {
    $timeout.cancel(file.scheduledSave);
    delete file.scheduledSave;
  }

  function scheduleFileSave(file) {
    cancelScheduledSave(file);
    file.scheduledSave = $timeout(function() {
      saveFile(file);
    }, 1000);
  }

  function startWatchingFile(file) {
    $scope.files[file.path] = file;
    file.dismiss = $scope.$watch('files["' + file.path + '"].data', function(newData, oldData) {
      if(newData != oldData)
        scheduleFileSave(file);
    });
  }

  function stopWatchFile(file) {
    delete $scope.files[file.path];
    file.dismiss();
  }

  function initFile(path, data) {
    var pos = findCurrentActiveFile() + 1;
    var file;
    for(var i = 0; i < $scope.files.length; i++) {
      if($scope.files[i].path == path) {
        file = $scope.files[i];
        break;
      }
    }
    if(file == null) {
      file = {
        path: path,
        data: data,
        aceOptions: {
          theme: 'merbivore_soft',
          mode: aceModeList.getModeForPath(path).name
        }
      };
      $scope.files.splice(pos, 0, file);
      startWatchingFile(file);
    }
    showFile(file)
  }

  function prepareTabScroll() {
    $timeout(function() {
      $scope.tabsScroll.doRecalculate();
      $scope.tabsScroll.scrollTabIntoView();
    });
  }

  function showFile(file) {
    deactivateAll();
    file.active = true;
    prepareTabScroll();
  }

  $scope.focusFile = function() {
    for(var i = 0; i < $scope.files.length; i++) {
      var file = $scope.files[i];
      if(file.scheduledSave != null)
        saveFile(file);
    }
  };

  $scope.closeFile = function(file) {
    var index = $scope.files.indexOf(file);
    if(file.active) {
      file.active = false;
      var neighbour = index == $scope.files.length - 1 ? $scope.files[index - 1] : $scope.files[index + 1];
      if(neighbour != null)
        neighbour.active = true;
    }
    $scope.files.splice(index, 1);
    prepareTabScroll();
    stopWatchFile(file);
    saveFile(file);
  };

  $scope._fileClass = function(file) {
    var classes = [];
    if(file.scheduledSave != null)
      classes.push('file-dirty');
    return classes.join(' ');
  };

  $scope.$on('ready', function() {
    $scope.files = [];
  });

  $scope.$on('open-file', function(event, path) {
    var file = $scope.files[path];
    if(file != null)
      showFile(file);
    else
      WorkspaceService.request('file', path);
  });

  $scope.$on('file', function(event, response) {
    initFile(response.target, response.data);
  });

});
@@ -879,548 +879,366 @@
 ion 
-startWatchingFile(file) %7B%0A    $scope.files%5Bfile.path%5D = file;%0A    file.dismiss = $scope.$watch('files%5B%22' + file.path + '%22%5D.data', function(newData, oldData) %7B%0A      if(newData != oldData)%0A        scheduleFileSave(file);%0A    %7D);%0A  %7D%0A%0A  function stopWatchFile(file) %7B%0A    delete $scope.files%5Bfile.path%5D;%0A    file.dismiss();%0A  %7D%0A%0A  function initFile(path, data) %7B%0A    var pos = findCurrentActiveFile() + 1;%0A    var file;%0A    for(var i = 0; i %3C $scope.files.length; i++) %7B%0A      if($scope.files%5Bi%5D.path == path) %7B%0A        file = $scope.files%5Bi%5D
+createFileTab(path, data) %7B%0A    var ret = %7B%0A      path: path,%0A      data: data,%0A      initialized: false,%0A      aceOptions: %7B%0A        theme: 'merbivore_soft',%0A        mode: aceModeList.getModeForPath(path).name,%0A        onChange: function() %7B%0A          if(!ret.initialized)%0A            ret.initialized = true;%0A          else%0A            scheduleFileSave(ret)
 ;%0A  
@@ -1247,14 +1247,9 @@
     
-break;
+%7D
 %0A   
@@ -1262,219 +1262,150 @@
    %7D
+;
 %0A    
-if(file == null) %7B%0A      file = %7B%0A        path: path,%0A        data: data,%0A        aceOptions: %7B%0A          theme: 'merbivore_soft',%0A          mode: aceModeList.getModeForPath(path).name%0A        %7D%0A      %7D;%0A  
+return ret;%0A  %7D%0A%0A  function initFile(path, data) %7B%0A    var pos = findCurrentActiveFile() + 1;%0A    var file = createFileTab(path, data);%0A
     
@@ -1447,40 +1447,34 @@
     
-  startWatchingFile(file);%0A    %7D
+$scope.files%5Bpath%5D = file;
 %0A   
@@ -2294,50 +2294,61 @@
     
-prepareTabScroll();%0A    stopWatchFile(file
+delete $scope.files%5Bfile.path%5D;%0A    prepareTabScroll(
 );%0A 

use ace callback instead of watch