diff --git a/lib/hooks/basicemitter.php b/lib/hooks/basicemitter.php
index e615a58cfe846c3fde3d4aaf1d6ffdaf2b8a65c9..9ffe1af23144f6aae36841e3fbc3c689f5c272a9 100644
--- a/lib/hooks/basicemitter.php
+++ b/lib/hooks/basicemitter.php
@@ -13,7 +13,7 @@ abstract class BasicEmitter implements Emitter {
 	/**
 	 * @var (callable[])[] $listeners
 	 */
-	private $listeners = array();
+	protected $listeners = array();
 
 	/**
 	 * @param string $scope
diff --git a/lib/hooks/forwardingemitter.php b/lib/hooks/forwardingemitter.php
new file mode 100644
index 0000000000000000000000000000000000000000..1aacc4012e0014cb933af81f56a2d5f5e88da362
--- /dev/null
+++ b/lib/hooks/forwardingemitter.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Hooks;
+
+/**
+ * Class ForwardingEmitter
+ *
+ * allows forwarding all listen calls to other emitters
+ *
+ * @package OC\Hooks
+ */
+abstract class ForwardingEmitter extends BasicEmitter {
+	/**
+	 * @var \OC\Hooks\Emitter[] array
+	 */
+	private $forwardEmitters = array();
+
+	/**
+	 * @param string $scope
+	 * @param string $method
+	 * @param callable $callback
+	 */
+	public function listen($scope, $method, $callback) {
+		parent::listen($scope, $method, $callback);
+		foreach ($this->forwardEmitters as $emitter) {
+			$emitter->listen($scope, $method, $callback);
+		}
+	}
+
+	/**
+	 * @param \OC\Hooks\Emitter $emitter
+	 */
+	protected function forward($emitter) {
+		$this->forwardEmitters[] = $emitter;
+
+		//forward all previously connected hooks
+		foreach ($this->listeners as $key => $listeners) {
+			list($scope, $method) = explode('::', $key, 2);
+			foreach ($listeners as $listener) {
+				$emitter->listen($scope, $method, $listener);
+			}
+		}
+	}
+}
diff --git a/tests/lib/hooks/forwardingemitter.php b/tests/lib/hooks/forwardingemitter.php
new file mode 100644
index 0000000000000000000000000000000000000000..decf6bb354cae24f0bf1afc7572cd5dee7e10bf7
--- /dev/null
+++ b/tests/lib/hooks/forwardingemitter.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Hooks;
+use OC\Hooks\PublicEmitter;
+
+class DummyForwardingEmitter extends \OC\Hooks\ForwardingEmitter {
+	public function emitEvent($scope, $method, $arguments = array()) {
+		$this->emit($scope, $method, $arguments);
+	}
+
+	/**
+	 * @param \OC\Hooks\Emitter $emitter
+	 */
+	public function forward($emitter) {
+		parent::forward($emitter);
+	}
+}
+
+/**
+ * Class ForwardingEmitter
+ *
+ * allows forwarding all listen calls to other emitters
+ *
+ * @package OC\Hooks
+ */
+class ForwardingEmitter extends BasicEmitter {
+	public function testSingleForward() {
+		$baseEmitter = new PublicEmitter();
+		$forwardingEmitter = new DummyForwardingEmitter();
+		$forwardingEmitter->forward($baseEmitter);
+		$hookCalled = false;
+		$forwardingEmitter->listen('Test', 'test', function () use (&$hookCalled) {
+			$hookCalled = true;
+		});
+		$baseEmitter->emit('Test', 'test');
+		$this->assertTrue($hookCalled);
+	}
+
+	public function testMultipleForwards() {
+		$baseEmitter1 = new PublicEmitter();
+		$baseEmitter2 = new PublicEmitter();
+		$forwardingEmitter = new DummyForwardingEmitter();
+		$forwardingEmitter->forward($baseEmitter1);
+		$forwardingEmitter->forward($baseEmitter2);
+		$hookCalled = 0;
+		$forwardingEmitter->listen('Test', 'test1', function () use (&$hookCalled) {
+			$hookCalled++;
+		});
+		$forwardingEmitter->listen('Test', 'test2', function () use (&$hookCalled) {
+			$hookCalled++;
+		});
+		$baseEmitter1->emit('Test', 'test1');
+		$baseEmitter1->emit('Test', 'test2');
+		$this->assertEquals(2, $hookCalled);
+	}
+
+	public function testForwardExistingHooks() {
+		$baseEmitter = new PublicEmitter();
+		$forwardingEmitter = new DummyForwardingEmitter();
+		$hookCalled = false;
+		$forwardingEmitter->listen('Test', 'test', function () use (&$hookCalled) {
+			$hookCalled = true;
+		});
+		$forwardingEmitter->forward($baseEmitter);
+		$baseEmitter->emit('Test', 'test');
+		$this->assertTrue($hookCalled);
+	}
+}