diff --git a/mtp/MtpStorage.cpp b/mtp/MtpStorage.cpp
index 57c8774..4c55361 100755
--- a/mtp/MtpStorage.cpp
+++ b/mtp/MtpStorage.cpp
@@ -21,6 +21,7 @@
 #include "MtpDataPacket.h"
 #include "MtpServer.h"
 #include "MtpEventPacket.h"
+#include "MtpDatabase.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -35,12 +36,9 @@
 #include <signal.h>
 #include <sys/inotify.h>
 #include <fcntl.h>
-#include <sstream>
 
 #define WATCH_FLAGS ( IN_CREATE | IN_DELETE | IN_MOVE | IN_MODIFY )
 
-static int mtpid = 0;
-
 MtpStorage::MtpStorage(MtpStorageID id, const char* filePath,
 		const char* description, uint64_t reserveSpace,
 		bool removable, uint64_t maxFileSize, MtpServer* refserver)
@@ -54,9 +52,9 @@
 		mServer(refserver)
 {
 	MTPI("MtpStorage id: %d path: %s\n", id, filePath);
-	mtpparentid = 0;
 	inotify_thread = 0;
 	sendEvents = false;
+	handleCurrentlySending = 0;
 	use_mutex = true;
 	if (pthread_mutex_init(&mtpMutex, NULL) != 0) {
 		MTPE("Failed to init mtpMutex\n");
@@ -71,8 +69,9 @@
 
 MtpStorage::~MtpStorage() {
 	if (inotify_thread) {
+		// TODO: what does this do? manpage says it does not kill the thread
 		pthread_kill(inotify_thread, 0);
-		for (std::map<int, std::string>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
+		for (std::map<int, Tree*>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
 			inotify_rm_watch(inotify_fd, i->first);
 		}
 		close(inotify_fd);
@@ -124,12 +123,8 @@
 int MtpStorage::createDB() {
 	std::string mtpParent = "";
 	mtpstorageparent = getPath();
-	readParentDirs(getPath());
-	while (!mtpParentList.empty()) {
-		mtpParent = mtpParentList.front();
-		mtpParentList.pop_front();
-		readParentDirs(mtpParent);
-	}
+	// root directory is special: handle 0, parent 0, and empty path
+	mtpmap[0] = new Tree(0, 0, "");
 	MTPD("MtpStorage::createDB DONE\n");
 	if (use_mutex) {
 		MTPD("Starting inotify thread\n");
@@ -138,524 +133,399 @@
 	} else {
 		MTPD("NOT starting inotify thread\n");
 	}
+	// for debugging and caching purposes, read the root dir already now
+	readDir(mtpstorageparent, mtpmap[0]);
+	// all other dirs are read on demand
 	return 0;
 }
 
 MtpObjectHandleList* MtpStorage::getObjectList(MtpStorageID storageID, MtpObjectHandle parent) {
-	std::vector<int> mtpids;
-	int local_mtpparentid;
-	MTPD("MtpStorage::getObjectList\n");
-	MTPD("parent: %d\n", parent);
+	MTPD("MtpStorage::getObjectList, parent: %u\n", parent);
 	//append object id  (numerical #s) of database to int array
 	MtpObjectHandleList* list = new MtpObjectHandleList();
 	if (parent == MTP_PARENT_ROOT) {
 		MTPD("parent == MTP_PARENT_ROOT\n");
-		local_mtpparentid = 1;
+		parent = 0;
 	}
-	else {
-		for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-			MTPD("root: %d\n", i->second->Root());
-			Node* node = i->second->findNode(parent, i->second->Root());
-			if (node != NULL) {
-				local_mtpparentid = i->second->getMtpParentId(node);
-				MTPD("path: %s\n", i->second->getPath(node).c_str());
-				MTPD("mtpparentid: %d going to endloop\n", local_mtpparentid);
-				goto endloop;
-			}
-		}
-	}
-	MTPD("got to endloop\n");
-	endloop:
 
-	if (mtpmap[local_mtpparentid] == NULL) {
-		MTPD("mtpmap[mtpparentid] == NULL, returning\n");
+	if (mtpmap.find(parent) == mtpmap.end()) {
+		MTPE("parent handle not found, returning empty list\n");
 		return list;
 	}
 
-	MTPD("root: %d\n", mtpmap[local_mtpparentid]->Root());
-	mtpmap[local_mtpparentid]->getmtpids(mtpmap[local_mtpparentid]->Root(), &mtpids);
-	MTPD("here, mtpids->size(): %i\n", mtpids.size());
-
-	for (unsigned index = 0; index < mtpids.size(); index++) {
-		MTPD("mtpidhere[%i]: %d\n", index, mtpids.at(index));
-		list->push(mtpids.at(index));
+	Tree* tree = mtpmap[parent];
+	if (!tree->wasAlreadyRead())
+	{
+		std::string path = getNodePath(tree);
+		MTPD("reading directory on demand for tree %p (%u), path: %s\n", tree, tree->Mtpid(), path.c_str());
+		readDir(path, tree);
 	}
+
+	mtpmap[parent]->getmtpids(list);
+	MTPD("returning %u objects in %s.\n", list->size(), tree->getName().c_str());
 	return list;
 }
 
 int MtpStorage::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) {
 	struct stat st;
 	uint64_t size = 0;
-	MTPD("MtpStorage::getObjectInfo handle: %d\n", handle);
-	for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-		Node* node = i->second->findNode(handle, i->second->Root());
-		MTPD("node returned: %d\n", node);
-		if (node != NULL) {
-				MTPD("found mtpid: %d\n", node->Mtpid());
-				info.mStorageID = getStorageID();
-				MTPD("info.mStorageID: %d\n", info.mStorageID);
-				info.mParent = node->getMtpParentId();
-				MTPD("mParent: %d\n", info.mParent);
-				if (lstat(node->getPath().c_str(), &st) == 0)
-					size = st.st_size;
-				MTPD("size is: %llu\n", size);
-				info.mCompressedSize = size;//(size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size);
-				info.mDateModified = st.st_mtime;
-				if (S_ISDIR(st.st_mode)) {
-					info.mFormat = MTP_FORMAT_ASSOCIATION;
-				}
-				else {
-					info.mFormat = MTP_FORMAT_UNDEFINED;
-				}
-				info.mName = strdup(basename(node->getPath().c_str()));
-				MTPD("MtpStorage::getObjectInfo found, Exiting getObjectInfo()\n");
-				return 0;
-		}
+	MTPD("MtpStorage::getObjectInfo, handle: %u\n", handle);
+	Node* node = findNode(handle);
+	if (!node) {
+		// Item is not on this storage device
+		return -1;
 	}
-	// Item is not on this storage device
-	return -1;
+	
+	info.mStorageID = getStorageID();
+	MTPD("info.mStorageID: %u\n", info.mStorageID);
+	info.mParent = node->getMtpParentId();
+	MTPD("mParent: %u\n", info.mParent);
+	// TODO: do we want to lstat again here, or read from the node properties?
+	if (lstat(getNodePath(node).c_str(), &st) == 0)
+		size = st.st_size;
+	MTPD("size is: %llu\n", size);
+	info.mCompressedSize = (size > 0xFFFFFFFFLL ? 0xFFFFFFFF : size);
+	info.mDateModified = st.st_mtime;
+	if (S_ISDIR(st.st_mode)) {
+		info.mFormat = MTP_FORMAT_ASSOCIATION;
+	}
+	else {
+		info.mFormat = MTP_FORMAT_UNDEFINED;
+	}
+	info.mName = strdup(node->getName().c_str());
+	MTPD("MtpStorage::getObjectInfo found, Exiting getObjectInfo()\n");
+	return 0;
 }
 
 MtpObjectHandle MtpStorage::beginSendObject(const char* path,
 											MtpObjectFormat format,
 											MtpObjectHandle parent,
-											MtpStorageID storage,
 											uint64_t size,
 											time_t modified) {
-	MTPD("MtpStorage::beginSendObject(), path: '%s', parent: %d, storage: %d, format: %04x\n", path, parent, storage, format);
-	Node* node;
-	std::string parentdir;
-	std::string pathstr(path);
-	int parent_id;
-	parentdir = pathstr.substr(0, pathstr.find_last_of('/'));
-	MTPD("MtpStorage::beginSendObject() parentdir: %s\n", parentdir.c_str());
-	if (parentdir.compare(mtpstorageparent) == 0) {
-		// root directory
-		MTPD("MtpStorage::beginSendObject() root dir\n");
-		parent_id = 1;
-		++mtpid;
-		node = mtpmap[parent_id]->addNode(mtpid, path);
-		MTPD("node: %d\n", node);
-		node->addProperties(storage, 0);
-		if (format == MTP_FORMAT_ASSOCIATION) {
-			createEmptyDir(path);
-		}
-		return mtpid;
-	} else {
-		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-			node = i->second->findNodePath(parentdir, i->second->Root());
-			if (node != NULL) {
-				MTPD("mtpid: %d\n", mtpid);
-				MTPD("path: %s\n", i->second->getPath(node).c_str());
-				parentdir = i->second->getPath(node);
-				parent = i->second->getMtpParentId(node);
-				if (parent == 0) {
-					MTPD("MtpStorage::beginSendObject parent is 0, error.\n");
-					return -1;
-				} else {
-					++mtpid;
-					node = mtpmap[parent]->addNode(mtpid, path);
-					node->addProperties(getStorageID(), getParentObject(parentdir));
-					for (iter i2 = mtpmap.begin(); i2 != mtpmap.end(); i2++) {
-						node = i2->second->findNodePath(path, i2->second->Root());
-						if (node != NULL) {
-							i2->second->setMtpParentId(parent, node);
-						}
-					}
-					if (format == MTP_FORMAT_ASSOCIATION) {
-						createEmptyDir(path);
-					}
-				}
-				return mtpid;
-			}
-		}
+	MTPD("MtpStorage::beginSendObject(), path: '%s', parent: %u, format: %04x\n", path, parent, format);
+	iter it = mtpmap.find(parent);
+	if (it == mtpmap.end()) {
+		MTPE("parent node not found, returning error\n");
+		return kInvalidObjectHandle;
 	}
-	MTPE("MtpStorage::beginSendObject(), path: '%s', parent: %d, storage: %d, format: %04x\n", path, parent, storage, format);
-	return -1;
+	Tree* tree = it->second;
+
+	std::string pathstr(path);
+	size_t slashpos = pathstr.find_last_of('/');
+	if (slashpos == std::string::npos) {
+		MTPE("path has no slash, returning error\n");
+		return kInvalidObjectHandle;
+	}
+	std::string parentdir = pathstr.substr(0, slashpos);
+	std::string basename = pathstr.substr(slashpos + 1);
+	if (parent != 0 && parentdir != getNodePath(tree)) {
+		MTPE("beginSendObject into path '%s' but parent tree has path '%s', returning error\n", parentdir.c_str(), getNodePath(tree).c_str());
+		return kInvalidObjectHandle;
+	}
+
+	MTPD("MtpStorage::beginSendObject() parentdir: %s basename: %s\n", parentdir.c_str(), basename.c_str());
+	// note: for directories, the mkdir call is done later in MtpServer, here we just reserve a handle
+	bool isDir = format == MTP_FORMAT_ASSOCIATION;
+	Node* node = addNewNode(isDir, tree, basename);
+	handleCurrentlySending = node->Mtpid();	// suppress inotify for this node while sending
+
+	return node->Mtpid();
+}
+
+void MtpStorage::endSendObject(const char* path, MtpObjectHandle handle, MtpObjectFormat format, bool succeeded)
+{
+	Node* node = findNode(handle);
+	if (!node)
+		return;	// just ignore if this is for another storage
+
+	node->addProperties(path, mStorageID);
+	handleCurrentlySending = 0;
+	// TODO: are we supposed to send an event about an upload by the initiator?
+	if (sendEvents)
+		mServer->sendObjectAdded(node->Mtpid());
 }
 
 int MtpStorage::getObjectFilePath(MtpObjectHandle handle, MtpString& outFilePath, int64_t& outFileLength, MtpObjectFormat& outFormat) {
-	struct stat st;
-	Node* node;
-	MTPD("MtpStorage::getObjectFilePath handle: %i\n", handle);
-	for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-		MTPD("handle: %d\n", handle);
-		node = i->second->findNode(handle, i->second->Root());
-		MTPD("node returned: %d\n", node);
-		if (node != NULL) {
-			if (lstat(node->getPath().c_str(), &st) == 0)
-				outFileLength = st.st_size;
-			else
-				outFileLength = 0;
-			outFilePath = strdup(node->getPath().c_str());
-			MTPD("outFilePath: %s\n", node->getPath().c_str());
-			goto end;
-		}
+	MTPD("MtpStorage::getObjectFilePath handle: %u\n", handle);
+	Node* node = findNode(handle);
+	if (!node)
+	{
+		// Item is not on this storage device
+		return -1;
 	}
-	// Item is not on this storage
-	return -1;
-end:
-	outFormat = MTP_FORMAT_ASSOCIATION;
+	// TODO: do we want to lstat here, or just read the info from the node?
+	struct stat st;
+	if (lstat(getNodePath(node).c_str(), &st) == 0)
+		outFileLength = st.st_size;
+	else
+		outFileLength = 0;
+	outFilePath = getNodePath(node).c_str();
+	MTPD("outFilePath: %s\n", outFilePath.string());
+	outFormat = node->isDir() ? MTP_FORMAT_ASSOCIATION : MTP_FORMAT_UNDEFINED;
 	return 0;
 }
 
-int MtpStorage::readParentDirs(std::string path) {
+int MtpStorage::readDir(const std::string& path, Tree* tree)
+{
 	struct dirent *de;
-	struct stat st;
-	DIR *d;
-	std::string parent, item, prevparent = "";
-	Node* node;
 	int storageID = getStorageID();
+	MtpObjectHandle parent = tree->Mtpid();
 
-	d = opendir(path.c_str());
-	MTPD("opening '%s'\n", path.c_str());
+	DIR *d = opendir(path.c_str());
+	MTPD("reading dir '%s', parent handle %u\n", path.c_str(), parent);
 	if (d == NULL) {
-		MTPD("error opening '%s' -- error: %s\n", path.c_str(), strerror(errno));
-		closedir(d);
+		MTPE("error opening '%s' -- error: %s\n", path.c_str(), strerror(errno));
+		return -1;
 	}
+	// TODO: for refreshing dirs: capture old entries here
 	while ((de = readdir(d)) != NULL) {
 		// Because exfat-fuse causes issues with dirent, we will use stat
 		// for some things that dirent should be able to do
-		item = path + "/" + de->d_name;
+		std::string item = path + "/" + de->d_name;
+		struct stat st;
 		if (lstat(item.c_str(), &st)) {
 			MTPE("Error running lstat on '%s'\n", item.c_str());
 			return -1;
 		}
-		if ((st.st_mode & S_IFDIR) && strcmp(de->d_name, ".") == 0)
+		// TODO: if we want to use this for refreshing dirs too, first find existing name and overwrite
+		if (strcmp(de->d_name, ".") == 0)
 			continue;
-		if ((st.st_mode & S_IFDIR) && strcmp(de->d_name, "..") != 0) {
-			// Handle dirs
-			MTPD("dir: %s\n", item.c_str());
-			mtpParentList.push_back(item);
-			parent = item.substr(0, item.find_last_of('/'));
-			++mtpid;
-			MTPD("parent: %s\n", parent.c_str());
-			MTPD("mtpid: %d\n", mtpid);
-			if (prevparent != parent) {
-				mtpparentid++;
-				MTPD("Handle dirs, prevparent != parent, mtpparentid: %d\n", mtpparentid);
-				mtpmap[mtpparentid] = new Tree();
-				MTPD("prevparent addNode\n");
-				for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-					node = i->second->findNodePath(parent, i->second->Root());
-					if (node != NULL) {
-						i->second->setMtpParentId(mtpparentid, node);
-					}
-				}
-				node = mtpmap[mtpparentid]->addNode(mtpid, item);
-				node->addProperties(storageID, getParentObject(path));
-				if (sendEvents)
-					mServer->sendObjectAdded(mtpid);
-			}
-			else {
-				MTPD("add node\n");
-				mtpmap[mtpparentid]->addNode(mtpid, item);
-				for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-					node = i->second->findNodePath(item, i->second->Root());
-					if (node != NULL) {
-						i->second->setMtpParentId(mtpparentid, node);
-						node->addProperties(storageID, getParentObject(path));
-					}
-				}
-				if (sendEvents)
-					mServer->sendObjectAdded(mtpid);
-			}
-			prevparent = parent;
-		}
-		else {
-			if (strcmp(de->d_name, "..") != 0) {
-				// Handle files
-				item = path + "/" + de->d_name;
-				MTPD("file: %s\n", item.c_str());
-				parent = item.substr(0, item.find_last_of('/'));
-				MTPD("parent: %s\n", parent.c_str());
-				++mtpid;
-				MTPD("mtpid: %d\n", mtpid);
-				if (prevparent != parent) {
-					mtpparentid++;
-					MTPD("mtpparentid1: %d\n", mtpparentid);
-					for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-						node = i->second->findNodePath(path, i->second->Root());
-						if (node != NULL) {
-							i->second->setMtpParentId(mtpparentid, node);
-							node->addProperties(storageID, getParentObject(path));
-						}
-					}
-				}
-				if (mtpmap[mtpparentid] == NULL) {
-					mtpmap[mtpparentid] = new Tree();
-				}
-				MTPD("blank addNode\n");
-				node = mtpmap[mtpparentid]->addNode(mtpid, item);
-				node->addProperties(storageID, getParentObject(path));
-				prevparent = parent;
-				if (sendEvents)
-					mServer->sendObjectAdded(mtpid);
-			}
-			else {
-				// Handle empty dirs?
-				MTPD("checking for empty dir '%s'\n", path.c_str());
-				int count = 0;
-				DIR *dirc;
-				struct dirent *ep;
-				dirc = opendir(path.c_str());
-				if (dirc != NULL) {
-					while ((ep = readdir(dirc)))
-						++count;
-					MTPD("count: %d\n", count);
-					closedir(dirc);
-				}
-				if (count == 2) {
-					MTPD("'%s' is an empty dir\n", path.c_str());
-					createEmptyDir(path.c_str());
-					goto end;
-				}
-			}
-		}
+		if (strcmp(de->d_name, "..") == 0)
+			continue;
+		Node* node = addNewNode(st.st_mode & S_IFDIR, tree, de->d_name);
+		node->addProperties(item, storageID);
+		//if (sendEvents)
+		//	mServer->sendObjectAdded(node->Mtpid());
+		//	sending events here makes simple-mtpfs very slow, and it is probably the wrong thing to do anyway
 	}
-	end:
-		closedir(d);
-		return 0;
-}
-
-void MtpStorage::deleteTrees(int parent) {
-	Node* node = mtpmap[parent]->Root();
-	MTPD("MtpStorage::deleteTrees deleting %i\n", parent);
-	while (node != NULL) {
-		if (node->getIntProperty(MTP_PROPERTY_OBJECT_FORMAT) == MTP_FORMAT_ASSOCIATION) {
-			deleteTrees(node->getMtpParentId());
-		}
-		node = mtpmap[parent]->getNext(node);
-	}
-	delete mtpmap[parent];
-	mtpmap.erase(parent);
-	MTPD("MtpStorage::deleteTrees deleted %i\n", parent);
-}
-
-int MtpStorage::deleteFile(MtpObjectHandle handle) {
-	int local_parent_id = 0;
-	for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-		MTPD("MtpStorage::deleteFile handle: %d\n", handle);
-		Node* node = i->second->findNode(handle, i->second->Root());
-		MTPD("MtpStorage::deleteFile node returned: %d\n", node);
-		if (node != NULL) {
-			if (node->getIntProperty(MTP_PROPERTY_OBJECT_FORMAT) == MTP_FORMAT_ASSOCIATION) {
-				local_parent_id = node->getMtpParentId();
-			}
-			MTPD("deleting handle: %d\n", handle);
-			i->second->deleteNode(handle);
-			MTPD("deleted\n");
-			goto end;
-		}
-	}
-	return -1;
-end:
-	if (local_parent_id) {
-		deleteTrees(local_parent_id);
-	}
+	closedir(d);
+	// TODO: for refreshing dirs: remove entries that no longer exist (with their nodes)
+	tree->setAlreadyRead(true);
+	addInotify(tree);
 	return 0;
 }
 
-int MtpStorage::getObjectPropertyList(MtpObjectHandle handle, uint32_t format, uint32_t property, int groupCode, int depth, MtpDataPacket& packet) {
-	Node *n;
-	int local_mtpid = 0;
-	int local_mtpparentid = 0;
-	std::vector<int> propertyCodes;
-	std::vector<int> dataTypes;
-	std::vector<std::string> valueStrs;
-	std::vector<int> longValues;
-	int count = 0;
-	MTPD("MtpStorage::getObjectPropertyList handle: %d, format: %d, property: %lx\n", handle, format, property);
-	if (property == MTP_PROPERTY_OBJECT_FORMAT) {
-		MTPD("MtpStorage::getObjectPropertyList MTP_PROPERTY_OBJECT_FORMAT\n");
-		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-			MTPD("root: %d\n", i->second->Root());
-			Node *node = i->second->findNode(handle, i->second->Root());
-			MTPD("index: %d\n", index);
-			MTPD("node: %d\n", node);
-			if (node != NULL) {
-				uint64_t longval = node->getIntProperty(MTP_PROPERTY_OBJECT_FORMAT);
-				local_mtpparentid = i->second->getMtpParentId(node);
-				MTPD("object format longValue: %llu\n", longval);
-				propertyCodes.push_back(MTP_PROPERTY_OBJECT_FORMAT);
-				longValues.push_back(node->getIntProperty(MTP_PROPERTY_OBJECT_FORMAT));
-				valueStrs.push_back("");
-				dataTypes.push_back(4);
-				count = 1;
-				local_mtpid = node->Mtpid();
-				goto endloop;
-			}
-		}
-	}
-	else if (property == MTP_PROPERTY_STORAGE_ID) {
-		MTPD("MtpStorage::getObjectPropertyList MTP_PROPERTY_STORAGE_ID\n");
-		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-			MTPD("root: %d\n", i->second->Root());
-			Node *node = i->second->findNode(handle, i->second->Root());
-			if (node != NULL) {
-				propertyCodes.push_back(MTP_PROPERTY_STORAGE_ID);
-				longValues.push_back(getStorageID());
-				valueStrs.push_back("");
-				dataTypes.push_back(4);
-				count = 1;
-				local_mtpid = node->Mtpid();
-				goto endloop;
-			}
-		}
-	}
-	else if (property == MTP_PARENT_ROOT) {
-		MTPD("MtpStorage::getObjectPropertyList MTP_PARENT_ROOT\n");
-		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-			MTPD("root: %d\n", i->second->Root());
-			Node* node = i->second->findNode(handle, i->second->Root());
-			if (node != NULL) {
-				local_mtpparentid = i->second->getMtpParentId(node);
-				MTPD("path: %s\n", i->second->getPath(node).c_str());
-				MTPD("mtpparentid: %d going to endloop\n", local_mtpparentid);
-				std::vector<Node::mtpProperty> mtpprop = node->getMtpProps();
-				count = mtpprop.size();
-				for (int i = 0; i < count; ++i) {
-					propertyCodes.push_back(mtpprop[i].property);
-					longValues.push_back(mtpprop[i].valueInt);
-					valueStrs.push_back(mtpprop[i].valueStr);
-					dataTypes.push_back(mtpprop[i].dataType);
-				}
-				local_mtpid = node->Mtpid();
-				goto endloop;
-			}
-		}
-	}
-	else if (property == MTP_PROPERTY_PROTECTION_STATUS) {
-		MTPD("MtpStorage::getObjectPropertyList MTP_PROPERTY_PROTECTION_STATUS\n");
-		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-			MTPD("root: %d\n", i->second->Root());
-			Node *node = i->second->findNode(handle, i->second->Root());
-			if (node != NULL) {
-				propertyCodes.push_back(MTP_PROPERTY_PROTECTION_STATUS);
-				longValues.push_back(0);
-				valueStrs.push_back("");
-				dataTypes.push_back(8);
-				count = 1;
-				local_mtpid = node->Mtpid();
-				goto endloop;
-			}
-		}
-	}
-	else if (property == MTP_PROPERTY_OBJECT_SIZE) {
-		MTPD("MtpStorage::getObjectPropertyList MTP_PROPERTY_OBJECT_SIZE\n");
-		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-			MTPD("root: %d\n", i->second->Root());
-			Node *node = i->second->findNode(handle, i->second->Root());
-			if (node != NULL) {
-				struct stat st;
-				uint64_t size = 0;
-				if (lstat(node->getPath().c_str(), &st) == 0)
-					size = st.st_size;
-				propertyCodes.push_back(MTP_PROPERTY_OBJECT_SIZE);
-				longValues.push_back(size);
-				valueStrs.push_back("");
-				dataTypes.push_back(8);
-				count = 1;
-				local_mtpid = node->Mtpid();
-				goto endloop;
-			}
-		}
-	}
-	else {
-		// Either the property is not supported or the handle is not on this storage
+int MtpStorage::deleteFile(MtpObjectHandle handle) {
+	MTPD("MtpStorage::deleteFile handle: %u\n", handle);
+	Node* node = findNode(handle);
+	if (!node) {
+		// Item is not on this storage device
 		return -1;
 	}
-	// handle not found on this storage
-	return -1;
+	MtpObjectHandle parent = node->getMtpParentId();
+	Tree* tree = mtpmap[parent];
+	if (!tree) {
+		MTPE("parent tree for handle %u not found\n", parent);
+		return -1;
+	}
+	if (node->isDir()) {
+		MTPD("deleting tree from mtpmap: %u\n", handle);
+		mtpmap.erase(handle);
+	}
 
-endloop:
-	MTPD("mtpparentid: %d\n", local_mtpparentid);
-	MTPD("count: %d\n", count);
-	packet.putUInt32(count);
+	MTPD("deleting handle: %u\n", handle);
+	tree->deleteNode(handle);
+	MTPD("deleted\n");
+	return 0;
+}
 
-	if (count > 0) {
-		std::string stringValuesArray;
-		for (int i = 0; i < count; ++i) {
-			packet.putUInt32(local_mtpid);
-			packet.putUInt16(propertyCodes[i]);
-			MTPD("dataTypes: %d\n", dataTypes[i]);
-			packet.putUInt16(dataTypes[i]);
-			MTPD("propertyCode: %s\n", MtpDebug::getObjectPropCodeName(propertyCodes[i]));
-			MTPD("longValues: %d\n", longValues[i]);
-			switch (dataTypes[i]) {
-				case MTP_TYPE_INT8:
-					MTPD("MTP_TYPE_INT8\n");
-					packet.putInt8(longValues[i]);
-					break;
-				case MTP_TYPE_UINT8:
-					MTPD("MTP_TYPE_UINT8\n");
-					packet.putUInt8(longValues[i]);
-					break;
-				case MTP_TYPE_INT16:
-					MTPD("MTP_TYPE_INT16\n");
-					packet.putInt16(longValues[i]);
-					break;
-				case MTP_TYPE_UINT16:
-					MTPD("MTP_TYPE_UINT16\n");
-					packet.putUInt16(longValues[i]);
-					break;
-				case MTP_TYPE_INT32:
-					MTPD("MTP_TYPE_INT32\n");
-					packet.putInt32(longValues[i]);
-					break;
-				case MTP_TYPE_UINT32:
-					MTPD("MTP_TYPE_UINT32\n");
-					packet.putUInt32(longValues[i]);
-					break;
-				case MTP_TYPE_INT64:
-					MTPD("MTP_TYPE_INT64\n");
-					packet.putInt64(longValues[i]);
-					break;
-				case MTP_TYPE_UINT64:
-					MTPD("MTP_TYPE_UINT64\n");
-					packet.putUInt64(longValues[i]);
-					break;
-				case MTP_TYPE_INT128:
-					MTPD("MTP_TYPE_INT128\n");
-					packet.putInt128(longValues[i]);
-					break;
-				case MTP_TYPE_UINT128:
-					MTPD("MTP_TYPE_UINT128\n");
-					packet.putUInt128(longValues[i]);
-					break;
-				case MTP_TYPE_STR:
-					MTPD("MTP_TYPE_STR: %s\n", valueStrs[i].c_str());
-					packet.putString((const char*) valueStrs[i].c_str());
-					break;
-				default:
-					MTPE("bad or unsupported data type: %i in MyMtpDatabase::getObjectPropertyList", dataTypes[i]);
-					break;
+void MtpStorage::queryNodeProperties(std::vector<MtpStorage::PropEntry>& results, Node* node, uint32_t property, int groupCode, MtpStorageID storageID)
+{
+	MTPD("queryNodeProperties handle %u, path: %s\n", node->Mtpid(), getNodePath(node).c_str());
+	PropEntry pe;
+	pe.handle = node->Mtpid();
+	pe.property = property;
+
+	if (property == 0xffffffff)
+	{
+		// add all properties
+		MTPD("MtpStorage::queryNodeProperties for all properties\n");
+		std::vector<Node::mtpProperty> mtpprop = node->getMtpProps();
+		for (size_t i = 0; i < mtpprop.size(); ++i) {
+			pe.property = mtpprop[i].property;
+			pe.datatype = mtpprop[i].dataType;
+			pe.intvalue = mtpprop[i].valueInt;
+			pe.strvalue = mtpprop[i].valueStr;
+			results.push_back(pe);
+		}
+		return;
+	}
+	else if (property == 0)
+	{
+		// TODO: use groupCode
+	}
+
+	// single property
+	// TODO: this should probably be moved to the Node class and/or merged with getObjectPropertyValue
+	switch (property) {
+//		case MTP_PROPERTY_OBJECT_FORMAT:
+//			pe.datatype = MTP_TYPE_UINT16;
+//			pe.intvalue = node->getIntProperty(MTP_PROPERTY_OBJECT_FORMAT);
+//			break;
+
+		case MTP_PROPERTY_STORAGE_ID:
+			pe.datatype = MTP_TYPE_UINT32;
+			pe.intvalue = storageID;
+			break;
+
+		case MTP_PROPERTY_PROTECTION_STATUS:
+			pe.datatype = MTP_TYPE_UINT16;
+			pe.intvalue = 0;
+			break;
+
+		case MTP_PROPERTY_OBJECT_SIZE:
+		{
+			pe.datatype = MTP_TYPE_UINT64;
+			struct stat st;
+			pe.intvalue = 0;
+			if (lstat(getNodePath(node).c_str(), &st) == 0)
+				pe.intvalue = st.st_size;
+			break;
+		}
+
+		default:
+		{
+			const Node::mtpProperty& prop = node->getProperty(property);
+			if (prop.property != property)
+			{
+				MTPD("queryNodeProperties: unknown property %x\n", property);
+				return;
 			}
+			pe.datatype = prop.dataType;
+			pe.intvalue = prop.valueInt;
+			pe.strvalue = prop.valueStr;
+			// TODO: all the special case stuff in MyMtpDatabase::getObjectPropertyValue is missing here
+		}
+
+	}
+	results.push_back(pe);
+}
+
+int MtpStorage::getObjectPropertyList(MtpObjectHandle handle, uint32_t format, uint32_t property, int groupCode, int depth, MtpDataPacket& packet) {
+	MTPD("MtpStorage::getObjectPropertyList handle: %u, format: %x, property: %x\n", handle, format, property);
+	if (groupCode != 0)
+	{
+		MTPE("getObjectPropertyList: groupCode unsupported\n");
+		return -1; // TODO: RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED
+	}
+	// TODO: support all the special stuff, like:
+	// handle == 0 -> all objects at the root level
+	// handle == 0xffffffff -> all objects (on all storages? how could we support that?)
+	// format == 0 -> all formats, otherwise filter by ObjectFormatCode
+	// property == 0xffffffff -> all properties except those with group code 0xffffffff
+	// if property == 0 then use groupCode
+	//   groupCode == 0 -> return Specification_By_Group_Unsupported
+	// depth == 0xffffffff -> all objects incl. and below handle
+
+	std::vector<PropEntry> results;
+
+	if (handle == 0xffffffff) {
+		// TODO: all object on all storages (needs a different design, result packet needs to be built by server instead of storage)
+	} else if (handle == 0)	{
+		// all objects at the root level
+		Tree* root = mtpmap[0];
+		MtpObjectHandleList list;
+		root->getmtpids(&list);
+		for (MtpObjectHandleList::iterator it = list.begin(); it != list.end(); ++it) {
+			Node* node = root->findNode(*it);
+			if (!node) {
+				MTPE("BUG: node not found for root entry with handle %u\n", *it);
+				break;
+			}
+			queryNodeProperties(results, node, property, groupCode, mStorageID);
+		}
+	} else {
+		// single object
+		Node* node = findNode(handle);
+		if (!node) {
+			// Item is not on this storage device
+			return -1;
+		}
+		queryNodeProperties(results, node, property, groupCode, mStorageID);
+	}
+
+	MTPD("count: %u\n", results.size());
+	packet.putUInt32(results.size());
+
+	for (size_t i = 0; i < results.size(); ++i) {
+		PropEntry& p = results[i];
+		MTPD("handle: %u, propertyCode: %x = %s, datatype: %x, value: %llu\n",
+				p.handle, p.property, MtpDebug::getObjectPropCodeName(p.property),
+				p.datatype, p.intvalue);
+		packet.putUInt32(p.handle);
+		packet.putUInt16(p.property);
+		packet.putUInt16(p.datatype);
+		switch (p.datatype) {
+			case MTP_TYPE_INT8:
+				MTPD("MTP_TYPE_INT8\n");
+				packet.putInt8(p.intvalue);
+				break;
+			case MTP_TYPE_UINT8:
+				MTPD("MTP_TYPE_UINT8\n");
+				packet.putUInt8(p.intvalue);
+				break;
+			case MTP_TYPE_INT16:
+				MTPD("MTP_TYPE_INT16\n");
+				packet.putInt16(p.intvalue);
+				break;
+			case MTP_TYPE_UINT16:
+				MTPD("MTP_TYPE_UINT16\n");
+				packet.putUInt16(p.intvalue);
+				break;
+			case MTP_TYPE_INT32:
+				MTPD("MTP_TYPE_INT32\n");
+				packet.putInt32(p.intvalue);
+				break;
+			case MTP_TYPE_UINT32:
+				MTPD("MTP_TYPE_UINT32\n");
+				packet.putUInt32(p.intvalue);
+				break;
+			case MTP_TYPE_INT64:
+				MTPD("MTP_TYPE_INT64\n");
+				packet.putInt64(p.intvalue);
+				break;
+			case MTP_TYPE_UINT64:
+				MTPD("MTP_TYPE_UINT64\n");
+				packet.putUInt64(p.intvalue);
+				break;
+			case MTP_TYPE_INT128:
+				MTPD("MTP_TYPE_INT128\n");
+				packet.putInt128(p.intvalue);
+				break;
+			case MTP_TYPE_UINT128:
+				MTPD("MTP_TYPE_UINT128\n");
+				packet.putUInt128(p.intvalue);
+				break;
+			case MTP_TYPE_STR:
+				MTPD("MTP_TYPE_STR: %s\n", p.strvalue.c_str());
+				packet.putString(p.strvalue.c_str());
+				break;
+			default:
+				MTPE("bad or unsupported data type: %x in MyMtpDatabase::getObjectPropertyList", p.datatype);
+				break;
 		}
 	}
 	return 0;
 }
 
 int MtpStorage::renameObject(MtpObjectHandle handle, std::string newName) {
-	int index;
-	MTPD("MtpStorage::renameObject, handle: %d, new name: '%s'\n", handle, newName.c_str());
+	MTPD("MtpStorage::renameObject, handle: %u, new name: '%s'\n", handle, newName.c_str());
 	if (handle == MTP_PARENT_ROOT) {
 		MTPE("parent == MTP_PARENT_ROOT, cannot rename root\n");
 		return -1;
 	} else {
 		for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-			MTPD("root: %d\n", i->second->Root());
-			Node* node = i->second->findNode(handle, i->second->Root());
+			Node* node = i->second->findNode(handle);
 			if (node != NULL) {
-				std::string oldName = i->second->getPath(node);
+				std::string oldName = getNodePath(node);
 				std::string parentdir = oldName.substr(0, oldName.find_last_of('/'));
 				std::string newFullName = parentdir + "/" + newName;
 				MTPD("old: '%s', new: '%s'\n", oldName.c_str(), newFullName.c_str());
 				if (rename(oldName.c_str(), newFullName.c_str()) == 0) {
-					node->rename(newFullName);
+					node->rename(newName);
 					return 0;
 				} else {
-					MTPE("MtpStorage::renameObject failed, handle: %d, new name: '%s'\n", handle, newName.c_str());
+					MTPE("MtpStorage::renameObject failed, handle: %u, new name: '%s'\n", handle, newName.c_str());
 					return -1;
 				}
 			}
@@ -665,32 +535,28 @@
 	return -1;
 }
 
-void MtpStorage::createEmptyDir(const char* path) {
-	Node *node;
-	++mtpparentid;
-	MtpStorageID storage = getStorageID();
-	MTPD("MtpStorage::createEmptyDir path: '%s', storage: %i, mtpparentid: %d\n", path, storage, mtpparentid);
-	mtpmap[mtpparentid] = new Tree();
-	for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-		node = i->second->findNodePath(path, i->second->Root());
-		if (node != NULL) {
-			mtpmap[mtpparentid]->setMtpParentId(mtpparentid, node);
-		}
-	}
-}
-
-int MtpStorage::getObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, uint64_t &longValue) {
+int MtpStorage::getObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, MtpStorage::PropEntry& pe) {
 	Node *node;
 	for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
-		node = i->second->findNode(handle, i->second->Root());
+		node = i->second->findNode(handle);
 		if (node != NULL) {
-			longValue = node->getIntProperty(property);
+			const Node::mtpProperty& prop = node->getProperty(property);
+			if (prop.property != property) {
+				MTPD("getObjectPropertyValue: unknown property %x for handle %u\n", property, handle);
+				return -1;
+			}
+			pe.datatype = prop.dataType;
+			pe.intvalue = prop.valueInt;
+			pe.strvalue = prop.valueStr;
+			pe.handle = handle;
+			pe.property = property;
 			return 0;
 		}
 	}
 	// handle not found on this storage
 	return -1;
 }
+
 pthread_t MtpStorage::inotify(void) {
 	pthread_t thread;
 	ThreadPtr inotifyptr = &MtpStorage::inotify_t;
@@ -699,229 +565,227 @@
 	return thread;
 }
 
-int MtpStorage::addInotifyDirs(std::string path) {
-	struct dirent *de;
-	DIR *d;
-	struct stat st;
-	std::string inotifypath;
-
-	d = opendir(path.c_str());
-	if (d == NULL) {
-		MTPE("MtpStorage::addInotifyDirs unable to open '%s'\n", path.c_str());
-		closedir(d);
+int MtpStorage::addInotify(Tree* tree) {
+	std::string path = getNodePath(tree);
+	MTPD("adding inotify for tree %x, dir: %s\n", tree, path.c_str());
+	int wd = inotify_add_watch(inotify_fd, path.c_str(), WATCH_FLAGS);
+	if (wd < 0) {
+		MTPE("inotify_add_watch failed: %s\n", strerror(errno));
 		return -1;
 	}
-
-	while ((de = readdir(d)) != NULL) {
-		inotifypath = path + "/" + de->d_name;
-		if (lstat(inotifypath.c_str(), &st)) {
-			MTPE("Error using lstat on '%s'\n", inotifypath.c_str());
-			return -1;
-		}
-		if (!(st.st_mode & S_IFDIR) || strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
-			continue;
-		if (addInotifyDirs(inotifypath)) {
-			closedir(d);
-			return -1;
-		}
-		inotify_wd = inotify_add_watch(inotify_fd, inotifypath.c_str(), WATCH_FLAGS);
-		inotifymap[inotify_wd] = inotifypath;
-		MTPD("added inotify dir: '%s'\n", inotifypath.c_str());
-	}
-	closedir(d);
+	inotifymap[wd] = tree;
 	return 0;
 }
 
+void MtpStorage::handleInotifyEvent(struct inotify_event* event)
+{
+	std::map<int, Tree*>::iterator it = inotifymap.find(event->wd);
+	if (it == inotifymap.end()) {
+		MTPE("Unable to locate inotify_wd: %i\n", event->wd);
+		return;
+	}
+	Tree* tree = it->second;
+	MTPD("inotify_t tree: %x '%s'\n", tree, tree->getName().c_str());
+	Node* node = tree->findEntryByName(basename(event->name));
+	if (node && node->Mtpid() == handleCurrentlySending) {
+		MTPD("ignoring inotify event for currently uploading file, handle: %u\n", node->Mtpid());
+		return;
+	}
+	if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO) {
+		if (event->mask & IN_ISDIR) {
+			MTPD("inotify_t create is dir\n");
+		} else {
+			MTPD("inotify_t create is file\n");
+		}
+		if (node == NULL) {
+			node = addNewNode(event->mask & IN_ISDIR, tree, event->name);
+			std::string item = getNodePath(tree) + "/" + event->name;
+			node->addProperties(item, getStorageID());
+			mServer->sendObjectAdded(node->Mtpid());
+		} else {
+			MTPD("inotify_t item already exists.\n");
+		}
+		if (event->mask & IN_ISDIR) {
+			// TODO: do we need to do anything here? probably not until someone reads from the dir...
+		}
+	} else if (event->mask & IN_DELETE || event->mask & IN_MOVED_FROM) {
+		if (event->mask & IN_ISDIR) {
+			MTPD("inotify_t Directory %s deleted\n", event->name);
+		} else {
+			MTPD("inotify_t File %s deleted\n", event->name);
+		}
+		if (node)
+		{
+			if (event->mask & IN_ISDIR) {
+				for (std::map<int, Tree*>::iterator it = inotifymap.begin(); it != inotifymap.end(); ++it) {
+					if (it->second == node) {
+						inotify_rm_watch(inotify_fd, it->first);
+						MTPD("inotify_t removing watch on '%s'\n", getNodePath(it->second).c_str());
+						inotifymap.erase(it->first);
+						break;
+					}
+
+				}
+			}
+			MtpObjectHandle handle = node->Mtpid();
+			deleteFile(handle);
+			mServer->sendObjectRemoved(handle);
+		} else {
+			MTPD("inotify_t already removed.\n");
+		}
+	} else if (event->mask & IN_MODIFY) {
+		MTPD("inotify_t item %s modified.\n", event->name);
+		if (node != NULL) {
+			uint64_t orig_size = node->getProperty(MTP_PROPERTY_OBJECT_SIZE).valueInt;
+			struct stat st;
+			uint64_t new_size = 0;
+			if (lstat(getNodePath(node).c_str(), &st) == 0)
+				new_size = (uint64_t)st.st_size;
+			if (orig_size != new_size) {
+				MTPD("size changed from %llu to %llu on mtpid: %u\n", orig_size, new_size, node->Mtpid());
+				node->updateProperty(MTP_PROPERTY_OBJECT_SIZE, new_size, "", MTP_TYPE_UINT64);
+				mServer->sendObjectUpdated(node->Mtpid());
+			}
+		} else {
+			MTPE("inotify_t modified item not found\n");
+		}
+	} else if (event->mask & IN_DELETE_SELF || event->mask & IN_MOVE_SELF) {
+		// TODO: is this always already handled by IN_DELETE for the parent dir?
+	}
+}
+
 int MtpStorage::inotify_t(void) {
-	int len, i = 0;
-	int local_mtpparentid;
-	Node* node = NULL;
-	struct stat st;
 	#define EVENT_SIZE ( sizeof(struct inotify_event) )
 	#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16) )
 	char buf[EVENT_BUF_LEN];
-	std::string item, parent = "";
 
-	MTPD("starting inotify thread\n");
+	MTPD("inotify thread: inotify_init\n");
 	inotify_fd = inotify_init();
 
-	if (inotify_fd < 0){
-		MTPE("Can't run inotify for mtp server\n");
-	}
-
-	inotify_wd = inotify_add_watch(inotify_fd, getPath(), WATCH_FLAGS);
-	inotifymap[inotify_wd] = getPath();
-	if (addInotifyDirs(getPath())) {
-		MTPE("MtpStorage::inotify_t failed to add watches to directories\n");
-		for (std::map<int, std::string>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
-			inotify_rm_watch(inotify_fd, i->first);
-		}
-		close(inotify_fd);
+	if (inotify_fd < 0) {
+		MTPE("Can't run inotify for mtp server: %s\n", strerror(errno));
 		return -1;
 	}
 
 	while (true) {
-		i = 0;
-		len = read(inotify_fd, buf, EVENT_BUF_LEN);
+		int i = 0;
+		int len = read(inotify_fd, buf, EVENT_BUF_LEN);
 
 		if (len < 0) {
+			if (errno == EINTR)
+				continue;
 			MTPE("inotify_t Can't read inotify events\n");
 		}
 
 		while (i < len) {
-			struct inotify_event *event = ( struct inotify_event * ) &buf[ i ];
-			if ( event->len ) {
-				if (inotifymap[event->wd].empty()) {
-					MTPE("Unable to locate inotify_wd: %i\n", event->wd);
-					goto end;
-				} else {
-					item = inotifymap[event->wd];
-					item = item	+ "/" + event->name;
-					MTPD("inotify_t item: '%s'\n", item.c_str());
-					if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO) {
-						lockMutex(1);
-						if (event->mask & IN_ISDIR) {
-							MTPD("inotify_t create is dir\n");
-						} else {
-							MTPD("inotify_t create is file\n");
-						}
-						for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-							node = i->second->findNodePath(item, i->second->Root());
-							if (node != NULL)
-								break;
-						}
-						if (node == NULL) {
-							parent = item.substr(0, item.find_last_of('/'));
-							MTPD("parent: %s\n", parent.c_str());
-							if (parent == getPath()) {
-								local_mtpparentid = 1;
-							} else {
-								for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-									node = i->second->findNodePath(parent, i->second->Root());
-									MTPD("searching for node: %d\n", (int)node);
-									if (node != NULL) {
-										local_mtpparentid = i->second->getMtpParentId(node);
-										break;
-									}
-								}
-								if (node == NULL) {
-									MTPE("inotify_t unable to locate mtparentid\n");
-									goto end;
-								}
-							}
-							++mtpid;
-							MTPD("mtpid: %d\n", mtpid);
-							MTPD("mtpparentid1: %d\n", local_mtpparentid);
-							node = mtpmap[local_mtpparentid]->addNode(mtpid, item);
-							mtpmap[local_mtpparentid]->setMtpParentId(local_mtpparentid, node);
-							node->addProperties(getStorageID(), getParentObject(parent));
-							if (event->mask & IN_ISDIR) {
-								createEmptyDir(item.c_str());
-							}
-							mServer->sendObjectAdded(mtpid);
-						} else {
-							MTPD("inotify_t item already exists.\n");
-						}
-						if (event->mask & IN_ISDIR) {
-							inotify_wd = inotify_add_watch(inotify_fd, item.c_str(), WATCH_FLAGS);
-							inotifymap[inotify_wd] = item;
-							MTPD("added inotify dir: '%s'\n", item.c_str());
-							MTPD("inotify_t scanning new dir\n");
-							readParentDirs(item);
-							std::string mtpParent;
-							while (!mtpParentList.empty()) {
-								mtpParent = mtpParentList.front();
-								mtpParentList.pop_front();
-								readParentDirs(mtpParent);
-								inotify_wd = inotify_add_watch(inotify_fd, mtpParent.c_str(), WATCH_FLAGS);
-								inotifymap[inotify_wd] = mtpParent;
-								MTPD("added inotify dir: '%s'\n", mtpParent.c_str());
-							}
-						}
-					} else if (event->mask & IN_DELETE || event->mask & IN_MOVED_FROM) {
-						lockMutex(1);
-						if (event->mask & IN_ISDIR) {
-							MTPD("inotify_t Directory %s deleted\n", event->name);
-						} else {
-							MTPD("inotify_t File %s deleted\n", event->name);
-						}
-						for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-							node = i->second->findNodePath(item, i->second->Root());
-							if (node != NULL)
-								break;
-						}
-						if (node != NULL && node->Mtpid() > 0) {
-							int local_id = node->Mtpid();
-							node = NULL;
-							deleteFile(local_id);
-							mServer->sendObjectRemoved(local_id);
-						} else {
-							MTPD("inotify_t already removed.\n");
-						}
-						if (event->mask & IN_ISDIR) {
-							std::string orig_item = item + "/";
-							size_t item_size = orig_item.size();
-							std::string path_check;
-							for (std::map<int, std::string>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
-								if ((i->second.size() > item_size && i->second.substr(0, item_size) == orig_item) || i->second == item) {
-									inotify_rm_watch(inotify_fd, i->first);
-									MTPD("inotify_t removing watch on '%s'\n", i->second.c_str());
-									inotifymap.erase(i->first);
-								}
-							}
-						}
-					} else if (event->mask & IN_MODIFY) {
-						MTPD("inotify_t item %s modified.\n", event->name);
-						for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-							node = i->second->findNodePath(item, i->second->Root());
-							if (node != NULL)
-								break;
-						}
-						if (node != NULL) {
-							uint64_t orig_size = node->getIntProperty(MTP_PROPERTY_OBJECT_SIZE);
-							struct stat st;
-							uint64_t new_size = 0;
-							if (lstat(item.c_str(), &st) == 0)
-								new_size = (uint64_t)st.st_size;
-							if (orig_size != new_size) {
-								MTPD("size changed from %llu to %llu on mtpid: %i\n", orig_size, new_size, node->Mtpid());
-								node->updateProperty(MTP_PROPERTY_OBJECT_SIZE, new_size, "", MTP_TYPE_UINT64);
-								mServer->sendObjectUpdated(node->Mtpid());
-							}
-						} else {
-							MTPE("inotify_t modified item not found\n");
-						}
-					}
-				}
+			struct inotify_event *event = (struct inotify_event *) &buf[i];
+			if (event->len) {
+				MTPD("inotify event: wd: %i, mask: %x, name: %s\n", event->wd, event->mask, event->name);
+				lockMutex(1);
+				handleInotifyEvent(event);
+				unlockMutex(1);
 			}
-end:
-			unlockMutex(1);
 			i += EVENT_SIZE + event->len;
 		}
 	}
 
-	for (std::map<int, std::string>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
+	for (std::map<int, Tree*>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
 		inotify_rm_watch(inotify_fd, i->first);
 	}
 	close(inotify_fd);
 	return 0;
 }
 
-int MtpStorage::getParentObject(std::string parent_path) {
-	Node* node;
-	if (parent_path == getPath()) {
-		MTPD("MtpStorage::getParentObject for: '%s' returning: 0 for root\n", parent_path.c_str());
-		return 0;
+Node* MtpStorage::findNodeByPath(const std::string& path) {
+	MTPD("findNodeByPath: %s\n", path.c_str());
+	std::string match = path.substr(0, mtpstorageparent.size());
+	if (match != mtpstorageparent) {
+		// not on this device
+		MTPD("no match: %s is not on storage %s\n", match.c_str(), mtpstorageparent.c_str());
+		return NULL;
 	}
-	for (iter i = mtpmap.begin(); i != mtpmap.end(); ++i) {
-		node = i->second->findNodePath(parent_path, i->second->Root());
-		if (node != NULL) {
-			MTPD("MtpStorage::getParentObject for: '%s' returning: %i\n", parent_path.c_str(), node->Mtpid());
-			return node->Mtpid();
+
+	// TODO: fix and test this
+	std::string p = path.substr(mtpstorageparent.size()+1);	// cut off "/" after storage root too
+	Tree* tree = mtpmap[0]; // start at storage root
+
+	Node* node = NULL;
+	while (!p.empty()) {
+		size_t slashpos = p.find('/');
+		std::string e;
+		if (slashpos != std::string::npos) {
+			e = p;
+			p.clear();
+		} else {
+			e = p.substr(0, slashpos);
+			p = p.substr(slashpos + 1);
+		}
+		MTPD("path element: %s, rest: %s\n", e.c_str(), p.c_str());
+		node = tree->findEntryByName(e);
+		if (!node) {
+			MTPE("path element of %s not found: %s\n", path.c_str(), e.c_str());
+			return NULL;
+		}
+		if (node->isDir())
+			tree = static_cast<Tree*>(node);
+		else if (!p.empty()) {
+			MTPE("path element of %s is not a directory: %s node: %p\n", path.c_str(), e.c_str(), node);
+			return NULL;
 		}
 	}
-	MTPE("MtpStorage::getParentObject for: '%s' unable to locate node\n", parent_path.c_str());
-	return -1;
+	MTPD("findNodeByPath: found node %p, handle: %u, name: %s\n", node, node->Mtpid(), node->getName().c_str());
+	return node;
+}
+
+Node* MtpStorage::addNewNode(bool isDir, Tree* tree, const std::string& name)
+{
+	// global counter for new object handles
+	static MtpObjectHandle mtpid = 0;
+
+	++mtpid;
+	MTPD("adding new %s node for %s, new handle: %u\n", isDir ? "dir" : "file", name.c_str(), mtpid);
+	MtpObjectHandle parent = tree->Mtpid();
+	MTPD("parent tree: %x, handle: %u, name: %s\n", tree, parent, tree->getName().c_str());
+	Node* node;
+	if (isDir)
+		node = mtpmap[mtpid] = new Tree(mtpid, parent, name);
+	else
+		node = new Node(mtpid, parent, name);
+	tree->addEntry(node);
+	return node;
+}
+
+Node* MtpStorage::findNode(MtpObjectHandle handle) {
+	for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
+		Node* node = i->second->findNode(handle);
+		if (node != NULL) {
+			MTPD("findNode: found node %p for handle %u, name: %s\n", node, handle, node->getName().c_str());
+			if (node->Mtpid() != handle)
+			{
+				MTPE("BUG: entry for handle %u points to node with handle %u\n", handle, node->Mtpid());
+			}
+			return node;
+		}
+	}
+	// Item is not on this storage device
+	MTPE("MtpStorage::findNode: no node found for handle %u, searched %u trees\n", handle, mtpmap.size());
+	return NULL;
+}
+
+std::string MtpStorage::getNodePath(Node* node) {
+	std::string path;
+	MTPD("getNodePath: node %p, handle %u\n", node, node->Mtpid());
+	while (node)
+	{
+		path = "/" + node->getName() + path;
+		MtpObjectHandle parent = node->getMtpParentId();
+		if (parent == 0)	// root
+			break;
+		node = findNode(parent);
+	}
+	path = mtpstorageparent + path;
+	MTPD("getNodePath: path %s\n", path.c_str());
+	return path;
 }
 
 void MtpStorage::lockMutex(int thread_type) {
