diff --git a/mtp/mtp_MtpDatabase.cpp b/mtp/mtp_MtpDatabase.cpp
new file mode 100755
index 0000000..60a871c
--- /dev/null
+++ b/mtp/mtp_MtpDatabase.cpp
@@ -0,0 +1,884 @@
+/*
+ * 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 <utils/Log.h>
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string>
+#include <map>
+#include <libgen.h>
+#include <cutils/properties.h>
+
+#include "MtpDatabase.h"
+#include "MtpStorage.h"
+#include "MtpDataPacket.h"
+#include "MtpObjectInfo.h"
+#include "MtpProperty.h"
+#include "MtpDebug.h"
+#include "MtpStringBuffer.h"
+#include "MtpUtils.h"
+#include "mtp.h"
+#include "mtp_MtpDatabase.hpp"
+#include "btree.hpp"
+
+MyMtpDatabase::MyMtpDatabase()
+{
+	storagenum = 0;
+	count = -1;
+}
+
+MyMtpDatabase::~MyMtpDatabase() {
+	std::map<int, MtpStorage*>::iterator i;
+	for (i = storagemap.begin(); i != storagemap.end(); i++) {
+		delete i->second;
+	}
+}
+
+int MyMtpDatabase::FILE_PROPERTIES[10] = {
+	// NOTE must match beginning of AUDIO_PROPERTIES, VIDEO_PROPERTIES
+	// and IMAGE_PROPERTIES below
+	MTP_PROPERTY_STORAGE_ID,
+	MTP_PROPERTY_OBJECT_FORMAT,
+	MTP_PROPERTY_PROTECTION_STATUS,
+	MTP_PROPERTY_OBJECT_SIZE,
+	MTP_PROPERTY_OBJECT_FILE_NAME,
+	MTP_PROPERTY_DATE_MODIFIED,
+	MTP_PROPERTY_PARENT_OBJECT,
+	MTP_PROPERTY_PERSISTENT_UID,
+	MTP_PROPERTY_NAME,
+	MTP_PROPERTY_DATE_ADDED
+};
+int MyMtpDatabase::AUDIO_PROPERTIES[19] = {
+	// NOTE must match FILE_PROPERTIES above
+	MTP_PROPERTY_STORAGE_ID,
+	MTP_PROPERTY_OBJECT_FORMAT,
+	MTP_PROPERTY_PROTECTION_STATUS,
+	MTP_PROPERTY_OBJECT_SIZE,
+	MTP_PROPERTY_OBJECT_FILE_NAME,
+	MTP_PROPERTY_DATE_MODIFIED,
+	MTP_PROPERTY_PARENT_OBJECT,
+	MTP_PROPERTY_PERSISTENT_UID,
+	MTP_PROPERTY_NAME,
+	MTP_PROPERTY_DISPLAY_NAME,
+	MTP_PROPERTY_DATE_ADDED,
+
+	// audio specific properties
+	MTP_PROPERTY_ARTIST,
+	MTP_PROPERTY_ALBUM_NAME,
+	MTP_PROPERTY_ALBUM_ARTIST,
+	MTP_PROPERTY_TRACK,
+	MTP_PROPERTY_ORIGINAL_RELEASE_DATE,
+	MTP_PROPERTY_DURATION,
+	MTP_PROPERTY_GENRE,
+	MTP_PROPERTY_COMPOSER
+};
+
+int MyMtpDatabase::VIDEO_PROPERTIES[15] = {
+	// NOTE must match FILE_PROPERTIES above
+	MTP_PROPERTY_STORAGE_ID,
+	MTP_PROPERTY_OBJECT_FORMAT,
+	MTP_PROPERTY_PROTECTION_STATUS,
+	MTP_PROPERTY_OBJECT_SIZE,
+	MTP_PROPERTY_OBJECT_FILE_NAME,
+	MTP_PROPERTY_DATE_MODIFIED,
+	MTP_PROPERTY_PARENT_OBJECT,
+	MTP_PROPERTY_PERSISTENT_UID,
+	MTP_PROPERTY_NAME,
+	MTP_PROPERTY_DISPLAY_NAME,
+	MTP_PROPERTY_DATE_ADDED,
+
+	// video specific properties
+	MTP_PROPERTY_ARTIST,
+	MTP_PROPERTY_ALBUM_NAME,
+	MTP_PROPERTY_DURATION,
+	MTP_PROPERTY_DESCRIPTION
+};
+
+int MyMtpDatabase::IMAGE_PROPERTIES[12] = {
+	// NOTE must match FILE_PROPERTIES above
+	MTP_PROPERTY_STORAGE_ID,
+	MTP_PROPERTY_OBJECT_FORMAT,
+	MTP_PROPERTY_PROTECTION_STATUS,
+	MTP_PROPERTY_OBJECT_SIZE,
+	MTP_PROPERTY_OBJECT_FILE_NAME,
+	MTP_PROPERTY_DATE_MODIFIED,
+	MTP_PROPERTY_PARENT_OBJECT,
+	MTP_PROPERTY_PERSISTENT_UID,
+	MTP_PROPERTY_NAME,
+	MTP_PROPERTY_DISPLAY_NAME,
+	MTP_PROPERTY_DATE_ADDED,
+
+	// image specific properties
+	MTP_PROPERTY_DESCRIPTION
+};
+
+int MyMtpDatabase::ALL_PROPERTIES[25] = {
+	// NOTE must match FILE_PROPERTIES above
+	MTP_PROPERTY_STORAGE_ID,
+	MTP_PROPERTY_OBJECT_FORMAT,
+	MTP_PROPERTY_PROTECTION_STATUS,
+	MTP_PROPERTY_OBJECT_SIZE,
+	MTP_PROPERTY_OBJECT_FILE_NAME,
+	MTP_PROPERTY_DATE_MODIFIED,
+	MTP_PROPERTY_PARENT_OBJECT,
+	MTP_PROPERTY_PERSISTENT_UID,
+	MTP_PROPERTY_NAME,
+	MTP_PROPERTY_DISPLAY_NAME,
+	MTP_PROPERTY_DATE_ADDED,
+
+	// image specific properties
+	MTP_PROPERTY_DESCRIPTION,
+
+	// audio specific properties
+	MTP_PROPERTY_ARTIST,
+	MTP_PROPERTY_ALBUM_NAME,
+	MTP_PROPERTY_ALBUM_ARTIST,
+	MTP_PROPERTY_TRACK,
+	MTP_PROPERTY_ORIGINAL_RELEASE_DATE,
+	MTP_PROPERTY_DURATION,
+	MTP_PROPERTY_GENRE,
+	MTP_PROPERTY_COMPOSER,
+
+	// video specific properties
+	MTP_PROPERTY_ARTIST,
+	MTP_PROPERTY_ALBUM_NAME,
+	MTP_PROPERTY_DURATION,
+	MTP_PROPERTY_DESCRIPTION,
+
+	// image specific properties
+	MTP_PROPERTY_DESCRIPTION
+};
+
+int MyMtpDatabase::SUPPORTED_PLAYBACK_FORMATS[26] = {
+	SUPPORTED_PLAYBACK_FORMAT_UNDEFINED,
+	SUPPORTED_PLAYBACK_FORMAT_ASSOCIATION,
+	SUPPORTED_PLAYBACK_FORMAT_TEXT,
+	SUPPORTED_PLAYBACK_FORMAT_HTML,
+	SUPPORTED_PLAYBACK_FORMAT_WAV,
+	SUPPORTED_PLAYBACK_FORMAT_MP3,
+	SUPPORTED_PLAYBACK_FORMAT_MPEG,
+	SUPPORTED_PLAYBACK_FORMAT_EXIF_JPEG,
+	SUPPORTED_PLAYBACK_FORMAT_TIFF_EP,
+	SUPPORTED_PLAYBACK_FORMAT_BMP,
+	SUPPORTED_PLAYBACK_FORMAT_GIF,
+	SUPPORTED_PLAYBACK_FORMAT_JFIF,
+	SUPPORTED_PLAYBACK_FORMAT_PNG,
+	SUPPORTED_PLAYBACK_FORMAT_TIFF,
+	SUPPORTED_PLAYBACK_FORMAT_WMA,
+	SUPPORTED_PLAYBACK_FORMAT_OGG,
+	SUPPORTED_PLAYBACK_FORMAT_AAC,
+	SUPPORTED_PLAYBACK_FORMAT_MP4_CONTAINER,
+	SUPPORTED_PLAYBACK_FORMAT_MP2,
+	SUPPORTED_PLAYBACK_FORMAT_3GP_CONTAINER,
+	SUPPORTED_PLAYBACK_FORMAT_ABSTRACT_AV_PLAYLIST,
+	SUPPORTED_PLAYBACK_FORMAT_WPL_PLAYLIST,
+	SUPPORTED_PLAYBACK_FORMAT_M3U_PLAYLIST,
+	SUPPORTED_PLAYBACK_FORMAT_PLS_PLAYLIST,
+	SUPPORTED_PLAYBACK_FORMAT_XML_DOCUMENT,
+	SUPPORTED_PLAYBACK_FORMAT_FLAC
+};
+
+MtpObjectHandle MyMtpDatabase::beginSendObject(const char* path,
+											MtpObjectFormat format,
+											MtpObjectHandle parent,
+											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);
+}
+
+void MyMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle,
+								MtpObjectFormat format, bool succeeded) {
+	MTPD("endSendObject() %s\n", path);
+	if (!succeeded) {
+		MTPE("endSendObject() failed, unlinking %s\n", path);
+		unlink(path);
+	}
+}
+
+void MyMtpDatabase::createDB(MtpStorage* storage, MtpStorageID storageID) {
+	storagemap[storageID] = storage;
+	storage->createDB();
+}
+
+MtpObjectHandleList* MyMtpDatabase::getObjectList(MtpStorageID storageID,
+									MtpObjectFormat format,
+									MtpObjectHandle parent) {
+	MTPD("storageID: %d\n", storageID);
+	MtpObjectHandleList* list = new MtpObjectHandleList();
+	list = storagemap[storageID]->getObjectList(storageID, parent);
+	MTPD("list: %d\n", list->size());
+	return list;
+}
+
+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;
+}
+
+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);
+	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]);
+	}
+	return list;
+}
+
+MtpObjectFormatList* MyMtpDatabase::getSupportedCaptureFormats() {
+	// Android OS implementation of this function returns NULL
+	// so we are not implementing this function either.
+	MTPD("MyMtpDatabase::getSupportedCaptureFormats returning NULL (This is what Android does as well).\n");
+	return NULL;
+}
+
+MtpObjectPropertyList* MyMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) {
+	int* properties;
+	MtpObjectPropertyList* list = new MtpObjectPropertyList();
+	properties = FILE_PROPERTIES;
+	int length = sizeof(FILE_PROPERTIES);
+	MTPD("MyMtpDatabase::getSupportedObjectProperties length is: %i, format: %x, sizeof: %i, forcing length to 10\n", length, format, sizeof(properties));
+	for (int i = 0; i < length; i++) {
+		MTPD("supported object property: %x\n", properties[i]);
+		list->push(properties[i]);
+	}
+	return list;
+}
+
+MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
+	int properties[] = {
+		MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,
+		MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,
+		MTP_DEVICE_PROPERTY_IMAGE_SIZE,
+	};
+	MtpDevicePropertyList* list = new MtpDevicePropertyList();
+	int length = sizeof(properties) / sizeof(int);
+	MTPD("MyMtpDatabase::getSupportedDeviceProperties length was: %i, forcing to 3\n", length);
+	length = 3;
+	for (int i = 0; i < length; i++)
+		list->push(properties[i]);
+	return list;
+}
+
+int* MyMtpDatabase::getSupportedObjectProperties(int format) {
+	switch (format) {
+		case MTP_FORMAT_MP3:
+		case MTP_FORMAT_WAV:
+		case MTP_FORMAT_WMA:
+		case MTP_FORMAT_OGG:
+		case MTP_FORMAT_AAC:
+			return AUDIO_PROPERTIES;
+		case MTP_FORMAT_MPEG:
+		case MTP_FORMAT_3GP_CONTAINER:
+		case MTP_FORMAT_WMV:
+			return VIDEO_PROPERTIES;
+		case MTP_FORMAT_EXIF_JPEG:
+		case MTP_FORMAT_GIF:
+		case MTP_FORMAT_PNG:
+		case MTP_FORMAT_BMP:
+			return IMAGE_PROPERTIES;
+		case 0:
+			return ALL_PROPERTIES;
+		default:
+			return FILE_PROPERTIES;
+	}
+}
+
+MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
+											MtpObjectProperty property,
+											MtpDataPacket& packet) {
+	MTPD("MyMtpDatabase::getObjectPropertyValue mtpid: %i, property: %x\n", handle, property);
+	int type;
+	MtpResponseCode result;
+	uint64_t longValue;
+	if (!getObjectPropertyInfo(property, type)) {
+		MTPE("MyMtpDatabase::setObjectPropertyValue 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) {
+			result = MTP_RESPONSE_OK;
+			break;
+		}
+	}
+
+	// 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) {
+		char date[20];
+		formatDateTime(longValue, date, sizeof(date));
+		packet.putString(date);
+		goto out;
+	}
+	// release date is stored internally as just the year
+	if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
+		char date[20];
+		snprintf(date, sizeof(date), "%04lld0101T000000", longValue);
+		packet.putString(date);
+		goto out;
+	}
+
+	switch (type) {
+		case MTP_TYPE_INT8:
+			packet.putInt8(longValue);
+			break;
+		case MTP_TYPE_UINT8:
+			packet.putUInt8(longValue);
+			break;
+		case MTP_TYPE_INT16:
+			packet.putInt16(longValue);
+			break;
+		case MTP_TYPE_UINT16:
+			packet.putUInt16(longValue);
+			break;
+		case MTP_TYPE_INT32:
+			packet.putInt32(longValue);
+			break;
+		case MTP_TYPE_UINT32:
+			packet.putUInt32(longValue);
+			break;
+		case MTP_TYPE_INT64:
+			packet.putInt64(longValue);
+			break;
+		case MTP_TYPE_UINT64:
+			packet.putUInt64(longValue);
+			break;
+		case MTP_TYPE_INT128:
+			packet.putInt128(longValue);
+			break;
+		case MTP_TYPE_UINT128:
+			packet.putInt128(longValue);
+			break;
+		case MTP_TYPE_STR:
+			{
+				/*std::string stringValue = (string)stringValuesArray[0];
+				if (stringValue) {
+					const char* str = stringValue.c_str();
+					if (str == NULL) {
+						return MTP_RESPONSE_GENERAL_ERROR;
+					}
+					packet.putString(str);
+				} else {
+					packet.putEmptyString();
+				}*/
+				MTPE("STRING unsupported type in getObjectPropertyValue\n");
+				result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
+				break;
+			}
+		default:
+			MTPE("unsupported type in getObjectPropertyValue\n");
+			result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
+	}
+out:
+	return result;
+}
+
+MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
+											MtpObjectProperty property,
+											MtpDataPacket& packet) {
+	int type;
+	MTPD("MyMtpDatabase::setObjectPropertyValue start\n");
+	if (!getObjectPropertyInfo(property, type)) {
+		MTPE("MyMtpDatabase::setObjectPropertyValue returning MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED\n");
+		return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
+	}
+	MTPD("MyMtpDatabase::setObjectPropertyValue continuing\n");
+	long longValue = 0;
+	std::string stringValue;
+
+	switch (type) {
+		case MTP_TYPE_INT8:
+			MTPD("int8\n");
+			longValue = packet.getInt8();
+			break;
+		case MTP_TYPE_UINT8:
+			MTPD("uint8\n");
+			longValue = packet.getUInt8();
+			break;
+		case MTP_TYPE_INT16:
+			MTPD("int16\n");
+			longValue = packet.getInt16();
+			break;
+		case MTP_TYPE_UINT16:
+			MTPD("uint16\n");
+			longValue = packet.getUInt16();
+			break;
+		case MTP_TYPE_INT32:
+			MTPD("int32\n");
+			longValue = packet.getInt32();
+			break;
+		case MTP_TYPE_UINT32:
+			MTPD("uint32\n");
+			longValue = packet.getUInt32();
+			break;
+		case MTP_TYPE_INT64:
+			MTPD("int64\n");
+			longValue = packet.getInt64();
+			break;
+		case MTP_TYPE_UINT64:
+			MTPD("uint64\n");
+			longValue = packet.getUInt64();
+			break;
+		case MTP_TYPE_STR:
+			{
+				MTPD("string\n");
+				MtpStringBuffer buffer;
+				packet.getString(buffer);
+				stringValue = (const char *)buffer;
+				break;
+			 }
+		default:
+			MTPE("MyMtpDatabase::setObjectPropertyValue unsupported type %i in getObjectPropertyValue\n", type);
+			return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
+	}
+
+	int result = MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
+
+	switch (property) {
+		case MTP_PROPERTY_OBJECT_FILE_NAME:
+			{
+				MTPD("MyMtpDatabase::setObjectPropertyValue renaming file, handle: %d, new name: '%s'\n", handle, stringValue.c_str());
+				std::map<int, MtpStorage*>::iterator storit;
+				for (storit = storagemap.begin(); storit != storagemap.end(); storit++) {
+					if (storit->second->renameObject(handle, stringValue) == 0) {
+						MTPD("MTP_RESPONSE_OK\n");
+						result = MTP_RESPONSE_OK;
+						break;
+					}
+				}
+			}
+			break;
+
+		default:
+			MTPE("MyMtpDatabase::setObjectPropertyValue property %x not supported.\n", property);
+			result = MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
+	}
+	MTPD("MyMtpDatabase::setObjectPropertyValue returning %d\n", result);
+	return result;
+}
+
+MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
+											MtpDataPacket& packet) {
+	int type, result = 0;
+	char prop_value[PROPERTY_VALUE_MAX];
+	MTPD("property %s\n",
+			MtpDebug::getDevicePropCodeName(property));
+	if (!getDevicePropertyInfo(property, type)) {
+		MTPE("MyMtpDatabase::getDevicePropertyValue MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED\n");
+		return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+	}
+	MTPD("property %s\n",
+			MtpDebug::getDevicePropCodeName(property));
+	MTPD("property %x\n", property);
+	MTPD("MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME %x\n", MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME); 
+	switch (property) {
+		case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
+		case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
+			result =  MTP_RESPONSE_OK;
+			break;
+		default:
+		{
+			MTPE("MyMtpDatabase::getDevicePropertyValue property %x not supported\n", property);
+			result = MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+			break;
+		}
+	}
+
+	if (result != MTP_RESPONSE_OK) {
+		MTPD("MTP_REPONSE_OK NOT OK\n");
+		return result;
+	}
+
+	long longValue = 0;
+	property_get("ro.build.product", prop_value, "unknown manufacturer");
+	switch (type) {
+		case MTP_TYPE_INT8: {
+			MTPD("MTP_TYPE_INT8\n");
+			packet.putInt8(longValue);
+			break;
+		}
+		case MTP_TYPE_UINT8:
+		{
+			MTPD("MTP_TYPE_UINT8\n");
+			packet.putUInt8(longValue);
+			break;
+		}
+		case MTP_TYPE_INT16:
+		{
+			MTPD("MTP_TYPE_INT16\n");
+			packet.putInt16(longValue);
+			break;
+		}
+		case MTP_TYPE_UINT16:
+		{
+			MTPD("MTP_TYPE_UINT16\n");
+			packet.putUInt16(longValue);
+			break;
+		}
+		case MTP_TYPE_INT32:
+		{
+			MTPD("MTP_TYPE_INT32\n");
+			packet.putInt32(longValue);
+			break;
+		}
+		case MTP_TYPE_UINT32:
+		{
+			MTPD("MTP_TYPE_UINT32\n");
+			packet.putUInt32(longValue);
+			break;
+		}
+		case MTP_TYPE_INT64:
+		{
+			MTPD("MTP_TYPE_INT64\n");
+			packet.putInt64(longValue);
+			break;
+		}
+		case MTP_TYPE_UINT64:
+		{
+			MTPD("MTP_TYPE_UINT64\n");
+			packet.putUInt64(longValue);
+			break;
+		}
+		case MTP_TYPE_INT128:
+		{
+			MTPD("MTP_TYPE_INT128\n");
+			packet.putInt128(longValue);
+			break;
+		}
+		case MTP_TYPE_UINT128:
+		{
+			MTPD("MTP_TYPE_UINT128\n");
+			packet.putInt128(longValue);
+			break;
+		}
+		case MTP_TYPE_STR:
+		{
+			MTPD("MTP_TYPE_STR\n");
+			char* str = prop_value;
+			packet.putString(str);
+			break;
+		 }
+		default:
+			MTPE("MyMtpDatabase::getDevicePropertyValue unsupported type %i in getDevicePropertyValue\n", type);
+			return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
+	}
+
+	return MTP_RESPONSE_OK;
+}
+
+MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property, MtpDataPacket& packet) {
+   	int type;
+	MTPE("MyMtpDatabase::setDevicePropertyValue not implemented, returning 0\n");
+	return 0;
+}
+
+MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
+	MTPE("MyMtpDatabase::resetDeviceProperty not implemented, returning -1\n");
+   	return -1;
+}
+
+MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle, uint32_t format, uint32_t property, int groupCode, int depth, MtpDataPacket& packet) {
+	MTPD("getObjectPropertyList()\n");
+	MTPD("property: %x\n", property);
+	std::map<int, MtpStorage*>::iterator storit;
+	for (storit = storagemap.begin(); storit != storagemap.end(); storit++) {
+		MTPD("MyMtpDatabase::getObjectPropertyList calling getObjectPropertyList\n");
+		if (storit->second->getObjectPropertyList(handle, format, property, groupCode, depth, packet) == 0) {
+			MTPD("MTP_RESPONSE_OK\n");
+   			return MTP_RESPONSE_OK;
+		}
+	}
+	MTPE("MyMtpDatabase::getObjectPropertyList MTP_RESPOSNE_INVALID_OBJECT_HANDLE %i\n", handle);
+	return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+}
+
+MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) {
+	std::map<int, MtpStorage*>::iterator storit;
+	for (storit = storagemap.begin(); storit != storagemap.end(); storit++) {
+		if (storit->second->getObjectInfo(handle, info) == 0) {
+			MTPD("MTP_RESPONSE_OK\n");
+			return MTP_RESPONSE_OK;
+		}
+	}
+	MTPE("MyMtpDatabase::getObjectInfo MTP_RESPONSE_INVALID_OBJECT_HANDLE %i\n", handle);
+	return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+}
+
+void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
+	MtpString path;
+	int64_t length;
+	MtpObjectFormat format;
+	void* result = NULL;
+	outThumbSize = 0;
+	MTPE("MyMtpDatabase::getThumbnail not implemented, returning 0\n");
+	return 0;
+}
+
+MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle, MtpString& outFilePath, int64_t& outFileLength, MtpObjectFormat& outFormat) {
+	std::map<int, MtpStorage*>::iterator storit;
+	for (storit = storagemap.begin(); storit != storagemap.end(); storit++) {
+		MTPD("MyMtpDatabase::getObjectFilePath calling getObhectFilePath\n");
+		if (storit->second->getObjectFilePath(handle, outFilePath, outFileLength, outFormat) == 0) {
+			MTPD("MTP_RESPONSE_OK\n");
+			return MTP_RESPONSE_OK;
+		}
+	}
+	MTPE("MyMtpDatabase::getObjectFilePath MTP_RESPOSNE_INVALID_OBJECT_HANDLE %i\n", handle);
+	return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+}
+
+MtpResponseCode MyMtpDatabase::deleteFile(MtpObjectHandle handle) {
+	MTPD("deleteFile\n");
+	std::map<int, MtpStorage*>::iterator storit;
+	for (storit = storagemap.begin(); storit != storagemap.end(); storit++) {
+		if (storit->second->deleteFile(handle) == 0) {
+			MTPD("MTP_RESPONSE_OK\n");
+			return MTP_RESPONSE_OK;
+		}
+	}
+	MTPE("MyMtpDatabase::deleteFile MTP_RESPONSE_INVALID_OBJECT_HANDLE %i\n", handle);
+	return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+}
+
+struct PropertyTableEntry {
+	MtpObjectProperty   property;
+	int				 type;
+};
+
+static const PropertyTableEntry   kObjectPropertyTable[] = {
+	{   MTP_PROPERTY_STORAGE_ID,		MTP_TYPE_UINT32	 },
+	{   MTP_PROPERTY_OBJECT_FORMAT,	 MTP_TYPE_UINT16	 },
+	{   MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16	 },
+	{   MTP_PROPERTY_OBJECT_SIZE,	   MTP_TYPE_UINT64	 },
+	{   MTP_PROPERTY_OBJECT_FILE_NAME,  MTP_TYPE_STR		},
+	{   MTP_PROPERTY_DATE_MODIFIED,	 MTP_TYPE_STR		},
+	{   MTP_PROPERTY_PARENT_OBJECT,	 MTP_TYPE_UINT32	 },
+	{   MTP_PROPERTY_PERSISTENT_UID,	MTP_TYPE_UINT128	},
+	{   MTP_PROPERTY_NAME,			  MTP_TYPE_STR		},
+	{   MTP_PROPERTY_DISPLAY_NAME,	  MTP_TYPE_STR		},
+	{   MTP_PROPERTY_DATE_ADDED,		MTP_TYPE_STR		},
+	{   MTP_PROPERTY_ARTIST,			MTP_TYPE_STR		},
+	{   MTP_PROPERTY_ALBUM_NAME,		MTP_TYPE_STR		},
+	{   MTP_PROPERTY_ALBUM_ARTIST,	  MTP_TYPE_STR		},
+	{   MTP_PROPERTY_TRACK,			 MTP_TYPE_UINT16	 },
+	{   MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR	},
+	{   MTP_PROPERTY_GENRE,			 MTP_TYPE_STR		},
+	{   MTP_PROPERTY_COMPOSER,		  MTP_TYPE_STR		},
+	{   MTP_PROPERTY_DURATION,		  MTP_TYPE_UINT32	 },
+	{   MTP_PROPERTY_DESCRIPTION,	   MTP_TYPE_STR		},
+};
+
+static const PropertyTableEntry   kDevicePropertyTable[] = {
+	{   MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,	MTP_TYPE_STR },
+	{   MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,	   MTP_TYPE_STR },
+	{   MTP_DEVICE_PROPERTY_IMAGE_SIZE,				 MTP_TYPE_STR },
+};
+
+bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
+	int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]);
+	const PropertyTableEntry* entry = kObjectPropertyTable;
+	MTPD("MyMtpDatabase::getObjectPropertyInfo size is: %i\n", count);
+	for (int i = 0; i < count; i++, entry++) {
+		if (entry->property == property) {
+			type = entry->type;
+			return true;
+		}
+	}
+	return false;
+}
+
+bool MyMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) {
+	int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]);
+	const PropertyTableEntry* entry = kDevicePropertyTable;
+	MTPD("MyMtpDatabase::getDevicePropertyInfo count is: %i\n", count);
+	for (int i = 0; i < count; i++, entry++) {
+		if (entry->property == property) {
+			type = entry->type;
+			MTPD("type: %x\n", type);
+			return true;
+		}
+	}
+	return false;
+}
+
+MtpObjectHandleList* MyMtpDatabase::getObjectReferences(MtpObjectHandle handle) {
+	// call function and place files with associated handles into int array
+	MTPD("MyMtpDatabase::getObjectReferences returning null, this seems to be what Android always does.\n");
+	MTPD("handle: %d\n", handle);
+	// Windows + Android seems to always return a NULL in this function, c == null path
+	// The way that this is handled in Android then is to do this:
+	return NULL;
+}
+
+MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
+													MtpObjectHandleList* references) {
+	int count = references->size();
+	MTPE("MyMtpDatabase::setObjectReferences not implemented, returning 0\n");
+	return 0;
+}
+
+MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
+											MtpObjectFormat format) {
+	MTPD("MyMtpDatabase::getObjectPropertyDesc start\n");
+	MtpProperty* result = NULL;
+	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:
+		case MTP_PROPERTY_DISPLAY_NAME:
+		case MTP_PROPERTY_ARTIST:
+		case MTP_PROPERTY_ALBUM_NAME:
+		case MTP_PROPERTY_ALBUM_ARTIST:
+		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;
+	}
+	return result;
+}
+
+MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
+	MtpProperty* result = NULL;
+	int ret;
+	bool writable = true;
+	switch (property) {
+		case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
+		case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
+			ret = MTP_RESPONSE_OK;
+			// 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) {
+				MTPD("here\n");
+				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;
+			break;
+		}
+
+	return result;
+}
+
+void MyMtpDatabase::sessionStarted() {
+	MTPD("MyMtpDatabase::sessionStarted not implemented or does nothing, returning\n");
+	return;
+}
+
+void MyMtpDatabase::sessionEnded() {
+	MTPD("MyMtpDatabase::sessionEnded not implemented or does nothing, returning\n");
+	return;
+}
+
+// ----------------------------------------------------------------------------
+
+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++) {
+		storit->second->lockMutex(0);
+	}
+}
+
+void MyMtpDatabase::unlockMutex(void) {
+	std::map<int, MtpStorage*>::iterator storit;
+	for (storit = storagemap.begin(); storit != storagemap.end(); storit++) {
+		storit->second->unlockMutex(0);
+	}
+}
