diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index a08544909bab28f8005755277282421aa87fcf2a..7495a5bbe6cb2682c5c20293b86db9454636f66d 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -1,7 +1,8 @@
 <?php
 
 OC::$CLASSPATH['OC_Share'] = "apps/files_sharing/lib_share.php";
-OC::$CLASSPATH['OC_Share_Backend_File'] = "apps/files_sharing/share.php";
+OC::$CLASSPATH['OC_Share_Backend_File'] = "apps/files_sharing/lib/share/file.php";
+OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'apps/files_sharing/lib/share/folder.php';
 OC::$CLASSPATH['OC_Filestorage_Shared'] = "apps/files_sharing/sharedstorage.php";
 
 OCP\App::registerAdmin('files_sharing', 'settings');
@@ -24,3 +25,4 @@ OCP\Util::addscript("3rdparty", "chosen/chosen.jquery.min");
 OCP\Util::addStyle( 'files_sharing', 'sharing' );
 OCP\Util::addStyle("3rdparty", "chosen/chosen");
 OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
+OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
diff --git a/apps/files_sharing/lib/share/file.php b/apps/files_sharing/lib/share/file.php
new file mode 100644
index 0000000000000000000000000000000000000000..86b82b19acd27caadf6dae7eac8ba4f97e29b1c5
--- /dev/null
+++ b/apps/files_sharing/lib/share/file.php
@@ -0,0 +1,94 @@
+<?php
+/**
+* ownCloud
+*
+* @author Michael Gapczynski
+* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+class OC_Share_Backend_File extends OCP\Share_Backend {
+
+	const FORMAT_SOURCE_PATH = 0;
+	const FORMAT_FILE_APP = 1;
+	const FORMAT_FILE_APP_ROOT = 2;
+	const FORMAT_OPENDIR = 3;
+
+	public function getSource($item, $uid) {
+		if (OC_Filesystem::file_exists($item)) {
+			return array('item' => null, 'file' => $item);
+		}
+		return false;
+	}
+
+	public function generateTarget($item, $uid, $exclude = null) {
+		// TODO Make sure target path doesn't exist already
+		return '/Shared'.$item;
+	}
+
+	public function formatItems($items, $format, $parameters = null) {
+		if ($format == self::FORMAT_OPENDIR) {
+			$files = array();
+			foreach ($items as $file) {
+				$files[] = basename($file['file_target']);
+			}
+			return $files;
+		} else {
+			$shares = array();
+			$ids = array();
+			foreach ($items as $item) {
+				$shares[$item['file_source']] = $item;
+				$ids[] = $item['file_source'];
+			}
+			$ids = "'".implode("','", $ids)."'";
+			if ($format == self::FORMAT_SOURCE_PATH) {
+				$query = OCP\DB::prepare('SELECT path FROM *PREFIX*fscache WHERE id IN ('.$ids.')');
+				$result = $query->execute()->fetchAll();
+				if (isset($result[0]['path'])) {
+					return $result[0]['path'];
+				}
+				return false;
+			} else if ($format == self::FORMAT_FILE_APP) {
+				$query = OCP\DB::prepare('SELECT id, path, name, ctime, mtime, mimetype, size, encrypted, versioned, writable FROM *PREFIX*fscache WHERE id IN ('.$ids.')');
+				$result = $query->execute();
+				$files = array();
+				while ($file = $result->fetchRow()) {
+					// Set target path
+					$file['path'] = $shares[$file['id']]['file_target'];
+					$file['name'] = basename($file['path']);
+					// TODO Set permissions: $file['writable']
+					$files[] = $file;
+				}
+				return $files;
+			} else if ($format == self::FORMAT_FILE_APP_ROOT) {
+				$query = OCP\DB::prepare('SELECT id, path, name, ctime, mtime, mimetype, size, encrypted, versioned, writable FROM *PREFIX*fscache WHERE id IN ('.$ids.')');
+				$result = $query->execute();
+				$mtime = 0;
+				$size = 0;
+				while ($file = $result->fetchRow()) {
+					if ($file['mtime'] > $mtime) {
+						$mtime = $file['mtime'];
+					}
+					$size += $file['size'];
+				}
+				return array(0 => array('name' => 'Shared', 'mtime' => $mtime, 'mimetype' => 'httpd/unix-directory', 'size' => $size, 'writable' => false));
+			}
+		}
+		return array();
+	}
+
+}
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/lib/share/folder.php b/apps/files_sharing/lib/share/folder.php
new file mode 100644
index 0000000000000000000000000000000000000000..033e2ba966735630cbb94d03f4376d1160acd7e3
--- /dev/null
+++ b/apps/files_sharing/lib/share/folder.php
@@ -0,0 +1,64 @@
+<?php
+/**
+* ownCloud
+*
+* @author Michael Gapczynski
+* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+class OC_Share_Backend_Folder extends OC_Share_Backend_File {
+
+	public function inCollection($collections, $item) {
+		// TODO
+	}
+
+	public function getChildrenSources($item) {
+		return OC_FileCache::getFolderContent($item);
+	}
+
+	public function formatItems($items, $format, $parameters = null) {
+		if ($format == self::FORMAT_FILE_APP && isset($parameters['folder'])) {
+			$folder = $items[key($items)];
+			$query = OCP\DB::prepare('SELECT path FROM *PREFIX*fscache WHERE id = ?');
+			$result = $query->execute(array($folder['file_source']))->fetchRow();
+			if (isset($result['path'])) {
+				if (isset($parameters['mimetype_filter'])) {
+					$mimetype_filter = $parameters['mimetype_filter'];
+				} else {
+					$mimetype_filter = '';
+				}
+				$pos = strpos($result['path'], $folder['item']);
+				$path = substr($result['path'], $pos).substr($parameters['folder'], strlen($folder['file_target']));
+				$root = substr($result['path'], 0, $pos);
+				return OC_FileCache::getFolderContent($path, $root, $mimetype_filter);
+			}
+		}/* else if ($format == self::FORMAT_OPENDIR_ROOT) {
+			$query = OCP\DB::prepare('SELECT name FROM *PREFIX*fscache WHERE id IN ('.$ids.')');
+			$result = $query->execute();
+			$files = array();
+			while ($file = $result->fetchRow()) {
+				// Set target path
+				$files[] = basename($shares[$file['id']]['item_target']);
+			}
+			return $files;
+		}*/
+		return array();
+	}
+
+}
+
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/sharedstorage.php b/apps/files_sharing/sharedstorage.php
index 11a5d39f011441f29f098f97a37884cb59980a02..1dfdf133791b5e0c0193bd0e090f88dd64186481 100644
--- a/apps/files_sharing/sharedstorage.php
+++ b/apps/files_sharing/sharedstorage.php
@@ -32,30 +32,25 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 		$this->sharedFolder = $arguments['sharedFolder'];
 	}
 
-	public function getSourcePath($target) {
-		$target = $this->sharedFolder.$target;
+	private function getSourcePath($target) {
+		$target = $this->sharedFolder.'/'.$target;
+		$target = rtrim($target, '/');
 		if (isset($this->sourcePaths[$target])) {
 			return $this->sourcePaths[$target];
 		} else {
-			if (dirname($target) != $this->sharedFolder) {
-				$len = strlen($this->sharedFolder);
-				$pos = strpos($target, '/', $len);
-				// Get shared folder name
-				$itemTarget = substr($target, $len, $pos);
-				$insideFolder = true;
+			$pos = strpos($target, '/', 8);
+			// Get shared folder name
+			if ($pos !== false) {
+				$itemTarget = substr($target, 0, $pos);
 			} else {
 				$itemTarget = $target;
-				$insideFolder = false;
 			}
 			$sourcePath = OCP\Share::getItemSharedWith('file', $itemTarget, OC_Share_Backend_File::FORMAT_SOURCE_PATH);
 			if ($sourcePath) {
-				if ($insideFolder) {
-					$this->sourcePaths[$target] = $sourcePath.substr($target, $pos);
-				} else {
-					$this->sourcePaths[$target] = $sourcePath;
-				}
+				$this->sourcePaths[$target] = $sourcePath.substr($target, strlen($itemTarget));
 				return $this->sourcePaths[$target];
 			}
+			OCP\Util::writeLog('files_sharing', 'File source path not found for: '.$target, OCP\Util::ERROR);
 			return false;
 		}
 	}
@@ -70,8 +65,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 		if ($path == "" || $path == "/" || !$this->is_writable($path)) {
 			return false; 
 		} else {
-			$source = $this->getSourcePath($path);
-			if ($source) {
+			if ($source = $this->getSourcePath($path)) {
 				$storage = OC_Filesystem::getStorage($source);
 				return $storage->mkdir($this->getInternalPath($source));
 			}
@@ -80,116 +74,54 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 	
 	public function rmdir($path) {
 		// The folder will be removed from the database, but won't be deleted from the owner's filesystem
-		OC_Share::unshareFromMySelf($this->datadir.$path);
-		$this->clearFolderSizeCache($path);
+		// TODO
 	}
 	
 	public function opendir($path) {
-		if ($path == "" || $path == "/") {
-			$path = $this->datadir.$path;
-			// TODO
-			$sharedItems = OC_Share::getItemsInFolder($path);
-			$files = array();
-			foreach ($sharedItems as $item) {
-				// If item is in the root of the shared storage provider and the item exists add it to the fakedirs
-				if (dirname($item['target'])."/" == $path && $this->file_exists(basename($item['target']))) {
-					$files[] = basename($item['target']);
-				}
-			}
-			OC_FakeDirStream::$dirs['shared']=$files;
+		if ($path == '' || $path == '/') {
+			$files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_Folder::FORMAT_OPENDIR);
+			OC_FakeDirStream::$dirs['shared'] = $files;
 			return opendir('fakedir://shared');
 		} else {
-			$source = $this->getSourcePath($path);
-			if ($source) {
+			if ($source = $this->getSourcePath($path)) {
 				$storage = OC_Filesystem::getStorage($source);
-				$dh = $storage->opendir($this->getInternalPath($source));
-				$modifiedItems = OC_Share::getItemsInFolder($source);
-				if ($modifiedItems && $dh) {
-					$sources = array();
-					$targets = array();
-					// Remove any duplicate or trailing '/'
-					$path = preg_replace('{(/)\1+}', "/", $path);
-					$targetFolder = rtrim($this->datadir.$path, "/");
-					foreach ($modifiedItems as $item) {
-						// If the item is in the current directory and the item exists add it to the arrays
-						if (dirname($item['target']) == $targetFolder && $this->file_exists($path."/".basename($item['target']))) {
-							// If the item was unshared from self, add it it to the arrays
-							if ($item['permissions'] == OC_Share::UNSHARED) {
-								$sources[] = basename($item['source']);
-								$targets[] = "";
-							} else {
-								$sources[] = basename($item['source']);
-								$targets[] = basename($item['target']);
-							}
-						}
-					}
-					// Don't waste time if there aren't any modified items in the current directory
-					if (empty($sources)) {
-						return $dh;
-					} else {
-						global $FAKEDIRS;
-						$files = array();
-						while (($filename = readdir($dh)) !== false) {
-							if ($filename != "." && $filename != "..") {
-								// If the file isn't in the sources array it isn't modified and can be added as is
-								if (!in_array($filename, $sources)) {
-									$files[] = $filename;
-								// The file has a different name than the source and is added to the fakedirs
-								} else {
-									$target = $targets[array_search($filename, $sources)];
-									// Don't add the file if it was unshared from self by the user
-									if ($target != "") {
-										$files[] = $target;
-									}
-								}
-							}
-						}
-						$FAKEDIRS['shared'] = $files;
-						return opendir('fakedir://shared');
-					}
-				} else {
-					return $dh;
-				}
+				return $storage->opendir($this->getInternalPath($source));
 			}
 		}
 	}
-	
+
 	public function is_dir($path) {
-		if ($path == "" || $path == "/") {
+		if ($path == '' || $path == '/') {
 			return true;
 		} else {
-			$source = $this->getSourcePath($path);
-			if ($source) {
+			if ($source = $this->getSourcePath($path)) {
 				$storage = OC_Filesystem::getStorage($source);
 				return $storage->is_dir($this->getInternalPath($source));
 			}
 		}
 	}
-	
+
 	public function is_file($path) {
-		$source = $this->getSourcePath($path);
-		if ($source) {
+		if ($source = $this->getSourcePath($path)) {
 			$storage = OC_Filesystem::getStorage($source);
 			return $storage->is_file($this->getInternalPath($source));
 		}
 	}
-	
-	// TODO fill in other components of array
+
 	public function stat($path) {
-		if ($path == "" || $path == "/") {
-			$stat["size"] = $this->filesize($path);
-			$stat["mtime"] = $this->filemtime($path);
-			$stat["ctime"] = $this->filectime($path);
+		if ($path == '' || $path == '/') {
+			$stat['size'] = $this->filesize($path);
+			$stat['mtime'] = $this->filemtime($path);
+			$stat['ctime'] = $this->filectime($path);
 			return $stat;
 		} else {
-			$source = $this->getSourcePath($path);
-			if ($source) {
+			if ($source = $this->getSourcePath($path)) {
 				$storage = OC_Filesystem::getStorage($source);
 				return $storage->stat($this->getInternalPath($source));
 			}
 		}
 	}
-	
+
 	public function filetype($path) {
 		if ($path == "" || $path == "/") {
 			return "dir";
@@ -202,7 +134,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 		}
 
 	}
-	
+
 	public function filesize($path) {
 		if ($path == "" || $path == "/" || $this->is_dir($path)) {
 			return $this->getFolderSize($path);
@@ -215,55 +147,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 		}
 	}
 
-	public function getFolderSize($path) {
-		return 0; //depricated
-	}
-	
-	private function calculateFolderSize($path) {
-		if ($this->is_file($path)) {
-			$path = dirname($path);
-		}
-		$size = 0;
-		if ($dh = $this->opendir($path)) {
-			while (($filename = readdir($dh)) !== false) {
-				if ($filename != "." && $filename != "..") {
-					$subFile = $path."/".$filename;
-					if ($this->is_file($subFile)) {
-						$size += $this->filesize($subFile);
-					} else {
-						$size += $this->getFolderSize($subFile);
-					}
-				}
-			}
-			if ($size > 0) {
-				$dbpath = rtrim($this->datadir.$path, "/");
-// 				$query = OCP\DB::prepare("INSERT INTO *PREFIX*foldersize VALUES(?,?)");
-// 				$result = $query->execute(array($dbpath, $size));
-			}
-		}
-		return $size;
-	}
-
-	private function clearFolderSizeCache($path) {
-		$path = rtrim($path, "/");
-		$path = preg_replace('{(/)\1+}', "/", $path);
-		if ($this->is_file($path)) {
-			$path = dirname($path);
-		}
-		$dbpath = rtrim($this->datadir.$path, "/");
-// 		$query = OCP\DB::prepare("DELETE FROM *PREFIX*/*foldersize*/ WHERE path = ?");
-// 		$result = $query->execute(array($dbpath));
-		if ($path != "/" && $path != "") {
-			$parts = explode("/", $path);
-			$part = array_pop($parts);
-			if (empty($part)) {
-				array_pop($parts);
-			}
-			$parent = implode("/", $parts);
-			$this->clearFolderSizeCache($parent);
-		}
-	}
-
 	public function is_readable($path) {
 		return true;
 	}
@@ -271,7 +154,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 	public function is_writable($path) {
 		if($path == "" || $path == "/"){
 			return false;
-		}elseif (OC_Share::getPermissions($this->datadir.$path) & OC_Share::WRITE) {
+		}elseif (OC_Share::getPermissions($this->sharedFolder.$path) & OC_Share::WRITE) {
 			return true;
 		} else {
 			return false;
@@ -336,7 +219,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 		$source = $this->getSourcePath($path);
 		if ($source) {
 			$info = array(
-				'target' => $this->datadir.$path,
+				'target' => $this->sharedFolder.$path,
 				'source' => $source,
 			);
 			OCP\Util::emitHook('OC_Filestorage_Shared', 'file_get_contents', $info);
@@ -350,7 +233,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 			$source = $this->getSourcePath($path);
 			if ($source) {
 				$info = array(
-						'target' => $this->datadir.$path,
+						'target' => $this->sharedFolder.$path,
 						'source' => $source,
 					     );
 				OCP\Util::emitHook('OC_Filestorage_Shared', 'file_put_contents', $info);
@@ -366,7 +249,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 	
 	public function unlink($path) {
 		// The item will be removed from the database, but won't be touched on the owner's filesystem
-		$target = $this->datadir.$path;
+		$target = $this->sharedFolder.$path;
 		// Check if the item is inside a shared folder
 		if (OC_Share::getParentFolders($target)) {
 			// If entry for item already exists
@@ -385,8 +268,8 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 	}
 	
 	public function rename($path1, $path2) {
-		$oldTarget = $this->datadir.$path1;
-		$newTarget = $this->datadir.$path2;
+		$oldTarget = $this->sharedFolder.$path1;
+		$newTarget = $this->sharedFolder.$path2;
 		// Check if the item is inside a shared folder
 		if ($folders = OC_Share::getParentFolders($oldTarget)) {
 			$root1 = substr($path1, 0, strpos($path1, "/"));
@@ -442,7 +325,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 		$source = $this->getSourcePath($path);
 		if ($source) {
 			$info = array(
-				'target' => $this->datadir.$path,
+				'target' => $this->sharedFolder.$path,
 				'source' => $source,
 				'mode' => $mode,
 			);
@@ -541,7 +424,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 
 	public static function setup($options) {
 		$user_dir = $options['user_dir'];
-		OC_Filesystem::mount('OC_Filestorage_Shared', array('sharedFolder' => $user_dir.'/Shared'), $user_dir.'/Shared/');
+		OC_Filesystem::mount('OC_Filestorage_Shared', array('sharedFolder' => '/Shared'), $user_dir.'/Shared/');
 	}
 
 	/**
@@ -551,6 +434,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
 	 */
 	public function hasUpdated($path,$time){
 		//TODO
-		return $this->filemtime($path)>$time;
+		return false;
 	}
 }
diff --git a/core/js/share.js b/core/js/share.js
index 755e71e996eb00c8edd0aa5f61f350bb3954932c..3c7d2619eb262dd044a31f4e2c4113d5157076a2 100644
--- a/core/js/share.js
+++ b/core/js/share.js
@@ -84,10 +84,8 @@ OC.Share={
 		$(html).appendTo(appendTo);
 		var data = OC.Share.loadItem(itemType, item);
 		if (data) {
-			$.each(data, function(index, shares) {
-				$.each(shares, function(id, share) {
-					OC.Share.addShareWith(share.share_with, share.permissions);
-				});
+			$.each(data, function(index, share) {
+				OC.Share.addShareWith(share.share_with, share.permissions);
 			});
 		}
 		$('#dropdown').show('blind');
@@ -160,6 +158,7 @@ $(document).ready(function() {
 	});
 	
 	if (typeof FileActions !== 'undefined') {
+		
 		OC.Share.loadIcons('file');
 		FileActions.register('all', 'Share', function(filename) {
 			// Return the correct sharing icon
@@ -187,19 +186,24 @@ $(document).ready(function() {
 			}
 		}, function(filename) {
 			var item = $('#dir').val() + '/' + filename;
-			var appendTo = $('tr').filterAttr('data-file',filename).find('td.filename');
+			if ($('tr').filterAttr('data-file', filename).data('type') == 'dir') {
+				var itemType = 'folder';
+			} else {
+				var itemType = 'file';
+			}
+			var appendTo = $('tr').filterAttr('data-file', filename).find('td.filename');
 			// Check if drop down is already visible for a different file
 			if (($('#dropdown').length > 0)) {
 				if (item != $('#dropdown').data('item')) {
 					OC.Share.hideDropDown(function () {
 						$('tr').removeClass('mouseOver');
 						$('tr').filterAttr('data-file', filename).addClass('mouseOver');
-						OC.Share.showDropDown('file', item, appendTo, true);
+						OC.Share.showDropDown(itemType, item, appendTo, true);
 					});
 				}
 			} else {
 				$('tr').filterAttr('data-file',filename).addClass('mouseOver');
-				OC.Share.showDropDown('file', item, appendTo, true);
+				OC.Share.showDropDown(itemType, item, appendTo, true);
 			}
 		});
 	}
diff --git a/lib/filecache.php b/lib/filecache.php
index d956f34dc48790be0611be8729751c0102786922..b6f4d23986b8a75d655c78e06a270eb2f6eb8f85 100644
--- a/lib/filecache.php
+++ b/lib/filecache.php
@@ -324,6 +324,10 @@ class OC_FileCache{
 			$eventSource->send('scanning',array('file'=>$path,'count'=>$count));
 		}
 		$lastSend=$count;
+		// NOTE: Ugly hack to prevent shared files from going into the cache (the source already exists somewhere in the cache)
+		if (substr($path, 0, 7) == '/Shared') {
+			return;
+		}
 		if($root===false){
 			$view=OC_Filesystem::getView();
 		}else{
@@ -361,6 +365,10 @@ class OC_FileCache{
 	 * @return int size of the scanned file
 	 */
 	public static function scanFile($path,$root=false){
+		// NOTE: Ugly hack to prevent shared files from going into the cache (the source already exists somewhere in the cache)
+		if (substr($path, 0, 7) == '/Shared') {
+			return;
+		}
 		if($root===false){
 			$view=OC_Filesystem::getView();
 		}else{
diff --git a/lib/files.php b/lib/files.php
index 2feae20afe6e5dab2312cb3339eb499d036c9f23..4f58ff6782d28b7b4a3bbe45e594ed9e4255fb84 100644
--- a/lib/files.php
+++ b/lib/files.php
@@ -33,15 +33,30 @@ class OC_Files {
 	* @param dir $directory path under datadirectory
 	*/
 	public static function getDirectoryContent($directory, $mimetype_filter = ''){
-		$files=OC_FileCache::getFolderContent($directory, false, $mimetype_filter);
-		if ($directory == '') {
-			$files = array_merge($files, array());
-		} else if (substr($directory, 7) == '/Shared') {
-			$files = array_merge($files, OCP\Share::getItemsSharedWith('file', $directory, OC_Share_Backend_File::FORMAT_FILE_APP));
+		$files = array();
+		if (substr($directory, 0, 7) == '/Shared') {
+			if ($directory == '/Shared') {
+				$files = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP, array('mimetype_filter' => $mimetype_filter));
+			} else {
+				$pos = strpos($directory, '/', 8);
+				// Get shared folder name
+				if ($pos !== false) {
+					$itemTarget = substr($directory, 0, $pos);
+				} else {
+					$itemTarget = $directory;
+				}
+				$files = OCP\Share::getItemSharedWith('folder', $itemTarget, OC_Share_Backend_File::FORMAT_FILE_APP, array('folder' => $directory, 'mimetype_filter' => $mimetype_filter));
+			}
+		} else {
+			$files = OC_FileCache::getFolderContent($directory, false, $mimetype_filter);
+			if ($directory == '') {
+				// Add 'Shared' folder
+				$files = array_merge($files, OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT));
+			}
 		}
-		foreach($files as &$file){
-			$file['directory']=$directory;
-			$file['type']=($file['mimetype']=='httpd/unix-directory')?'dir':'file';
+		foreach ($files as &$file) {
+			$file['directory'] = $directory;
+			$file['type'] = ($file['mimetype'] == 'httpd/unix-directory') ? 'dir' : 'file';
 		}
 		usort($files, "fileCmp");//TODO: remove this once ajax is merged
 		return $files;
@@ -109,8 +124,7 @@ class OC_Files {
 				header('Content-Type: application/zip');
 				header('Content-Length: ' . filesize($filename));
 			}else{
-				$fileData=OC_FileCache::get($filename);
-				header('Content-Type: ' . $fileData['mimetype']);
+				header('Content-Type: '.OC_Filesystem::getMimeType($filename));
 			}
 		}elseif($zip or !OC_Filesystem::file_exists($filename)){
 			header("HTTP/1.0 404 Not Found");
diff --git a/lib/public/share.php b/lib/public/share.php
index 641d164001970aeb3c1960917119062adb422170..8c7f5a7ad84278135053d495324e1ee862b3ad1c 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -53,9 +53,9 @@ class Share {
 	* @param array (optional) List of supported file extensions if this item type depends on files
 	* @return Returns true if backend is registered or false if error
 	*/
-	public static function registerBackend($itemType, $class, $dependsOn = null, $supportedFileExtensions = null) {
+	public static function registerBackend($itemType, $class, $collectionOf = null, $supportedFileExtensions = null) {
 		if (!isset(self::$backendTypes[$itemType])) {
-			self::$backendTypes[$itemType] = array('class' => $class, 'dependsOn' => $dependsOn, 'supportedFileExtensions' => $supportedFileExtensions);
+			self::$backendTypes[$itemType] = array('class' => $class, 'collectionOf' => $collectionOf, 'supportedFileExtensions' => $supportedFileExtensions);
 			return true;
 		}
 		\OC_Log::write('OCP\Share', 'Sharing backend '.$class.' not registered, '.self::$backendTypes[$itemType]['class'].' is already registered for '.$itemType, \OC_Log::WARN);
@@ -69,8 +69,8 @@ class Share {
 	* @param int Number of items to return (optional) Returns all by default
 	* @return Return depends on format
 	*/
-	public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE, $limit = -1) {
-		return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $limit);
+	public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE, $parameters = null, $limit = -1) {
+		return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $parameters, $limit);
 	}
 
 	/**
@@ -80,8 +80,8 @@ class Share {
 	* @param int Format (optional) Format type must be defined by the backend
 	* @return Return depends on format
 	*/
-	public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE) {
-		return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, 1);
+	public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE, $parameters = null) {
+		return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $parameters, 1);
 	}
 
 	/**
@@ -91,8 +91,8 @@ class Share {
 	* @param int Format (optional) Format type must be defined by the backend
 	* @return Return depends on format
 	*/
-	public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE) {
-		return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, 1, true);
+	public static function getItemSharedWithBySource($itemType, $itemSource, $format = self::FORMAT_NONE, $parameters = null) {
+		return self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $parameters, 1, true);
 	}
 
 	/**
@@ -102,8 +102,8 @@ class Share {
 	* @param int Number of items to return (optional) Returns all by default
 	* @return Return depends on format
 	*/
-	public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $limit = -1) {
-		return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format, $limit);
+	public static function getItemsShared($itemType, $format = self::FORMAT_NONE, $parameters = null, $limit = -1) {
+		return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format, $parameters, $limit);
 	}
 
 	/**
@@ -113,8 +113,8 @@ class Share {
 	* @param int Format (optional) Format type must be defined by the backend
 	* @return Return depends on format
 	*/
-	public static function getItemShared($itemType, $item, $format = self::FORMAT_NONE) {
-		return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format);
+	public static function getItemShared($itemType, $item, $format = self::FORMAT_NONE, $parameters = null) {
+		return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format, $parameters);
 	}
 
 	/**
@@ -124,8 +124,8 @@ class Share {
 	* @param int Format (optional) Format type must be defined by the backend
 	* @return Return depends on format
 	*/
-	public static function getItemSharedBySource($itemType, $item, $format = self::FORMAT_NONE) {
-		return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format, -1, true);
+	public static function getItemSharedBySource($itemType, $item, $format = self::FORMAT_NONE, $parameters = null) {
+		return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format, $parameters, -1, true);
 	}
 
 	/**
@@ -195,7 +195,7 @@ class Share {
 			if ($parentFolder && $files = \OC_Files::getDirectoryContent($item)) {
 				for ($i = 0; $i < count($files); $i++) {
 					$name = substr($files[$i]['name'], strpos($files[$i]['name'], $item) - strlen($item));
-					if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = OC_Files::getDirectoryContent($name, '/')) {
+					if ($files[$i]['mimetype'] == 'httpd/unix-directory' && $children = \OC_Files::getDirectoryContent($name, '/')) {
 						// Continue scanning into child folders
 						array_push($files, $children);
 					} else {
@@ -370,19 +370,19 @@ class Share {
 	}
 
 	/**
-	* @brief Get a list of parent item types for the specified item type
+	* @brief Get a list of collection item types for the specified item type
 	* @param string Item type
 	* @return array
 	*/
-	private static function getParentItemTypes($itemType) {
-		$parents = array($itemType);
-		foreach (self::$backends as $type => $backend) {
-			if (in_array($backend->dependsOn, $parents)) {
-				$parents[] = $type;
+	private static function getCollectionItemTypes($itemType) {
+		$collections = array($itemType);
+		foreach (self::$backendTypes as $type => $backend) {
+			if (in_array($backend['collectionOf'], $collections)) {
+				$collections[] = $type;
 			}
 		}
-		if (!empty($parents)) {
-			return $parents;
+		if (count($collections) > 1) {
+			return $collections;
 		}
 		return false;
 	}
@@ -400,19 +400,13 @@ class Share {
 	* See public functions getItem(s)... for parameter usage
 	*
 	*/
-	private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $limit = -1, $isSource = false) {
+	private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $isSource = false) {
 		if ($backend = self::getBackend($itemType)) {
 			// Check if there are any parent types that include this type of items, e.g. a music album contains songs
-			if (isset($itemType)) {
-				if ($parents = self::getParentItemTypes($itemType)) {
-					$where = "WHERE item_type IN ('".implode("','", $parents)."')";
-				} else {
-					$where = "WHERE item_type = '".$itemType."'";
-				}
-				// TODO exclude items that are inside of folders and got converted i.e. songs, pictures
-				if ($itemType == 'files') {
-
-				}
+			if ($parents = self::getCollectionItemTypes($itemType)) {
+				$where = "WHERE item_type IN ('".implode("','", $parents)."')";
+			} else {
+				$where = "WHERE item_type = '".$itemType."'";
 			}
 			if (isset($shareType) && isset($shareWith)) {
 				// Include all user and group items
@@ -450,20 +444,21 @@ class Share {
 					}
 				} else {
 					if ($isSource) {
-						if ($itemType == 'file') {
+						if ($itemType == 'file' || $itemType == 'folder') {
 							$where .= " AND file_source = '".$item."'";
 						} else {
 							$where .= " AND item_source = '".$item."'";
 						}
 					} else {
-						if ($itemType == 'file' && substr($item, -1) == '/') {
-							// Special case to select only the shared files inside the folder
-							$where .= " AND file_target LIKE '".$item."%/'";
+						if ($itemType == 'file' || $itemType == 'folder') {
+							$where .= " AND file_target = '".$item."'";
 						} else {
 							$where .= " AND item_target = '".$item."'";
 						}
 					}
 				}
+			} else if ($itemType == 'file') {
+				// TODO Exclude converted items inside shared folders
 			}
 			if ($limit != -1) {
 				if ($limit == 1 && $shareType == self::$shareTypeUserAndGroups) {
@@ -486,16 +481,12 @@ class Share {
 			$result = $query->execute();
 			$items = array();
 			while ($item = $result->fetchRow()) {
-				if ($limit == 1) {
-					// Return just the item instead of 3-dimensional array
-					return $item;
-				}
 				// Filter out duplicate group shares for users with unique targets
 				if ($item['share_type'] == self::$shareTypeGroupUserUnique) {
 					// Remove the parent group share
-					unset($items[$item['item_source']][$item['parent']]);
+					unset($items[$item['parent']]);
 				}
-				$items[$item['item_source']][$item['id']] = $item;
+				$items[$item['id']] = $item;
 				// TODO Add in parent item types children?
 				if ($parents && in_array($item['item_type'], $parents)) {
 					$children[] = $item;
@@ -506,20 +497,17 @@ class Share {
 					return $items;
 				} else if ($format == self::FORMAT_STATUSES) {
 					$statuses = array();
-					foreach ($items as $shares) {
-						foreach ($shares as $info) {
-							if ($info['share_type'] == self::SHARE_TYPE_PRIVATE_LINK) {
-								$statuses[$info['item']] = true;
-								break;
-							} else if (!isset($statuses[$info['item']])) {
-								$statuses[$info['item']] = false;
-							}
+					foreach ($items as $item) {
+						if ($item['share_type'] == self::SHARE_TYPE_PRIVATE_LINK) {
+							$statuses[$item['item']] = true;
+							break;
+						} else if (!isset($statuses[$item['item']])) {
+							$statuses[$item['item']] = false;
 						}
-						
 					}
 					return $statuses;
 				} else {
-					return $backend->formatItems($items, $format);
+					return $backend->formatItems($items, $format, $parameters);
 				}
 			} else if ($limit == 1 || (isset($uidOwner) && isset($item))) {
 				return false;
@@ -764,12 +752,14 @@ abstract class Share_Backend {
 	* This function allows the backend to control the output of shared items with custom formats.
 	* It is only called through calls to the public getItem(s)Shared(With) functions.
 	*/
-	public abstract function formatItems($items, $format);
+	public abstract function formatItems($items, $format, $parameters = null);
 
 
 }
 
-abstract class Share_Backend_Parent extends Share_Backend {
+abstract class Share_Backend_Collection extends Share_Backend {
+
+	public abstract function inCollection($collections, $item);
 
 	public abstract function getChildren($item);