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) {
diff --git a/mtp/MtpStorage.h b/mtp/MtpStorage.h
index ad828d1..418e3db 100755
--- a/mtp/MtpStorage.h
+++ b/mtp/MtpStorage.h
@@ -30,6 +30,7 @@
 #include "MtpServer.h"
 
 class MtpDatabase;
+struct inotify_event;
 
 class MtpStorage {
 
@@ -43,16 +44,10 @@
     uint64_t                mReserveSpace;
     bool                    mRemovable;
 	MtpServer*				mServer;
-	std::deque<std::string> mtpParentList;
-	int mtpparentid;
-    Tree *mtpdbtree;
     typedef std::map<int, Tree*> maptree;
     typedef maptree::iterator iter;
     maptree mtpmap;
 	std::string mtpstorageparent;
-	pthread_t inotify_thread;
-	int inotify_fd;
-	int inotify_wd;
 	android::Mutex           mMutex;
 
 public:
@@ -71,30 +66,50 @@
     inline const char*      getPath() const { return (const char *)mFilePath; }
     inline bool             isRemovable() const { return mRemovable; }
     inline uint64_t         getMaxFileSize() const { return mMaxFileSize; }
-	int readParentDirs(std::string path);
+
+	struct PropEntry {
+		MtpObjectHandle handle;
+		uint16_t property;
+		uint16_t datatype;
+		uint64_t intvalue;
+		std::string strvalue;
+	};
+
+	int readDir(const std::string& path, Tree* tree);
 	int createDB();
 	MtpObjectHandleList* getObjectList(MtpStorageID storageID, MtpObjectHandle parent);
 	int getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info);
-	MtpObjectHandle beginSendObject(const char* path, MtpObjectFormat format, MtpObjectHandle parent, MtpStorageID storage, uint64_t size, time_t modified);
+	MtpObjectHandle beginSendObject(const char* path, MtpObjectFormat format, MtpObjectHandle parent, uint64_t size, time_t modified);
+	void endSendObject(const char* path, MtpObjectHandle handle, MtpObjectFormat format, bool succeeded);
 	int getObjectPropertyList(MtpObjectHandle handle, uint32_t format, uint32_t property, int groupCode, int depth, MtpDataPacket& packet);
 	int getObjectFilePath(MtpObjectHandle handle, MtpString& outFilePath, int64_t& outFileLength, MtpObjectFormat& outFormat);
 	int deleteFile(MtpObjectHandle handle);
 	int renameObject(MtpObjectHandle handle, std::string newName);
-	int getObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, uint64_t &longValue);
+	int getObjectPropertyValue(MtpObjectHandle handle, MtpObjectProperty property, PropEntry& prop);
 	void lockMutex(int thread_type);
 	void unlockMutex(int thread_type);
 
 private:
-	void createEmptyDir(const char* path);
 	pthread_t inotify();
 	int inotify_t();
 	typedef int (MtpStorage::*ThreadPtr)(void);
 	typedef void* (*PThreadPtr)(void *);
-	std::map<int, std::string> inotifymap;
-	int addInotifyDirs(std::string path);
-	void deleteTrees(int parent);
+	std::map<int, Tree*> inotifymap;	// inotify wd -> tree
+	pthread_t inotify_thread;
+	int inotify_fd;
+	int addInotify(Tree* tree);
+	void handleInotifyEvent(struct inotify_event* event);
+
 	bool sendEvents;
-	int getParentObject(std::string parent_path);
+	MtpObjectHandle handleCurrentlySending;
+
+	Node* addNewNode(bool isDir, Tree* tree, const std::string& name);
+	Node* findNode(MtpObjectHandle handle);
+	Node* findNodeByPath(const std::string& path);
+	std::string getNodePath(Node* node);
+
+	void queryNodeProperties(std::vector<PropEntry>& results, Node* node, uint32_t property, int groupCode, MtpStorageID storageID);
+
 	bool use_mutex;
 	pthread_mutex_t inMutex; // inotify mutex
 	pthread_mutex_t mtpMutex; // main mtp mutex
diff --git a/mtp/btree.cpp b/mtp/btree.cpp
index 7976ac3..3a5648d 100755
--- a/mtp/btree.cpp
+++ b/mtp/btree.cpp
@@ -20,289 +20,60 @@
 #include "MtpDebug.h"
 
 // Constructor
-Tree::Tree() {
-	root = NULL;
-	count = 0;
+Tree::Tree(MtpObjectHandle handle, MtpObjectHandle parent, const std::string& name)
+	: Node(handle, parent, name), alreadyRead(false) {
 }
 
 // Destructor
 Tree::~Tree() {
-	freeNode(root);
-}
-
-// Free the node
-void Tree::freeNode(Node* leaf)
-{
-	if ( leaf != NULL )
-	{
-		freeNode(leaf->Left());
-		freeNode(leaf->Right());
-		delete leaf;
-	}
+	for (std::map<MtpObjectHandle, Node*>::iterator it = entries.begin(); it != entries.end(); ++it)
+		delete it->second;
 }
 
 int Tree::getCount(void) {
+	int count = entries.size();
 	MTPD("node count: %d\n", count);
 	return count;
 }
 
-Node* Tree::addNode(int mtpid, std::string path)
-{
-	MTPD("root: %d\n", root);
-	// No elements. Add the root
-	if ( root == NULL ) {
-		Node* n = new Node();
-		count++;
-		MTPD("node count: %d\n", count);
-		MTPD("adding node address: %d\n", n);
-		MTPD("adding mtpid: %d\n", mtpid);
-		n->setMtpid(mtpid);
-		n->setPath(path);
-		root = n;
-		MTPD("set root to %d\n", root);
-		return n;
-	}
-	else {
-		count++;
-		MTPD("node count: %d\n", count);
-		MTPD("adding new child node\n");
-		return addNode(mtpid, root, path);
-	}
-}
-
-// Add a node (private)
-Node* Tree::addNode(int mtpid, Node* leaf, std::string path) {
-	Node* n;
-	if ( mtpid <= leaf->Mtpid() )
-	{
-		if ( leaf->Left() != NULL )
-			return addNode(mtpid, leaf->Left(), path);
-		else {
-			n = new Node();
-			MTPD("adding mtpid: %d node: %d\n", mtpid, n);
-			n->setMtpid(mtpid);
-			n->setPath(path);
-			n->setParent(leaf);
-			leaf->setLeft(n);
-		}
-	}
-	else
-	{
-		if ( leaf->Right() != NULL )
-			return addNode(mtpid, leaf->Right(), path);
-		else {
-			n = new Node();
-			MTPD("adding mtpid: %d node: %d\n", mtpid, n);
-			n->setMtpid(mtpid);
-			n->setPath(path);
-			n->setParent(leaf);
-			leaf->setRight(n);
-		}
-	}
-	return n;
-}
-
-void Tree::setMtpParentId(int mtpparentid, Node* node) {
-	node->setMtpParentId(mtpparentid);
-}
-
-std::string Tree::getPath(Node* node) {
-	return node->getPath();
-}
-
-int Tree::getMtpParentId(Node* node) {
-	return node->getMtpParentId();
-}
-
-Node* Tree::findNodePath(std::string path, Node* node) {
-	Node* n;
-	if ( node == NULL ) {
-		return NULL;
-	}
-	if ( node->getPath().compare(path) == 0 && node->Mtpid() > 0) {
-		return node;
-	}
-	else {
-		n = findNodePath(path, node->Left());
-		if (n)
-			return n;
-		n = findNodePath(path, node->Right());
-		if (n)
-			return n;
-	}
-	return NULL;
-}
-
-Node* Tree::getNext(Node *node) {
-	if (node == NULL)
-		return NULL;
-	else {
-		if (node->Left() != NULL)
-			return node->Left();
-		if (node->Right() != NULL)
-			return node->Right();
-	}
-	return NULL;
-}
-
-Node* Tree::findNode(int key, Node* node) {
-	//MTPD("key: %d\n", key);
-	//MTPD("node: %d\n", node);
-	if ( node == NULL ) {
-		return NULL;
-	}
-	else if ( node->Mtpid() == key ) {
-		return node;
-	}
-	else if ( key <= node->Mtpid() ) {
-		return findNode(key, node->Left());
-	}
-	else if ( key > node->Mtpid() ) {
-		return findNode(key, node->Right());
-	}
-	else {
-		return NULL;
-	}
-	return NULL;
-}
-
-void Tree::getmtpids(Node* node, std::vector<int>* mtpids)
-{
-	if ( node )
-	{
-		MTPD("node: %d\n", node->Mtpid());
-		mtpids->push_back(node->Mtpid());
-		if (node->Left())
-			getmtpids(node->Left(), mtpids);
-		if (node->Right())
-			getmtpids(node->Right(), mtpids);
-	} else {
-		mtpids->push_back(0);
-	}
-	return;
-}
-
-// Find the node with min key
-// Traverse the left sub-tree recursively
-// till left sub-tree is empty to get min
-Node* Tree::min(Node* node)
-{
-	if ( node == NULL )
-		return NULL;
-
-	if ( node->Left() )
-		min(node->Left());
-	else
-		return node;
-	return NULL;
-}
-
-// Find the node with max key
-// Traverse the right sub-tree recursively
-// till right sub-tree is empty to get max
-Node* Tree::max(Node* node)
-{
-	if ( node == NULL )
-		return NULL;
-
-	if ( node->Right() )
-		max(node->Right());
-	else
-		return node;
-	return NULL;
-}
-
-// Find successor to a node
-// Find the node, get the node with max value
-// for the right sub-tree to get the successor
-Node* Tree::successor(int key, Node *node)
-{
-	Node* thisKey = findNode(key, node);
-	if ( thisKey )
-		return max(thisKey->Right());
-	return NULL;
-}
-
-// Find predecessor to a node
-// Find the node, get the node with max value
-// for the left sub-tree to get the predecessor
-Node* Tree::predecessor(int key, Node *node)
-{
-	Node* thisKey = findNode(key, node);
-	if ( thisKey )
-		return max(thisKey->Left());
-	return NULL;
-}
-
-void Tree::deleteNode(int key)
-{
-	// Find the node.
-	Node* thisKey = findNode(key, root);
-	MTPD("Tree::deleteNode found node: %d\n", thisKey);
-	MTPD("handle: %d\n", thisKey->Mtpid());
-
-	if (thisKey == root) {
-		if (thisKey->Right()) {
-			root = thisKey->Right();
-			root->setParent(NULL);
-			return;
-		}
-		if (thisKey->Left()) {
-			root = thisKey->Left();
-			root->setParent(NULL);
-			return;
-		}
-		root = NULL;
-		delete thisKey;
+void Tree::addEntry(Node* node) {
+	if (node->Mtpid() == 0) {
+		MTPE("Tree::addEntry: not adding node with 0 handle.\n");
 		return;
 	}
-
-	if ( thisKey->Left() == NULL && thisKey->Right() == NULL )
-	{
-		if ( thisKey->Mtpid() > thisKey->Parent()->Mtpid() ) {
-			thisKey->Parent()->setRight(NULL);
-		}
-		else {
-			thisKey->Parent()->setLeft(NULL);
-		}
-		delete thisKey;
+	if (node->Mtpid() == node->getMtpParentId()) {
+		MTPE("Tree::addEntry: not adding node with handle %u == parent.\n", node->Mtpid());
 		return;
 	}
+	entries[node->Mtpid()] = node;
+}
 
-	if ( thisKey->Left() == NULL && thisKey->Right() != NULL )
+Node* Tree::findEntryByName(std::string name) {
+	for (std::map<MtpObjectHandle, Node*>::iterator it = entries.begin(); it != entries.end(); ++it)
 	{
-		if ( thisKey->Mtpid() > thisKey->Parent()->Mtpid() )
-			thisKey->Parent()->setRight(thisKey->Right());
-		else
-			thisKey->Parent()->setLeft(thisKey->Right());
-		thisKey->Right()->setParent(thisKey->Parent());
-		delete thisKey;
-		return;
+		Node* node = it->second;
+		if (node->getName().compare(name) == 0 && node->Mtpid() > 0)
+			return node;
 	}
-	if ( thisKey->Left() != NULL && thisKey->Right() == NULL )
-	{
-		if ( thisKey->Mtpid() > thisKey->Parent()->Mtpid() )
-			thisKey->Parent()->setRight(thisKey->Left());
-		else
-			thisKey->Parent()->setLeft(thisKey->Left());
-		thisKey->Left()->setParent(thisKey->Parent());
-		delete thisKey;
-		return;
-	}
+	return NULL;
+}
 
-	if ( thisKey->Left() != NULL && thisKey->Right() != NULL )
-	{
-		Node* sub = predecessor(thisKey->Mtpid(), thisKey);
-		if ( sub == NULL )
-			sub = successor(thisKey->Mtpid(), thisKey);
+Node* Tree::findNode(MtpObjectHandle handle) {
+	std::map<MtpObjectHandle, Node*>::iterator it = entries.find(handle);	
+	if (it != entries.end())
+		return it->second;
+	return NULL;
+}
 
-		if ( sub->Parent()->Mtpid() <= sub->Mtpid() )
-			sub->Parent()->setRight(sub->Right());
-		else
-			sub->Parent()->setLeft(sub->Left());
+void Tree::getmtpids(MtpObjectHandleList* mtpids) {
+	for (std::map<MtpObjectHandle, Node*>::iterator it = entries.begin(); it != entries.end(); ++it)
+		mtpids->push_back(it->second->Mtpid());
+}
 
-		thisKey->setMtpid(sub->Mtpid());
-		delete sub;
-		return;
+void Tree::deleteNode(MtpObjectHandle handle) {
+	std::map<MtpObjectHandle, Node*>::iterator it = entries.find(handle);	
+	if (it != entries.end()) {
+		delete it->second;
+		entries.erase(it);
 	}
 }
diff --git a/mtp/btree.hpp b/mtp/btree.hpp
index 1fa8d28..b284e4f 100755
--- a/mtp/btree.hpp
+++ b/mtp/btree.hpp
@@ -17,79 +17,65 @@
 #ifndef BTREE_HPP
 #define BTREE_HPP
 
-#include <iostream>
 #include <vector>
-#include <utils/threads.h>
-#include "MtpDebug.h"
+#include <map>
+#include "MtpTypes.h"
 
-// A generic tree node class
+// A directory entry
 class Node {
-	int mtpid;
-	int mtpparentid;
-	std::string path;
-	int parentID;
-	Node* left;
-	Node* right;
-	Node* parent;
+	MtpObjectHandle handle;
+	MtpObjectHandle parent;
+	std::string name;	// name only without path
 
 public:
 	Node();
-	void setMtpid(int aMtpid);
-	void setPath(std::string aPath);
-	void rename(std::string aPath);
-	void setLeft(Node* aLeft);
-	void setRight(Node* aRight);
-	void setParent(Node* aParent);
-	void setMtpParentId(int id);
-	int Mtpid();
-	int getMtpParentId();
-	std::string getPath();
-	Node* Left();
-	Node* Right();
-	Node* Parent();
-	void addProperty(uint64_t property, uint64_t valueInt, std::string valueStr, int dataType);
-	void updateProperty(uint64_t property, uint64_t valueInt, std::string valueStr, int dataType);
-	void addProperties(int storageID, int parent_object);
-	uint64_t getIntProperty(uint64_t property);
+	Node(MtpObjectHandle handle, MtpObjectHandle parent, const std::string& name);
+	virtual ~Node() {}
+
+	virtual bool isDir() const { return false; }
+
+	void rename(const std::string& newName);
+	MtpObjectHandle Mtpid() const;
+	MtpObjectHandle getMtpParentId() const;
+	const std::string& getName() const;
+
+	void addProperty(MtpPropertyCode property, uint64_t valueInt, std::string valueStr, MtpDataType dataType);
+	void updateProperty(MtpPropertyCode property, uint64_t valueInt, std::string valueStr, MtpDataType dataType);
+	void addProperties(const std::string& path, int storageID);
+	uint64_t getIntProperty(MtpPropertyCode property);
 	struct mtpProperty {
-		uint64_t property;
+		MtpPropertyCode property;
+		MtpDataType dataType;
 		uint64_t valueInt;
 		std::string valueStr;
-		int dataType;
+		mtpProperty() : property(0), dataType(0), valueInt(0) {}
 	};
 	std::vector<mtpProperty>& getMtpProps();
 	std::vector<mtpProperty> mtpProp;
+	const mtpProperty& getProperty(MtpPropertyCode property);
 };
 
-// Binary Search Tree class
-class Tree {
-	Node* root;
+// A directory
+class Tree : public Node {
+	std::map<MtpObjectHandle, Node*> entries;
+	bool alreadyRead;
 public:
-	Tree();
+	Tree(MtpObjectHandle handle, MtpObjectHandle parent, const std::string& name);
 	~Tree();
-	Node* Root() {
-		MTPD("root: %d\n", root);
-		return root; 
-	};
-	Node* addNode(int mtpid, std::string path);
-	void setMtpParentId(int mtpparentid, Node* node);
-	Node* findNode(int key, Node* parent);
-	void getmtpids(Node* node, std::vector<int>* mtpids);
-	void deleteNode(int key);
-	Node* min(Node* node);
-	Node* max(Node* node);
-	Node* successor(int key, Node* parent);
-	Node* predecessor(int key, Node* parent);
-	std::string getPath(Node* node);
-	int getMtpParentId(Node* node);
-	Node* findNodePath(std::string path, Node* node);
-	Node* getNext(Node* node);
-	int getCount();
 
-private:
-	Node* addNode(int mtpid, Node* leaf, std::string path);
-	void freeNode(Node* leaf);
-	int count;
+	virtual bool isDir() const { return true; }
+
+	void addEntry(Node* node);
+	Node* findNode(MtpObjectHandle handle);
+	void getmtpids(MtpObjectHandleList* mtpids);
+	void deleteNode(MtpObjectHandle handle);
+	std::string getPath(Node* node);
+	int getMtpParentId() { return Node::getMtpParentId(); }
+	int getMtpParentId(Node* node);
+	Node* findEntryByName(std::string name);
+	int getCount();
+	bool wasAlreadyRead() const { return alreadyRead; }
+	void setAlreadyRead(bool b) { alreadyRead = b; }
 };
 
 #endif
diff --git a/mtp/mtp_MtpDatabase.cpp b/mtp/mtp_MtpDatabase.cpp
index b5096fe..05bb5d9 100755
--- a/mtp/mtp_MtpDatabase.cpp
+++ b/mtp/mtp_MtpDatabase.cpp
@@ -42,7 +42,7 @@
 #include "MtpUtils.h"
 #include "mtp.h"
 #include "mtp_MtpDatabase.hpp"
-#include "btree.hpp"
+//#include "btree.hpp"
 
 MyMtpDatabase::MyMtpDatabase()
 {
@@ -75,6 +75,7 @@
 	MTP_PROPERTY_PARENT_OBJECT,
 	MTP_PROPERTY_PERSISTENT_UID,
 	MTP_PROPERTY_NAME,
+	// TODO: why is DISPLAY_NAME not here?
 	MTP_PROPERTY_DATE_ADDED
 };
 
@@ -214,8 +215,9 @@
 											MtpStorageID storage,
 											uint64_t size,
 											time_t modified) {
-	MTPD("MyMtpDatabase::beginSendObject() which passes to MtpStorage.cpp\n");
-	return storagemap[storage]->beginSendObject(path, format, parent, storage, size, modified);
+	if (storagemap.find(storage) == storagemap.end())
+		return kInvalidObjectHandle;
+	return storagemap[storage]->beginSendObject(path, format, parent, size, modified);
 }
 
 void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
@@ -225,6 +227,9 @@
 		MTPE("endSendObject() failed, unlinking %s\n", path);
 		unlink(path);
 	}
+	std::map<int, MtpStorage*>::iterator storit;
+	for (storit = storagemap.begin(); storit != storagemap.end(); storit++)
+		storit->second->endSendObject(path, handle, format, succeeded);
 }
 
 void MyMtpDatabase::createDB(MtpStorage* storage, MtpStorageID storageID) {
@@ -236,8 +241,7 @@
 									MtpObjectFormat format,
 									MtpObjectHandle parent) {
 	MTPD("storageID: %d\n", storageID);
-	MtpObjectHandleList* list = new MtpObjectHandleList();
-	list = storagemap[storageID]->getObjectList(storageID, parent);
+	MtpObjectHandleList* list = storagemap[storageID]->getObjectList(storageID, parent);
 	MTPD("list: %d\n", list->size());
 	return list;
 }
@@ -245,22 +249,20 @@
 int MyMtpDatabase::getNumObjects(MtpStorageID storageID,
 									MtpObjectFormat format,
 									MtpObjectHandle parent) {
-	MTPE("MyMtpDatabase::getNumObjects not implemented, returning 0\n");
-	int result = 0;
-	//get number of objects on filesystem storage
-	return result;
+	MtpObjectHandleList* list = storagemap[storageID]->getObjectList(storageID, parent);
+	int size = list->size();
+	delete list;
+	return size;
 }
 
 MtpObjectFormatList* MyMtpDatabase::getSupportedPlaybackFormats() {
 	// This function tells the host PC which file formats the device supports
-	int* formats;
 	MtpObjectFormatList* list = new MtpObjectFormatList();
-	formats = SUPPORTED_PLAYBACK_FORMATS;
-	int length = sizeof(formats)/ sizeof(int);
+	int length = sizeof(SUPPORTED_PLAYBACK_FORMATS) / sizeof(SUPPORTED_PLAYBACK_FORMATS[0]);
 	MTPD("MyMtpDatabase::getSupportedPlaybackFormats length: %i\n", length);
 	for (int i = 0; i < length; i++) {
-		MTPD("supported playback format: %d\n", formats[i]);
-		list->push(formats[i]);
+		MTPD("supported playback format: %x\n", SUPPORTED_PLAYBACK_FORMATS[i]);
+		list->push(SUPPORTED_PLAYBACK_FORMATS[i]);
 	}
 	return list;
 }
@@ -284,25 +286,29 @@
 		case MTP_FORMAT_AAC:
 			properties = AUDIO_PROPERTIES;
 			length = sizeof(AUDIO_PROPERTIES) / sizeof(AUDIO_PROPERTIES[0]);
+			break;
 		case MTP_FORMAT_MPEG:
 		case MTP_FORMAT_3GP_CONTAINER:
 		case MTP_FORMAT_WMV:
 			properties = VIDEO_PROPERTIES;
 			length = sizeof(VIDEO_PROPERTIES) / sizeof(VIDEO_PROPERTIES[0]);
+			break;
 		case MTP_FORMAT_EXIF_JPEG:
 		case MTP_FORMAT_GIF:
 		case MTP_FORMAT_PNG:
 		case MTP_FORMAT_BMP:
 			properties = IMAGE_PROPERTIES;
 			length = sizeof(IMAGE_PROPERTIES) / sizeof(IMAGE_PROPERTIES[0]);
+			break;
 		case 0:
 			properties = ALL_PROPERTIES;
 			length = sizeof(ALL_PROPERTIES) / sizeof(ALL_PROPERTIES[0]);
+			break;
 		default:
 			properties = FILE_PROPERTIES;
 			length = sizeof(FILE_PROPERTIES) / sizeof(FILE_PROPERTIES[0]);
 	}
-	MTPD("MyMtpDatabase::getSupportedObjectProperties length is: %i, format: %x, sizeof: %i", length, format);
+	MTPD("MyMtpDatabase::getSupportedObjectProperties length is: %i, format: %x", length, format);
 	for (int i = 0; i < length; i++) {
 		MTPD("supported object property: %x\n", properties[i]);
 		list->push(properties[i]);
@@ -313,35 +319,37 @@
 MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
 	MtpDevicePropertyList* list = new MtpDevicePropertyList();
 	int length = sizeof(DEVICE_PROPERTIES) / sizeof(DEVICE_PROPERTIES[0]);
-	MTPD("MyMtpDatabase::getSupportedDeviceProperties length was: %i\n");
+	MTPD("MyMtpDatabase::getSupportedDeviceProperties length was: %i\n", length);
 	for (int i = 0; i < length; i++)
 		list->push(DEVICE_PROPERTIES[i]);
 	return list;
 }
+
 MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
 											MtpObjectProperty property,
 											MtpDataPacket& packet) {
-	MTPD("MyMtpDatabase::getObjectPropertyValue mtpid: %i, property: %x\n", handle, property);
+	MTPD("MyMtpDatabase::getObjectPropertyValue mtpid: %u, property: %x\n", handle, property);
 	int type;
 	MtpResponseCode result = MTP_RESPONSE_INVALID_OBJECT_HANDLE;
-	uint64_t longValue;
+	MtpStorage::PropEntry prop;
 	if (!getObjectPropertyInfo(property, type)) {
-		MTPE("MyMtpDatabase::setObjectPropertyValue returning MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED\n");
+		MTPE("MyMtpDatabase::getObjectPropertyValue returning MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED\n");
 		return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
 	}
 	std::map<int, MtpStorage*>::iterator storit;
 	for (storit = storagemap.begin(); storit != storagemap.end(); storit++) {
-		if (storit->second->getObjectPropertyValue(handle, property, longValue) == 0) {
+		if (storit->second->getObjectPropertyValue(handle, property, prop) == 0) {
 			result = MTP_RESPONSE_OK;
 			break;
 		}
 	}
 
 	if (result != MTP_RESPONSE_OK) {
-		MTPE("MyMtpDatabase::setObjectPropertyValue unable to locate handle: %i\n", handle);
+		MTPE("MyMtpDatabase::getObjectPropertyValue unable to locate handle: %u\n", handle);
 		return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
 	}
 
+	uint64_t longValue = prop.intvalue;
 	// special case date properties, which are strings to MTP
 	// but stored internally as a uint64
 	if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
@@ -387,7 +395,7 @@
 			packet.putInt128(longValue);
 			break;
 		case MTP_TYPE_UINT128:
-			packet.putInt128(longValue);
+			packet.putUInt128(longValue);
 			break;
 		case MTP_TYPE_STR:
 			{
@@ -401,8 +409,10 @@
 				} else {
 					packet.putEmptyString();
 				}*/
-				MTPE("STRING unsupported type in getObjectPropertyValue\n");
-				result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
+				packet.putString(prop.strvalue.c_str());
+				MTPD("MTP_TYPE_STR: %x = %s\n", prop.property, prop.strvalue.c_str());
+				//MTPE("STRING unsupported type in getObjectPropertyValue\n");
+				//result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
 				break;
 			}
 		default:
@@ -764,26 +774,21 @@
 	switch (property) {
 		case MTP_PROPERTY_OBJECT_FORMAT:
 			// use format as default value
-			MTPD("MyMtpDatabase::getObjectPropertyDesc format\n");
 			result = new MtpProperty(property, MTP_TYPE_UINT16, false, format);
 			break;
 		case MTP_PROPERTY_PROTECTION_STATUS:
 		case MTP_PROPERTY_TRACK:
-			MTPD("MyMtpDatabase::getObjectPropertyDesc track\n");
 			result = new MtpProperty(property, MTP_TYPE_UINT16);
 			break;
 		case MTP_PROPERTY_STORAGE_ID:
 		case MTP_PROPERTY_PARENT_OBJECT:
 		case MTP_PROPERTY_DURATION:
-			MTPD("MyMtpDatabase::getObjectPropertyDesc duration\n");
 			result = new MtpProperty(property, MTP_TYPE_UINT32);
 			break;
 		case MTP_PROPERTY_OBJECT_SIZE:
-			MTPD("MyMtpDatabase::getObjectPropertyDesc size\n");
 			result = new MtpProperty(property, MTP_TYPE_UINT64);
 			break;
 		case MTP_PROPERTY_PERSISTENT_UID:
-			MTPD("MyMtpDatabase::getObjectPropertyDesc persistent uid\n");
 			result = new MtpProperty(property, MTP_TYPE_UINT128);
 			break;
 		case MTP_PROPERTY_NAME:
@@ -794,18 +799,15 @@
 		case MTP_PROPERTY_GENRE:
 		case MTP_PROPERTY_COMPOSER:
 		case MTP_PROPERTY_DESCRIPTION:
-			MTPD("MyMtpDatabase::getObjectPropertyDesc description\n");
 			result = new MtpProperty(property, MTP_TYPE_STR);
 			break;
 		case MTP_PROPERTY_DATE_MODIFIED:
 		case MTP_PROPERTY_DATE_ADDED:
 		case MTP_PROPERTY_ORIGINAL_RELEASE_DATE:
-			MTPD("MyMtpDatabase::getObjectPropertyDesc date\n");
 			result = new MtpProperty(property, MTP_TYPE_STR);
 			result->setFormDateTime();
 			break;
 		case MTP_PROPERTY_OBJECT_FILE_NAME:
-			MTPD("MyMtpDatabase::getObjectPropertyDesc file name\n");
 			// We allow renaming files and folders
 			result = new MtpProperty(property, MTP_TYPE_STR, true);
 			break;
@@ -816,26 +818,19 @@
 MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
 	MtpProperty* result = NULL;
 	int ret;
-	bool writable = true;
+	bool writable = false;
 	switch (property) {
 		case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
 		case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
-			ret = MTP_RESPONSE_OK;
+			writable = true;
 			// fall through
 		case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
 			result = new MtpProperty(property, MTP_TYPE_STR, writable);
-			ret = MTP_RESPONSE_OK;
 
 			// get current value
-			if (ret == MTP_RESPONSE_OK) {
-				result->setCurrentValue('\0');
-				result->setDefaultValue('\0');
-			} else {
-				MTPE("unable to read device property, response: %04X", ret);
-			}
-			break;
-		default:
-			ret = MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+			// TODO: add actual values
+			result->setCurrentValue('\0');
+			result->setDefaultValue('\0');
 			break;
 		}
 
@@ -854,26 +849,6 @@
 
 // ----------------------------------------------------------------------------
 
-static void
-android_mtp_MtpDatabase_setup()
-{
-	MyMtpDatabase* database = new MyMtpDatabase();
-}
-
-static void
-android_mtp_MtpDatabase_finalize()
-{
-	return;
-}
-
-static std::string
-android_mtp_MtpPropertyGroup_format_date_time(long seconds)
-{
-	char date[20];
-	formatDateTime(seconds, date, sizeof(date));
-	return date;
-}
-
 void MyMtpDatabase::lockMutex(void) {
 	std::map<int, MtpStorage*>::iterator storit;
 	for (storit = storagemap.begin(); storit != storagemap.end(); storit++) {
diff --git a/mtp/node.cpp b/mtp/node.cpp
index 17047ce..1bca1d9 100755
--- a/mtp/node.cpp
+++ b/mtp/node.cpp
@@ -33,38 +33,28 @@
 #include "MtpDebug.h"
 
 
-Node::Node() {
-	mtpid= -1;
-	path = "";
-	left = NULL;
-	right = NULL;
-	parent = NULL;
-	mtpparentid = 0;
+Node::Node()
+	: handle(-1), parent(0), name("")
+{
 }
 
-void Node::setMtpid(int aMtpid) { mtpid = aMtpid; }
-void Node::setPath(std::string aPath) { path = aPath; }
-void Node::rename(std::string aPath) {
-	path = aPath;
-	updateProperty(MTP_PROPERTY_OBJECT_FILE_NAME, 0, basename(aPath.c_str()), MTP_TYPE_STR);
-	updateProperty(MTP_PROPERTY_NAME, 0, basename(aPath.c_str()), MTP_TYPE_STR);
-	updateProperty(MTP_PROPERTY_DISPLAY_NAME, 0, basename(aPath.c_str()), MTP_TYPE_STR);
+Node::Node(MtpObjectHandle handle, MtpObjectHandle parent, const std::string& name)
+	: handle(handle), parent(parent), name(name)
+{
 }
-void Node::setLeft(Node* aLeft) { left = aLeft; }
-void Node::setRight(Node* aRight) { right = aRight; }
-void Node::setParent(Node* aParent) { parent = aParent; }
-void Node::setMtpParentId(int id) {
-	mtpparentid = id;
-	MTPD("setting mtpparentid: %i on mtpid: %i\n", mtpparentid, mtpid);
-}
-int Node::Mtpid() { return mtpid; }
-int Node::getMtpParentId() { return mtpparentid; }
-std::string Node::getPath() { return path; }
-Node* Node::Left() { return left; }
-Node* Node::Right() { return right; }
-Node* Node::Parent() { return parent; }
 
-uint64_t Node::getIntProperty(uint64_t property) {
+void Node::rename(const std::string& newName) {
+	name = newName;
+	updateProperty(MTP_PROPERTY_OBJECT_FILE_NAME, 0, name.c_str(), MTP_TYPE_STR);
+	updateProperty(MTP_PROPERTY_NAME, 0, name.c_str(), MTP_TYPE_STR);
+	updateProperty(MTP_PROPERTY_DISPLAY_NAME, 0, name.c_str(), MTP_TYPE_STR);
+}
+
+MtpObjectHandle Node::Mtpid() const { return handle; }
+MtpObjectHandle Node::getMtpParentId() const { return parent; }
+const std::string& Node::getName() const { return name; }
+
+uint64_t Node::getIntProperty(MtpPropertyCode property) {
 	for (unsigned index = 0; index < mtpProp.size(); ++index) {
 		if (mtpProp[index].property == property)
 			return mtpProp[index].valueInt;
@@ -73,8 +63,18 @@
 	return -1;
 }
 
-void Node::addProperty(uint64_t property, uint64_t valueInt, std::string valueStr, int dataType) {
-	MTPD("adding str property: %lld, valueInt: %lld, valueStr: %s, dataType: %d\n", property, valueInt, valueStr.c_str(), dataType);
+const Node::mtpProperty& Node::getProperty(MtpPropertyCode property) {
+	static const mtpProperty dummyProp;
+	for (size_t i = 0; i < mtpProp.size(); ++i) {
+		if (mtpProp[i].property == property)
+			return mtpProp[i];
+	}
+	MTPE("Node::getProperty failed to find property %x, returning dummy property\n", (unsigned)property);
+	return dummyProp;
+}
+
+void Node::addProperty(MtpPropertyCode property, uint64_t valueInt, std::string valueStr, MtpDataType dataType) {
+//	MTPD("adding property: %lld, valueInt: %lld, valueStr: %s, dataType: %d\n", property, valueInt, valueStr.c_str(), dataType);
 	struct mtpProperty prop;
 	prop.property = property;
 	prop.valueInt = valueInt;
@@ -83,7 +83,7 @@
 	mtpProp.push_back(prop);
 }
 
-void Node::updateProperty(uint64_t property, uint64_t valueInt, std::string valueStr, int dataType) {
+void Node::updateProperty(MtpPropertyCode property, uint64_t valueInt, std::string valueStr, MtpDataType dataType) {
 	for (unsigned i = 0; i < mtpProp.size(); i++) {
 		if (mtpProp[i].property == property) {
 			mtpProp[i].valueInt = valueInt;
@@ -99,43 +99,45 @@
 	return mtpProp;
 }
 
-void Node::addProperties(int storageID, int parent_object) {
+void Node::addProperties(const std::string& path, int storageID) {
+	MTPD("addProperties: handle: %u, filename: '%s'\n", handle, getName().c_str());
 	struct stat st;
 	int mFormat = 0;
 	uint64_t puid;
 	off_t file_size = 0;
-	std::string mtimeStr = "00101T000000";
 
-	std::string mtpidStr = static_cast<std::ostringstream*>( &(std::ostringstream() << mtpid) )->str();
+	std::string mtpidStr = static_cast<std::ostringstream*>( &(std::ostringstream() << handle) )->str();
 	std::string storageIDStr = static_cast<std::ostringstream*>( &(std::ostringstream() << storageID) )->str();
 	std::string puidStr = storageIDStr + mtpidStr;
 	if ( ! (std::istringstream(puidStr) >> puid) ) puid = 0;
 	mFormat = MTP_FORMAT_UNDEFINED;   // file
-	if (lstat(getPath().c_str(), &st) == 0) {
+	if (lstat(path.c_str(), &st) == 0) {
 		file_size = st.st_size;
 		if (S_ISDIR(st.st_mode))
 			mFormat = MTP_FORMAT_ASSOCIATION; // folder
-		mtimeStr = static_cast<std::ostringstream*>( &(std::ostringstream() << st.st_mtime) )->str();
 	}
 
+	// TODO: don't store properties with constant values at all, add them at query time instead
 	addProperty(MTP_PROPERTY_STORAGE_ID, storageID, "", MTP_TYPE_UINT32);
 	addProperty(MTP_PROPERTY_OBJECT_FORMAT, mFormat, "", MTP_TYPE_UINT16);
 	addProperty(MTP_PROPERTY_PROTECTION_STATUS, 0, "", MTP_TYPE_UINT16);
 	addProperty(MTP_PROPERTY_OBJECT_SIZE, file_size, "", MTP_TYPE_UINT64);
-	addProperty(MTP_PROPERTY_OBJECT_FILE_NAME, 0, basename(getPath().c_str()), MTP_TYPE_STR);
-	MTPD("mtpid: %i, filename: '%s', parent object: %i\n", mtpid, basename(getPath().c_str()), parent_object);
-	addProperty(MTP_PROPERTY_DATE_MODIFIED, 0, mtimeStr, MTP_TYPE_STR);
-	addProperty(MTP_PROPERTY_PARENT_OBJECT, parent_object, "", MTP_TYPE_UINT32);
+	addProperty(MTP_PROPERTY_OBJECT_FILE_NAME, 0, getName().c_str(), MTP_TYPE_STR);
+	addProperty(MTP_PROPERTY_DATE_MODIFIED, st.st_mtime, "", MTP_TYPE_UINT64);
+	addProperty(MTP_PROPERTY_PARENT_OBJECT, parent, "", MTP_TYPE_UINT32);
 	addProperty(MTP_PROPERTY_PERSISTENT_UID, puid, "", MTP_TYPE_UINT128);
-	addProperty(MTP_PROPERTY_NAME, 0, basename(getPath().c_str()), MTP_TYPE_STR);
-	addProperty(MTP_PROPERTY_DISPLAY_NAME, 0, basename(getPath().c_str()), MTP_TYPE_STR);
-	addProperty(MTP_PROPERTY_DATE_ADDED, 0, mtimeStr, MTP_TYPE_STR);
+		// TODO: we can't really support persistent UIDs without a persistent DB.
+		// probably a combination of volume UUID + st_ino would come close.
+		// doesn't help for fs with no native inodes numbers like fat though...
+	addProperty(MTP_PROPERTY_NAME, 0, getName().c_str(), MTP_TYPE_STR);
+	addProperty(MTP_PROPERTY_DISPLAY_NAME, 0, getName().c_str(), MTP_TYPE_STR);
+	addProperty(MTP_PROPERTY_DATE_ADDED, st.st_mtime, "", MTP_TYPE_UINT64);
 	addProperty(MTP_PROPERTY_DESCRIPTION, 0, "", MTP_TYPE_STR);
 	addProperty(MTP_PROPERTY_ARTIST, 0, "", MTP_TYPE_STR);
 	addProperty(MTP_PROPERTY_ALBUM_NAME, 0, "", MTP_TYPE_STR);
 	addProperty(MTP_PROPERTY_ALBUM_ARTIST, 0, "", MTP_TYPE_STR);
 	addProperty(MTP_PROPERTY_TRACK, 0, "", MTP_TYPE_UINT16);
-	addProperty(MTP_PROPERTY_ORIGINAL_RELEASE_DATE, 0, "00101T000000", MTP_TYPE_STR);
+	addProperty(MTP_PROPERTY_ORIGINAL_RELEASE_DATE, 2014, "", MTP_TYPE_UINT64);	// TODO: extract year from st.st_mtime?
 	addProperty(MTP_PROPERTY_DURATION, 0, "", MTP_TYPE_UINT32);
 	addProperty(MTP_PROPERTY_GENRE, 0, "", MTP_TYPE_STR);
 	addProperty(MTP_PROPERTY_COMPOSER, 0, "", MTP_TYPE_STR);
