diff --git a/mtp/MtpStorage.cpp b/mtp/MtpStorage.cpp
new file mode 100755
index 0000000..e20dab4
--- /dev/null
+++ b/mtp/MtpStorage.cpp
@@ -0,0 +1,941 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *	  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++
+ */
+
+#include "MtpDebug.h"
+#include "MtpStorage.h"
+#include "MtpDataPacket.h"
+#include "MtpServer.h"
+#include "MtpEventPacket.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <limits.h>
+#include <pthread.h>
+#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)
+	:	mStorageID(id),
+		mFilePath(filePath),
+		mDescription(description),
+		mMaxCapacity(0),
+		mMaxFileSize(maxFileSize),
+		mReserveSpace(reserveSpace),
+		mRemovable(removable),
+		mServer(refserver)
+{
+	MTPI("MtpStorage id: %d path: %s\n", id, filePath);
+	mtpparentid = 0;
+	inotify_thread = 0;
+	sendEvents = false;
+	use_mutex = true;
+	if (pthread_mutex_init(&mtpMutex, NULL) != 0) {
+		MTPE("Failed to init mtpMutex\n");
+		use_mutex = false;
+	}
+	if (pthread_mutex_init(&inMutex, NULL) != 0) {
+		MTPE("Failed to init inMutex\n");
+		use_mutex = false;
+	}
+	
+}
+
+MtpStorage::~MtpStorage() {
+	if (inotify_thread) {
+		pthread_kill(inotify_thread, 0);
+		for (std::map<int, std::string>::iterator i = inotifymap.begin(); i != inotifymap.end(); i++) {
+			inotify_rm_watch(inotify_fd, i->first);
+		}
+		close(inotify_fd);
+	}
+	for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
+		delete i->second;
+	}
+	if (use_mutex) {
+		use_mutex = false;
+		pthread_mutex_destroy(&mtpMutex);
+		pthread_mutex_destroy(&inMutex);
+	}
+}
+
+int MtpStorage::getType() const {
+	return (mRemovable ? MTP_STORAGE_REMOVABLE_RAM :  MTP_STORAGE_FIXED_RAM);
+}
+
+int MtpStorage::getFileSystemType() const {
+	return MTP_STORAGE_FILESYSTEM_HIERARCHICAL;
+}
+
+int MtpStorage::getAccessCapability() const {
+	return MTP_STORAGE_READ_WRITE;
+}
+
+uint64_t MtpStorage::getMaxCapacity() {
+	if (mMaxCapacity == 0) {
+		struct statfs   stat;
+		if (statfs(getPath(), &stat))
+			return -1;
+		mMaxCapacity = (uint64_t)stat.f_blocks * (uint64_t)stat.f_bsize;
+	}
+	return mMaxCapacity;
+}
+
+uint64_t MtpStorage::getFreeSpace() {
+	struct statfs   stat;
+	if (statfs(getPath(), &stat))
+		return -1;
+	uint64_t freeSpace = (uint64_t)stat.f_bavail * (uint64_t)stat.f_bsize;
+	return (freeSpace > mReserveSpace ? freeSpace - mReserveSpace : 0);
+}
+
+const char* MtpStorage::getDescription() const {
+	return (const char *)mDescription;
+}
+
+int MtpStorage::createDB() {
+	std::string mtpParent = "";
+	mtpstorageparent = getPath();
+	readParentDirs(getPath());
+	while (!mtpParentList.empty()) {
+		mtpParent = mtpParentList.front();
+		mtpParentList.pop_front();
+		readParentDirs(mtpParent);
+	}
+	MTPD("MtpStorage::createDB DONE\n");
+	if (use_mutex) {
+		MTPD("Starting inotify thread\n");
+		sendEvents = true;
+		inotify_thread = inotify();
+	} else {
+		MTPD("NOT starting inotify thread\n");
+	}
+	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);
+	//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;
+	}
+	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");
+		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));
+	}
+	return list;
+}
+
+int MtpStorage::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) {
+	struct stat st;
+	uint64_t size;
+	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);
+				lstat(node->getPath().c_str(), &st);
+				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;
+		}
+	}
+	MTPE("MtpStorage::getObjectInfo no object found, error!\n");
+	return -1;
+}
+
+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;
+			}
+		}
+	}
+	MTPE("MtpStorage::beginSendObject(), path: '%s', parent: %d, storage: %d, format: %04x\n", path, parent, storage, format);
+	return -1;
+}
+
+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) {
+			lstat(node->getPath().c_str(), &st);
+			outFileLength = st.st_size;
+			outFilePath = strdup(node->getPath().c_str());
+			MTPD("outFilePath: %s\n", node->getPath().c_str());
+			goto end;
+		}
+	}
+	MTPE("MtpStorage::getObjectFilePath fauled to find handle: %i\n", handle);
+	return -1;
+end:
+	outFormat = MTP_FORMAT_ASSOCIATION;
+	return 0;
+}
+
+int MtpStorage::readParentDirs(std::string path) {
+	struct dirent *de;
+	struct stat st;
+	DIR *d;
+	std::string parent, item, prevparent = "";
+	Node* node;
+	int storageID = getStorageID();
+
+	d = opendir(path.c_str());
+	MTPD("opening '%s'\n", path.c_str());
+	if (d == NULL) {
+		MTPD("error opening '%s' -- error: %s\n", path.c_str(), strerror(errno));
+		closedir(d);
+	}
+	while ((de = readdir(d)) != NULL) {
+		if (de->d_type == DT_DIR && strcmp(de->d_name, ".") == 0)
+			continue;
+		if (de->d_type == DT_DIR && strcmp(de->d_name, "..") != 0) {
+			// Handle dirs
+			item = path + "/" + de->d_name;
+			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;
+				}
+			}
+		}
+	}
+	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;
+		}
+	}
+	MTPE("MtpStorage::deleteFile deleting handle: %d FAILED\n", handle);
+	return -1;
+end:
+	if (local_parent_id) {
+		deleteTrees(local_parent_id);
+	}
+	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");
+		MTPD("mtpmap count: %d\n", mtpmap.size());
+		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;
+				lstat(node->getPath().c_str(), &st);
+				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 {
+		MTPE("MtpStorage::getObjectPropertyList unsupported property %x\n", property);
+		return -1;
+	}
+
+endloop:
+	MTPD("mtpparentid: %d\n", local_mtpparentid);
+	MTPD("count: %d\n", count);
+	packet.putUInt32(count);
+
+	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;
+			}
+		}
+	}
+	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());
+	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());
+			if (node != NULL) {
+				std::string oldName = i->second->getPath(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->setPath(newFullName);
+					return 0;
+				} else {
+					MTPE("MtpStorage::renameObject failed, handle: %d, new name: '%s'\n", handle, newName.c_str());
+					return -1;
+				}
+			}
+		}
+	}
+	MTPE("MtpStorage::renameObject handle / node not found, error!\n");
+	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) {
+	Node *node;
+	for (iter i = mtpmap.begin(); i != mtpmap.end(); i++) {
+		node = i->second->findNode(handle, i->second->Root());
+		if (node != NULL) {
+			longValue = node->getIntProperty(property);
+			return 0;
+		}
+	}
+	MTPE("MtpStorage::getObjectPropertyValue unable to locate handle: %i\n", handle);
+	return -1;
+}
+pthread_t MtpStorage::inotify(void) {
+	pthread_t thread;
+	ThreadPtr inotifyptr = &MtpStorage::inotify_t;
+	PThreadPtr p = *(PThreadPtr*)&inotifyptr;
+	pthread_create(&thread, NULL, p, this);
+	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);
+		return -1;
+	}
+
+	while ((de = readdir(d)) != NULL) {
+		if (de->d_type != DT_DIR || strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
+			continue;
+		inotifypath = path + "/" + de->d_name;
+		if (addInotifyDirs(inotifypath)) {
+			closedir(d);
+			return -1;
+		}
+		inotify_wd = inotify_add_watch(inotify_fd, inotifypath.c_str(), IN_CREATE | IN_DELETE);
+		inotifymap[inotify_wd] = inotifypath;
+		MTPD("added inotify dir: '%s'\n", inotifypath.c_str());
+	}
+	closedir(d);
+	return 0;
+}
+
+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");
+	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);
+		return -1;
+	}
+
+	while (true) {
+		i = 0;
+		len = read(inotify_fd, buf, EVENT_BUF_LEN);
+
+		if (len < 0) {
+			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;
+							lstat(item.c_str(), &st);
+							uint64_t 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");
+						}
+					}
+				}
+			}
+end:
+			unlockMutex(1);
+			i += EVENT_SIZE + event->len;
+		}
+	}
+
+	for (std::map<int, std::string>::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;
+	}
+	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();
+		}
+	}
+	MTPE("MtpStorage::getParentObject for: '%s' unable to locate node\n", parent_path.c_str());
+	return -1;
+}
+
+void MtpStorage::lockMutex(int thread_type) {
+	if (!use_mutex)
+		return; // mutex is disabled
+	if (thread_type) {
+		// inotify thread
+		pthread_mutex_lock(&inMutex);
+		while (pthread_mutex_trylock(&mtpMutex)) {
+			pthread_mutex_unlock(&inMutex);
+			usleep(32000);
+			pthread_mutex_lock(&inMutex);
+		}
+	} else {
+		// main mtp thread
+		pthread_mutex_lock(&mtpMutex);
+		while (pthread_mutex_trylock(&inMutex)) {
+			pthread_mutex_unlock(&mtpMutex);
+			usleep(13000);
+			pthread_mutex_lock(&mtpMutex);
+		}
+	}
+}
+
+void MtpStorage::unlockMutex(int thread_type) {
+	if (!use_mutex)
+		return; // mutex is disabled
+	pthread_mutex_unlock(&inMutex);
+	pthread_mutex_unlock(&mtpMutex);
+}
