diff --git a/apps/files/js/app.js b/apps/files/js/app.js
index 6d8a9788d97780d0f54b369c56424ff658c4342a..6ccf5135000f6f12073d65e7fd7c3a022c890d83 100644
--- a/apps/files/js/app.js
+++ b/apps/files/js/app.js
@@ -24,20 +24,27 @@
 		initialize: function() {
 			this.navigation = new OCA.Files.Navigation($('#app-navigation'));
 
-			// TODO: ideally these should be in a separate class / app (the embedded "all files" app)
-			this.fileActions = OCA.Files.FileActions.clone();
+			var fileActions = new OCA.Files.FileActions();
+			// default actions
+			fileActions.registerDefaultActions();
+			// legacy actions
+			fileActions.merge(window.FileActions);
+			// regular actions
+			fileActions.merge(OCA.Files.fileActions);
+
 			this.files = OCA.Files.Files;
 
+			// TODO: ideally these should be in a separate class / app (the embedded "all files" app)
 			this.fileList = new OCA.Files.FileList(
 				$('#app-content-files'), {
 					scrollContainer: $('#app-content'),
 					dragOptions: dragOptions,
-					folderDropOptions: folderDropOptions
+					folderDropOptions: folderDropOptions,
+					fileActions: fileActions,
+					allowLegacyActions: true
 				}
 			);
 			this.files.initialize();
-			this.fileActions.registerDefaultActions();
-			this.fileList.setFileActions(this.fileActions);
 
 			// for backward compatibility, the global FileList will
 			// refer to the one of the "files" view
@@ -146,7 +153,7 @@
 })();
 
 $(document).ready(function() {
-	// wait for other apps/extensions to register their event handlers
+	// wait for other apps/extensions to register their event handlers and file actions
 	// in the "ready" clause
 	_.defer(function() {
 		OCA.Files.App.initialize();
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index a12b1f03423a30eac321335e46baa8740bd98b2f..8cee037e29426ba25fb09652cc3fda89ee1641c4 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -11,11 +11,40 @@
 /* global trashBinApp */
 (function() {
 
-	var FileActions = {
+	/**
+	 * Construct a new FileActions instance
+	 */
+	var FileActions = function() {
+		this.initialize();
+	}
+	FileActions.prototype = {
 		actions: {},
 		defaults: {},
 		icons: {},
 		currentFile: null,
+		initialize: function() {
+			this.clear();
+		},
+		/**
+		 * Merges the actions from the given fileActions into
+		 * this instance.
+		 *
+		 * @param fileActions instance of OCA.Files.FileActions
+		 */
+		merge: function(fileActions) {
+			var self = this;
+			// merge first level to avoid unintended overwriting
+			_.each(fileActions.actions, function(sourceMimeData, mime) {
+				var targetMimeData = self.actions[mime];
+				if (!targetMimeData) {
+					targetMimeData = {};
+				}
+				self.actions[mime] = _.extend(targetMimeData, sourceMimeData);
+			});
+
+			this.defaults = _.extend(this.defaults, fileActions.defaults);
+			this.icons = _.extend(this.icons, fileActions.icons);
+		},
 		register: function (mime, name, permissions, icon, action, displayName) {
 			if (!this.actions[mime]) {
 				this.actions[mime] = {};
@@ -31,18 +60,6 @@
 			this.actions[mime][name]['displayName'] = displayName;
 			this.icons[name] = icon;
 		},
-		/**
-		 * Clones the current file actions handler including the already
-		 * registered actions.
-		 */
-		clone: function() {
-			var fileActions = _.extend({}, this);
-			// need to deep copy the actions as well
-			fileActions.actions = _.extend({}, this.actions);
-			fileActions.defaults = _.extend({}, this.defaults);
-			//fileActions.icons = _.extend({}, this.icons);
-			return fileActions;
-		},
 		clear: function() {
 			this.actions = {};
 			this.defaults = {};
@@ -137,6 +154,9 @@
 				event.preventDefault();
 
 				self.currentFile = event.data.elem;
+				// also set on global object for legacy apps
+				window.FileActions.currentFile = self.currentFile;
+
 				var file = self.getCurrentFile();
 				var $tr = $(this).closest('tr');
 
@@ -276,8 +296,25 @@
 	};
 
 	OCA.Files.FileActions = FileActions;
-})();
 
-// for backward compatibility
-window.FileActions = OCA.Files.FileActions;
+	// global file actions to be used by all lists
+	OCA.Files.fileActions = new OCA.Files.FileActions();
+	OCA.Files.legacyFileActions = new OCA.Files.FileActions();
+
+	// for backward compatibility
+	// 
+	// legacy apps are expecting a stateful global FileActions object to register
+	// their actions on. Since legacy apps are very likely to break with other
+	// FileList views than the main one ("All files"), actions registered
+	// through window.FileActions will be limited to the main file list.
+	window.FileActions = OCA.Files.legacyFileActions;
+	window.FileActions.register = function (mime, name, permissions, icon, action, displayName) {
+		console.warn('FileActions.register() is deprecated, please use OCA.Files.fileActions.register() instead');
+		OCA.Files.FileActions.prototype.register.call(window.FileActions, mime, name, permissions, icon, action, displayName);
+	};
+	window.FileActions.setDefault = function (mime, name) {
+		console.warn('FileActions.setDefault() is deprecated, please use OCA.Files.fileActions.setDefault() instead');
+		OCA.Files.FileActions.prototype.setDefault.call(window.FileActions, mime, name);
+	};
+})();
 
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index e1cbfc38566abe3b09f50f737a4e238563c5fa65..52d4c8ba3fe66bdcbc42926a3872be372c69a09a 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -125,7 +125,7 @@
 			this.$container = options.scrollContainer || $(window);
 			this.$table = $el.find('table:first');
 			this.$fileList = $el.find('#fileList');
-			this.fileActions = OCA.Files.FileActions;
+			this._initFileActions(options.fileActions);
 			this.files = [];
 			this._selectedFiles = {};
 			this._selectionSummary = new OCA.Files.FileSummary();
@@ -168,6 +168,14 @@
 			this.$container.on('scroll', _.bind(this._onScroll, this));
 		},
 
+		_initFileActions: function(fileActions) {
+			this.fileActions = fileActions;
+			if (!this.fileActions) {
+				this.fileActions = new OCA.Files.FileActions();
+				this.fileActions.registerDefaultActions();
+			}
+		},
+
 		/**
 		 * Event handler for when the URL changed
 		 */
@@ -248,6 +256,8 @@
 					var action = this.fileActions.getDefault(mime,type, permissions);
 					if (action) {
 						event.preventDefault();
+						// also set on global object for legacy apps
+						window.FileActions.currentFile = this.fileActions.currentFile;
 						action(filename, {
 							$file: $tr,
 							fileList: this,
@@ -791,15 +801,6 @@
 			return OC.linkTo('files', 'index.php')+"?dir="+ encodeURIComponent(dir).replace(/%2F/g, '/');
 		},
 
-		/**
-		 * Sets the file actions handler.
-		 *
-		 * @param fileActions FileActions handler
-		 */
-		setFileActions: function(fileActions) {
-			this.fileActions = fileActions;
-		},
-
 		/**
 		 * Sets the current directory name and updates the breadcrumb.
 		 * @param targetDir directory to display
diff --git a/apps/files/tests/js/appSpec.js b/apps/files/tests/js/appSpec.js
index 0e9abad6989c9c84b04e82a532aaeee309bcd103..a9bbab03ecb4914be8abeb3fa31cf530d0eac7a8 100644
--- a/apps/files/tests/js/appSpec.js
+++ b/apps/files/tests/js/appSpec.js
@@ -41,6 +41,10 @@ describe('OCA.Files.App tests', function() {
 			'</div>'
 		);
 
+		window.FileActions = new OCA.Files.FileActions();
+		OCA.Files.legacyFileActions = window.FileActions;
+		OCA.Files.fileActions = new OCA.Files.FileActions();
+
 		pushStateStub = sinon.stub(OC.Util.History, 'pushState');
 		parseUrlQueryStub = sinon.stub(OC.Util.History, 'parseUrlQuery');
 		parseUrlQueryStub.returns({});
@@ -51,8 +55,6 @@ describe('OCA.Files.App tests', function() {
 		App.navigation = null;
 		App.fileList = null;
 		App.files = null;
-		App.fileActions.clear();
-		App.fileActions = null;
 
 		pushStateStub.restore();
 		parseUrlQueryStub.restore();
@@ -64,6 +66,53 @@ describe('OCA.Files.App tests', function() {
 			expect(App.fileList.fileActions.actions.all).toBeDefined();
 			expect(App.fileList.$el.is('#app-content-files')).toEqual(true);
 		});
+		it('merges the legacy file actions with the default ones', function() {
+			var legacyActionStub = sinon.stub();
+			var actionStub = sinon.stub();
+			// legacy action
+			window.FileActions.register(
+					'all',
+					'LegacyTest',
+					OC.PERMISSION_READ,
+					OC.imagePath('core', 'actions/test'),
+					legacyActionStub
+			);
+			// legacy action to be overwritten
+			window.FileActions.register(
+					'all',
+					'OverwriteThis',
+					OC.PERMISSION_READ,
+					OC.imagePath('core', 'actions/test'),
+					legacyActionStub
+			);
+
+			// regular file actions
+			OCA.Files.fileActions.register(
+					'all',
+					'RegularTest',
+					OC.PERMISSION_READ,
+					OC.imagePath('core', 'actions/test'),
+					actionStub
+			);
+
+			// overwrite
+			OCA.Files.fileActions.register(
+					'all',
+					'OverwriteThis',
+					OC.PERMISSION_READ,
+					OC.imagePath('core', 'actions/test'),
+					actionStub
+			);
+
+			App.initialize();
+
+			var actions = App.fileList.fileActions.actions;
+			expect(actions.all.OverwriteThis.action).toBe(actionStub);
+			expect(actions.all.LegacyTest.action).toBe(legacyActionStub);
+			expect(actions.all.RegularTest.action).toBe(actionStub);
+			// default one still there
+			expect(actions.dir.Open.action).toBeDefined();
+		});
 	});
 
 	describe('URL handling', function() {
diff --git a/apps/files/tests/js/fileactionsSpec.js b/apps/files/tests/js/fileactionsSpec.js
index edd7e3438847e01b8fc587d7b755d220bf55f673..fa634da08a200d0f6eae74bc10bde8bf347170c1 100644
--- a/apps/files/tests/js/fileactionsSpec.js
+++ b/apps/files/tests/js/fileactionsSpec.js
@@ -21,7 +21,7 @@
 
 describe('OCA.Files.FileActions tests', function() {
 	var $filesTable, fileList;
-	var FileActions = OCA.Files.FileActions;
+	var FileActions; 
 
 	beforeEach(function() {
 		// init horrible parameters
@@ -31,10 +31,11 @@ describe('OCA.Files.FileActions tests', function() {
 		// dummy files table
 		$filesTable = $body.append('<table id="filestable"></table>');
 		fileList = new OCA.Files.FileList($('#testArea'));
-		FileActions.registerDefaultActions(fileList);
+		FileActions = new OCA.Files.FileActions();
+		FileActions.registerDefaultActions();
 	});
 	afterEach(function() {
-		FileActions.clear();
+		FileActions = null;
 		fileList = undefined;
 		$('#dir, #permissions, #filestable').remove();
 	});
diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js
index 739ae599c651505006ae5d99d8abb65af0a488b1..a197fd5722c81296e51c839a8807746db7e476d7 100644
--- a/apps/files/tests/js/filelistSpec.js
+++ b/apps/files/tests/js/filelistSpec.js
@@ -21,7 +21,6 @@
 
 describe('OCA.Files.FileList tests', function() {
 	var testFiles, alertStub, notificationStub, fileList;
-	var FileActions = OCA.Files.FileActions;
 
 	/**
 	 * Generate test file data
@@ -117,15 +116,11 @@ describe('OCA.Files.FileList tests', function() {
 		}];
 
 		fileList = new OCA.Files.FileList($('#app-content-files'));
-		FileActions.clear();
-		FileActions.registerDefaultActions(fileList);
-		fileList.setFileActions(FileActions);
 	});
 	afterEach(function() {
 		testFiles = undefined;
 		fileList = undefined;
 
-		FileActions.clear();
 		notificationStub.restore();
 		alertStub.restore();
 	});
diff --git a/apps/files_sharing/js/app.js b/apps/files_sharing/js/app.js
index 57551237a344666ea336d464f26ba22b4e5252ac..7a71684f1a16d2d397629f7437ca2cd22b3cee81 100644
--- a/apps/files_sharing/js/app.js
+++ b/apps/files_sharing/js/app.js
@@ -23,11 +23,11 @@ OCA.Sharing.App = {
 			$el,
 			{
 				scrollContainer: $('#app-content'),
-				sharedWithUser: true
+				sharedWithUser: true,
+				fileActions: this._createFileActions()
 			}
 		);
 
-		this._initFileActions(this._inFileList);
 		this._extendFileList(this._inFileList);
 		this._inFileList.appName = t('files_sharing', 'Shared with you');
 		this._inFileList.$el.find('#emptycontent').text(t('files_sharing', 'No files have been shared with you yet.'));
@@ -41,25 +41,31 @@ OCA.Sharing.App = {
 			$el,
 			{
 				scrollContainer: $('#app-content'),
-				sharedWithUser: false
+				sharedWithUser: false,
+				fileActions: this._createFileActions()
 			}
 		);
 
-		this._initFileActions(this._outFileList);
 		this._extendFileList(this._outFileList);
 		this._outFileList.appName = t('files_sharing', 'Shared with others');
 		this._outFileList.$el.find('#emptycontent').text(t('files_sharing', 'You haven\'t shared any files yet.'));
 	},
 
-	_initFileActions: function(fileList) {
-		var fileActions = OCA.Files.FileActions.clone();
+	_createFileActions: function() {
+		// inherit file actions from the files app
+		var fileActions = new OCA.Files.FileActions();
+		// note: not merging the legacy actions because legacy apps are not
+		// compatible with the sharing overview and need to be adapted first
+		fileActions.merge(OCA.Files.fileActions);
+
 		// when the user clicks on a folder, redirect to the corresponding
-		// folder in the files app
+		// folder in the files app instead of opening it directly
 		fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
 			OCA.Files.App.setActiveView('files', {silent: true});
 			OCA.Files.App.fileList.changeDirectory(context.$file.attr('data-path') + '/' + filename, true, true);
 		});
-		fileList.setFileActions(fileActions);
+		fileActions.setDefault('dir', 'Open');
+		return fileActions;
 	},
 
 	_extendFileList: function(fileList) {
diff --git a/apps/files_sharing/js/public.js b/apps/files_sharing/js/public.js
index d825ee9de15b227c2475192fc5e525553afc8b53..446f3f2442b65b553ed7143c3b421e048a051b00 100644
--- a/apps/files_sharing/js/public.js
+++ b/apps/files_sharing/js/public.js
@@ -19,9 +19,18 @@ OCA.Sharing.PublicApp = {
 
 	initialize: function($el) {
 		var self = this;
+		var fileActions;
 		if (this._initialized) {
 			return;
 		}
+		fileActions = new OCA.Files.FileActions();
+		// default actions
+		fileActions.registerDefaultActions();
+		// legacy actions
+		fileActions.merge(window.FileActions);
+		// regular actions
+		fileActions.merge(OCA.Files.fileActions);
+
 		this._initialized = true;
 		this.initialDir = $('#dir').val();
 
@@ -32,7 +41,8 @@ OCA.Sharing.PublicApp = {
 				{
 					scrollContainer: $(window),
 					dragOptions: dragOptions,
-					folderDropOptions: folderDropOptions
+					folderDropOptions: folderDropOptions,
+					fileActions: fileActions
 				}
 			);
 			this.files = OCA.Files.Files;
@@ -121,10 +131,8 @@ OCA.Sharing.PublicApp = {
 				};
 			});
 
-			this.fileActions = _.extend({}, OCA.Files.FileActions);
-			this.fileActions.registerDefaultActions(this.fileList);
-			delete this.fileActions.actions.all.Share;
-			this.fileList.setFileActions(this.fileActions);
+			// do not allow sharing from the public page
+			delete this.fileList.fileActions.actions.all.Share;
 
 			this.fileList.changeDirectory(this.initialDir || '/', false, true);
 
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 28586a179a4cfecb7ed60ad54ab6d55430b49c0e..1fcb1f088bf739c20feea10f4cb7b9113135f192 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -9,10 +9,7 @@
  */
 
 $(document).ready(function() {
-
-	var sharesLoaded = false;
-
-	if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined') {
+	if (!_.isUndefined(OC.Share) && !_.isUndefined(OCA.Files)) {
 		// TODO: make a separate class for this or a hook or jQuery event ?
 		if (OCA.Files.FileList) {
 			var oldCreateRow = OCA.Files.FileList.prototype._createRow;
@@ -64,18 +61,18 @@ $(document).ready(function() {
 				}
 			})
 
-			if (!sharesLoaded){
+			if (!OCA.Sharing.sharesLoaded){
 				OC.Share.loadIcons('file', $fileList);
 				// assume that we got all shares, so switching directories
 				// will not invalidate that list
-				sharesLoaded = true;
+				OCA.Sharing.sharesLoaded = true;
 			}
 			else{
 				OC.Share.updateIcons('file', $fileList);
 			}
 		});
 
-		OCA.Files.FileActions.register(
+		OCA.Files.fileActions.register(
 				'all',
 				'Share',
 				OC.PERMISSION_SHARE,
diff --git a/apps/files_trashbin/js/app.js b/apps/files_trashbin/js/app.js
index cf3fb1d0d162866c8e63ade15736c0da76502c14..c59a132b8c4475ea4b466441ce6d7eb188229007 100644
--- a/apps/files_trashbin/js/app.js
+++ b/apps/files_trashbin/js/app.js
@@ -19,22 +19,20 @@ OCA.Trashbin.App = {
 		this._initialized = true;
 		this.fileList = new OCA.Trashbin.FileList(
 			$('#app-content-trashbin'), {
-				scrollContainer: $('#app-content')
+				scrollContainer: $('#app-content'),
+				fileActions: this._createFileActions()
 			}
 		);
-		this.registerFileActions(this.fileList);
 	},
 
-	registerFileActions: function(fileList) {
-		var self = this;
-		var fileActions = _.extend({}, OCA.Files.FileActions);
-		fileActions.clear();
-		fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename) {
-			var dir = fileList.getCurrentDirectory();
+	_createFileActions: function() {
+		var fileActions = new OCA.Files.FileActions();
+		fileActions.register('dir', 'Open', OC.PERMISSION_READ, '', function (filename, context) {
+			var dir = context.fileList.getCurrentDirectory();
 			if (dir !== '/') {
 				dir = dir + '/';
 			}
-			fileList.changeDirectory(dir + filename);
+			context.fileList.changeDirectory(dir + filename);
 		});
 
 		fileActions.setDefault('dir', 'Open');
@@ -69,7 +67,7 @@ OCA.Trashbin.App = {
 				_.bind(fileList._removeCallback, fileList)
 			);
 		});
-		fileList.setFileActions(fileActions);
+		return fileActions;
 	}
 };
 
diff --git a/apps/files_trashbin/js/filelist.js b/apps/files_trashbin/js/filelist.js
index 205f879f335f944631013b10bb272f3fc6e972f9..826c1bd64d51a633ec34c4fa10cbb8a3682af3fa 100644
--- a/apps/files_trashbin/js/filelist.js
+++ b/apps/files_trashbin/js/filelist.js
@@ -26,8 +26,8 @@
 		return name;
 	}
 
-	var FileList = function($el) {
-		this.initialize($el);
+	var FileList = function($el, options) {
+		this.initialize($el, options);
 	};
 	FileList.prototype = _.extend({}, OCA.Files.FileList.prototype, {
 		id: 'trashbin',
diff --git a/apps/files_trashbin/tests/js/filelistSpec.js b/apps/files_trashbin/tests/js/filelistSpec.js
index d41c24c3cc9be9f74beb87189ea919c24daee292..11eeff68df81caf353410ba04a5bce9330e15839 100644
--- a/apps/files_trashbin/tests/js/filelistSpec.js
+++ b/apps/files_trashbin/tests/js/filelistSpec.js
@@ -21,7 +21,6 @@
 
 describe('OCA.Trashbin.FileList tests', function() {
 	var testFiles, alertStub, notificationStub, fileList;
-	var FileActions = OCA.Files.FileActions;
 
 	beforeEach(function() {
 		alertStub = sinon.stub(OC.dialogs, 'alert');
@@ -87,14 +86,18 @@ describe('OCA.Trashbin.FileList tests', function() {
 			etag: '456'
 		}];
 
-		fileList = new OCA.Trashbin.FileList($('#app-content-trashbin'));
-		OCA.Trashbin.App.registerFileActions(fileList);
+		// register file actions like the trashbin App does
+		var fileActions = OCA.Trashbin.App._createFileActions(fileList);
+		fileList = new OCA.Trashbin.FileList(
+			$('#app-content-trashbin'), {
+				fileActions: fileActions
+			}
+		);
 	});
 	afterEach(function() {
 		testFiles = undefined;
 		fileList = undefined;
 
-		FileActions.clear();
 		$('#dir').remove();
 		notificationStub.restore();
 		alertStub.restore();
diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js
index a23935495d74fda6fad11d364f47822a2292709c..942a1a929f796b56e8603e822a8e129113349a0a 100644
--- a/apps/files_versions/js/versions.js
+++ b/apps/files_versions/js/versions.js
@@ -8,7 +8,7 @@
  *
  */
 
-/* global FileActions, scanFiles, escapeHTML, formatDate */
+/* global scanFiles, escapeHTML, formatDate */
 $(document).ready(function(){
 
 	if ($('#isPublic').val()){
@@ -18,9 +18,9 @@ $(document).ready(function(){
 		return;
 	}
 
-	if (typeof FileActions !== 'undefined') {
+	if (OCA.Files) {
 		// Add versions button to 'files/index.php'
-		FileActions.register(
+		OCA.Files.fileActions.register(
 			'file',
 			'Versions',
 			OC.PERMISSION_UPDATE,