diff --git a/3rdparty/css/chosen/chosen-sprite.png b/3rdparty/css/chosen/chosen-sprite.png
new file mode 100644
index 0000000000000000000000000000000000000000..f20db4439ea5c1038126bf326c8fd048b03a8226
Binary files /dev/null and b/3rdparty/css/chosen/chosen-sprite.png differ
diff --git a/3rdparty/css/chosen/chosen.css b/3rdparty/css/chosen/chosen.css
new file mode 100644
index 0000000000000000000000000000000000000000..247d07bf0217901f93d6a1c83d214db4cef6831f
--- /dev/null
+++ b/3rdparty/css/chosen/chosen.css
@@ -0,0 +1,340 @@
+/* @group Base */
+select.chzn-select {
+  visibility: hidden;
+  height: 28px !important;
+  min-height: 28px !important;
+}
+.chzn-container {
+  font-size: 13px;
+  position: relative;
+  display: inline-block;
+  zoom: 1;
+  *display: inline;
+}
+.chzn-container .chzn-drop {
+  background: #fff;
+  border: 1px solid #aaa;
+  border-top: 0;
+  position: absolute;
+  top: 29px;
+  left: 0;
+  -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15);
+  -moz-box-shadow   : 0 4px 5px rgba(0,0,0,.15);
+  -o-box-shadow     : 0 4px 5px rgba(0,0,0,.15);
+  box-shadow        : 0 4px 5px rgba(0,0,0,.15);
+  z-index: 999;
+}
+/* @end */
+
+/* @group Single Chosen */
+.chzn-container-single .chzn-single {
+  background-color: #fff;
+  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
+  background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
+  background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);
+  background-image: -o-linear-gradient(top, #eeeeee 0%,#ffffff 50%);
+  background-image: -ms-linear-gradient(top, #eeeeee 0%,#ffffff 50%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );
+  background-image: linear-gradient(top, #eeeeee 0%,#ffffff 50%);
+  -webkit-border-radius: 4px;
+  -moz-border-radius   : 4px;
+  border-radius        : 4px;
+  -moz-background-clip   : padding;
+  -webkit-background-clip: padding-box;
+  background-clip        : padding-box;
+  border: 1px solid #aaa;
+  display: block;
+  overflow: hidden;
+  white-space: nowrap;
+  position: relative;
+  height: 26px;
+  line-height: 26px;
+  padding: 0 0 0 8px;
+  color: #444;
+  text-decoration: none;
+}
+.chzn-container-single .chzn-single span {
+  margin-right: 26px;
+  display: block;
+  overflow: hidden;
+  white-space: nowrap;
+  -o-text-overflow: ellipsis;
+  -ms-text-overflow: ellipsis;
+  -moz-binding: url('/xml/ellipsis.xml#ellipsis');
+  text-overflow: ellipsis;
+}
+.chzn-container-single .chzn-single div {
+  -webkit-border-radius: 0 4px 4px 0;
+  -moz-border-radius   : 0 4px 4px 0;
+  border-radius        : 0 4px 4px 0;
+  -moz-background-clip   : padding;
+  -webkit-background-clip: padding-box;
+  background-clip        : padding-box;
+  background: #ccc;
+  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
+  background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+  background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+  background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);
+  background-image: -ms-linear-gradient(top, #cccccc 0%,#eeeeee 60%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 );
+  background-image: linear-gradient(top, #cccccc 0%,#eeeeee 60%);
+  border-left: 1px solid #aaa;
+  position: absolute;
+  right: 0;
+  top: 0;
+  display: block;
+  height: 100%;
+  width: 18px;
+}
+.chzn-container-single .chzn-single div b {
+  background: url('chosen-sprite.png') no-repeat 0 1px;
+  display: block;
+  width: 100%;
+  height: 100%;
+}
+.chzn-container-single .chzn-search {
+  padding: 3px 4px;
+  margin: 0;
+  white-space: nowrap;
+}
+.chzn-container-single .chzn-search input {
+  background: #fff url('chosen-sprite.png') no-repeat 100% -20px;
+  background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
+  background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%);
+  margin: 1px 0;
+  padding: 4px 20px 4px 5px;
+  outline: 0;
+  border: 1px solid #aaa;
+  font-family: sans-serif;
+  font-size: 1em;
+}
+.chzn-container-single .chzn-drop {
+  -webkit-border-radius: 0 0 4px 4px;
+  -moz-border-radius   : 0 0 4px 4px;
+  border-radius        : 0 0 4px 4px;
+  -moz-background-clip   : padding;
+  -webkit-background-clip: padding-box;
+  background-clip        : padding-box;
+}
+/* @end */
+
+/* @group Multi Chosen */
+.chzn-container-multi .chzn-choices {
+  background-color: #fff;
+  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
+  background-image: -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+  background-image: -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+  background-image: -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
+  background-image: -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 );
+  background-image: linear-gradient(top, #ffffff 85%,#eeeeee 99%);
+  border: 1px solid #aaa;
+  margin: 0;
+  padding: 0;
+  cursor: text;
+  overflow: hidden;
+  height: auto !important;
+  height: 1%;
+  position: relative;
+}
+.chzn-container-multi .chzn-choices li {
+  float: left;
+  list-style: none;
+}
+.chzn-container-multi .chzn-choices .search-field {
+  white-space: nowrap;
+  margin: 0;
+  padding: 0;
+}
+.chzn-container-multi .chzn-choices .search-field input {
+  color: #666;
+  background: transparent !important;
+  border: 0 !important;
+  padding: 5px;
+  margin: 1px 0;
+  outline: 0;
+  -webkit-box-shadow: none;
+  -moz-box-shadow   : none;
+  -o-box-shadow     : none;
+  box-shadow        : none;
+}
+.chzn-container-multi .chzn-choices .search-field .default {
+  color: #999;
+}
+.chzn-container-multi .chzn-choices .search-choice {
+  -webkit-border-radius: 3px;
+  -moz-border-radius   : 3px;
+  border-radius        : 3px;
+  -moz-background-clip   : padding;
+  -webkit-background-clip: padding-box;
+  background-clip        : padding-box;
+  background-color: #e4e4e4;
+  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #e4e4e4), color-stop(0.7, #eeeeee));
+  background-image: -webkit-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%);
+  background-image: -moz-linear-gradient(center bottom, #e4e4e4 0%, #eeeeee 70%);
+  background-image: -o-linear-gradient(bottom, #e4e4e4 0%, #eeeeee 70%);
+  background-image: -ms-linear-gradient(top, #e4e4e4 0%,#eeeeee 70%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e4e4e4', endColorstr='#eeeeee',GradientType=0 );
+  background-image: linear-gradient(top, #e4e4e4 0%,#eeeeee 70%);
+  color: #333;
+  border: 1px solid #b4b4b4;
+  line-height: 13px;
+  padding: 3px 19px 3px 6px;
+  margin: 3px 0 3px 5px;
+  position: relative;
+}
+.chzn-container-multi .chzn-choices .search-choice span {
+  cursor: default;
+}
+.chzn-container-multi .chzn-choices .search-choice-focus {
+  background: #d4d4d4;
+}
+.chzn-container-multi .chzn-choices .search-choice .search-choice-close {
+  display: block;
+  position: absolute;
+  right: 5px;
+  top: 6px;
+  width: 8px;
+  height: 9px;
+  font-size: 1px;
+  background: url(chosen-sprite.png) right top no-repeat;
+}
+.chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover {
+  background-position: right -9px;
+}
+.chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close {
+  background-position: right -9px;
+}
+/* @end */
+
+/* @group Results */
+.chzn-container .chzn-results {
+  margin: 0 4px 4px 0;
+  max-height: 190px;
+  padding: 0 0 0 4px;
+  position: relative;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.chzn-container-multi .chzn-results {
+  margin: -1px 0 0;
+  padding: 0;
+}
+.chzn-container .chzn-results li {
+  line-height: 80%;
+  padding: 7px 7px 8px;
+  margin: 0;
+  list-style: none;
+}
+.chzn-container .chzn-results .active-result {
+  cursor: pointer;
+}
+.chzn-container .chzn-results .highlighted {
+  background: #3875d7;
+  color: #fff;
+}
+.chzn-container .chzn-results li em {
+  background: #feffde;
+  font-style: normal;
+}
+.chzn-container .chzn-results .highlighted em {
+  background: transparent;
+}
+.chzn-container .chzn-results .no-results {
+  background: #f4f4f4;
+}
+.chzn-container .chzn-results .group-result {
+  cursor: default;
+  color: #999;
+  font-weight: bold;
+}
+.chzn-container .chzn-results .group-option {
+  padding-left: 20px;
+}
+.chzn-container-multi .chzn-drop .result-selected {
+  display: none;
+}
+/* @end */
+
+/* @group Active  */
+.chzn-container-active .chzn-single {
+  -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
+  -moz-box-shadow   : 0 0 5px rgba(0,0,0,.3);
+  -o-box-shadow     : 0 0 5px rgba(0,0,0,.3);
+  box-shadow        : 0 0 5px rgba(0,0,0,.3);
+  border: 1px solid #5897fb;
+}
+.chzn-container-active .chzn-single-with-drop {
+  border: 1px solid #aaa;
+  -webkit-box-shadow: 0 1px 0 #fff inset;
+  -moz-box-shadow   : 0 1px 0 #fff inset;
+  -o-box-shadow     : 0 1px 0 #fff inset;
+  box-shadow        : 0 1px 0 #fff inset;
+  background-color: #eee;
+  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));
+  background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);
+  background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);
+  background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%);
+  background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%);
+  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee',GradientType=0 );
+  background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%);
+  -webkit-border-bottom-left-radius : 0;
+  -webkit-border-bottom-right-radius: 0;
+  -moz-border-radius-bottomleft : 0;
+  -moz-border-radius-bottomright: 0;
+  border-bottom-left-radius : 0;
+  border-bottom-right-radius: 0;
+}
+.chzn-container-active .chzn-single-with-drop div {
+  background: transparent;
+  border-left: none;
+}
+.chzn-container-active .chzn-single-with-drop div b {
+  background-position: -18px 1px;
+}
+.chzn-container-active .chzn-choices {
+  -webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
+  -moz-box-shadow   : 0 0 5px rgba(0,0,0,.3);
+  -o-box-shadow     : 0 0 5px rgba(0,0,0,.3);
+  box-shadow        : 0 0 5px rgba(0,0,0,.3);
+  border: 1px solid #5897fb;
+}
+.chzn-container-active .chzn-choices .search-field input {
+  color: #111 !important;
+}
+/* @end */
+
+/* @group Right to Left */
+.chzn-rtl { direction:rtl;text-align: right; }
+.chzn-rtl .chzn-single { padding-left: 0; padding-right: 8px; }
+.chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; }
+.chzn-rtl .chzn-single div { 
+  left: 0; right: auto; 
+  border-left: none; border-right: 1px solid #aaaaaa;
+  -webkit-border-radius: 4px 0 0 4px;
+  -moz-border-radius   : 4px 0 0 4px;
+  border-radius        : 4px 0 0 4px; 
+}
+.chzn-rtl .chzn-choices li { float: right; }
+.chzn-rtl .chzn-choices .search-choice { padding: 3px 6px 3px 19px; margin: 3px 5px 3px 0; }
+.chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 5px; right: auto; background-position: right top;}
+.chzn-rtl.chzn-container-single .chzn-results { margin-left: 4px; margin-right: 0; padding-left: 0; padding-right: 4px; }
+.chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 20px; }
+.chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; }
+.chzn-rtl .chzn-search input {
+  background: url('chosen-sprite.png') no-repeat -38px -20px, #ffffff;
+  background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
+  background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);  
+  background: url('chosen-sprite.png') no-repeat -38px -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat -38px -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%);
+  background: url('chosen-sprite.png') no-repeat -38px -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%);
+  padding: 4px 5px 4px 20px;
+}
+/* @end */
\ No newline at end of file
diff --git a/apps/files_publiclink/ajax/getlink.php b/apps/files_publiclink/ajax/getlink.php
new file mode 100644
index 0000000000000000000000000000000000000000..551bcc8780cd9d1cf14b8b2b8fb9e0766389b61a
--- /dev/null
+++ b/apps/files_publiclink/ajax/getlink.php
@@ -0,0 +1,8 @@
+<?php
+$RUNTIME_NOAPPS = true;
+
+require_once('../../../lib/base.php');
+require_once('../lib_public.php');
+
+$path = $_GET['path'];
+echo json_encode(OC_PublicLink::getLink($path));
\ No newline at end of file
diff --git a/apps/files_publiclink/appinfo/app.php b/apps/files_publiclink/appinfo/app.php
index e2d8d27c0072b744f814c3bbd58b334bdc71af62..5866e2d1c5e9baa6772826129f56008e55a1cf6f 100644
--- a/apps/files_publiclink/appinfo/app.php
+++ b/apps/files_publiclink/appinfo/app.php
@@ -1,6 +1,6 @@
 <?php
 
-OC_App::addNavigationEntry(array( "id" => "files_publiclink_administration", "order" => 2, "href" => OC_Helper::linkTo( "files_publiclink", "admin.php" ), "name" => "Public Links"));
+// OC_App::addNavigationEntry(array( "id" => "files_publiclink_administration", "order" => 2, "href" => OC_Helper::linkTo( "files_publiclink", "admin.php" ), "name" => "Public Links"));
 
 
 ?>
diff --git a/apps/files_publiclink/lib_public.php b/apps/files_publiclink/lib_public.php
index 22f06156e179263565e48d210219d76b192af249..ece0a540d398403db612d6571827f4a4337dd5d0 100644
--- a/apps/files_publiclink/lib_public.php
+++ b/apps/files_publiclink/lib_public.php
@@ -49,7 +49,15 @@ class OC_PublicLink{
 	public function getToken(){
 		return $this->token;
 	}
-	
+
+	public static function getLink($path) {
+		$query=OC_DB::prepare("SELECT token FROM *PREFIX*publiclink WHERE user=? AND path=? LIMIT 1");
+		$result=$query->execute(array(OC_User::getUser(),$path))->fetchAll();
+		if(count($result)>0){
+			return $result[0]['token'];
+		}
+	}
+
 	/**
 	 * gets all public links
 	 * @return array
diff --git a/apps/files_sharing/ajax/getitem.php b/apps/files_sharing/ajax/getitem.php
new file mode 100644
index 0000000000000000000000000000000000000000..43105d334eede059879a81c544c20b1b01befd43
--- /dev/null
+++ b/apps/files_sharing/ajax/getitem.php
@@ -0,0 +1,24 @@
+<?php
+$RUNTIME_NOAPPS = true;
+
+require_once('../../../lib/base.php');
+require_once('../lib_share.php');
+
+$userDirectory = "/".OC_User::getUser()."/files";
+$source = $userDirectory.$_GET['source'];
+$users = OC_Share::getMySharedItem($source);
+$source = dirname($source);
+while ($source != "" && $source != "/" && $source != "." && $source != $userDirectory) {
+	$values = array_values(OC_Share::getMySharedItem($source));
+	if (count($values) > 0) {
+		$parentUsers = array();
+		for ($i = 0; $i < count($values); $i++) {
+			$parentUsers[basename($source)."-".$i] = $values[$i];
+		}
+		$users = array_merge($users, $parentUsers);
+	}
+	$source = dirname($source);
+}
+echo json_encode($users);
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/ajax/setpermissions.php b/apps/files_sharing/ajax/setpermissions.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e0bac0b06f6dca8d2bd73cdfe26743ece80e826
--- /dev/null
+++ b/apps/files_sharing/ajax/setpermissions.php
@@ -0,0 +1,12 @@
+<?php
+$RUNTIME_NOAPPS = true;
+
+require_once('../../../lib/base.php');
+require_once('../lib_share.php');
+
+$source = "/".OC_User::getUser()."/files".$_GET['source'];
+$uid_shared_with = $_GET['uid_shared_with'];
+$permissions = $_GET['permissions'];
+OC_Share::setPermissions($source, $uid_shared_with, $permissions);
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/ajax/share.php b/apps/files_sharing/ajax/share.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9bf4ff7abebcf34efe93605f9ab77cce0927d21
--- /dev/null
+++ b/apps/files_sharing/ajax/share.php
@@ -0,0 +1,24 @@
+<?php
+$RUNTIME_NOAPPS = true;
+
+require_once('../../../lib/base.php');
+require_once('../lib_share.php');
+
+$sources = explode(";", $_POST['sources']);
+$uid_shared_with = $_POST['uid_shared_with'];
+$permissions = $_POST['permissions'];
+foreach ($sources as $source) {
+	if ($source && OC_FILESYSTEM::file_exists($source) && OC_FILESYSTEM::is_readable($source)) {
+		$source = "/".OC_User::getUser()."/files".$source;
+		try {
+			$shared = new OC_Share($source, $uid_shared_with, $permissions);
+			if ($uid_shared_with == OC_Share::PUBLICLINK) {
+				echo $shared->getToken();
+			}
+		} catch (Exception $exception) {
+			echo "false";
+		}
+	}
+}
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/ajax/unshare.php b/apps/files_sharing/ajax/unshare.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9230d257b767d9c32f01cb8446f9b34fedc082b
--- /dev/null
+++ b/apps/files_sharing/ajax/unshare.php
@@ -0,0 +1,11 @@
+<?php
+$RUNTIME_NOAPPS = true;
+
+require_once('../../../lib/base.php');
+require_once('../lib_share.php');
+
+$source = "/".OC_User::getUser()."/files".$_GET['source'];
+$uid_shared_with = $_GET['uid_shared_with'];
+OC_Share::unshare($source, $uid_shared_with);
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/ajax/userautocomplete.php b/apps/files_sharing/ajax/userautocomplete.php
new file mode 100644
index 0000000000000000000000000000000000000000..6da7afb659c957591e47e8a7e1d3006f8d51e623
--- /dev/null
+++ b/apps/files_sharing/ajax/userautocomplete.php
@@ -0,0 +1,28 @@
+<?php
+$RUNTIME_NOAPPS = true;
+
+require_once('../../../lib/base.php');
+
+if (!OC_User::isLoggedIn()) {
+	echo json_encode(array("status" => "error", "data" => array("message" => "Authentication error")));
+	exit();
+}
+$users = array();
+$ocusers = OC_User::getUsers();
+$self = OC_User::getUser();
+$groups = OC_Group::getUserGroups($self);
+$users[] = "<optgroup label='Users'>";
+foreach ($ocusers as $user) {
+	if ($user != $self) {
+		$users[] = "<option value='".$user."'>".$user."</option>";
+	}
+}
+$users[] = "</optgroup>";
+$users[] = "<optgroup label='Groups'>";
+foreach ($groups as $group) {
+	$users[] = "<option value='".$group."'>".$group."</option>";
+}
+$users[] = "</optgroup>";
+echo json_encode($users);
+
+?>
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ff82563b803f4ac5f1c6ea4f7330a1cbadd838b
--- /dev/null
+++ b/apps/files_sharing/appinfo/app.php
@@ -0,0 +1,17 @@
+<?php
+
+require_once('apps/files_sharing/lib_share.php');
+require_once('apps/files_sharing/sharedstorage.php');
+
+OC_Filesystem::registerStorageType("shared", "OC_Filestorage_Shared", array("datadir"=>"string"));
+OC_Util::addScript("files_sharing", "share");
+OC_Util::addScript("3rdparty", "chosen/chosen.jquery.min");
+OC_Util::addStyle( 'files_sharing', 'sharing' );
+OC_Util::addStyle("3rdparty", "chosen/chosen");
+OC_App::addNavigationEntry(array(
+  "id" => "files_sharing_list",
+  "order" => 2, 
+  "href" => OC_Helper::linkTo( "files_sharing", "list.php" ),
+  "name" => "Shared"));
+
+?>
diff --git a/apps/files_sharing/appinfo/database.xml b/apps/files_sharing/appinfo/database.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3378b6b09e53c0756ae1da961cd4db00dabff086
--- /dev/null
+++ b/apps/files_sharing/appinfo/database.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<database>
+	 <name>*dbname*</name>
+	 <create>true</create>
+	 <overwrite>false</overwrite>
+	 <charset>latin1</charset>
+	 <table>
+		<name>*dbprefix*sharing</name>
+		<declaration>
+			<field>
+				<name>uid_owner</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+			</field>
+			<field>
+				<name>uid_shared_with</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>64</length>
+			</field>
+			<field>
+				<name>source</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>128</length>
+			</field>
+			<field>
+				<name>target</name>
+				<type>text</type>
+				<notnull>true</notnull>
+				<length>128</length>
+			</field>
+			<field>
+				<name>permissions</name>
+				<type>integer</type>
+				<notnull>true</notnull>
+				<length>1</length>
+			 </field>
+		</declaration>
+	</table>
+</database>
diff --git a/apps/files_sharing/appinfo/info.xml b/apps/files_sharing/appinfo/info.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2fbb3300f69f7b08671235b3efdc1dd94e0bd7ff
--- /dev/null
+++ b/apps/files_sharing/appinfo/info.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<info>
+	<id>files_sharing</id>
+	<name>Share Files</name>
+	<description>File sharing between users</description>
+	<version>0.1</version>
+	<licence>AGPL</licence>
+	<author>Michael Gapczynski</author>
+	<require>2</require>
+</info>
\ No newline at end of file
diff --git a/apps/files_sharing/css/sharing.css b/apps/files_sharing/css/sharing.css
new file mode 100644
index 0000000000000000000000000000000000000000..0759af2c274425098ff35503bff4a914257d0bca
--- /dev/null
+++ b/apps/files_sharing/css/sharing.css
@@ -0,0 +1,8 @@
+#dropdown { display:block;  position:absolute; z-index:100; width:16em; right:0; margin-right:7em; background:#eee; padding:1em;
+-moz-box-shadow:0 1px 1px #777; -webkit-box-shadow:0 1px 1px #777; box-shadow:0 1px 1px #777;
+-moz-border-radius-bottomleft:1em; -webkit-border-bottom-left-radius:1em; border-bottom-left-radius:1em;
+-moz-border-radius-bottomright:1em; -webkit-border-bottom-right-radius:1em; border-bottom-right-radius:1em; }
+#shared_list { padding:0.5em; list-style-type: none; }
+#public { border-top:1px solid #ddd; padding-top:0.5em; }
+a.unshare { float:right; display:inline; margin:0 .5em; padding:.3em .3em 0 .3em !important; opacity:.5; }
+a.unshare:hover { opacity:1; }
\ No newline at end of file
diff --git a/apps/files_sharing/js/list.js b/apps/files_sharing/js/list.js
new file mode 100644
index 0000000000000000000000000000000000000000..41eabd1f4af7fe56caa71ef034f9f3cdd67179eb
--- /dev/null
+++ b/apps/files_sharing/js/list.js
@@ -0,0 +1,54 @@
+$(document).ready(function() {
+	$( "#source" ).autocomplete({
+		source: "../../files/ajax/autocomplete.php",
+		minLength: 1
+	});
+	$( "#uid_shared_with" ).autocomplete({
+		source: "ajax/userautocomplete.php",
+		minLength: 1
+	});
+	$("button.delete").live('click', function( event ) {
+		event.preventDefault();
+// 		var row=$(this);
+		var source=$(this).attr('data-source');
+		var uid_shared_with=$(this).attr('data-uid_shared_with');
+		var data='source='+encodeURIComponent(source)+'&uid_shared_with='+encodeURIComponent(uid_shared_with);
+		$.ajax({
+			type: 'GET',
+			url: 'ajax/unshare.php',
+			cache: false,
+			data: data
+// 			success: function(){
+// 				row.remove();
+// 			}
+		});
+	});
+	$('#share_item').submit(function( event ){
+		event.preventDefault();
+		var source=$('#source').val();
+		var uid_shared_with=$('#uid_shared_with').val();
+		var permissions=$('#permissions').val()||0;
+		var data='source='+source+'&uid_shared_with='+uid_shared_with+'&permissions='+permissions;
+		$.ajax({
+			type: 'GET',
+			url: 'ajax/share.php',
+			cache: false,
+			data: data,
+// 			success: function(token){
+// 				if(token){
+// 					var html="<tr class='link' id='"+token+"'>";
+// 					html+="<td class='path'>"+path+"</td>";
+// 					var expire=($('#expire').val())?$('#expire').val():'Never'
+// 					html+="<td class='expire'>"+expire+"</td>"
+// 					html+="<td class='link'><a href='get.php?token="+token+"'>"+$('#baseUrl').val()+"?token="+token+"</a></td>"
+// 					html+="<td><button class='delete fancybutton' data-token='"+token+"'>Delete</button></td>"
+// 					html+="</tr>"
+// 					$(html).insertBefore($('#newlink_row'));
+// 					$('#expire').val('');
+// 					$('#expire_time').val('');
+// 					$('#path').val('');
+// 				}
+// 			}
+		});
+	});
+});
\ No newline at end of file
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
new file mode 100644
index 0000000000000000000000000000000000000000..f9500ffd000249954740d98142a0f3a8cef6873b
--- /dev/null
+++ b/apps/files_sharing/js/share.js
@@ -0,0 +1,242 @@
+$(document).ready(function() {
+	if (typeof FileActions !== 'undefined') {
+		FileActions.register('all', 'Share', function(filename) {
+			var icon;
+			var file = $('#dir').val()+'/'+filename;
+			$.ajax({
+				type: 'GET',
+				url: OC.linkTo('files_sharing', 'ajax/getitem.php'),
+				dataType: 'json',
+				data: 'source='+file,
+				async: false,
+				success: function(users) {
+					if (users.length > 0) {
+						icon = OC.imagePath('core', 'actions/shared');
+					} else {
+						icon = OC.imagePath('core', 'actions/share');
+					}
+				}
+			});
+			$.ajax({
+				type: 'GET',
+				url: OC.linkTo('files_publiclink', 'ajax/getlink.php'),
+				dataType: 'json',
+				data: 'path='+file,
+				async: false,
+				success: function(link) {
+					if (link.length > 0) {
+						icon = OC.imagePath('core', 'actions/public');
+					} else {
+						icon = OC.imagePath('core', 'actions/share');
+					}
+				}
+			});
+			return icon;
+		}, function(filename) {
+			if (($('#dropdown').length > 0)) {
+				$('#dropdown').hide('blind', function() {
+					var dropdownFile = $('#dropdown').data('file') 
+					var file = $('#dir').val()+'/'+filename;
+					$('#dropdown').remove();
+					$('tr').removeClass('mouseOver');
+					if (dropdownFile != file) {
+						createDropdown(filename, file);
+					}
+				});
+			} else {
+				createDropdown(filename, $('#dir').val()+'/'+filename);
+			}
+		});
+	};
+
+	$('.share').click(function(event) {
+		event.preventDefault();
+		var filenames = getSelectedFiles('name');
+		var length = filenames.length;
+		var files = '';
+		for (var i = 0; i < length; i++) {
+			files += $('#dir').val()+'/'+filenames[i]+';';
+		}
+		createDropdown(false, files);
+	});
+	
+	$(this).click(function(event) {
+		if (!($(event.target).hasClass('drop')) && $(event.target).parents().index($('#dropdown')) == -1) {
+			if ($('#dropdown').is(':visible')) {
+				$('#dropdown').hide('blind', function() {
+					$('#dropdown').remove();
+					$('tr').removeClass('mouseOver');
+				});
+			}
+		}
+	});
+	
+	$('#share_with').live('change', function() {
+		var source = $('#dropdown').data('file');
+		var uid_shared_with = $(this).val();
+		var permissions = 0;
+		var data = 'sources='+encodeURIComponent(source)+'&uid_shared_with='+encodeURIComponent(uid_shared_with)+'&permissions='+encodeURIComponent(permissions);
+		$.ajax({
+			type: 'POST',
+			url: OC.linkTo('files_sharing','ajax/share.php'),
+			cache: false,
+			data: data,
+			success: function(result) {
+				if (result !== 'false') {
+					addUser(uid_shared_with, permissions, false);
+				}
+			}
+		});
+	});
+	
+	$('#shared_list > li').live('mouseenter', function(event) {
+		$(':hidden', this).show();
+	});
+	
+	$('#shared_list > li').live('mouseleave', function(event) {
+		$('a', this).hide();
+		if (!$('input:[type=checkbox]', this).is(':checked')) {
+			$('input:[type=checkbox]', this).hide();
+			$('label', this).hide();
+		}
+	});
+	
+	$('.permissions').live('change', function() {
+		var permissions = (this.checked) ? 1 : 0;
+		var source = $('#dropdown').data('file');
+		var uid_shared_with = $(this).parent().data('uid_shared_with');
+		var data = 'source='+encodeURIComponent(source)+'&uid_shared_with='+encodeURIComponent(uid_shared_with)+'&permissions='+encodeURIComponent(permissions);
+		$.ajax({
+			type: 'GET',
+			url: OC.linkTo('files_sharing','ajax/setpermissions.php'),
+			cache: false,
+			data: data
+		});
+	});
+
+	$('.unshare').live('click', function(event) {
+		event.preventDefault();
+		var user = $(this).parent();
+		var source = $('#dropdown').data('file');
+		var uid_shared_with = user.data('uid_shared_with');
+		var data = 'source='+encodeURIComponent(source)+'&uid_shared_with='+encodeURIComponent(uid_shared_with);
+		$.ajax({
+			type: 'GET',
+			url: OC.linkTo('files_sharing','ajax/unshare.php'),
+			cache: false,
+			data: data,
+			success: function() {
+				var option = "<option value='"+uid_shared_with+"'>"+uid_shared_with+"</option>";
+				$(user).remove();
+				$(option).appendTo('#share_with');
+				$('#share_with').trigger('liszt:updated');
+			}
+		});
+	});
+	
+	$('#makelink').live('change', function() {
+		if (this.checked) {
+			var source = $('#dropdown').data('file');
+			var uid_shared_with = "public";
+			var permissions = 0;
+			var data = 'sources='+encodeURIComponent(source)+'&uid_shared_with='+encodeURIComponent(uid_shared_with)+'&permissions='+encodeURIComponent(permissions);
+			$.ajax({
+				type: 'POST',
+				url: OC.linkTo('files_sharing','ajax/share.php'),
+				cache: false,
+				data: data,
+				success: function(token) {
+					if (token) {
+						showPublicLink(token);
+					}
+				}
+			});
+		} else {
+			var source = $('#dropdown').data('file');
+			var uid_shared_with = "public";
+			var data = 'source='+encodeURIComponent(source)+'&uid_shared_with='+encodeURIComponent(uid_shared_with);
+			$.ajax({
+				type: 'GET',
+				url: OC.linkTo('files_sharing','ajax/unshare.php'),
+				cache: false,
+				data: data,
+				success: function(){
+					$('#link').hide('blind');
+				}
+			});
+		}
+	});
+	
+	$('#link').live('click', function() {
+		$(this).focus();
+		$(this).select();
+	});
+});
+
+function createDropdown(filename, files) {
+	var html = "<div id='dropdown' class='drop' data-file='"+files+"'>";
+	html += "<div id='private'>";
+	html += "<select data-placeholder='User or Group' style='width:220px;' id='share_with' class='chzen-select'>";
+	html += "<option value=''></option>";
+	html += "</select>";
+	html += "<ul id='shared_list'></ul>";
+	html += "</div>";
+	html += "<div id='public'>";
+	html += "<input type='checkbox' name='makelink' id='makelink' value='1' /><label for='makelink'>make public</label>";
+	//html += "<input type='checkbox' name='public_link_write' id='public_link_write' value='1' /><label for='public_link_write'>allow upload</label>";
+	html += "<br />";
+	html += "<input id='link' style='display:none; width:90%;' />";
+	html += "</div>";
+	if (filename) {
+		$('tr[data-file="'+filename+'"]').addClass('mouseOver');
+		$(html).appendTo($('tr[data-file="'+filename+'"] td.filename'));
+	} else {
+		$(html).appendTo($('thead .share'));
+	}
+	$.getJSON(OC.linkTo('files_sharing', 'ajax/userautocomplete.php'), function(users) {
+		if (users) {
+			$.each(users, function(index, row) {
+				$(row).appendTo('#share_with');
+			});
+			$('#share_with').trigger('liszt:updated');
+		}
+	});
+	$.getJSON(OC.linkTo('files_sharing', 'ajax/getitem.php'), { source: files }, function(users) {
+		if (users) {
+			$.each(users, function(index, row) {
+				if (row.uid_shared_with == 'public') {
+					var token = 1234;
+					showPublicLink(token);
+				} else if (isNaN(index)) {
+					addUser(row.uid_shared_with, row.permissions, index.substr(0, index.lastIndexOf('-')));
+				} else {
+					addUser(row.uid_shared_with, row.permissions, false);
+				}
+			});
+		}
+	});
+	$('#dropdown').show('blind');
+	$('#share_with').chosen();
+}
+
+function addUser(uid_shared_with, permissions, parentFolder) {
+	if (parentFolder) {
+		var user = "<li>Parent folder "+parentFolder+" shared with "+uid_shared_with+"</li>";
+	} else {
+		var checked = ((permissions > 0) ? "checked='checked'" : "style='display:none;'");
+		var style = ((permissions == 0) ? "style='display:none;'" : "");
+		var user = "<li data-uid_shared_with='"+uid_shared_with+"'>"+uid_shared_with;
+		user += "<input type='checkbox' name='permissions' id='"+uid_shared_with+"' class='permissions' "+checked+"/><label for='"+uid_shared_with+"' "+style+">can edit</label>";
+		user += "<a href='' title='Unshare' class='unshare' style='display:none;'><img class='svg' src='"+OC.imagePath('core','actions/delete')+"'/></a></li>";
+	}
+	$('#share_with option[value="'+uid_shared_with+'"]').remove();
+	$('#share_with').trigger('liszt:updated');
+	$(user).appendTo('#shared_list');
+}
+
+function showPublicLink(token) {
+	$('#makelink').attr('checked', true);
+	$('#link').data('token', token);
+	$('#link').val(parent.location.protocol+"//"+location.host+OC.linkTo('files_publiclink','get.php')+'?token='+token);
+	$('#link').show('blind');
+}
diff --git a/apps/files_sharing/lib_share.php b/apps/files_sharing/lib_share.php
new file mode 100644
index 0000000000000000000000000000000000000000..f682e1a30f14f698ea6babb08b3ff9a4f389bd80
--- /dev/null
+++ b/apps/files_sharing/lib_share.php
@@ -0,0 +1,396 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Michael Gapczynski
+ * @copyright 2011 Michael Gapczynski GapczynskiM@gmail.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/>.
+ *
+ */
+
+OC_Hook::connect("OC_FILESYSTEM","post_delete", "OC_Share", "deleteItem");
+OC_Hook::connect("OC_FILESYSTEM","post_rename", "OC_Share", "renameItem");
+
+/**
+ * This class manages shared items within the database. 
+ */
+class OC_Share {
+
+	const WRITE = 1;
+	const DELETE = 2;
+	const PUBLICLINK = "public";
+
+	private $token;
+      
+	/**
+	 * Share an item, adds an entry into the database
+	 * @param $source The source location of the item
+	 * @param $uid_shared_with The user or group to share the item with
+	 * @param $permissions The permissions, use the constants WRITE and DELETE
+	 */
+	public function __construct($source, $uid_shared_with, $permissions) {
+		$uid_owner = OC_User::getUser();
+		$query = OC_DB::prepare("INSERT INTO *PREFIX*sharing VALUES(?,?,?,?,?)");
+		if ($uid_shared_with == self::PUBLICLINK) {
+			$token = sha1("$uid_shared_with-$source");
+			$query->execute(array($uid_owner, self::PUBLICLINK, $source, $token, $permissions));
+			$this->token = $token;
+		} else {
+			if (OC_Group::groupExists($uid_shared_with)) {
+				$gid = $uid_shared_with;
+				$uid_shared_with = OC_Group::usersInGroup($gid);
+				// Remove the owner from the list of users in the group
+				$uid_shared_with = array_diff($uid_shared_with, array($uid_owner));
+			} else if (OC_User::userExists($uid_shared_with)) {
+				$gid = null;
+				$uid_shared_with = array($uid_shared_with);
+			} else {
+				throw new Exception($uid_shared_with." is not a user");
+			}
+			foreach ($uid_shared_with as $uid) {
+				// Check if this item is already shared with the user
+				$checkSource = OC_DB::prepare("SELECT source FROM *PREFIX*sharing WHERE source = ? AND uid_shared_with ".self::getUsersAndGroups($uid));
+				$resultCheckSource = $checkSource->execute(array($source, $uid))->fetchAll();
+				// TODO Check if the source is inside a folder
+				if (count($resultCheckSource) > 0 && !isset($gid)) {
+					throw new Exception("This item is already shared with ".$uid);
+				}
+				// Check if the target already exists for the user, if it does append a number to the name
+				$target = "/".$uid."/files/Shared/".basename($source);
+				if (self::getSource($target)) {
+					if ($pos = strrpos($target, ".")) {
+						$name = substr($target, 0, $pos);
+						$ext = substr($target, $pos);
+					} else {
+						$name = $target;
+						$ext = "";
+					}
+					$counter = 1;
+					while ($checkTarget !== false) {
+						$newTarget = $name."_".$counter.$ext;
+						$checkTarget = self::getSource($newTarget);
+						$counter++;
+					}
+					$target = $newTarget;
+				}
+				if (isset($gid)) {
+					$uid = $uid."@".$gid;
+				}
+				$query->execute(array($uid_owner, $uid, $source, $target, $permissions));
+			}
+		}
+	}
+
+	/**
+	* Remove any duplicate or trailing '/' from the path
+	* @return A clean path
+	*/
+	private static function cleanPath($path) {
+		$path = rtrim($path, "/");
+		return preg_replace('{(/)\1+}', "/", $path);
+	}
+
+	/**
+	* Generate a string to be used for searching for uid_shared_with that handles both users and groups
+	* @param $uid (Optional) The uid to get the user groups for, a gid to get the users in a group, or if not set the current user
+	* @return An IN operator as a string
+	*/
+	private static function getUsersAndGroups($uid = null) {
+		$in = " IN(";
+		if (isset($uid) && OC_Group::groupExists($uid)) {
+			$users = OC_Group::usersInGroup($uid);
+			foreach ($users as $user) {
+				// Add a comma only if the the current element isn't the last
+				if ($user !== end($users)) {
+					$in .= "'".$user."@".$uid."', ";
+				} else {
+					$in .= "'".$user."@".$uid."'";
+				}
+			}
+		} else if (isset($uid)) {
+			// TODO Check if this is necessary, only constructor needs it as IN. It would be better for other queries to just return =$uid
+			$in .= "'".$uid."'";
+			$groups = OC_Group::getUserGroups($uid);
+			foreach ($groups as $group) {
+				$in .= ", '".$uid."@".$group."'";
+			}
+		} else {
+			$uid = OC_User::getUser();
+			$in .= "'".$uid."'";
+			$groups = OC_Group::getUserGroups($uid);
+			foreach ($groups as $group) {
+				$in .= ", '".$uid."@".$group."'";
+			}
+		}
+		$in .= ")";
+		return $in;
+	}
+
+	/**
+	 * Create a new entry in the database for a file inside a shared folder
+	 *
+	 * $oldTarget and $newTarget may be the same value. $oldTarget exists in case the file is being moved outside of the folder
+	 *
+	 * @param $oldTarget The current target location
+	 * @param $newTarget The new target location
+	 */
+	public static function pullOutOfFolder($oldTarget, $newTarget) {
+		$folders = self::getParentFolders($oldTarget);
+		$source = $folders['source'].substr($oldTarget, strlen($folders['target']));
+		$item = self::getItem($folders['target']);
+		$query = OC_DB::prepare("INSERT INTO *PREFIX*sharing VALUES(?,?,?,?,?)");
+		$query->execute(array($item[0]['uid_owner'], OC_User::getUser(), $source, $newTarget, $item[0]['permissions']));
+	}
+
+	/**
+	 * Get the item with the specified target location
+	 * @param $target The target location of the item
+	 * @return An array with the item
+	 */
+	public static function getItem($target) {
+		$target = self::cleanPath($target);
+		$query = OC_DB::prepare("SELECT uid_owner, source, permissions FROM *PREFIX*sharing WHERE target = ? AND uid_shared_with = ? LIMIT 1");
+		return $query->execute(array($target, OC_User::getUser()))->fetchAll();
+	}
+
+	 /**
+	 * Get the item with the specified source location
+	 * @param $source The source location of the item
+	 * @return An array with the users and permissions the item is shared with
+	 */
+	public static function getMySharedItem($source) {
+		$source = self::cleanPath($source);
+		$query = OC_DB::prepare("SELECT uid_shared_with, permissions FROM *PREFIX*sharing WHERE source = ? AND uid_owner = ?");
+		return $query->execute(array($source, OC_User::getUser()))->fetchAll();
+	}
+	/**
+	 * Get all items the current user is sharing
+	 * @return An array with all items the user is sharing
+	 */
+	public static function getMySharedItems() {
+		$query = OC_DB::prepare("SELECT uid_shared_with, source, permissions FROM *PREFIX*sharing WHERE uid_owner = ?");
+		return $query->execute(array(OC_User::getUser()))->fetchAll();
+	}
+	
+	/**
+	 * Get the items within a shared folder that have their own entry for the purpose of name, location, or permissions that differ from the folder itself
+	 *
+	 * Works for both target and source folders. Can be used for getting all items shared with you e.g. pass '/MTGap/files'
+	 *
+	 * @param $folder The folder of the items to look for
+	 * @return An array with all items in the database that are in the folder
+	 */
+	public static function getItemsInFolder($folder) {
+		$folder = self::cleanPath($folder);
+		// Append '/' in order to filter out the folder itself if not already there
+		if (substr($folder, -1) !== "/") {
+			$folder .= "/";
+		}
+		$length = strlen($folder);
+		$query = OC_DB::prepare("SELECT uid_owner, source, target FROM *PREFIX*sharing WHERE SUBSTR(source, 1, ?) = ? OR SUBSTR(target, 1, ?) = ? AND uid_shared_with ".self::getUsersAndGroups());
+		return $query->execute(array($length, $folder, $length, $folder))->fetchAll();
+	}
+	
+	/**
+	 * Get the source and target parent folders of the specified target location
+	 * @param $target The target location of the item
+	 * @return An array with the keys 'source' and 'target' with the values of the source and target parent folders
+	 */
+	public static function getParentFolders($target) {
+		$target = self::cleanPath($target);
+		$query = OC_DB::prepare("SELECT source FROM *PREFIX*sharing WHERE target = ? AND uid_shared_with".self::getUsersAndGroups()." LIMIT 1");
+		// Prevent searching for user directory e.g. '/MTGap/files'
+		$userDirectory = substr($target, 0, strpos($target, "files") + 5);
+		$target = dirname($target);
+		$result = array();
+		while ($target != "" && $target != "/" && $target != "." && $target != $userDirectory) {
+			// Check if the parent directory of this target location is shared
+			$result = $query->execute(array($target))->fetchAll();
+			if (count($result) > 0) {
+				break;
+			}
+			$target = dirname($target);
+		}
+		if (count($result) > 0) {
+			// Return both the source folder and the target folder
+			return array("source" => $result[0]['source'], "target" => $target);
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * Get the source location of the item at the specified target location
+	 * @param $target The target location of the item
+	 * @return Source location or false if target location is not valid
+	 */
+	public static function getSource($target) {
+		$target = self::cleanPath($target);
+		$query = OC_DB::prepare("SELECT source FROM *PREFIX*sharing WHERE target = ? AND uid_shared_with ".self::getUsersAndGroups()." LIMIT 1");
+		$result = $query->execute(array($target))->fetchAll();
+		if (count($result) > 0) {
+			return $result[0]['source'];
+		} else {
+			$folders = self::getParentFolders($target);
+			if ($folders == true) {
+				return $folders['source'].substr($target, strlen($folders['target']));
+			} else {
+				return false;
+			}
+		}
+	}
+
+	/**
+	 * Get the user's permissions for the item at the specified target location
+	 * @param $target The target location of the item
+	 * @return The permissions, use bitwise operators to check against the constants WRITE and DELETE
+	 */
+	public static function getPermissions($target) {
+		$target = self::cleanPath($target);
+		$query = OC_DB::prepare("SELECT permissions FROM *PREFIX*sharing WHERE target = ? AND uid_shared_with ".self::getUsersAndGroups()." LIMIT 1");
+		$result = $query->execute(array($target))->fetchAll();
+		if (count($result) > 0) {
+			return $result[0]['permissions'];
+		} else {
+			$folders =self::getParentFolders($target);
+			if ($folders == true) {
+				$result = $query->execute(array($folders))->fetchAll();
+				if (count($result) > 0) {
+					return $result[0]['permissions'];
+				}
+			} else {
+				return false;
+			}
+		}
+	}
+
+	/**
+	 * Get the token for a public link
+	 * @return The token of the public link, a sha1 hash
+	 */
+	public function getToken() {
+		return $this->token;
+	}
+
+	/**
+	 * Get the token for a public link
+	 * @param $source The source location of the item
+	 * @return The token of the public link, a sha1 hash
+	 */
+	public static function getTokenFromSource($source) {
+		$query = OC_DB::prepare("SELECT target FROM *PREFIX*sharing WHERE source = ? AND uid_shared_with = ? AND uid_owner = ? LIMIT 1");
+		$result = $query->execute(array($source, self::PUBLICLINK, OC_User::getUser()))->fetchAll();
+		if (count($result) > 0) {
+			return $result[0]['target'];
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * Set the source location to a new value
+	 * @param $oldSource The current source location
+	 * @param $newTarget The new source location
+	 */
+	public static function setSource($oldSource, $newSource) {
+		$oldSource = self::cleanPath($oldSource);
+		$newSource = self::cleanPath($newSource);
+		$query = OC_DB::prepare("UPDATE *PREFIX*sharing SET source = REPLACE(source, ?, ?) WHERE uid_owner = ?");
+		$query->execute(array($oldSource, $newSource, OC_User::getUser()));
+	}
+	
+	/**
+	 * Set the target location to a new value
+	 *
+	 * You must use the pullOutOfFolder() function to change the target location of a file inside a shared folder if the target location differs from the folder
+	 *
+	 * @param $oldTarget The current target location
+	 * @param $newTarget The new target location 
+	 */
+	public static function setTarget($oldTarget, $newTarget) {
+		$oldTarget = self::cleanPath($oldTarget);
+		$newTarget = self::cleanPath($newTarget);
+		$query = OC_DB::prepare("UPDATE *PREFIX*sharing SET target = REPLACE(target, ?, ?) WHERE uid_shared_with ".self::getUsersAndGroups());
+		$query->execute(array($oldTarget, $newTarget));
+	}
+	
+	/**
+	* Change the permissions for the specified item and user
+	*
+	* You must construct a new shared item to change the permissions of a file inside a shared folder if the permissions differ from the folder
+	*
+	* @param $source The source location of the item
+	* @param $uid_shared_with The user to change the permissions for
+	* @param $permissions The permissions, use the constants WRITE and DELETE
+	*/
+	public static function setPermissions($source, $uid_shared_with, $permissions) {
+		$source = self::cleanPath($source);
+		$query = OC_DB::prepare("UPDATE *PREFIX*sharing SET permissions = ? WHERE SUBSTR(source, 1, ?) = ? AND uid_owner = ? AND uid_shared_with ".self::getUsersAndGroups($uid_shared_with));
+		$query->execute(array($permissions, strlen($source), $source, OC_User::getUser()));
+	}
+	
+	/**
+	* Unshare the item, removes it from all specified users
+	*
+	* You must use the pullOutOfFolder() function to unshare a file inside a shared folder and set $newTarget to nothing
+	*
+	* @param $source The source location of the item
+	* @param $uid_shared_with Array of users to unshare the item from
+	*/
+	public static function unshare($source, $uid_shared_with) {
+		$source = self::cleanPath($source);
+		$query = OC_DB::prepare("DELETE FROM *PREFIX*sharing WHERE SUBSTR(source, 1, ?) = ? AND uid_owner = ? AND uid_shared_with ".self::getUsersAndGroups($uid_shared_with));
+		$query->execute(array(strlen($source), $source, OC_User::getUser()));
+	}
+	
+	/**
+	* Unshare the item from the current user, removes it only from the database and doesn't touch the source file
+	*
+	* You must use the pullOutOfFolder() function to unshare a file inside a shared folder and set $newTarget to nothing
+	*
+	* @param $target The target location of the item
+	*/
+	public static function unshareFromMySelf($target) {
+		$target = self::cleanPath($target);
+		$query = OC_DB::prepare("DELETE FROM *PREFIX*sharing WHERE SUBSTR(target, 1, ?) = ? AND uid_shared_with ".self::getUsersAndGroups());
+		$query->execute(array(strlen($target), $target));
+	}
+
+	/**
+	* Remove the item from the database, the owner deleted the file
+	* @param $arguments Array of arguments passed from OC_HOOK
+	*/
+	public static function deleteItem($arguments) {
+		$source = "/".OC_User::getUser()."/files".$arguments['path'];
+		$source = self::cleanPath($source);
+		$query = OC_DB::prepare("DELETE FROM *PREFIX*sharing WHERE SUBSTR(source, 1, ?) = ? AND uid_owner = ?");
+		$query->execute(array(strlen($source), $source, OC_User::getUser()));
+	}
+
+	/**
+	* Rename the item in the database, the owner renamed the file
+	* @param $arguments Array of arguments passed from OC_HOOK
+	*/
+	public static function renameItem($arguments) {
+		$oldSource = "/".OC_User::getUser()."/files".$arguments['oldpath'];
+		$oldSource = self::cleanPath($oldSource);
+		$newSource = "/".OC_User::getUser()."/files".$arguments['newpath'];
+		$newSource = self::cleanPath($newSource);
+		self::setSource($oldSource, $newSource);
+	}
+
+}
+
+?>
diff --git a/apps/files_sharing/list.php b/apps/files_sharing/list.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a11f438eb7b59073a72b419e3584a9266e3a880
--- /dev/null
+++ b/apps/files_sharing/list.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Michael Gapczynski
+ * @copyright 2011 Michael Gapczynski GapczynskiM@gmail.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/>.
+ *
+ */
+
+require_once('../../lib/base.php');
+require_once('lib_share.php');
+
+if (!OC_User::isLoggedIn()){
+	header( "Location: ".OC_HELPER::linkTo( "index.php" ));
+	exit();
+}
+
+OC_App::setActiveNavigationEntry("files_sharing_list");
+
+OC_Util::addScript("files_sharing", "list");
+
+$tmpl = new OC_Template("files_sharing", "list", "user");
+$tmpl->assign("shared_items", OC_Share::getMySharedItems());
+$tmpl->printPage();
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/sharedstorage.php b/apps/files_sharing/sharedstorage.php
new file mode 100644
index 0000000000000000000000000000000000000000..271819782b708171133ec52a80ad77f19729db85
--- /dev/null
+++ b/apps/files_sharing/sharedstorage.php
@@ -0,0 +1,574 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Michael Gapczynski
+ * @copyright 2011 Michael Gapczynski GapczynskiM@gmail.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/>.
+ *
+ */
+
+require_once( 'lib_share.php' );
+
+/**
+ * Convert target path to source path and pass the function call to the correct storage provider
+ */
+class OC_Filestorage_Shared extends OC_Filestorage {
+	
+	private $datadir;
+	private $sourcePaths = array();
+	
+	public function __construct($arguments) {
+		$this->datadir = $arguments['datadir'];
+		if (!OC_Filesystem::is_dir($this->datadir)) {
+			OC_Filesystem::mkdir($this->datadir);
+		}
+		$this->datadir .= "/";
+	}
+	
+	public function getInternalPath($path) {
+		$mountPoint = OC_Filesystem::getMountPoint($path);
+		$internalPath = substr($path, strlen($mountPoint));
+		return $internalPath;
+	}
+	
+	public function getSource($target) {
+		$target = $this->datadir.$target;
+		if (array_key_exists($target, $this->sourcePaths)) {
+			return $this->sourcePaths[$target];
+		} else {
+			$source = OC_Share::getSource($target);
+			$this->sourcePaths[$target] = $source;
+			return $source;
+		}
+	}
+	
+	public function mkdir($path) {
+		if ($path == "" || $path == "/") {
+			return false; 
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				if ($this->is_writeable($path)) {
+					$storage = OC_Filesystem::getStorage($source);
+					return $storage->mkdir($this->getInternalPath($source));
+				}
+			}
+		}
+	}
+	
+	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);
+	}
+	
+	public function opendir($path) {
+		if ($path == "" || $path == "/") {
+			global $FAKEDIRS;
+			$path = $this->datadir.$path;
+			$sharedItems = OC_Share::getItemsInFolder($path);
+			if (empty($sharedItems)) {
+				return false;
+			}
+			$files = array();
+			foreach ($sharedItems as $item) {
+				// If item is in the root of the shared storage provider add it to the fakedirs
+				if (dirname($item['target'])."/" == $path) {
+					$files[] = basename($item['target']);
+				}
+			}
+			$FAKEDIRS['shared'] = $files;
+			return opendir('fakedir://shared');
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				$dh = $storage->opendir($this->getInternalPath($source));
+				// Remove any duplicate or trailing '/'
+				$path = rtrim($this->datadir.$path, "/");
+				$path = preg_replace('{(/)\1+}', "/", $path);
+				$modifiedItems = OC_Share::getItemsInFolder($source);
+				if ($modifiedItems && $dh) {
+					global $FAKEDIRS;
+					$sources = array();
+					$targets = array();
+					foreach ($modifiedItems as $item) {
+						// If the item is in the current directory and has a different name than the source, add it to the arrays
+						if (dirname($item['target']) == $path && basename($item['source']) != basename($item['target'])) {
+							$sources[] = basename($item['source']);
+							$targets[] = basename($item['target']);
+						// If the item was unshared from self, add it it to the arrays
+						} elseif ($item['target'] == "/") {
+							$sources[] = basename($item['source']);
+							$targets[] = "";
+						}
+					}
+					// Don't waste time if there aren't any modified items in the current directory
+					if (empty($sources)) {
+						return $dh;
+					} else {
+						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;
+				}
+			}
+		}
+	}
+	
+	public function is_dir($path) {
+		if ($path == "" || $path == "/") {
+			return true;
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->is_dir($this->getInternalPath($source));
+			}
+		}
+	}
+	
+	public function is_file($path) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$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["dev"] = "";
+			$stat["ino"] = "";
+			$stat["mode"] = "";
+			$stat["nlink"] = "";
+			$stat["uid"] = "";
+			$stat["gid"] = "";
+			$stat["rdev"] = "";
+			$stat["size"] = $this->filesize($path);
+			$stat["atime"] = $this->fileatime($path);
+			$stat["mtime"] = $this->filemtime($path);
+			$stat["ctime"] = $this->filectime($path);
+			$stat["blksize"] = "";
+			$stat["blocks"] = "";
+			return $stat;
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->stat($this->getInternalPath($source));
+			}
+		}
+	}
+	
+	public function filetype($path) {
+		if ($path == "" || $path == "/") {
+			return "dir";
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->filetype($this->getInternalPath($source));
+			}
+		}
+
+	}
+	
+	public function filesize($path) {
+		
+		if ($path == "" || $path == "/" || $this->is_dir($path)) {
+			return $this->getFolderSize($path);
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->filesize($this->getInternalPath($source));
+			}
+		}
+	}
+	
+	public function getFolderSize($path) {
+		$dbpath = OC_User::getUser()."/files/Share/".$path."/";
+		$query = OC_DB::prepare("SELECT size FROM *PREFIX*foldersize WHERE path=?");
+		$size = $query->execute(array($dbpath))->fetchAll();
+		if (count($size) > 0) {
+			return $size[0]['size'];
+		} else {
+			return $this->calculateFolderSize($path);
+		}
+	}
+	
+	public function calculateFolderSize($path) {
+		if ($this->is_file($path)) {
+			$path = dirname($path);
+		}
+		$path = str_replace("//", "/", $path);
+		if ($this->is_dir($path) && substr($path, -1) != "/") {
+			$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 = OC_User::getUser()."/files/Share/".$path;
+				$query = OC_DB::prepare("INSERT INTO *PREFIX*foldersize VALUES(?,?)");
+				$result = $query->execute(array($dbpath, $size));
+			}
+		}
+		return $size;
+	}
+
+	public function clearFolderSizeCache($path){
+		if ($this->is_file($path)) {
+			$path = dirname($path);
+		}
+		$path = str_replace("//", "/", $path);
+		if ($this->is_dir($path) && substr($path, -1) != "/") {
+			$path .= "/";
+		}
+		$query = OC_DB::prepare("DELETE FROM *PREFIX*foldersize WHERE path = ?");
+		$result = $query->execute(array($path));
+		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;
+	}
+	
+	public function is_writeable($path) {
+		if ($path == "" || $path == "/" || OC_Share::getPermissions($this->datadir.$path) & OC_Share::WRITE) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+	public function file_exists($path) {
+		if ($path == "" || $path == "/") {
+			return true;
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->file_exists($this->getInternalPath($source));
+			}
+		}
+	}
+	
+	public function readfile($path) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->readfile($this->getInternalPath($source));
+		}	
+	}
+	
+	public function filectime($path) {
+		if ($path == "" || $path == "/") {
+			$ctime = 0; 
+			if ($dh = $this->opendir($path)) {
+				while (($filename = readdir($dh)) !== false) {
+					$tempctime = $this->filectime($filename);
+					if ($tempctime < $ctime) {
+						$ctime = $tempctime;
+					}
+				}
+				return $ctime;
+			}
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->filectime($this->getInternalPath($source));
+			}
+		}
+	}
+	
+	public function filemtime($path) {
+		if ($path == "" || $path == "/") {
+			$mtime = 0; 
+			if ($dh = $this->opendir($path)) {
+				while (($filename = readdir($dh)) !== false) {
+					$tempmtime = $this->filemtime($filename);
+					if ($tempmtime > $mtime) {
+						$mtime = $tempmtime;
+					}
+				}
+				return $mtime;
+			}
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->filemtime($this->getInternalPath($source));
+			}
+		}
+	}
+	
+	public function fileatime($path) {
+		if ($path == "" || $path == "/") {
+			$atime = 0; 
+			if ($dh = $this->opendir($path)) {
+				while (($filename = readdir($dh)) !== false) {
+					$tempatime = $this->fileatime($filename);
+					if ($tempatime > $atime) {
+						$atime = $tempatime;
+					}
+				}
+				return $atime;
+			}
+		} else {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->fileatime($this->getInternalPath($source));
+			}
+		}
+	}
+	
+	public function file_get_contents($path) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->file_get_contents($this->getInternalPath($source));
+		}
+	}
+	
+	public function file_put_contents($path, $data) {
+		if ($this->is_writeable($path)) {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->file_put_contents($this->getInternalPath($source), $data);
+			}
+		}
+	}
+	
+	public function unlink($path) {
+		$target = $this->datadir.$path;
+		// If the user has delete permission for the item, the source item will be deleted
+		if (OC_Share::getPermissions($target) & OC_Share::DELETE) {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->unlink($this->getInternalPath($source));
+			}
+		// The item will be removed from the database, but won't be touched on the owner's filesystem
+		} else {
+			// Check if the item is inside a shared folder
+			if (OC_Share::getParentFolders($target)) {
+				// If entry for item already exists
+				if (OC_Share::getItem($target)) {
+					OC_Share::setTarget($target, "/");
+				} else {
+					OC_Share::pullOutOfFolder($target, "/");
+				}
+			// Delete the database entry
+			} else {
+				OC_Share::unshareFromMySelf($target);
+			}
+			$this->clearFolderSizeCache($this->getInternalPath($target));
+		}
+		return true;
+	}
+	
+	public function rename($path1, $path2) {
+		// If the user has write permission for the item, the source item will be renamed
+		if ($this->is_writeable($path1)) {
+			$source = $this->getSource($path1);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->rename($path1, $path2);
+			}
+		// The item will be renamed in the database, but won't be touched on the owner's filesystem
+		} else {
+			$oldTarget = $this->datadir.$path1;
+			$newTarget = $this->datadir.$path2;
+			if (OC_Share::getItem($oldTarget)) {
+				OC_Share::setTarget($oldTarget, $newTarget);
+			// There is no entry in the database for the item, it must be inside a shared folder
+			} else {
+				OC_Share::pullOutOfFolder($oldTarget, $newTarget);
+				// If this is a folder being renamed, call setTarget in case there are any database entries inside the folder
+				if (self::is_dir($path1)) {
+					OC_Share::setTarget($oldTarget, $newTarget);
+				}
+			}
+			$this->clearFolderSizeCache($this->getInternalPath($oldTarget));
+			$this->clearFolderSizeCache($this->getInternalPath($newTarget));
+			return true;
+		}
+	}
+	
+	public function copy($path1, $path2) {
+		if ($path2 == "" || $path2 == "/") {
+			// TODO Construct new shared item or should this not be allowed?
+		} else {
+			if ($this->is_writeable($path2)) {
+				$tmpFile = $this->toTmpFile($path1);
+				return $this->fromTmpFile($tmpFile, $path2);
+			} else {
+				return false;
+			}
+		}
+	}
+	
+	public function fopen($path, $mode) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->fopen($this->getInternalPath($source), $mode);
+		}
+	}
+	
+	public function toTmpFile($path) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->toTmpFile($this->getInternalPath($source));
+		}
+	}
+	
+	public function fromTmpFile($tmpFile, $path) {
+		if ($this->is_writeable($path)) {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->fromTmpFile($tmpFile, $this->getInternalPath($source));
+			}
+		} else {
+			return false;
+		}
+	}
+	
+	public function fromUploadedFile($tmpPath, $path) {
+		$source = $this->getSource($tmpPath);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->fromUploadedFile($this->getInternalPath($source), $path);
+		}
+	}
+	
+	public function getMimeType($path) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->getMimeType($this->getInternalPath($source));
+		}
+	}
+	
+	public function delTree($path) {
+		$target = $this->datadir.$path;
+		if (OC_Share::getPermissions($target) & OC_Share::DELETE) {
+			$source = $this->getSource($path);
+			if ($source) {
+				$storage = OC_Filesystem::getStorage($source);
+				return $storage->delTree($this->getInternalPath($source));
+			}
+		} else {
+			// Check if the folder is inside a shared folder
+			if (OC_Share::getParentFolders($target)) {
+				// If entry for folder already exists
+				if (OC_Share::getItem($target)) {
+					OC_Share::setTarget($target, "/");
+				} else {
+					OC_Share::pullOutOfFolder($target, "/");
+					// Call setTarget in case there are any database entries for items inside this folder
+					OC_Share::setTarget($target, "/");
+				}
+			// Delete the database entry
+			} else {
+				OC_Share::unshareFromMySelf($target);
+			}
+			$this->clearFolderSizeCache($this->getInternalPath($target));
+			return true;
+		}
+	}
+	
+	public function find($path) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->find($this->getInternalPath($source));
+		}
+	}
+	
+	public function getTree($path) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->getTree($this->getInternalPath($source));
+		}
+	}
+	
+	public function hash($type, $path, $raw) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->hash($type, $this->getInternalPath($source), $raw);
+		}
+	}
+	
+	public function free_space($path) {
+		$source = $this->getSource($path);
+		if ($source) {
+			$storage = OC_Filesystem::getStorage($source);
+			return $storage->free_space($this->getInternalPath($source));
+		}
+	}
+	
+	// TODO query all shared files?
+	public function search($query) { 
+		
+	}
+	
+}
+
+?>
\ No newline at end of file
diff --git a/apps/files_sharing/templates/list.php b/apps/files_sharing/templates/list.php
new file mode 100644
index 0000000000000000000000000000000000000000..7faf2cf4ba611676280bd92c838616bdad36ed0e
--- /dev/null
+++ b/apps/files_sharing/templates/list.php
@@ -0,0 +1,30 @@
+<fieldset>
+	<legend>Your Shared Files</legend>
+	<table id="itemlist">
+		<thead>
+			<tr>
+				<th>Item</th>
+				<th>Shared With</th>
+				<th>Permissions</th>
+			</tr>
+		</thead>
+		<tbody>
+			<?php foreach($_['shared_items'] as $item):?>
+				<tr class="item">
+					<td class="source"><?php echo substr($item['source'], strlen("/".$_SESSION['user_id']."/files/"));?></td>
+					<td class="uid_shared_with"><?php echo $item['uid_shared_with'];?></td>
+					<td class="permissions"><?php echo "Read"; echo($item['permissions'] & OC_SHARE::WRITE ? ", Edit" : ""); echo($item['permissions'] & OC_SHARE::DELETE ? ", Delete" : "");?></td>
+					<td><button class="delete" data-source="<?php echo $item['source'];?>" data-uid_shared_with="<?php echo $item['uid_shared_with'];?>">Delete</button></td>
+				</tr>
+			<?php endforeach;?>
+			<tr id="share_item_row">
+				<form action="#" id="share_item">
+					<td class="source"><input placeholder="Item" id="source" /></td>
+					<td class="uid_shared_with"><input placeholder="Share With" id="uid_shared_with" /></td>
+					<td class="permissions"><input placeholder="Permissions" id="permissions" /></td>
+					<td><input type="submit" value="Share" /></td>
+				</form>
+			</tr>
+		</tbody>
+	</table>
+</fieldset>
diff --git a/files/templates/index.php b/files/templates/index.php
index cd061596a024212da2d6fcf5c345eac5e84c645e..f5a212add48dbf493e2e9068b3f8adf8739a8f8c 100644
--- a/files/templates/index.php
+++ b/files/templates/index.php
@@ -29,7 +29,7 @@
 				<span class='name'><?php echo $l->t( 'Name' ); ?></span>
 				<span class='selectedActions'>
 					<a href="" title="<?php echo $l->t('Download')?>" class="download"><img class='svg' alt="Download" src="../core/img/actions/download.svg" /></a>
-					<!--<a href="" title="" class="share">Share</a>-->
+					<a href="" title="Share" class="share"><img class='svg' alt="Share" src="../core/img/actions/share.svg" /></a>
 				</span>
 			</th>
 			<th id="headerSize"><?php echo $l->t( 'Size' ); ?></th>
diff --git a/lib/filesystem.php b/lib/filesystem.php
index 911a85e4a33d3afe343a319b93438418b1e9a0a2..76032fae204483ac0c7032d0b7cdcd309f22ab1a 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -175,7 +175,7 @@ class OC_Filesystem{
 	* @param string path
 	* @return OC_Filestorage
 	*/
-	static private function getStorage($path){
+	static public function getStorage($path){
 		$mountpoint=self::getMountPoint($path);
 		if($mountpoint){
 			return self::$storages[$mountpoint];
@@ -189,7 +189,7 @@ class OC_Filesystem{
 	* @param string path
 	* @return string
 	*/
-	static private function getMountPoint($path){
+	static public function getMountPoint($path){
 		if(!$path){
 			$path='/';
 		}
@@ -214,6 +214,7 @@ class OC_Filesystem{
 		}
 		return $foundMountPoint;
 	}
+	
 	/**
 	* return the path to a local version of the file
 	* we need this because we can't know if a file is stored local or not from outside the filestorage and for some purposes a local file is needed
diff --git a/lib/util.php b/lib/util.php
index 0fdfa0123057e248be3df4e92aa83fd89ec27abd..f4ca879a9bc589f6af9486ab447c4918a3fad650 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -53,6 +53,10 @@ class OC_Util {
 // 			}
 			OC_Filesystem::mount($rootStorage,'/');
 
+			// TODO add this storage provider in a proper way
+			$sharedStorage = OC_Filesystem::createStorage('shared',array('datadir'=>'/'.OC_User::getUser().'/files/Shared'));
+			OC_Filesystem::mount($sharedStorage,'/'.OC_User::getUser().'/files/Shared/');
+
 			$CONFIG_DATADIRECTORY = "$CONFIG_DATADIRECTORY_ROOT/$user/$root";
 			if( !is_dir( $CONFIG_DATADIRECTORY )){
 				mkdir( $CONFIG_DATADIRECTORY, 0755, true );